From 876a5e6657d67df66bb525d02dd6d147ba81cae5 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 05 一月 2023 09:53:37 +0800
Subject: [PATCH] 2023-01-05

---
 src/views/systemproc/proc/index.jsx                                                |  363 +++
 src/templates/zshare/modalform/index.jsx                                           |    2 
 src/mob/header/index.jsx                                                           |   16 
 src/tabviews/custom/components/iframe/index.scss                                   |   26 
 src/mob/mobshell/index.jsx                                                         |    1 
 src/menu/components/card/cardcellcomponent/elementform/index.jsx                   |    3 
 src/templates/sharecomponent/actioncomponent/verifyprint/editable/index.jsx        |   17 
 src/menu/components/table/edit-table/options.jsx                                   |   13 
 src/views/systemfunc/index.jsx                                                     |    5 
 src/menu/tablenodes/index.scss                                                     |    9 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx               |    8 
 src/assets/css/main.scss                                                           |   28 
 src/tabviews/custom/components/table/edit-table/index.scss                         |    1 
 src/menu/components/form/formaction/formconfig.jsx                                 |    1 
 src/menu/components/card/cardsimplecomponent/index.scss                            |   15 
 src/menu/components/card/table-card/index.scss                                     |   12 
 src/components/header/index.scss                                                   |   53 
 src/tabviews/custom/components/card/cardcellList/index.jsx                         |   48 
 src/tabviews/custom/components/card/prop-card/index.jsx                            |   14 
 src/menu/components/card/cardcellcomponent/index.jsx                               |    2 
 src/menu/components/card/data-card/options.jsx                                     |    8 
 src/tabviews/custom/components/table/edit-table/normalTable/index.jsx              |    7 
 src/tabviews/zshare/mutilform/index.jsx                                            |    8 
 src/views/systemproc/proc/index.scss                                               |   91 
 src/menu/components/share/actioncomponent/actionform/index.jsx                     |    8 
 src/mob/components/menubar/normal-menubar/index.scss                               |   10 
 src/menu/components/table/edit-table/columns/index.scss                            |    6 
 src/tabviews/custom/index.jsx                                                      |   11 
 src/pc/components/navbar/normal-navbar/index.scss                                  |   13 
 src/menu/components/card/cardcomponent/index.scss                                  |   18 
 src/pc/components/login/normal-login/signform.jsx                                  |   11 
 src/mob/components/menubar/common-menubar/index.scss                               |   12 
 src/menu/components/table/normal-table/columns/index.jsx                           |    8 
 src/views/appmanage/submutilform/index.jsx                                         |   17 
 src/tabviews/zshare/cardcomponent/index.jsx                                        |    1 
 src/menu/components/table/edit-table/columns/index.jsx                             |    8 
 src/menu/components/module/voucher/voucherTable/index.scss                         |  259 ++
 src/assets/css/viewstyle.scss                                                      |  339 --
 src/menu/components/card/cardcellcomponent/dragaction/index.scss                   |    6 
 src/assets/mobimg/account.png                                                      |    0 
 src/tabviews/custom/components/module/account/index.jsx                            |  148 +
 src/tabviews/zshare/topSearch/index.jsx                                            |    6 
 src/menu/components/form/tab-form/index.scss                                       |   14 
 src/tabviews/custom/components/chart/antv-G6/index.jsx                             |   93 
 src/menu/components/card/prop-card/index.scss                                      |   12 
 src/pc/menushell/index.jsx                                                         |    3 
 src/tabviews/zshare/actionList/exceloutbutton/index.jsx                            |    2 
 src/menu/components/card/cardcellcomponent/dragaction/card.jsx                     |   15 
 src/menu/components/card/balcony/index.scss                                        |   12 
 src/views/design/sidemenu/index.scss                                               |    2 
 src/tabviews/zshare/actionList/index.jsx                                           |   33 
 src/api/index.js                                                                   |    2 
 src/templates/sharecomponent/actioncomponent/verifyprint/utils.jsx                 |   77 
 src/tabviews/custom/components/iframe/index.jsx                                    |   46 
 src/menu/components/module/voucher/options.jsx                                     |   42 
 src/menu/components/table/base-table/columns/index.scss                            |    5 
 src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx                 |  559 +++++
 src/tabviews/custom/components/table/base-table/index.scss                         |    1 
 src/tabviews/zshare/tablenodes/index.jsx                                           |   61 
 src/tabviews/zshare/mutilform/mkCheckCard/index.jsx                                |    2 
 src/pc/components/login/normal-login/loginform.jsx                                 |   11 
 src/menu/components/card/cardsimplecomponent/index.jsx                             |    2 
 src/menu/components/search/main-search/index.jsx                                   |   10 
 src/tabviews/custom/components/module/account/index.scss                           |   27 
 src/tabviews/custom/components/module/voucher/voucherTable/index.jsx               |   21 
 src/views/login/index.scss                                                         |   30 
 src/menu/components/module/account/index.jsx                                       |  147 +
 src/menu/components/module/account/options.jsx                                     |   61 
 src/menu/components/module/account/index.scss                                      |   52 
 src/pc/components/login/normal-login/index.scss                                    |   14 
 src/components/keyInterface/index.jsx                                              |    8 
 src/menu/components/share/searchcomponent/index.jsx                                |   10 
 src/utils/utils-custom.js                                                          |   27 
 src/views/main/index.jsx                                                           |    2 
 src/templates/comtableconfig/updatetable/index.jsx                                 |    6 
 src/tabviews/custom/components/share/normalTable/index.scss                        |    7 
 src/pc/components/login/normal-login/options.jsx                                   |   21 
 src/templates/modalconfig/checkCard/index.jsx                                      |    2 
 src/menu/components/module/voucher/index.jsx                                       |   38 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx              |   18 
 src/menu/tablenodes/index.jsx                                                      |   55 
 src/menu/components/card/data-card/index.scss                                      |   12 
 src/menu/components/form/step-form/index.scss                                      |   14 
 src/menu/components/iframe/index.scss                                              |    3 
 src/menu/menushell/card.jsx                                                        |    3 
 src/menu/components/iframe/options.jsx                                             |   13 
 src/views/mobdesign/index.jsx                                                      |   52 
 src/tabviews/custom/components/table/normal-table/index.scss                       |    1 
 src/views/menudesign/index.jsx                                                     |    3 
 src/menu/modulesource/option.jsx                                                   |    6 
 src/views/design/index.scss                                                        |   18 
 src/tabviews/custom/components/module/voucher/index.jsx                            |   81 
 src/templates/zshare/modalform/datatable/index.jsx                                 |   13 
 src/menu/components/share/actioncomponent/formconfig.jsx                           |    5 
 src/templates/sharecomponent/actioncomponent/actionform/index.jsx                  |    2 
 src/views/main/index.scss                                                          |    5 
 src/views/systemfunc/index.scss                                                    |    6 
 src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx                      |    2 
 src/menu/components/table/base-table/columns/index.jsx                             |   64 
 src/views/appmanage/index.jsx                                                      |    7 
 src/menu/components/carousel/data-card/index.scss                                  |   12 
 src/tabviews/zshare/tablenodes/index.scss                                          |    9 
 src/templates/sharecomponent/searchcomponent/index.scss                            |    3 
 src/templates/sharecomponent/searchcomponent/searchform/index.jsx                  |    2 
 src/components/tabview/index.jsx                                                   |    5 
 src/tabviews/zshare/actionList/index.scss                                          |   31 
 src/menu/components/form/simple-form/index.scss                                    |   14 
 src/views/design/index.jsx                                                         |    2 
 src/menu/components/timeline/normal-timeline/index.scss                            |   13 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx |  190 +-
 src/menu/components/carousel/prop-card/index.scss                                  |   12 
 src/menu/components/chart/antv-G6/index.jsx                                        |  102 
 src/menu/components/table/normal-table/options.jsx                                 |   25 
 src/components/sidemenu/index.scss                                                 |   50 
 src/views/mobdesign/menuform/index.jsx                                             |   12 
 src/templates/sharecomponent/searchcomponent/index.jsx                             |   10 
 src/tabviews/custom/components/share/normalTable/index.jsx                         |    7 
 src/menu/components/table/normal-table/columns/index.scss                          |    6 
 src/menu/components/search/main-search/index.scss                                  |    3 
 src/utils/utils.js                                                                 |   14 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx              |   64 
 src/index.js                                                                       |    7 
 src/templates/zshare/formconfig.jsx                                                |   14 
 src/menu/components/table/base-table/options.jsx                                   |   24 
 src/tabviews/custom/components/module/voucher/voucherTable/index.scss              |  100 
 src/templates/zshare/verifycard/index.jsx                                          |    6 
 src/menu/modulecell/index.jsx                                                      |    1 
 src/tabviews/zshare/actionList/printbutton/index.jsx                               |  620 ++++-
 src/tabviews/custom/components/table/edit-table/normalTable/index.scss             |    7 
 src/templates/sharecomponent/actioncomponent/verifyprint/index.scss                |   51 
 src/menu/components/card/cardcellcomponent/formconfig.jsx                          |    1 
 src/menu/components/module/voucher/voucherTable/index.jsx                          |  362 +++
 src/templates/sharecomponent/actioncomponent/index.jsx                             |    3 
 src/tabviews/custom/components/module/voucher/index.scss                           |   31 
 src/assets/mobimg/voucher.png                                                      |    0 
 src/menu/components/module/voucher/index.scss                                      |   97 
 src/tabviews/custom/components/card/cardcellList/index.scss                        |    8 
 src/menu/components/table/base-table/index.jsx                                     |   33 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/datasource/index.jsx   |   22 
 src/menu/menushell/index.jsx                                                       |    1 
 140 files changed, 4,078 insertions(+), 1,388 deletions(-)

diff --git a/src/api/index.js b/src/api/index.js
index 12f10a6..aeead48 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -12,7 +12,7 @@
 window.GLOB.WebSql = null
 window.GLOB.IndexDB = null
 window.GLOB.OuterToken = {}
-const systemMenuKeys = `1581067625930haged11ieaivpavv77k,1581734956310scks442ul2d955g9tu5,1583991994144ndddg0bhh0is6shi0v1,1583979633842550imkchl4qt4qppsiv,1578900109100np8aqd0a77q3na46oas,
+const systemMenuKeys = `1581067625930haged11ieaivpavv77k,1581734956310scks442ul2d955g9tu5,1583991994144ndddg0bhh0is6shi0v1,1583979633842550imkchl4qt4qppsiv,
   1585192949946f3et2ts8tn82krmumdf,15855615451212m12ip23vpcm79kloro,1587005717541lov40vg61q7l1rbveon,1590458676585agbbr63t6ihighg2i1g,1602315375262ikd33ii0nii34pt861o,1582771068837vsv54a089lgp45migbg,
   1582777675954ifu05upurs465omoth7,158294809668898cklbv6c5bou8e1fpu,1584676379094iktph45fb8imhg96bql,1584695125339vo5g7iqgfn01qmrd6s2,1584699661372vhmpp9dn9foo0eob722,15848421131551gg04ie8sitsd3f7467,
   1589782279158ngr675kk3oksin35sul,1589788042787ffdt9hle4s45k9r1nvs,1594095599055qicg2eb642v5qglhnuo,1577972969199lei1g0qkvlh4tkc908m,16044812935562g807p3p12huk8kokmb,
diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss
index 3e21319..630b514 100644
--- a/src/assets/css/main.scss
+++ b/src/assets/css/main.scss
@@ -36,11 +36,9 @@
 
 /*鑳屾櫙鑹�*/
 html, body {
+  --mk-sys-color: #1890ff;
   width: 100%;
   font-size: 14px;
-  // .ant-table, .ant-dropdown {
-  //   color: rgba(0, 0, 0, 0.85);
-  // }
 }
 #root {
   height: 100%;
@@ -180,9 +178,9 @@
   z-index: 1090!important;
 }
 
-.ant-dropdown {
-  z-index: 1090!important;
-}
+// .ant-dropdown {
+//   z-index: 1090!important;
+// }
 
 .mk-normal-dropdown {
   .ant-dropdown-menu {
@@ -472,4 +470,22 @@
   .video-react .video-react-poster {
     background-size: cover;
   }
+}
+
+.table-vertical-top {
+  table td {
+    vertical-align: top;
+  }
+}
+.table-vertical-bottom {
+  table td {
+    vertical-align: bottom;
+  }
+}
+
+// 绯荤粺鑹茶缃�
+.mk-main-view {
+  display: flex;
+  flex: auto;
+  min-height: 100%;
 }
\ No newline at end of file
diff --git a/src/assets/css/viewstyle.scss b/src/assets/css/viewstyle.scss
index 0f54397..e3460e3 100644
--- a/src/assets/css/viewstyle.scss
+++ b/src/assets/css/viewstyle.scss
@@ -1,6 +1,3 @@
-// bg1     涓昏儗鏅壊
-// bg2     娆¤儗鏅壊
-// font1   涓诲瓧浣撻鑹�
 // color1  1闃惰壊 - 搴曡壊
 // color2  2闃惰壊
 // color3  3闃惰壊
@@ -11,142 +8,8 @@
 // color8  8闃惰壊
 // color9  9闃惰壊
 // color10 10闃惰壊
-@mixin viewstyle($bg1, $bg2, $font1, $font2, $color1, $color2, $color3, $color4, $color5, $color6, $color7, $color8, $color9, $color10) {
-  .login-container {
-    background-color: $bg1;
-    .logo {
-      border-color: $color6;
-      .plat-name {
-        color: $font1;
-      }
-    }
-    .login-middle {
-      border-color: $color6;
-      .login-form-button {
-        background-color: $color6;
-        border-color: $color6;
-      }
-      .login-form-button[disabled] {
-        background-color: $color5;
-        border-color: $color5;
-      }
-      button.vercode {
-        color: $color6;
-      }
-      .login-way-wrap {
-        .login-way.active, .login-way:hover {
-          color: $color6;
-        }
-      }
-      .anticon-eye {
-        color: $color6;
-      }
-    }
-    .login-bottom {
-      color: $font1;
-      a {
-        color: $font1;
-      }
-    }
-  }
-
-  .menu-board {
-    .menu-wrap {
-      .title {
-        color: $color6;
-      }
-      .menu-detail {
-        div:hover {
-          color: $color5;
-        }
-      }
-    }
-  }
-
+@mixin viewstyle($color1, $color2, $color3, $color4, $color5, $color6, $color7) {
   #root > .mk-main-view {
-    > .header-container {
-      background: $bg1;
-      color: $font1;
-      box-shadow: 0 1px 1px #d9d9d9;
-
-      .header-setting span {
-        color: $font1;
-      }
-      > .header-collapse .anticon {
-        color: $font1;
-      }
-      > .header-menu {
-        li {
-          span {
-            color: $font1;
-          }
-    
-          &:hover {
-            span {
-              color: $color6;
-              border-bottom: 4px solid $color6;
-            }
-          }
-          &.active {
-            span {
-              color: $color6;
-              border-bottom: 4px solid $color6;
-            }
-          }
-        }
-      }
-    }
-    > .mk-side-menu {
-      border-right: 1px solid #d9d9d9;
-      background: $bg1;
-      > .ant-menu {
-        background: $bg1;
-        > .ant-menu-submenu {
-          color: $font1;
-          background: transparent;
-          > .ant-menu-submenu-title {
-            &:hover {
-              color: $font1;
-            }
-            > .ant-menu-submenu-arrow:before {
-              background: $font1;
-            }
-            > .ant-menu-submenu-arrow:after {
-              background: $font1;
-            }
-          }
-          > .ant-menu-sub {
-            background: transparent;
-            box-shadow: none;
-            .ant-menu-item {
-              a {
-                color: $font2;
-              }
-            }
-          }
-        }
-        > .ant-menu-submenu.ant-menu-submenu-open {
-          > .ant-menu-submenu-title {
-            background: $bg2;
-          }
-        }
-      }
-    }
-    > .mk-side-menu:not(.edit) {
-      > .ant-menu {
-        > .ant-menu-submenu {
-          > .ant-menu-sub {
-            .ant-menu-item.ant-menu-item-active, .ant-menu-item.ant-menu-item-selected {
-              background: $color5;
-              color: #ffffff;
-              a {
-                color: #ffffff;
-              }
-            }
-          }
-        }
-      }
-    }
     >.mk-tabview-wrap {
       >.content-header {
         >.ant-tabs {
@@ -444,11 +307,7 @@
   .system-color {
     color: $color6;
   }
-  .system-background {
-    background: $color6;
-    border-color: $color6;
-    color: #ffffff;
-  }
+  
   .ant-timeline.system {
     .ant-timeline-item-tail {
       border-color: $color2;
@@ -497,6 +356,11 @@
       }
     }
   }
+  .ant-spin {
+    .ant-spin-dot-item {
+      background-color: $color6;
+    }
+  }
 }
 
 body.hidden-split-line #root { // 鍘婚櫎鐧诲綍椤靛垎鍓茬嚎
@@ -510,152 +374,99 @@
   }
 }
 
-@mixin bgblack() {
-  #root > .mk-main-view {
-    > .header-container {
-      box-shadow: none;
-      > .header-menu {
-        li {
-          &:hover, &.active {
-            span {
-              color: #ffffff;
-            }
-          }
-        }
-      }
-      .header-menu::-webkit-scrollbar-track {
-        box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.05);
-        border: 1px solid rgba(255, 255, 255, 0.07);
-        background: rgba(255, 255, 255, 255);
-        border-radius: 3px;
-      }
-    }
-  }
+// 鐨偆鑳屾櫙涓庡瓧浣撻鑹�
+body[class*='-black'] {
+  --mk-sys-background: #000000;
+  --mk-sys-light-background: #434343;
+  --mk-sys-font-color: rgba(255, 255, 255, 0.85);
+  --mk-sys-light-font-color: rgba(255, 255, 255, 0.65);
+}
+body[class*='-white'] {
+  --mk-sys-background: #ffffff;
+  --mk-sys-light-background: #ffffff;
+  --mk-sys-font-color: rgba(0, 0, 0, 0.85);
+  --mk-sys-light-font-color: rgba(0, 0, 0, 0.65);
+}
+body[class*='mk-blue-'] {
+  --mk-sys-color: #1890ff;
+  --mk-sys-color5: #40a9ff;
+  @include viewstyle(#e6f7ff, #bae7ff, #91d5ff, #69c0ff, #40a9ff, #1890ff, #096dd9);
 }
 
-body.mk-blue-black {
-  --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 {
-  --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 {
+body[class*='mk-red-'] {
   --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();
+  --mk-sys-color5: #ff4d4f;
+  @include viewstyle(#fff1f0, #ffccc7, #ffa39e, #ff7875, #ff4d4f, #f5222d, #cf1322);
 }
-body.mk-red-white {
-  --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 {
+
+body[class*='mk-orange-red-'] {
   --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();
+  --mk-sys-color5: #ff7a45;
+  @include viewstyle(#fff2e8, #ffd8bf, #ffbb96, #ff9c6e, #ff7a45, #fa541c, #d4380d);
 }
-body.mk-orange-red-white {
-  --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 {
+
+body[class*='mk-orange-'] {
   --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();
+  --mk-sys-color5: #ffa940;
+  @include viewstyle(#fff7e6, #ffe7ba, #ffd591, #ffc069, #ffa940, #fa8c16, #d46b08);
 }
-body.mk-orange-white {
-  --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 {
+
+body[class*='mk-orange-yellow-'] {
   --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();
+  --mk-sys-color5: #ffc53d;
+  @include viewstyle(#fffbe6, #fff1b8, #ffe58f, #ffd666, #ffc53d, #faad14, #d48806);
 }
-body.mk-orange-yellow-white {
-  --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 {
+
+body[class*='mk-yellow-'] {
   --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();
+  --mk-sys-color5: #ffec3d;
+  @include viewstyle(#feffe6, #ffffb8, #fffb8f, #fff566, #ffec3d, #fadb14, #d4b106);
 }
-body.mk-yellow-white {
-  --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 {
+
+body[class*='mk-yellow-green-'] {
   --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();
+  --mk-sys-color5: #bae637;
+  @include viewstyle(#fcffe6, #f4ffb8, #eaff8f, #d3f261, #bae637, #a0d911, #7cb305);
 }
-body.mk-yellow-green-white {
-  --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 {
+
+body[class*='mk-green-'] {
   --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();
+  --mk-sys-color5: #73d13d;
+  @include viewstyle(#f6ffed, #d9f7be, #b7eb8f, #95de64, #73d13d, #52c41a, #389e0d);
 }
-body.mk-green-white {
-  --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 {
+
+body[class*='mk-cyan-'] {
   --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();
+  --mk-sys-color5: #36cfc9;
+  @include viewstyle(#e6fffb, #b5f5ec, #87e8de, #5cdbd3, #36cfc9, #13c2c2, #08979c);
 }
-body.mk-cyan-white {
-  --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 {
+
+body[class*='mk-blue-purple-'] {
   --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();
+  --mk-sys-color5: #597ef7;
+  @include viewstyle(#f0f5ff, #d6e4ff, #adc6ff, #85a5ff, #597ef7, #2f54eb, #1d39c4);
 }
-body.mk-blue-purple-white {
-  --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 {
+
+body[class*='mk-purple-'] {
   --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();
+  --mk-sys-color5: #9254de;
+  @include viewstyle(#f9f0ff, #efdbff, #d3adf7, #b37feb, #9254de, #722ed1, #531dab);
 }
-body.mk-purple-white {
-  --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 {
+
+body[class*='mk-magenta-'] {
   --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();
+  --mk-sys-color5: #f759ab;
+  @include viewstyle(#fff0f6, #ffd6e7, #ffadd2, #ff85c0, #f759ab, #eb2f96, #c41d7f);
 }
-body.mk-magenta-white {
-  --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 {
+
+body[class*='mk-grass-green-'] {
   --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();
+  --mk-sys-color5: #bfbf22;
+  @include viewstyle(#f2efda, #e6de97, #d9d26c, #ccc845, #bfbf22, #aeb303, #838c00);
 }
-body.mk-grass-green-white {
-  --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 {
+
+body[class*='mk-deep-red-'] {
   --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 {
-  --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);
+  --mk-sys-color5: #cf4856;
+  @include viewstyle(#fff0f0, #f5cbcb, #e89b9e, #db7077, #cf4856, #c32539, #9c162c);
 }
diff --git a/src/assets/mobimg/account.png b/src/assets/mobimg/account.png
new file mode 100644
index 0000000..e84dc74
--- /dev/null
+++ b/src/assets/mobimg/account.png
Binary files differ
diff --git a/src/assets/mobimg/voucher.png b/src/assets/mobimg/voucher.png
new file mode 100644
index 0000000..229323c
--- /dev/null
+++ b/src/assets/mobimg/voucher.png
Binary files differ
diff --git a/src/components/header/index.scss b/src/components/header/index.scss
index 0c8a8d0..913208f 100644
--- a/src/components/header/index.scss
+++ b/src/components/header/index.scss
@@ -7,6 +7,8 @@
   width: 100%;
   height: 48px;
   display: flex;
+  background: var(--mk-sys-background);
+  color: var(--mk-sys-font-color);
 
   .header-logo {
     width: 180px;
@@ -39,7 +41,7 @@
       position: relative;
       top: 3px;
       font-size: 20px;
-      color: #ffffff;
+      color: var(--mk-sys-font-color);
     }
   }
   .header-collapse.collapse {
@@ -62,18 +64,21 @@
         padding: 0 10px;
         height: 42px;
         display: inline-block;
+        color: var(--mk-sys-font-color);
       }
 
       &:hover {
         color: #eeeeee;
         span {
-          border-bottom: 4px solid #fafcfb;
+          color: var(--mk-sys-color);
+          border-bottom: 4px solid var(--mk-sys-color);
         }
       }
       &.active {
         color: #ffffff;
         span {
-          border-bottom: 4px solid #1890ff;
+          color: var(--mk-sys-color);
+          border-bottom: 4px solid var(--mk-sys-color);
         }
       }
     }
@@ -95,9 +100,9 @@
     border-radius: 5px;
   }
   .header-menu::-webkit-scrollbar-track {
-    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
-    border: 1px solid rgba(0, 0, 0, 0.07);
-    background: rgba(0, 0, 0, 0);
+    box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.05);
+    border: 1px solid rgba(255, 255, 255, 0.07);
+    background: rgba(255, 255, 255, 255);
     border-radius: 3px;
   }
 
@@ -111,7 +116,7 @@
       margin-right: 7px;
     }
     span {
-      color: #ffffff;
+      color: var(--mk-sys-font-color);
       font-size: 0.95rem;
       .username {
         vertical-align: middle;
@@ -216,7 +221,7 @@
   // left: 11.8%;
   .menu-wrap {
     .title {
-      color: #1890ff;
+      color: var(--mk-sys-color);
       font-size: 15px;
       font-weight: 600;
     }
@@ -224,18 +229,14 @@
       max-width: 60vw;
       padding: 5px 0 5px 15px;
       div {
-        // float: left;
         display: inline-block;
         vertical-align: top;
         margin-bottom: 8px;
         width: 120px;
-        // overflow: hidden;
-        // white-space: nowrap;
-        // text-overflow: ellipsis;
         cursor: pointer;
       }
       div:hover {
-        color: #40a9ff;
+        color: var(--mk-sys-color5);
       }
       div:not(:last-child) {
         margin-right: 15px;
@@ -247,4 +248,30 @@
       clear: both;
     }
   }
+}
+
+body[class*='-white'] {
+  .header-container {
+    box-shadow: 0 1px 1px #d9d9d9;
+
+    .header-menu::-webkit-scrollbar-track {
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+      border: 1px solid rgba(0, 0, 0, 0.07);
+      background: rgba(0, 0, 0, 0);
+      border-radius: 3px;
+    }
+  }
+}
+body[class*='-black'] {
+  .header-container {
+    .header-menu {
+      li {
+        &:hover, &.active {
+          span {
+            color: #ffffff;
+          }
+        }
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/components/keyInterface/index.jsx b/src/components/keyInterface/index.jsx
index 517b091..11a459d 100644
--- a/src/components/keyInterface/index.jsx
+++ b/src/components/keyInterface/index.jsx
@@ -57,7 +57,7 @@
       }
     }
 
-    this.setState({visible: true, setting: _setting || {}})
+    this.setState({visible: true, setting: _setting || {ssoInterface: 'http://sso.mk9h.cn/cloud/webapi/dostars'}})
   }
 
   decrypt = (token, value) => {
@@ -193,7 +193,7 @@
             <Form>
               <Form.Item label="鎺ュ彛鍦板潃">
                 {getFieldDecorator('interface', {
-                  initialValue: setting.interface,
+                  initialValue: setting.interface || 'http://******/webapi/dostars',
                   rules: [
                     {
                       required: true,
@@ -204,7 +204,7 @@
                       message: '鍙彲浣跨敤鑻辨枃銆佹暟瀛椾互鍙�:_./'
                     }
                   ]
-                })(<TextArea rows={2}/>)}
+                })(<TextArea placeholder="http://******/webapi/dostars" rows={2}/>)}
               </Form.Item>
               <Form.Item label="sso鍦板潃">
                 {getFieldDecorator('ssoInterface', {
@@ -215,7 +215,7 @@
                       message: '鍙彲浣跨敤鑻辨枃銆佹暟瀛椾互鍙�:_./'
                     }
                   ]
-                })(<TextArea rows={2}/>)}
+                })(<TextArea placeholder="http://sso.mk9h.cn/cloud/webapi/dostars" rows={2}/>)}
               </Form.Item>
               <Form.Item label="appkey">
                 {getFieldDecorator('appkey', {
diff --git a/src/components/sidemenu/index.scss b/src/components/sidemenu/index.scss
index c9b71c5..b92ca04 100644
--- a/src/components/sidemenu/index.scss
+++ b/src/components/sidemenu/index.scss
@@ -1,10 +1,12 @@
-@import '../../assets/css/iconfont.css';
+// @import '../../assets/css/iconfont.css';
 
 .mk-side-menu {
   flex: 0 0 235px;
   width: 235px;
   padding: 48px 0 40px;
   transition: width 0.2s, flex 0.2s;
+  border-right: 1px solid #d9d9d9;
+  background: var(--mk-sys-background);
   .ant-menu-item {
     padding-left: 0!important;
     cursor: default;
@@ -29,12 +31,6 @@
     .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;
@@ -92,6 +88,46 @@
     width: 48px;
     left: 187px;
   }
+
+  > .ant-menu {
+    background: var(--mk-sys-background);
+    > .ant-menu-submenu {
+      color: var(--mk-sys-font-color);
+      background: transparent;
+      > .ant-menu-submenu-title {
+        &:hover {
+          color: var(--mk-sys-font-color);
+        }
+        > .ant-menu-submenu-arrow:before {
+          background: var(--mk-sys-font-color);
+        }
+        > .ant-menu-submenu-arrow:after {
+          background: var(--mk-sys-font-color);
+        }
+      }
+      > .ant-menu-sub {
+        background: transparent;
+        box-shadow: none;
+        .ant-menu-item {
+          a {
+            color: var(--mk-sys-light-font-color);
+          }
+        }
+        .ant-menu-item.ant-menu-item-active, .ant-menu-item.ant-menu-item-selected {
+          background: var(--mk-sys-color5);
+          color: #ffffff;
+          a {
+            color: #ffffff;
+          }
+        }
+      }
+    }
+    > .ant-menu-submenu.ant-menu-submenu-open {
+      > .ant-menu-submenu-title {
+        background: var(--mk-sys-light-background);
+      }
+    }
+  }
 }
 
 // .mk-side-menu.mk-iframe { // tab椤典腑涓篿frame鏃�
diff --git a/src/components/tabview/index.jsx b/src/components/tabview/index.jsx
index 2d23bc8..d6f95ae 100644
--- a/src/components/tabview/index.jsx
+++ b/src/components/tabview/index.jsx
@@ -264,11 +264,11 @@
     const { tabviews, activeId } = this.state
 
     return (
-      <section id="mk-tabview-wrap" className={'mk-tabview-wrap' + (this.props.collapse ? ' collapsed' : '') + (tabviews && tabviews.length > 0 ? ' hastab' : '')}>
+      <section className={'mk-tabview-wrap' + (this.props.collapse ? ' collapsed' : '')}>
         <div className="content-header">
           {tabviews && tabviews.length > 0 &&
             <Tabs activeKey={activeId}>
-              {tabviews.map((view, index) => {
+              {tabviews.map(view => {
                 return (
                   <Tabs.TabPane
                     tab={
@@ -292,7 +292,6 @@
                         </div>
                       </div>
                     </BackTop>
-                    {/* {options.sysType === 'local' && window.GLOB.systemType !== 'production' ? <div className="mk-water-mark">娴嬭瘯绯荤粺</div> : null} */}
                   </Tabs.TabPane>
                 )
               })}
diff --git a/src/index.js b/src/index.js
index 97fbbe4..278a82b 100644
--- a/src/index.js
+++ b/src/index.js
@@ -8,7 +8,7 @@
 import options, { styles } from '@/store/options.js'
 import '@/assets/css/main.scss'
 import '@/assets/css/action.scss'
-import '@/assets/css/minkeicon.css'
+// import '@/assets/css/minkeicon.css'
 import '@/assets/css/viewstyle.scss'
 
 if (window.location.href.indexOf('#/design') > -1) { // 缂栬緫椤甸潰鍒锋柊鏃讹紝璺宠浆鑷充富椤�
@@ -156,6 +156,7 @@
     let _systemMsg = localStorage.getItem(_href + 'system')
 
     GLOB.navBar = 'shutter' // 榛樿涓虹櫨鍙剁獥
+    let className = 'mk-blue-black'
 
     if (_systemMsg) {
       try {
@@ -184,13 +185,15 @@
           document.getElementsByTagName('head')[0].appendChild(link)
         }
         if (GLOB.style && styles[GLOB.style]) {
-          document.body.className = styles[GLOB.style] + ' ' + (GLOB.showline === 'false' ? 'hidden-split-line' : '')
+          className = styles[GLOB.style] + ' ' + (GLOB.showline === 'false' ? 'hidden-split-line' : '')
         }
       } catch (e) {
         console.warn('Parse Failure')
       }
     }
 
+    document.body.className = className
+
     if (/^https/.test(window.location.protocol) || (process.env.NODE_ENV !== 'production' && /^https/.test(config.host))) { // https杞崲
       let meta = document.createElement('meta')
       meta.content = 'upgrade-insecure-requests'
diff --git a/src/menu/components/card/balcony/index.scss b/src/menu/components/card/balcony/index.scss
index 7253e9b..6d5f095 100644
--- a/src/menu/components/card/balcony/index.scss
+++ b/src/menu/components/card/balcony/index.scss
@@ -17,17 +17,7 @@
   .model-menu-card-cell-list {
     flex: 1;
   }
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
-  .anticon-tool {
+  >.anticon-tool {
     position: absolute;
     z-index: 2;
     font-size: 16px;
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
index 66b04b5..197c671 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
@@ -180,6 +180,19 @@
           {val}
         </div>
       )
+    } else if (card.eleType === 'color') {
+      _style.overflow = 'hidden'
+      let _bgstyle = {backgroundColor: card.value || '#1890ff'}
+
+      if (PicRadio[card.lenWidRadio]) {
+        _bgstyle.paddingTop = PicRadio[card.lenWidRadio]
+      } else {
+        _bgstyle.paddingTop = '100%'
+      }
+
+      return (
+        <div style={_bgstyle}></div>
+      )
     }
   }
 
@@ -191,7 +204,7 @@
   }
 
   let able = true
-  if ((appType === 'mob' || appType === 'pc') && (parent.setting.click === 'menu' || parent.setting.click === 'menus')) {
+  if ((appType === 'mob' || appType === 'pc') && parent.setting && (parent.setting.click === 'menu' || parent.setting.click === 'menus')) {
     able = false
   }
 
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/index.scss b/src/menu/components/card/cardcellcomponent/dragaction/index.scss
index 3683516..aade5ba 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/index.scss
+++ b/src/menu/components/card/cardcellcomponent/dragaction/index.scss
@@ -140,4 +140,10 @@
     width: 26px;
     height: 26px;
   }
+
+  .card-cell > div {
+    background-position: center center;
+    background-repeat: no-repeat;
+    background-size: cover;
+  }
 }
\ No newline at end of file
diff --git a/src/menu/components/card/cardcellcomponent/elementform/index.jsx b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
index 93e0b43..cb4f601 100644
--- a/src/menu/components/card/cardcellcomponent/elementform/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
@@ -26,6 +26,7 @@
   qrcode: ['eleType', 'datatype', 'width', 'qrWidth', 'color', 'url', 'noValue'],
   currentDate: ['eleType', 'width', 'dateFormat', 'prefix', 'postfix', 'fixStyle'],
   formula: ['eleType', 'width', 'height', 'prefix', 'postfix', 'eval', 'formula', 'noValue', 'fixStyle'],
+  color: ['eleType', 'datatype', 'width', 'lenWidRadio', 'noValue', 'copyable'],
 }
 
 class MainSearch extends Component {
@@ -104,7 +105,7 @@
   getOptions = (eleType, datatype, link, showType, showInfo, fixStyle, posterType) => {
     let _options = fromJS(cardTypeOptions[eleType]).toJS() // 閫夐」鍒楄〃
     
-    if (['text', 'number', 'picture', 'slider', 'barcode', 'qrcode', 'video'].includes(eleType)) {
+    if (['text', 'number', 'picture', 'slider', 'barcode', 'qrcode', 'video', 'color'].includes(eleType)) {
       if (datatype === 'dynamic') {
         _options.push('field')
         if (eleType === 'number') {
diff --git a/src/menu/components/card/cardcellcomponent/formconfig.jsx b/src/menu/components/card/cardcellcomponent/formconfig.jsx
index 35cb31d..c63b76f 100644
--- a/src/menu/components/card/cardcellcomponent/formconfig.jsx
+++ b/src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -18,6 +18,7 @@
     { value: 'qrcode', text: '浜岀淮鐮�'},
     { value: 'currentDate', text: '褰撳墠鏃堕棿'},
     { value: 'formula', text: '鍏紡'},
+    { value: 'color', text: '棰滆壊'},
   ]
 
   let anchors = []
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index 96f02a0..a71506f 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -155,6 +155,8 @@
       }
     } else if (element.eleType === 'picture') {
       options = ['border', 'margin']
+    } else if (element.eleType === 'color') {
+      options = ['border', 'margin', 'padding']
     } else if (element.eleType === 'text') {
       options[0] = 'font2'
       options.push('display')
diff --git a/src/menu/components/card/cardcomponent/index.scss b/src/menu/components/card/cardcomponent/index.scss
index d8fcee1..a32dfaa 100644
--- a/src/menu/components/card/cardcomponent/index.scss
+++ b/src/menu/components/card/cardcomponent/index.scss
@@ -45,4 +45,20 @@
       }
     }
   }
-}
\ No newline at end of file
+}
+
+.card-control {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  .anticon-tool {
+    position: absolute;
+    left: 1px;
+    top: 1px;
+    padding: 1px;
+    z-index: 2;
+    font-size: 16px;
+    cursor: pointer;
+    background: rgba(255, 255, 255, 0.55);
+  }
+}
diff --git a/src/menu/components/card/cardsimplecomponent/index.jsx b/src/menu/components/card/cardsimplecomponent/index.jsx
index e46f414..1edd5d7 100644
--- a/src/menu/components/card/cardsimplecomponent/index.jsx
+++ b/src/menu/components/card/cardsimplecomponent/index.jsx
@@ -10,7 +10,7 @@
 import { getTableSetting, getCarouselSetting } from './options'
 import Utils from '@/utils/utils.js'
 import MKEmitter from '@/utils/events.js'
-// import './index.scss'
+import './index.scss'
 
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const NodesWrap = asyncComponent(() => import('./node-wrap'))
diff --git a/src/menu/components/card/cardsimplecomponent/index.scss b/src/menu/components/card/cardsimplecomponent/index.scss
index e69de29..0f6054d 100644
--- a/src/menu/components/card/cardsimplecomponent/index.scss
+++ b/src/menu/components/card/cardsimplecomponent/index.scss
@@ -0,0 +1,15 @@
+.card-control {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  .anticon-tool {
+    position: absolute;
+    left: 1px;
+    top: 1px;
+    padding: 1px;
+    z-index: 2;
+    font-size: 16px;
+    cursor: pointer;
+    background: rgba(255, 255, 255, 0.55);
+  }
+}
\ No newline at end of file
diff --git a/src/menu/components/card/data-card/index.scss b/src/menu/components/card/data-card/index.scss
index 0ffc607..3ccba56 100644
--- a/src/menu/components/card/data-card/index.scss
+++ b/src/menu/components/card/data-card/index.scss
@@ -8,17 +8,7 @@
   min-height: 20px;
   overflow-y: auto;
   
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
-  .anticon-tool {
+  >.anticon-tool {
     position: absolute;
     z-index: 2;
     font-size: 16px;
diff --git a/src/menu/components/card/data-card/options.jsx b/src/menu/components/card/data-card/options.jsx
index 8026bd2..0487c0f 100644
--- a/src/menu/components/card/data-card/options.jsx
+++ b/src/menu/components/card/data-card/options.jsx
@@ -303,15 +303,15 @@
     {
       type: 'radio',
       field: 'goback',
-      label: '绌哄�艰繑鍥�',
+      label: appType === 'mob' ? '绌哄�艰繑鍥�' : '绌哄�煎叧闂�',
       initval: wrap.goback || 'false',
-      tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岃繑鍥炰笂涓�鐣岄潰銆�',
+      tooltip: appType === 'mob' ? '褰撴煡璇㈡暟鎹负绌烘椂锛岃繑鍥炰笂涓�鐣岄潰銆�' : '褰撴煡璇㈡暟鎹负绌烘椂锛屽叧闂綋鍓嶆爣绛鹃〉銆�',
       required: false,
       options: [
-        {value: 'true', label: '鏄�'},
         {value: 'false', label: '鍚�'},
+        {value: 'true', label: '鏄�'},
       ],
-      forbid: subtype !== 'propcard' || appType !== 'mob'
+      forbid: subtype !== 'propcard' || appType === 'pc'
     },
     {
       type: 'radio',
diff --git a/src/menu/components/card/prop-card/index.scss b/src/menu/components/card/prop-card/index.scss
index b3fd307..6f1ec06 100644
--- a/src/menu/components/card/prop-card/index.scss
+++ b/src/menu/components/card/prop-card/index.scss
@@ -7,17 +7,7 @@
   background-size: cover;
   min-height: 20px;
   
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
-  .anticon-tool {
+  >.anticon-tool {
     position: absolute;
     z-index: 2;
     font-size: 16px;
diff --git a/src/menu/components/card/table-card/index.scss b/src/menu/components/card/table-card/index.scss
index 8ececec..aef713c 100644
--- a/src/menu/components/card/table-card/index.scss
+++ b/src/menu/components/card/table-card/index.scss
@@ -24,17 +24,7 @@
       z-index: 1;
     }
   }
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
-  .anticon-tool {
+  >.anticon-tool {
     position: absolute;
     z-index: 2;
     font-size: 16px;
diff --git a/src/menu/components/carousel/data-card/index.scss b/src/menu/components/carousel/data-card/index.scss
index b4a77ec..7d9fda3 100644
--- a/src/menu/components/carousel/data-card/index.scss
+++ b/src/menu/components/carousel/data-card/index.scss
@@ -7,17 +7,7 @@
   background-size: cover;
   min-height: 30px;
   
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
-  .anticon-tool {
+  >.anticon-tool {
     position: absolute;
     z-index: 2;
     font-size: 16px;
diff --git a/src/menu/components/carousel/prop-card/index.scss b/src/menu/components/carousel/prop-card/index.scss
index 3fb2fb0..07e359f 100644
--- a/src/menu/components/carousel/prop-card/index.scss
+++ b/src/menu/components/carousel/prop-card/index.scss
@@ -7,17 +7,7 @@
   background-size: cover;
   min-height: 30px;
   
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
-  .anticon-tool {
+  >.anticon-tool {
     position: absolute;
     z-index: 2;
     font-size: 16px;
diff --git a/src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx
index 35b9d60..b5f74db 100644
--- a/src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx
@@ -218,7 +218,7 @@
       controlFields: [
         {field: 'dirField', values: ['mindmap']},
         {field: 'nodeColor', values: ['mindmap']},
-        {field: 'collapsed', values: ['indentTree', 'kapmap']},
+        // {field: 'collapsed', values: ['indentTree', 'kapmap']},
       ]
     },
     {
diff --git a/src/menu/components/chart/antv-G6/index.jsx b/src/menu/components/chart/antv-G6/index.jsx
index 2900881..670a880 100644
--- a/src/menu/components/chart/antv-G6/index.jsx
+++ b/src/menu/components/chart/antv-G6/index.jsx
@@ -93,29 +93,7 @@
   },
   'single-node',
 )
-G6.registerNode(
-  'dice-mind-map-sub', {
-    jsx: (cfg) => {
-      const width = Util.getTextSize(cfg.label, 14)[0] + 24
 
-      return `
-        <group>
-          <rect style={{width: ${width}, height: 22, cursor: pointer}}>
-            <text style={{ fontSize: 14, fill: ${cfg.selected ? systemColor : '#000000'}, marginLeft: 12, marginTop: 6, cursor: pointer }}>${cfg.label}</text>
-          </rect>
-          <rect style={{ fill: ${cfg.color}, width: ${width}, height: 2, x: 0, y: 22, cursor: pointer }} />
-        </group>
-      `
-    },
-    getAnchorPoints() {
-      return [
-        [0, 0.965],
-        [1, 0.965]
-      ]
-    }
-  },
-  'single-node',
-)
 G6.registerNode(
   'dice-mind-map-leaf', {
     jsx: (cfg) => {
@@ -203,38 +181,6 @@
     ev.preventDefault()
   }
 })
-
-const dataMapTransform = (data) => {
-  const changeData = (d, level = 0, color) => {
-    const data = { ...d }
-
-    switch (level) {
-      case 0:
-        data.type = 'dice-mind-map-root'
-        break
-      case 1:
-        data.type = 'dice-mind-map-sub'
-        break
-      default:
-        data.type = 'dice-mind-map-leaf'
-        break
-    }
-
-    if (color) {
-      data.color = color
-    }
-
-    if (level === 1 && !d.direction) {
-      data.direction = 'right'
-    }
-
-    if (d.children) {
-      data.children = d.children.map((child) => changeData(child, level + 1, data.color))
-    }
-    return data
-  }
-  return changeData(data)
-}
 
 // 缂╄繘鏂囦欢鏍�
 G6.registerNode('indentedRoot', {
@@ -1137,9 +1083,27 @@
         if (item.direction === 'left') {
           item.color = card.plot.leftColor || '#26C281'
         } else {
+          item.direction = 'right'
           item.color = card.plot.nodeColor || '#1890ff'
         }
       })
+
+      data.collapsed = false
+      data.type = 'dice-mind-map-root'
+
+      const collapse = (item) => {
+        if (!item.children) return
+
+        item.children.forEach(cell => {
+          cell.collapsed = card.plot.collapsed === 'true'
+          cell.direction = cell.direction || 'right'
+          cell.type = 'dice-mind-map-leaf'
+          cell.color = cell.color || item.color
+          collapse(cell)
+        })
+      }
+
+      collapse(data)
     } else if (card.plot.subtype === 'indentTree') {
       data.isRoot = true
       data.collapsed = false
@@ -1184,11 +1148,12 @@
     const { card } = this.state
     const plot = card.plot
     const data = this.getdata()
+    const height = getHeight(plot.height)
 
     const graph = new G6.TreeGraph({
       container: card.uuid + 'canvas',
       width: this.wrap.scrollWidth - 30,
-      height: getHeight(plot.height),
+      height: height,
       modes: {
         default: [
           {
@@ -1235,6 +1200,10 @@
     graph.data(data)
     graph.render()
     graph.fitView()
+
+    if (plot.collapsed === 'true') {
+      graph.zoomTo(1, { x: 0, y: height / 2 })
+    }
   }
 
   indentrender = () => {
@@ -1306,11 +1275,18 @@
     const { card } = this.state
     const plot = card.plot
     const data = this.getdata()
+    const width = this.wrap.scrollWidth - 30
+    const height = getHeight(plot.height)
+    let modes = ['drag-canvas', 'zoom-canvas', 'dice-mindmap']
+
+    if (plot.collapsed === 'true') {
+      modes = [{ type: 'collapse-expand' },'drag-canvas', 'zoom-canvas', 'dice-mindmap']
+    }
 
     const tree = new G6.TreeGraph({
       container: card.uuid + 'canvas',
-      width: this.wrap.scrollWidth - 30,
-      height: getHeight(plot.height),
+      width: width,
+      height: height,
       fitView: true,
       layout: {
         type: 'mindmap',
@@ -1341,13 +1317,19 @@
       },
       minZoom: 0.5,
       modes: {
-        default: ['drag-canvas', 'zoom-canvas', 'dice-mindmap']
+        default: modes
       }
     })
 
-    tree.data(dataMapTransform(data))
-
+    tree.data(data)
+    
     tree.render()
+
+    if (plot.collapsed === 'true' && plot.dirField) {
+      tree.zoomTo(1, { x: width / 2, y: height / 2 })
+    } else if (plot.collapsed === 'true') {
+      tree.zoomTo(1, { x: 0, y: height / 2 })
+    }
   }
 
   updateComponent = (card) => {
diff --git a/src/menu/components/form/formaction/formconfig.jsx b/src/menu/components/form/formaction/formconfig.jsx
index 163739f..47ce8dd 100644
--- a/src/menu/components/form/formaction/formconfig.jsx
+++ b/src/menu/components/form/formaction/formconfig.jsx
@@ -97,6 +97,7 @@
       key: 'procMode',
       label: '鍙傛暟澶勭悊',
       initVal: card.procMode || 'system',
+      tooltip: '褰撹繑鍥炲�煎瓨鍦� mk_ex_invoke 涓斿�间负 false 鏃讹紝涓嶄細璋冪敤澶栭儴鎺ュ彛銆�',
       required: true,
       options: [{
         value: 'system',
diff --git a/src/menu/components/form/simple-form/index.scss b/src/menu/components/form/simple-form/index.scss
index c02b072..bf874bf 100644
--- a/src/menu/components/form/simple-form/index.scss
+++ b/src/menu/components/form/simple-form/index.scss
@@ -6,18 +6,8 @@
   background-repeat: no-repeat;
   background-size: cover;
   min-height: 30px;
-  
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
-  .anticon-tool {
+
+  >.anticon-tool {
     position: absolute;
     z-index: 2;
     font-size: 16px;
diff --git a/src/menu/components/form/step-form/index.scss b/src/menu/components/form/step-form/index.scss
index 506e5ff..8ca4c7c 100644
--- a/src/menu/components/form/step-form/index.scss
+++ b/src/menu/components/form/step-form/index.scss
@@ -6,18 +6,8 @@
   background-repeat: no-repeat;
   background-size: cover;
   min-height: 30px;
-  
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
-  .anticon-tool {
+
+  >.anticon-tool {
     position: absolute;
     z-index: 2;
     font-size: 16px;
diff --git a/src/menu/components/form/tab-form/index.scss b/src/menu/components/form/tab-form/index.scss
index 506e5ff..8ca4c7c 100644
--- a/src/menu/components/form/tab-form/index.scss
+++ b/src/menu/components/form/tab-form/index.scss
@@ -6,18 +6,8 @@
   background-repeat: no-repeat;
   background-size: cover;
   min-height: 30px;
-  
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
-  .anticon-tool {
+
+  >.anticon-tool {
     position: absolute;
     z-index: 2;
     font-size: 16px;
diff --git a/src/menu/components/iframe/index.scss b/src/menu/components/iframe/index.scss
index f1a9bf5..0ebffb8 100644
--- a/src/menu/components/iframe/index.scss
+++ b/src/menu/components/iframe/index.scss
@@ -25,8 +25,7 @@
     height: 45px;
     padding-top: 5px;
     .ant-input-group-wrapper {
-      width: 40%;
-      max-width: 400px;
+      width: 65%;
       float: right;
     }
   }
diff --git a/src/menu/components/iframe/options.jsx b/src/menu/components/iframe/options.jsx
index 73bee16..8a54190 100644
--- a/src/menu/components/iframe/options.jsx
+++ b/src/menu/components/iframe/options.jsx
@@ -79,9 +79,22 @@
       ],
       controlFields: [
         {field: 'linkUrl', values: ['fixed']},
+        {field: 'focus', values: ['input']},
       ]
     },
     {
+      type: 'radio',
+      field: 'focus',
+      label: '鑷姩鑱氱劍',
+      initval: wrap.focus || 'true',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄�'},
+        {value: 'false', label: '鍚�'},
+      ],
+      forbid: appType === 'mob'
+    },
+    {
       type: 'textarea',
       field: 'linkUrl',
       label: '鍦板潃閾炬帴',
diff --git a/src/menu/components/module/account/index.jsx b/src/menu/components/module/account/index.jsx
new file mode 100644
index 0000000..db814a9
--- /dev/null
+++ b/src/menu/components/module/account/index.jsx
@@ -0,0 +1,147 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Popover } from 'antd'
+import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, CaretDownOutlined } from '@ant-design/icons'
+import moment from 'moment'
+
+import asyncIconComponent from '@/utils/asyncIconComponent'
+import MKEmitter from '@/utils/events.js'
+import getWrapForm from './options'
+
+import './index.scss'
+
+const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
+
+class Account extends Component {
+  static propTpyes = {
+    card: PropTypes.object,
+    deletecomponent: PropTypes.func,
+    updateConfig: PropTypes.func,
+  }
+
+  state = {
+    card: null,
+    date: moment().format('YYYY骞碝M鏈�')
+  }
+
+  UNSAFE_componentWillMount () {
+    const { card } = this.props
+
+    if (card.isNew) {
+      let _card = {
+        uuid: card.uuid,
+        type: card.type,
+        format: 'array',    // 缁勪欢灞炴�� - 鏁版嵁鏍煎紡
+        pageable: false,    // 缁勪欢灞炴�� - 鏄惁鍙垎椤�
+        switchable: true,   // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹�
+        width: card.width || 24,
+        name: '璐﹀',
+        subtype: card.subtype,
+        wrap: { name: '璐﹀', width: card.width || 24 },
+        style: { paddingLeft: '20px', paddingRight: '20px', paddingTop: '10px', paddingBottom: '10px' },
+      }
+
+      this.updateComponent(_card)
+    } else {
+      this.setState({
+        card: fromJS(card).toJS()
+      })
+    }
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  /**
+   * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
+   */
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+    
+    this.setState({
+      card: card
+    })
+
+    this.props.updateConfig(card)
+  }
+
+  changeStyle = () => {
+    const { card } = this.state
+
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
+  }
+
+  getStyle = (style) => {
+    let _card = {...this.state.card, style}
+    
+    this.updateComponent(_card)
+  }
+
+  getWrapForms = () => {
+    const { card } = this.state
+
+    return getWrapForm(card.wrap)
+  }
+
+  updateWrap = (res) => {
+    if (res.linkmenu) {
+      let list = null
+      try {
+        list = JSON.parse(sessionStorage.getItem('thdMenuList')) || []
+      } catch (e) {
+        list = []
+      }
+
+      let id = res.linkmenu[res.linkmenu.length - 1]
+      res.MenuID = id
+
+      list.forEach(item => {
+        if (item.MenuID === id) {
+          res.MenuName = item.MenuName
+          res.MenuNo = item.MenuNo
+          res.tabType = item.type
+        }
+      })
+    }
+
+    this.updateComponent({...this.state.card, wrap: res})
+  }
+
+  render() {
+    const { card, date } = this.state
+
+    return (
+      <div className="menu-account-box" style={card.style} 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}>
+              <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
+            </NormalForm>
+            <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
+            <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
+          </div>
+        } trigger="hover">
+          <ToolOutlined />
+        </Popover>
+        <div className="account-box">
+          <div className="company">鍖椾含鏄庣鏅崕淇℃伅鎶�鏈湁闄愬叕鍙� <CaretDownOutlined /></div>
+          <div className="date">{date}</div>
+        </div>
+      </div>
+    )
+  }
+}
+
+export default Account
\ No newline at end of file
diff --git a/src/menu/components/module/account/index.scss b/src/menu/components/module/account/index.scss
new file mode 100644
index 0000000..e69767f
--- /dev/null
+++ b/src/menu/components/module/account/index.scss
@@ -0,0 +1,52 @@
+.menu-account-box {
+  position: relative;
+  box-sizing: border-box;
+  background: #ffffff;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-size: cover;
+  color: #000000;
+
+  .anticon-tool {
+    position: absolute;
+    z-index: 2;
+    font-size: 16px;
+    right: 1px;
+    top: 1px;
+    cursor: pointer;
+    padding: 5px;
+    background: rgba(255, 255, 255, 0.55);
+  }
+
+  .account-box {
+    display: flex;
+    .company {
+      border: 1px solid #d9d9d9;
+      padding: 3px 10px 3px 5px;
+      border-radius: 4px;
+      margin-right: 15px;
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+
+      .anticon-caret-down {
+        margin-left: 20px;
+      }
+    }
+    .date {
+      padding-top: 3px;
+      flex: 1;
+    }
+  }
+}
+.menu-account-box::after {
+  display: block;
+  content: ' ';
+  clear: both;
+}
+.menu-account-box:hover {
+  z-index: 1;
+  box-shadow: 0px 0px 4px #1890ff;
+}
+
+
diff --git a/src/menu/components/module/account/options.jsx b/src/menu/components/module/account/options.jsx
new file mode 100644
index 0000000..9d027e8
--- /dev/null
+++ b/src/menu/components/module/account/options.jsx
@@ -0,0 +1,61 @@
+/**
+ * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
+ */
+export default function (wrap) {
+  let menulist = sessionStorage.getItem('fstMenuList')
+  if (menulist) {
+    try {
+      menulist = JSON.parse(menulist)
+    } catch (e) {
+      menulist = []
+    }
+  } else {
+    menulist = []
+  }
+
+  const wrapForm = [
+    {
+      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: 'addable',
+      label: '鍙柊澧�',
+      initval: wrap.addable || 'false',
+      required: true,
+      options: [
+        {value: 'true', label: '鏄�'},
+        {value: 'false', label: '鍚�'},
+      ],
+      controlFields: [
+        {field: 'linkmenu', values: ['true']},
+      ],
+    },
+    {
+      type: 'cascader',
+      field: 'linkmenu',
+      label: '鍏宠仈鑿滃崟',
+      initVal: wrap.linkmenu || [],
+      required: true,
+      options: menulist
+    },
+  ]
+
+  return wrapForm
+} 
\ No newline at end of file
diff --git a/src/menu/components/module/voucher/index.jsx b/src/menu/components/module/voucher/index.jsx
index 5f13cd1..def62fe 100644
--- a/src/menu/components/module/voucher/index.jsx
+++ b/src/menu/components/module/voucher/index.jsx
@@ -1,18 +1,17 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Popover } from 'antd'
-import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
+import { Popover, Button } from 'antd'
+import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, DownOutlined, CalendarOutlined } from '@ant-design/icons'
 
-// import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
 import MKEmitter from '@/utils/events.js'
 import getWrapForm from './options'
+import VoucherTable from './voucherTable'
 
 import './index.scss'
 
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
-// const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
 
 class Voucher extends Component {
   static propTpyes = {
@@ -39,9 +38,9 @@
         width: card.width || 12,
         name: '鍑瘉',
         subtype: card.subtype,
-        setting: { interType: 'system' },
+        // setting: { interType: 'system' },
         wrap: { name: '鍑瘉', title: '', width: card.width || 12, type: 'edit' },
-        style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
+        style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px', paddingBottom: '20px' },
         headerStyle: {},
         columns: [],
         scripts: [],
@@ -112,7 +111,6 @@
 
     return (
       <div className="menu-voucher-box" style={card.style} 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">
             <NormalForm title="鍩烘湰璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
@@ -125,7 +123,31 @@
           <ToolOutlined />
         </Popover>
         <div className="voucher-box">
-          jjj
+          <div className="voucher-header">
+            <Button className="add-background header-btn">鏂板</Button>
+            <Button className="add-background header-btn">淇濆瓨</Button>
+            <Button className="print-background header-btn">鎵撳嵃</Button>
+            <Button className="system-background header-btn">瀵煎叆</Button>
+            <Button className="out-background header-btn">瀵煎嚭</Button>
+          </div>
+          <div className="voucher-body">
+          <div className="pre-wrap">
+            <div className="voucher-code">
+              <div>璁�<DownOutlined/></div>
+              <div>1</div>
+              鍙�
+            </div>
+            <div className="voucher-date">
+              鏃ユ湡锛�<div>璇烽�夋嫨鏃ユ湡 <CalendarOutlined /></div>
+            </div>
+            <div className="voucher-affix">
+              闄勫崟鎹� <div>2</div> 寮�
+              <Button type="link" className="">闄勪欢</Button>
+              <Button type="link" className="">澶囨敞</Button>
+            </div>
+          </div>
+          <VoucherTable config={card}/>
+        </div>
         </div>
       </div>
     )
diff --git a/src/menu/components/module/voucher/index.scss b/src/menu/components/module/voucher/index.scss
index c5f6e98..c7def70 100644
--- a/src/menu/components/module/voucher/index.scss
+++ b/src/menu/components/module/voucher/index.scss
@@ -18,12 +18,97 @@
     padding: 5px;
     background: rgba(255, 255, 255, 0.55);
   }
-  .empty-content {
-    text-align: center;
-    font-size: 30px;
-    margin: 0;
-    line-height: 90px;
-    color: #bcbcbc;
+
+  .voucher-header {
+    padding: 10px;
+    border-bottom: 1px solid #eeeeee;
+
+    .header-btn {
+      height: 28px;
+      min-width: 80px;
+      margin-right: 10px;
+    }
+  }
+  .voucher-body {
+    padding: 0 15px;
+    .voucher-code {
+      display: inline-block;
+      width: 160px;
+      margin-right: 15px;
+      
+      div {
+        display: inline-block;
+        min-width: 50px;
+        margin-right: 10px;
+        border: 1px solid #d9d9d9;
+        padding: 4px 10px;
+        border-radius: 4px;
+
+        .anticon-down {
+          position: relative;
+          left: 3px;
+          color: #c8c8c8;
+          font-size: 12px;
+          margin-left: 5px;
+        }
+      }
+    }
+    .pre-wrap {
+      padding: 10px 0px;
+    }
+    .voucher-date {
+      display: inline-block;
+      div {
+        display: inline-block;
+        min-width: 50px;
+        margin-right: 10px;
+        border: 1px solid #d9d9d9;
+        padding: 4px 10px;
+        border-radius: 4px;
+        color: #c8c8c8;
+
+        .anticon {
+          position: relative;
+          left: 3px;
+          color: #c8c8c8;
+          margin-left: 5px;
+        }
+      }
+    }
+    .voucher-affix {
+      float: right;
+      width: 250px;
+      div {
+        display: inline-block;
+        min-width: 50px;
+        margin-right: 10px;
+        border: 1px solid #d9d9d9;
+        padding: 4px 10px;
+        border-radius: 4px;
+      }
+    }
+  }
+
+  .add-background {
+    background: #26C281;
+    border-color: #26C281;
+    color: #ffffff;
+  }
+  .print-background {
+    background-color: #8E44AD;
+    border-color: #8E44AD;
+    color: #ffffff;
+  }
+  .out-background {
+    background-color: rgb(50, 197, 210);
+    border-color: rgb(50, 197, 210);
+    color: #ffffff;
+  }
+
+  .system-background {
+    background: #1890ff;
+    border-color: #1890ff;
+    color: #ffffff;
   }
 }
 .menu-voucher-box::after {
diff --git a/src/menu/components/module/voucher/options.jsx b/src/menu/components/module/voucher/options.jsx
index a837e93..343594e 100644
--- a/src/menu/components/module/voucher/options.jsx
+++ b/src/menu/components/module/voucher/options.jsx
@@ -4,21 +4,21 @@
  * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
  */
 export default function (wrap, id) {
-  let roleList = sessionStorage.getItem('sysRoles')
-  let appType = sessionStorage.getItem('appType')
-
   let menu = window.GLOB.customMenu
   let modules = MenuUtils.getSupModules(menu.components, id, menu.interfaces)
-
-  if (roleList) {
-    try {
-      roleList = JSON.parse(roleList)
-    } catch (e) {
-      roleList = []
+  let books = []
+  let bookids = []
+  menu.components.forEach(item => {
+    if (item.subtype === 'account') {
+      books.push({
+        value: item.uuid,
+        label: item.name
+      })
+      bookids.push(item.uuid)
     }
-  } else {
-    roleList = []
-  }
+  })
+
+  modules = modules.filter(item => !bookids.includes(item.value))
 
   const wrapForm = [
     // {
@@ -59,6 +59,15 @@
       required: true
     },
     {
+      type: 'select',
+      field: 'supBook',
+      label: '璐﹀',
+      initval: wrap.supBook || '',
+      required: true,
+      options: books,
+      allowClear: true
+    },
+    {
       type: 'cascader',
       field: 'supModule',
       label: '涓婄骇缁勪欢',
@@ -66,15 +75,6 @@
       required: false,
       options: modules,
       allowClear: true,
-    },
-    {
-      type: 'multiselect',
-      field: 'blacklist',
-      label: '榛戝悕鍗�',
-      initval: wrap.blacklist || [],
-      required: false,
-      options: roleList,
-      forbid: !!appType
     },
   ]
 
diff --git a/src/menu/components/module/voucher/voucherTable/index.jsx b/src/menu/components/module/voucher/voucherTable/index.jsx
new file mode 100644
index 0000000..447365c
--- /dev/null
+++ b/src/menu/components/module/voucher/voucherTable/index.jsx
@@ -0,0 +1,362 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Table } from 'antd'
+
+import Utils from '@/utils/utils.js'
+import '@/assets/css/table.scss'
+import './index.scss'
+
+class BodyRow extends React.Component {
+  render() {
+    let { data, ...resProps } = this.props
+    let style = {}
+    let className = ''
+
+    return <tr {...resProps} className={className} style={style}/>
+  }
+}
+
+class BodyCell extends React.Component {
+  state = {}
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  render() {
+    let { col, record, className } = this.props
+    let children = null
+    let colSpan = 1
+
+    if (col.field === 'remark') {
+      let val = record.remark || ''
+
+      if (record.type === 'total') {
+        children = <div className="content-wrap" style={{lineHeight: '60px'}}>鍚堣: {val}</div>
+        colSpan = 2
+      } else {
+        children = <div className="content-wrap">{val}</div>
+      }
+    } else if (col.field === 'subject') {
+      if (record.type === 'total') {
+        colSpan = 0
+      } else {
+        let val = record.subject || ''
+  
+        children = <div className="content-wrap">{val}</div>
+      }
+    } else if (col.field === 'debtor') {
+      let val = record.debtor
+      let down = false
+      let vals = []
+      if (typeof(val) === 'number') {
+        if (val < 0) {
+          down = true
+          val = Math.abs(val)
+        }
+        vals = (val * 100).toFixed(0).split('').reverse()
+      }
+
+      children = <div className={'money-uint' + (down ? ' down' : '')}>
+        <span>{vals[10] || ''}</span> <span>{vals[9] || ''}</span> <span>{vals[8] || ''}</span> <span>{vals[7] || ''}</span> <span>{vals[6] || ''}</span> <span>{vals[5] || ''}</span>
+        <span>{vals[4] || ''}</span> <span>{vals[3] || ''}</span> <span>{vals[2] || ''}</span> <span>{vals[1] || ''}</span> <span className="last">{vals[0] || ''}</span>
+      </div>
+    } else if (col.field === 'creditor') {
+      let val = record.creditor
+      let down = false
+      let vals = []
+      if (typeof(val) === 'number') {
+        if (val < 0) {
+          down = true
+          val = Math.abs(val)
+        }
+        vals = (val * 100).toFixed(0).split('').reverse()
+      }
+
+      children = <div className={'money-uint' + (down ? ' down' : '')}>
+        <span>{vals[10] || ''}</span> <span>{vals[9] || ''}</span> <span>{vals[8] || ''}</span> <span>{vals[7] || ''}</span> <span>{vals[6] || ''}</span> <span>{vals[5] || ''}</span>
+        <span>{vals[4] || ''}</span> <span>{vals[3] || ''}</span> <span>{vals[2] || ''}</span> <span>{vals[1] || ''}</span> <span className="last">{vals[0] || ''}</span>
+      </div>
+    }
+
+    if (!colSpan) return null
+
+    return (<td colSpan={colSpan} className={className}>{children}</td>)
+  }
+}
+
+class VoucherTable extends Component {
+  static propTpyes = {
+    config: PropTypes.object,        // 鑿滃崟Id
+    BID: PropTypes.any,              // 涓昏〃ID
+    total: PropTypes.any,            // 鎬绘暟
+    loading: PropTypes.bool,         // 琛ㄦ牸鍔犺浇涓�
+    refreshdata: PropTypes.func,     // 琛ㄦ牸涓帓搴忓垪銆侀〉鐮佺殑鍙樺寲鏃跺埛鏂�
+  }
+
+  state = {
+    data: [],
+    edData: [],
+    edColumns: [],
+    tableId: '',          // 琛ㄦ牸ID
+    pageSize: 10,         // 姣忛〉鏁版嵁鏉℃暟
+    columns: null,        // 鏄剧ず鍒�
+    loading: false,
+  }
+
+  UNSAFE_componentWillMount () {
+    const { config } = this.props
+
+    let data = [
+      {remark: '鎻愮幇', subject: '1001 搴撳瓨鐜伴噾', debtor: 124, creditor: ''},
+      {remark: '璐叆鍥哄畾璧勪骇', subject: '1001 搴撳瓨鐜伴噾', debtor: '', creditor: 124},
+      {remark: '杞粨閿�鍞垚鏈�', subject: '1001 搴撳瓨鐜伴噾', debtor: -524, creditor: ''},
+      {remark: '鎻愮幇', subject: '1001 搴撳瓨鐜伴噾', debtor: 34, creditor: ''},
+    ]
+
+    data = this.initData(data)
+    data.push(this.getTotalLine(data))
+
+    let columns = [
+      {
+        title: '鎽樿',
+        dataIndex: 'remark',
+        key: 'remark',
+        width: '22%',
+        onCell: record => ({
+          record,
+          col: {uuid: 'remark', field: 'remark', tableId: config.uuid},
+        })
+      },
+      {
+        title: '浼氳绉戠洰',
+        dataIndex: 'subject',
+        key: 'subject',
+        width: '34%',
+        onCell: record => ({
+          record,
+          col: {uuid: 'subject', field: 'subject', tableId: config.uuid},
+        })
+      },
+      {
+        title: () => (<>
+          <div className="money-title">鍊熸柟閲戦</div>
+          <div className="money-uint">
+            <span>浜�</span> <span>鍗�</span> <span>鐧�</span> <span>鍗�</span> <span>涓�</span> <span>鍗�</span>
+            <span>鐧�</span> <span>鍗�</span> <span>鍏�</span> <span>瑙�</span> <span className="last">鍒�</span>
+          </div>
+        </>),
+        dataIndex: 'debtor',
+        key: 'debtor',
+        width: '22%',
+        onCell: record => ({
+          record,
+          col: {uuid: 'debtor', field: 'debtor', tableId: config.uuid},
+        })
+      },
+      {
+        title: () => (<>
+          <div className="money-title">璐锋柟閲戦</div>
+          <div className="money-uint">
+            <span>浜�</span> <span>鍗�</span> <span>鐧�</span> <span>鍗�</span> <span>涓�</span> <span>鍗�</span>
+            <span>鐧�</span> <span>鍗�</span> <span>鍏�</span> <span>瑙�</span> <span className="last">鍒�</span>
+          </div>
+        </>),
+        dataIndex: 'creditor',
+        key: 'creditor',
+        width: '22%',
+        onCell: record => ({
+          record,
+          col: {uuid: 'creditor', field: 'creditor', tableId: config.uuid},
+        })
+      }
+    ]
+
+    this.setState({
+      data: data,
+      edData: fromJS(data).toJS(),
+      columns,
+      tableId: config.uuid
+    })
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  initData = (data) => {
+    let _data = data.map((item, i) => {
+      item.uuid = Utils.getuuid()
+      item.index = i
+      
+      return item
+    })
+
+    if (_data.length < 4) {
+      for (let i = _data.length - 1; i < 4; i++) {
+        _data.push({uuid: Utils.getuuid(), index: i + 1, remark: '', subject: '', debtor: '', creditor: ''})
+      }
+    }
+    return _data
+  }
+
+  getTotalLine = (data) => {
+    let totalLine = {uuid: Utils.getuuid(), type: 'total'}
+    let debtor = ''
+    let creditor = ''
+
+    data.forEach(item => {
+      if (typeof(item.debtor) === 'number') {
+        if (debtor === '') {
+          debtor = 0
+        }
+
+        debtor += item.debtor
+      } else if (typeof(item.creditor) === 'number') {
+        if (debtor === '') {
+          debtor = 0
+        }
+        if (creditor === '') {
+          creditor = 0
+        }
+        creditor += item.creditor
+      }
+    })
+
+    totalLine.debtor = debtor
+    totalLine.creditor = creditor
+
+    totalLine.remark = this.changeMoneyToChinese(debtor)
+    
+    return totalLine
+  }
+  
+  changeMoneyToChinese = (money) => {
+    let cnNums = ['闆�', '澹�', '璐�', '鍙�', '鑲�', '浼�', '闄�', '鏌�', '鎹�', '鐜�']
+    let cnIntRadice = ['', '鎷�', '浣�', '浠�']
+    let cnIntUnits = ['', '涓�', '浜�', '鍏�']
+    let cnDecUnits = ['瑙�', '鍒�', '姣�', '鍘�']
+    let cnInteger = '鏁�'
+    let cnIntLast = '鍏�'
+    let maxNum = 999999999999999.9999 // 鏈�澶у鐞嗙殑鏁板瓧
+    let IntegerNum = null
+    let DecimalNum = null
+    let ChineseStr = ''
+    let parts = null // 鍒嗙閲戦鍚庣敤鐨勬暟缁勶紝棰勫畾涔�
+    let Symbol = ''  // 姝h礋鍊兼爣璁�
+
+    if (money === '') return ''
+
+    if (money >= maxNum) return '瓒呭嚭鏈�澶у鐞嗘暟瀛�'
+
+    if (money === 0) {
+      ChineseStr = cnNums[0] + cnIntLast + cnInteger;
+      return ChineseStr
+    }
+    if(money < 0) {
+      money = -money
+      Symbol = '璐�'       
+    }
+    money = money.toString() // 杞崲涓哄瓧绗︿覆
+    if (money.indexOf('.') === -1) {
+      IntegerNum = money
+      DecimalNum = ''
+    } else {
+      parts = money.split('.')
+      IntegerNum = parts[0]
+      DecimalNum = parts[1].substr(0, 4)
+    }
+
+    if (parseInt(IntegerNum, 10) > 0) { // 鑾峰彇鏁村瀷閮ㄥ垎杞崲
+      let zeroCount = 0
+      let IntLen = IntegerNum.length
+      for (let i = 0; i < IntLen; i++) {
+        let n = IntegerNum.substr(i, 1)
+        let p = IntLen - i - 1
+        let q = p / 4
+        let m = p % 4
+        
+        if (n === '0') {
+          zeroCount++
+        } else {
+          if (zeroCount > 0) {
+            ChineseStr += cnNums[0]
+          }
+          zeroCount = 0 // 褰掗浂
+          ChineseStr += cnNums[parseInt(n)] + cnIntRadice[m]
+        }
+
+        if (m === 0 && zeroCount < 4) {
+          ChineseStr += cnIntUnits[q]
+        }
+      }
+      ChineseStr += cnIntLast
+    }
+
+    if (DecimalNum !== '') { // 灏忔暟閮ㄥ垎
+      let decLen = DecimalNum.length
+
+      for (let i = 0; i < decLen; i++) {
+        let n = DecimalNum.substr(i, 1)
+        if (n !== '0') {
+          ChineseStr += cnNums[Number(n)] + cnDecUnits[i]
+        }
+      }
+    }
+    if (ChineseStr === '') {
+      ChineseStr += cnNums[0] + cnIntLast + cnInteger
+    } else if (DecimalNum === '') {
+      ChineseStr += cnInteger
+    }
+
+    ChineseStr = Symbol + ChineseStr
+    
+    return ChineseStr
+  }
+
+  render() {
+    const { edData, columns} = this.state
+
+    const components = {
+      body: {
+        row: BodyRow,
+        cell: BodyCell
+      }
+    }
+
+    return (
+      <div className="voucher-table-wrap">
+        <Table
+          rowKey="uuid"
+          components={components}
+          columns={columns}
+          dataSource={edData}
+          bordered={true}
+          onRow={(record, index) => {
+            return {
+              data: record
+            }
+          }}
+          pagination={false}
+        />
+      </div>
+    )
+  }
+}
+
+export default VoucherTable
\ No newline at end of file
diff --git a/src/menu/components/module/voucher/voucherTable/index.scss b/src/menu/components/module/voucher/voucherTable/index.scss
new file mode 100644
index 0000000..e8175c8
--- /dev/null
+++ b/src/menu/components/module/voucher/voucherTable/index.scss
@@ -0,0 +1,259 @@
+.voucher-table-wrap {
+  position: relative;
+  padding: 0px;
+
+  .normal-table-footer {
+    padding: 10px 0px;
+    color: rgba(0, 0, 0, 0.65);
+  }
+  .normal-table-footer.pagination {
+    position: absolute;
+    bottom: 10px;
+  }
+  >.ant-table-wrapper {
+    position: relative;
+    z-index: 1;
+  }
+  .ant-table {
+    color: inherit;
+    font-size: inherit;
+  }
+
+  .money-uint {
+    display: flex;
+    span {
+      display: inline-block;
+      flex: 1;
+      text-align: center;
+      font-size: 12px;
+    }
+    span:not(.last) {
+      border-right: 1px solid #e9e9e9;
+    }
+    span:nth-child(3), span:nth-child(6) {
+      border-color: #91d5ff;
+    }
+    span:nth-child(9) {
+      border-color: #ffa39e;
+    }
+  }
+
+  table {
+    max-width: 100%;
+    width: 100%;
+    .ant-table-thead {
+      tr {
+        th {
+          position: relative;
+          background-color: transparent;
+          padding: 0;
+          height: 60px;
+          line-height: 60px;
+          text-align: center;
+
+          .ant-table-header-column {
+            display: block;
+            width: 100%;
+            height: 100%;
+
+            .ant-table-column-title {
+              display: block;
+              width: 100%;
+              height: 100%;
+              font-weight: bold;
+              font-size: 13px;
+            }
+          }
+          .money-title {
+            line-height: 30px;
+            font-weight: bold;
+            font-size: 13px;
+          }
+          .money-uint {
+            line-height: 30px;
+            border-top: 1px solid #dadada;
+          }
+        }
+      }
+    }
+    .ant-table-selection-column {
+      width: 60px;
+      min-width: 60px;
+      max-width: 60px;
+    }
+    .ant-table-tbody {
+      tr td {
+        position: relative;
+        background-color: transparent;
+        padding: 0;
+        height: 60px;
+        vertical-align: top;
+
+        .content-wrap {
+          padding: 5px;
+          height: 100%;
+          font-size: 13px;
+          font-weight: bold;
+        }
+        .money-uint {
+          height: 100%;
+          line-height: 60px;
+
+          span {
+            font-size: 14px;
+            font-weight: bold;
+          }
+        }
+        .money-uint.down {
+          span {
+            color: #ff4d4f;
+          }
+        }
+      }
+    }
+  }
+  .ant-input {
+    height: 60px;
+    border-radius: 0;
+    resize: none;
+  }
+  .ant-input-number {
+    height: 60px;
+    border-radius: 0;
+    
+    .ant-input-number-handler-wrap {
+      display: none;
+    }
+    .ant-input-number-input {
+      border-radius: 0;
+      height: 60px;
+    }
+  }
+  .editing_table_cell {
+    .ant-input {
+      padding: 0px;
+      position: absolute;
+      top: 0px;
+      left: 0px;
+      right: 0px;
+      bottom: 0px;
+      border: 1px solid #1890ff;
+    }
+    .ant-input-number-input {
+      position: absolute;
+      top: 0px;
+      left: 0px;
+      right: 0px;
+      bottom: 0px;
+      border: 1px solid #1890ff;
+    }
+    .anticon {
+      color: #ff4d4f;
+      position: absolute;
+      right: 3px;
+      top: calc(50% - 8px);
+    }
+  }
+  td.pointer {
+    position: relative;
+  }
+  td.pointer {
+    .mk-mask {
+      display: none;
+      cursor: pointer;
+      position: absolute;
+      top: 0;
+      left: 0;
+      bottom: 0;
+      right: 0;
+    }
+  }
+}
+.edit-custom-table.editable {
+  td {
+    background-color: #ffffff!important;
+  }
+  td.pointer .mk-mask {
+    display: block;
+  }
+  .mk-operation {
+    display: none;
+  }
+  .ant-table-placeholder {
+    display: none;
+  }
+}
+.edit-custom-table:not(.fixed-height) {
+  .ant-table-body::-webkit-scrollbar {
+    width: 8px;
+    height: 10px;
+  }
+  ::-webkit-scrollbar-thumb {
+    border-radius: 5px;
+    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+    background: rgba(0, 0, 0, 0.13);
+  }
+  ::-webkit-scrollbar-track {/*婊氬姩鏉¢噷闈㈣建閬�*/
+    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+    border-radius: 3px;
+    border: 1px solid rgba(0, 0, 0, 0.07);
+    background: rgba(0, 0, 0, 0);
+  }
+}
+.edit-custom-table.fixed-height {
+  .ant-table-body {
+    border-bottom: 1px solid rgba(0, 0, 0, .05);
+    .ant-table-fixed {
+      border-bottom: 0;
+    }
+  }
+}
+.edit-custom-table.hidden {
+  thead {
+    display: none;
+  }
+}
+.edit-custom-table.ghost {
+  .ant-table-thead > tr {
+    > th {
+      color: inherit;
+      background: transparent;
+      .ant-table-column-sorter .ant-table-column-sorter-inner {
+        color: inherit;
+      }
+    }
+    > th:hover {
+      background: transparent;
+    }
+  }
+  .ant-table-body {
+    overflow-x: auto;
+    tr {
+      td {
+        background: transparent!important;
+      }
+    }
+    tr:hover td {
+      background: transparent!important;
+    }
+  }
+}
+.image-scale-modal {
+  width: 70vw;
+  min-height: 80vh;
+  top: 10vh;
+  .ant-modal-body {
+    min-height: calc(80vh - 110px);
+    line-height: calc(80vh - 160px);
+    text-align: center;
+  }
+  .ant-modal-footer {
+    text-align: center;
+    span {
+      display: inline-block;
+      color: #1890ff;
+      padding: 5px 15px;
+      cursor: pointer;
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/menu/components/search/main-search/index.jsx b/src/menu/components/search/main-search/index.jsx
index 8741554..8407229 100644
--- a/src/menu/components/search/main-search/index.jsx
+++ b/src/menu/components/search/main-search/index.jsx
@@ -207,7 +207,6 @@
 
     this.searchFormRef.handleConfirm().then(res => {
       let fieldrepet = false // 瀛楁閲嶅
-      let labelrepet = false // 鎻愮ず鏂囧瓧閲嶅
 
       card.search = card.search.map(item => { // 鏁版嵁鏇存柊鍙婇噸澶嶆娴�
         if (item.uuid !== res.uuid && res.field && item.field) {
@@ -233,8 +232,6 @@
 
           if (setFields.length < itemFields.length + resFields.length && (res.type !== 'date' || item.type !== 'date')) {
             fieldrepet = true
-          } else if (item.label === res.label) {
-            labelrepet = true
           }
         }
 
@@ -249,13 +246,6 @@
         notification.warning({
           top: 92,
           message: '瀛楁宸插瓨鍦�!',
-          duration: 5
-        })
-        return
-      } else if (labelrepet) {
-        notification.warning({
-          top: 92,
-          message: '鍚嶇О宸插瓨鍦�!',
           duration: 5
         })
         return
diff --git a/src/menu/components/search/main-search/index.scss b/src/menu/components/search/main-search/index.scss
index d68899b..be92a36 100644
--- a/src/menu/components/search/main-search/index.scss
+++ b/src/menu/components/search/main-search/index.scss
@@ -102,6 +102,9 @@
     }
   }
   .mk-search-item-wrap.action {
+    .ant-form-item {
+      white-space: nowrap;
+    }
     .ant-form-item-label, .ant-form-item-control-wrapper {
       display: inline-block;
     }
diff --git a/src/menu/components/share/actioncomponent/actionform/index.jsx b/src/menu/components/share/actioncomponent/actionform/index.jsx
index ddbb440..56a2345 100644
--- a/src/menu/components/share/actioncomponent/actionform/index.jsx
+++ b/src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -420,6 +420,9 @@
         if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
           shows.push('resetPageIndex')
         }
+        if (this.record.execMode === 'pop' || this.record.execMode === 'prompt') {
+          shows.push('position')
+        }
       } else if (_funcType === 'mkBinding' || _funcType === 'mkUnBinding') {
         shows.push('execSuccess', 'execError')
       } else if (_funcType === 'closetab') {
@@ -549,14 +552,13 @@
       } else if (value === 'excelIn') {
         _fieldval.intertype = 'system'
         _fieldval.Ot = 'notRequired'
-        
+        _fieldval.execSuccess = 'grid'
         _fieldval.label = '瀵煎叆Excel'
         _fieldval.class = 'dgreen'
         this.record.Ot = 'notRequired'
         this.record.label = '瀵煎叆Excel'
         this.record.class = 'dgreen'
-       
-  
+        this.record.execSuccess = 'grid'
       } else if (value === 'excelOut') {
         _fieldval.intertype = 'system'
         _fieldval.label = '瀵煎嚭Excel'
diff --git a/src/menu/components/share/actioncomponent/formconfig.jsx b/src/menu/components/share/actioncomponent/formconfig.jsx
index ae79d94..254577c 100644
--- a/src/menu/components/share/actioncomponent/formconfig.jsx
+++ b/src/menu/components/share/actioncomponent/formconfig.jsx
@@ -128,6 +128,7 @@
   if (appType === 'mob') {
     opentypes = opentypes.filter(item => ['pop', 'prompt', 'exec', 'excelOut', 'innerpage', 'funcbutton'].includes(item.value))
     funTypes = [
+      { value: 'print', text: '鏍囩鎵撳嵃' },
       { value: 'scan', text: '鎵爜' },
       { value: 'pay', text: '鏀粯' },
       { value: 'refund', text: '閫�娆�' },
@@ -147,7 +148,7 @@
   } else if (appType === 'pc') {
     opentypes = opentypes.filter(item => item.value !== 'tab')
     funTypes = [
-      { value: 'refund', text: '閫�娆�' },
+      { value: 'print', text: '鏍囩鎵撳嵃' },
       { value: 'changeuser', text: '鍒囨崲鐢ㄦ埛' },
     ]
     pageTemps = [
@@ -311,6 +312,7 @@
       key: 'procMode',
       label: '鍙傛暟澶勭悊',
       initVal: card.procMode || (card.innerFunc ? 'inner' : 'system'),
+      tooltip: '褰撹繑鍥炲�煎瓨鍦� mk_ex_invoke 涓斿�间负 false 鏃讹紝涓嶄細璋冪敤澶栭儴鎺ュ彛銆�',
       required: true,
       options: [{
         value: 'system',
@@ -1211,6 +1213,7 @@
       key: 'procMode',
       label: '鍙傛暟澶勭悊',
       initVal: card.procMode || (card.innerFunc ? 'inner' : 'system'),
+      tooltip: '褰撹繑鍥炲�煎瓨鍦� mk_ex_invoke 涓斿�间负 false 鏃讹紝涓嶄細璋冪敤澶栭儴鎺ュ彛銆�',
       required: true,
       options: [{
         value: 'system',
diff --git a/src/menu/components/share/searchcomponent/index.jsx b/src/menu/components/share/searchcomponent/index.jsx
index 80730a4..3d94abe 100644
--- a/src/menu/components/share/searchcomponent/index.jsx
+++ b/src/menu/components/share/searchcomponent/index.jsx
@@ -153,7 +153,6 @@
 
     this.searchFormRef.handleConfirm().then(res => {
       let fieldrepet = false // 瀛楁閲嶅
-      let labelrepet = false // 鎻愮ず鏂囧瓧閲嶅
 
       _searchlist = _searchlist.filter(item => !item.origin || item.uuid === res.uuid) // 鍘婚櫎绯荤粺椤�
 
@@ -181,8 +180,6 @@
 
           if (setFields.length < itemFields.length + resFields.length && (res.type !== 'date' || item.type !== 'date')) {
             fieldrepet = true
-          } else if (item.label === res.label) {
-            labelrepet = true
           }
         }
 
@@ -197,13 +194,6 @@
         notification.warning({
           top: 92,
           message: '瀛楁宸插瓨鍦�!',
-          duration: 5
-        })
-        return
-      } else if (labelrepet) {
-        notification.warning({
-          top: 92,
-          message: '鍚嶇О宸插瓨鍦�!',
           duration: 5
         })
         return
diff --git a/src/menu/components/table/base-table/columns/index.jsx b/src/menu/components/table/base-table/columns/index.jsx
index a5f8102..b7cd7e3 100644
--- a/src/menu/components/table/base-table/columns/index.jsx
+++ b/src/menu/components/table/base-table/columns/index.jsx
@@ -3,7 +3,7 @@
 import { is, fromJS } from 'immutable'
 import { DndProvider, DragSource, DropTarget } from 'react-dnd'
 import { Table, Popover, Modal, message, notification } from 'antd'
-import { PlusOutlined, EditOutlined, CopyOutlined, DeleteOutlined, FontColorsOutlined, CloseCircleOutlined, AntDesignOutlined } from '@ant-design/icons'
+import { PlusOutlined, EditOutlined, CopyOutlined, DeleteOutlined, FontColorsOutlined, CloseCircleOutlined, AntDesignOutlined, InfoOutlined } from '@ant-design/icons'
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
@@ -68,7 +68,7 @@
               }
               <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
               {column && column.type === 'custom' ? <PasteComponent options={['customCardElement']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              {column && column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
+              {column && (column.type === 'custom' || column.type === 'action') ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
               <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
               {column && ['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
             </div>
@@ -140,6 +140,34 @@
   }))(HeaderCol),
 )
 
+class HeaderEmptyCol extends Component {
+  render() {
+    const { connectDragSource, connectDropTarget } = this.props
+
+    return connectDragSource(
+      connectDropTarget(<div style={{border: '1px solid #e8e8e8', textAlign: 'center', height: '100px', lineHeight: '100px', color: '#bcbcbc'}}>璇锋坊鍔犳樉绀哄垪</div>)
+    )
+  }
+}
+
+const ColEmptyTarget = {
+  drop(props, monitor) {
+    const item = monitor.getItem()
+
+    if (item.$init) {
+      props.dropCol(item, 0)
+    }
+  }
+}
+
+const DragableEmptyCol = DropTarget('col', ColEmptyTarget, connect => ({
+  connectDropTarget: connect.dropTarget()
+}))(
+  DragSource('col', rowSource, connect => ({
+    connectDragSource: connect.dragSource(),
+  }))(HeaderEmptyCol)
+)
+
 class EditableColumnCell extends Component {
   updateCard = (vals, btn) => {
     const { column } = this.props
@@ -167,7 +195,7 @@
       )
     } else if (column && column.type === 'action') {
       return (
-        <td style={{padding: '0 5px', textAlign: column.Align}} className={'action-column ' + className}>
+        <td style={{padding: 0, textAlign: column.Align, ...(column.style || {})}} className={'action-column ' + className}>
           <CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/>
         </td>
       )
@@ -396,8 +424,10 @@
     if (col.type === 'colspan') {
       col.subcols = card.subcols || []
     } else if (col.type === 'custom') {
+      col.style = card.style || {}
       col.elements = card.type === 'custom' ? (card.elements || []) : []
     } else if (col.type === 'action') {
+      col.style = card.style || {}
       col.elements = card.type === 'action' ? (card.elements || []) : []
     }
 
@@ -560,6 +590,27 @@
     })
   }
 
+  copyFields = () => {
+    const { config } = this.props
+    let m = []
+    let n = []
+
+    config.columns.forEach(col => {
+      m.push(`${col.field}(${col.label})`)
+      n.push(col.field)
+    })
+
+    let oInput = document.createElement('input')
+    oInput.value = `/*${m.join(',')}*/
+      ${n.join(',')}`
+    document.body.appendChild(oInput)
+    oInput.select()
+    document.execCommand('Copy')
+    document.body.removeChild(oInput)
+
+    message.success('澶嶅埗鎴愬姛銆�')
+  }
+
   componentDidMount () {
     MKEmitter.addListener('plusColumns', this.plusColumns)
   }
@@ -599,11 +650,12 @@
     }
 
     return (
-      <div className={`normal-table-columns ${config.setting.laypage} ${config.wrap.tableType} ${config.wrap.mode || ''}`} id={tableId}>
+      <div className={`normal-table-columns ${config.setting.laypage} ${config.wrap.tableType} ${config.wrap.mode || ''} table-vertical-${config.wrap.vertical || ''}`} id={tableId}>
         <div className="col-control">
           <FieldsComponent config={config} type="columns" />
           <CopyOutlined title="澶嶅埗鏄剧ず鍒�" onClick={this.copycolumn} />
           <MarkColumn columns={fields} type="line" marks={lineMarks} onSubmit={this.updateLineMarks} />
+          <InfoOutlined title="澶嶅埗瀛楁" style={{color: 'orange'}} onClick={this.copyFields}/>
         </div>
         <DndProvider>
           {groups ? groups.map((group, i) => {
@@ -626,7 +678,7 @@
               } : false}
             />
           }) :
-          <Table
+          (columns.length === 0 ? <DragableEmptyCol dropCol={this.dropCol}/> : <Table
             rowKey="uuid"
             size={config.wrap.size || 'middle'}
             bordered={config.wrap.bordered !== 'false'}
@@ -642,7 +694,7 @@
               total: 58,
               showTotal: (total, range) => `${range[0]}-${range[1]} 鍏� ${total} 鏉
             }}
-          />}
+          />)}
         </DndProvider>
         <EditColumn column={card} fields={fields} submitCol={this.submitCol} cancelCol={this.cancelCol}/>
       </div>
diff --git a/src/menu/components/table/base-table/columns/index.scss b/src/menu/components/table/base-table/columns/index.scss
index 8f8cf70..46cb41d 100644
--- a/src/menu/components/table/base-table/columns/index.scss
+++ b/src/menu/components/table/base-table/columns/index.scss
@@ -105,16 +105,17 @@
   }
   table tr {
     th .ant-table-column-title {
-      // color: var(--mk-table-color)!important;
       font-size: var(--mk-table-font-size)!important;
       font-weight: var(--mk-table-font-weight)!important;
     }
     td {
-      color: var(--mk-table-color)!important;
       font-size: var(--mk-table-font-size)!important;
       font-weight: var(--mk-table-font-weight)!important;
     }
   }
+  table tbody tr {
+    color: var(--mk-table-color);
+  }
 }
 .normal-table-columns.false {
   .ant-pagination {
diff --git a/src/menu/components/table/base-table/index.jsx b/src/menu/components/table/base-table/index.jsx
index 5b982cd..a1d88d9 100644
--- a/src/menu/components/table/base-table/index.jsx
+++ b/src/menu/components/table/base-table/index.jsx
@@ -99,6 +99,39 @@
     MKEmitter.removeListener('completeSave', this.completeSave)
   }
 
+  // updateFix = (card) => {
+  //   let fixs = {}
+
+  //   card.cols.forEach(col => {
+  //     if (!col.field) return
+  //     if (col.postfix || col.prefix) {
+  //       fixs[col.field] = col
+  //     }
+  //   })
+
+  //   card.cols.forEach(col => {
+  //     if (col.type === 'custom') {
+  //       col.elements.forEach(cell => {
+  //         if (cell.datatype === 'dynamic') {
+  //           cell.height = ''
+  //           cell.innerHeight = 'auto'
+
+  //           if (fixs[cell.field]) {
+  //             if (!cell.prefix && fixs[cell.field].prefix) {
+  //               cell.prefix = fixs[cell.field].prefix
+  //             }
+  //             if (!cell.postfix && fixs[cell.field].postfix) {
+  //               cell.postfix = fixs[cell.field].postfix
+  //             }
+  //           }
+  //         }
+  //       })
+  //     }
+  //   })
+
+  //   return card
+  // }
+
   completeSave = () => {
     const { card } = this.state
 
diff --git a/src/menu/components/table/base-table/options.jsx b/src/menu/components/table/base-table/options.jsx
index 6a9c6c7..80fd9bd 100644
--- a/src/menu/components/table/base-table/options.jsx
+++ b/src/menu/components/table/base-table/options.jsx
@@ -100,6 +100,30 @@
       required: false
     },
     {
+      type: 'radio',
+      field: 'vertical',
+      label: '鍨傜洿瀵归綈',
+      initval: wrap.vertical || 'middle',
+      tooltip: '鍗曞厓鏍肩殑鍨傜洿瀵归綈鏂瑰紡銆�',
+      required: false,
+      options: [
+        {value: 'top', label: '鍚戜笂'},
+        {value: 'middle', label: '灞呬腑'},
+        {value: 'bottom', label: '鍚戜笅'},
+      ]
+    },
+    {
+      type: 'number',
+      field: 'btnlimit',
+      label: '鎸夐挳闄愬埗',
+      initval: wrap.btnlimit || '',
+      tooltip: '鎸夐挳鏁伴噺闄愬埗锛岃秴鍑虹殑鎸夐挳浼氬湪鏇村涓笅鎷夋樉绀猴紝娉細鏇村涓殑鎸夐挳涓嶈缁戝畾鍙屽嚮浜嬩欢銆�',
+      min: 3,
+      max: 3000,
+      precision: 0,
+      required: false
+    },
+    {
       type: 'number',
       field: 'height',
       label: '琛ㄦ牸楂樺害',
diff --git a/src/menu/components/table/edit-table/columns/index.jsx b/src/menu/components/table/edit-table/columns/index.jsx
index 25bd842..319b9af 100644
--- a/src/menu/components/table/edit-table/columns/index.jsx
+++ b/src/menu/components/table/edit-table/columns/index.jsx
@@ -75,7 +75,7 @@
             <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
             {column.type === 'custom' ? <PasteComponent options={['customCardElement']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
             {column.type === 'action' ? <PasteComponent options={['action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-            {column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
+            {column.type === 'custom' || column.type === 'action' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
             <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
             {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
           </div>
@@ -148,7 +148,7 @@
       )
     } else if (column && column.type === 'action') {
       return (
-        <td style={{padding: '0 5px', textAlign: column.Align}} className={'action-column ' + className}>
+        <td style={{padding: 0, textAlign: column.Align, ...(column.style || {})}} className={'action-column ' + className}>
           <CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/>
         </td>
       )
@@ -359,8 +359,10 @@
     const { card } = this.state
     
     if (col.type === 'custom') {
+      col.style = card.style || {}
       col.elements = card.type === 'custom' ? (card.elements || []) : []
     } else if (col.type === 'action') {
+      col.style = card.style || {}
       col.elements = card.type === 'action' ? (card.elements || []) : []
     }
 
@@ -592,7 +594,7 @@
     })
 
     return (
-      <div className={`edit-table-columns ${config.setting.laypage} ${config.wrap.mode || ''}`} id={tableId}>
+      <div className={`edit-table-columns ${config.setting.laypage} ${config.wrap.mode || ''} table-vertical-${config.wrap.vertical || ''}`} id={tableId}>
         <div className="col-control">
           <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
             <div className="mk-popover-control">
diff --git a/src/menu/components/table/edit-table/columns/index.scss b/src/menu/components/table/edit-table/columns/index.scss
index 699ad86..b7e3f7b 100644
--- a/src/menu/components/table/edit-table/columns/index.scss
+++ b/src/menu/components/table/edit-table/columns/index.scss
@@ -32,6 +32,7 @@
         .col-copy {
           margin-bottom: 0;
           display: inline-block;
+          color: inherit;
           .ant-typography-copy {
             position: absolute;
             left: 2px;
@@ -132,16 +133,17 @@
   }
   table tr {
     th .ant-table-column-title, th .ant-table-column-title > span {
-      // color: var(--mk-table-color)!important;
       font-size: var(--mk-table-font-size)!important;
       font-weight: var(--mk-table-font-weight)!important;
     }
     td {
-      color: var(--mk-table-color)!important;
       font-size: var(--mk-table-font-size)!important;
       font-weight: var(--mk-table-font-weight)!important;
     }
   }
+  table tbody tr {
+    color: var(--mk-table-color);
+  }
 }
 .edit-table-columns.false {
   .ant-pagination {
diff --git a/src/menu/components/table/edit-table/options.jsx b/src/menu/components/table/edit-table/options.jsx
index 977367f..565be7f 100644
--- a/src/menu/components/table/edit-table/options.jsx
+++ b/src/menu/components/table/edit-table/options.jsx
@@ -225,6 +225,19 @@
       tooltip: '榛樿鍊� #e8e8e8銆�',
       required: false
     },
+    {
+      type: 'radio',
+      field: 'vertical',
+      label: '鍨傜洿瀵归綈',
+      initval: wrap.vertical || 'middle',
+      tooltip: '鍗曞厓鏍肩殑鍨傜洿瀵归綈鏂瑰紡銆�',
+      required: false,
+      options: [
+        {value: 'top', label: '鍚戜笂'},
+        {value: 'middle', label: '灞呬腑'},
+        {value: 'bottom', label: '鍚戜笅'},
+      ]
+    },
     // {
     //   type: 'color',
     //   field: 'color',
diff --git a/src/menu/components/table/normal-table/columns/index.jsx b/src/menu/components/table/normal-table/columns/index.jsx
index e976c72..1097ef5 100644
--- a/src/menu/components/table/normal-table/columns/index.jsx
+++ b/src/menu/components/table/normal-table/columns/index.jsx
@@ -70,7 +70,7 @@
               <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
               {column && column.type === 'custom' ? <PasteComponent options={['customCardElement']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
               {column && column.type === 'action' ? <PasteComponent options={['action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              {column && column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
+              {column && (column.type === 'custom' || column.type === 'action') ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
               <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
               {column && ['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
             </div>
@@ -170,7 +170,7 @@
       )
     } else if (column && column.type === 'action') {
       return (
-        <td style={{padding: '0 5px', textAlign: column.Align}} className={'action-column ' + className}>
+        <td style={{padding: 0, textAlign: column.Align, ...(column.style || {})}} className={'action-column ' + className}>
           <CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/>
         </td>
       )
@@ -400,8 +400,10 @@
     if (col.type === 'colspan') {
       col.subcols = card.subcols || []
     } else if (col.type === 'custom') {
+      col.style = card.style || {}
       col.elements = card.type === 'custom' ? (card.elements || []) : []
     } else if (col.type === 'action') {
+      col.style = card.style || {}
       col.elements = card.type === 'action' ? (card.elements || []) : []
     }
 
@@ -605,7 +607,7 @@
     const columns = this.handlecolumns(this.state.columns, fields, config)
 
     return (
-      <div className={`normal-table-columns ${config.setting.laypage} ${config.wrap.tableType} ${config.wrap.mode || ''}`} id={tableId}>
+      <div className={`normal-table-columns ${config.setting.laypage} ${config.wrap.tableType} ${config.wrap.mode || ''} table-vertical-${config.wrap.vertical || ''}`} id={tableId}>
         <div className="col-control">
           <CopyOutlined title="澶嶅埗鏄剧ず鍒�" onClick={this.copycolumn} />
           <MarkColumn columns={fields} type="line" marks={lineMarks} onSubmit={this.updateLineMarks} />
diff --git a/src/menu/components/table/normal-table/columns/index.scss b/src/menu/components/table/normal-table/columns/index.scss
index 7c8baaa..5de869d 100644
--- a/src/menu/components/table/normal-table/columns/index.scss
+++ b/src/menu/components/table/normal-table/columns/index.scss
@@ -23,6 +23,7 @@
         .col-copy {
           margin-bottom: 0;
           display: inline-block;
+          color: inherit;
           .ant-typography-copy {
             position: absolute;
             left: 2px;
@@ -124,16 +125,17 @@
   }
   table tr {
     th .ant-table-column-title {
-      // color: var(--mk-table-color)!important;
       font-size: var(--mk-table-font-size)!important;
       font-weight: var(--mk-table-font-weight)!important;
     }
     td {
-      color: var(--mk-table-color)!important;
       font-size: var(--mk-table-font-size)!important;
       font-weight: var(--mk-table-font-weight)!important;
     }
   }
+  table tbody tr {
+    color: var(--mk-table-color);
+  }
 }
 .normal-table-columns.false {
   .ant-pagination {
diff --git a/src/menu/components/table/normal-table/options.jsx b/src/menu/components/table/normal-table/options.jsx
index c6caecc..70cf580 100644
--- a/src/menu/components/table/normal-table/options.jsx
+++ b/src/menu/components/table/normal-table/options.jsx
@@ -161,6 +161,19 @@
       tooltip: '榛樿鍊� #e8e8e8銆�',
       required: false
     },
+    {
+      type: 'radio',
+      field: 'vertical',
+      label: '鍨傜洿瀵归綈',
+      initval: wrap.vertical || 'middle',
+      tooltip: '鍗曞厓鏍肩殑鍨傜洿瀵归綈鏂瑰紡銆�',
+      required: false,
+      options: [
+        {value: 'top', label: '鍚戜笂'},
+        {value: 'middle', label: '灞呬腑'},
+        {value: 'bottom', label: '鍚戜笅'},
+      ]
+    },
     // {
     //   type: 'color',
     //   field: 'color',
@@ -192,6 +205,18 @@
     //   forbid: appType === 'mob'
     // },
     {
+      type: 'number',
+      field: 'btnlimit',
+      label: '鎸夐挳闄愬埗',
+      initval: wrap.btnlimit || '',
+      tooltip: '鎸夐挳鏁伴噺闄愬埗锛岃秴鍑虹殑鎸夐挳浼氬湪鏇村涓笅鎷夋樉绀猴紝娉細鏇村涓殑鎸夐挳涓嶈缁戝畾鍙屽嚮浜嬩欢銆�',
+      min: 3,
+      max: 3000,
+      precision: 0,
+      required: false,
+      forbid: appType !== ''
+    },
+    {
       type: 'select',
       field: 'doubleClick',
       label: '鍙屽嚮浜嬩欢',
diff --git a/src/menu/components/timeline/normal-timeline/index.scss b/src/menu/components/timeline/normal-timeline/index.scss
index dffd8b4..2f88860 100644
--- a/src/menu/components/timeline/normal-timeline/index.scss
+++ b/src/menu/components/timeline/normal-timeline/index.scss
@@ -10,17 +10,8 @@
   .model-menu-card-cell-list {
     flex: 1;
   }
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
-  .anticon-tool {
+
+  >.anticon-tool {
     position: absolute;
     z-index: 2;
     font-size: 16px;
diff --git a/src/menu/menushell/card.jsx b/src/menu/menushell/card.jsx
index 3af7dc8..0226f8f 100644
--- a/src/menu/menushell/card.jsx
+++ b/src/menu/menushell/card.jsx
@@ -28,6 +28,7 @@
 const CustomChart = asyncComponent(() => import('@/menu/components/chart/chart-custom'))
 const Timeline = asyncComponent(() => import('@/menu/components/timeline/normal-timeline'))
 const Voucher = asyncComponent(() => import('@/menu/components/module/voucher'))
+const Account = asyncComponent(() => import('@/menu/components/module/account'))
 const Iframe = asyncComponent(() => import('@/menu/components/iframe'))
 const AntvG6 = asyncComponent(() => import('@/menu/components/chart/antv-G6'))
 
@@ -121,6 +122,8 @@
       return (<AntvG6 card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'module' && card.subtype === 'voucher') {
       return (<Voucher card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'module' && card.subtype === 'account') {
+      return (<Account card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     }
   }
   return (
diff --git a/src/menu/menushell/index.jsx b/src/menu/menushell/index.jsx
index ecef5dc..9024341 100644
--- a/src/menu/menushell/index.jsx
+++ b/src/menu/menushell/index.jsx
@@ -100,6 +100,7 @@
         timeline: '鏃堕棿杞�',
         antvG6: '鏍戝浘',
         iframe: 'iframe',
+        module: '妯″潡',
         card: '鍗$墖'
       }
       let i = 1
diff --git a/src/menu/modulecell/index.jsx b/src/menu/modulecell/index.jsx
index 5bc7ea3..279ab51 100644
--- a/src/menu/modulecell/index.jsx
+++ b/src/menu/modulecell/index.jsx
@@ -22,6 +22,7 @@
           { value: 'qrcode', text: '浜岀淮鐮�', type: 'action', class: 'element', $init: true},
           { value: 'currentDate', text: '褰撳墠鏃堕棿', type: 'action', class: 'element', $init: true},
           { value: 'formula', text: '鍏紡', type: 'action', class: 'element', $init: true},
+          { value: 'color', text: '棰滆壊', type: 'action', class: 'element', $init: true},
           { value: 'sequence', text: '搴忓彿', type: 'action', class: 'element', $init: true }
         ]
       },
diff --git a/src/menu/modulesource/option.jsx b/src/menu/modulesource/option.jsx
index 4c97918..8273421 100644
--- a/src/menu/modulesource/option.jsx
+++ b/src/menu/modulesource/option.jsx
@@ -30,7 +30,8 @@
 import mindmap from '@/assets/mobimg/mindmap.png'
 import indent from '@/assets/mobimg/indent.jfif'
 import kapmap from '@/assets/mobimg/kapmap.jfif'
-// import Voucher from '@/assets/mobimg/voucher.jpg'
+import Voucher from '@/assets/mobimg/voucher.png'
+import Account from '@/assets/mobimg/account.png'
 
 // 缁勪欢閰嶇疆淇℃伅
 export const menuOptions = [
@@ -68,5 +69,6 @@
   { type: 'menu', url: SandBox, component: 'code', subtype: 'sandbox', title: '鑷畾涔�', width: 24 },
   { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '鍒嗙粍', width: 24, forbid: ['billPrint'] },
   { type: 'menu', url: Iframe, component: 'iframe', subtype: 'iframe', title: 'iframe', width: 24, forbid: ['billPrint'] },
-  // { type: 'menu', url: Voucher, component: 'module', subtype: 'voucher', title: '鍑瘉', width: 24, forbid: ['billPrint'] },
+  { type: 'menu', url: Account, component: 'module', subtype: 'account', title: '璐﹀', width: 24, forbid: ['billPrint'] },
+  { type: 'menu', url: Voucher, component: 'module', subtype: 'voucher', title: '鍑瘉', width: 24, forbid: ['billPrint'] },
 ]
diff --git a/src/menu/tablenodes/index.jsx b/src/menu/tablenodes/index.jsx
index 2b5eed1..36281b2 100644
--- a/src/menu/tablenodes/index.jsx
+++ b/src/menu/tablenodes/index.jsx
@@ -173,6 +173,7 @@
 
         if (result.tb_list) {
           result.tb_list.sort((a, b) => a.tbname > b.tbname ? 1 : -1)
+          let length = result.tb_list.length
           result.tb_list.forEach((item, i) => {
             let cell = {
               label: item.tbname,
@@ -180,6 +181,8 @@
               id: 'table' + i,
               direction: 'right',
               color: '#1890ff',
+              collapsed: false,
+              collable: true,
               children: []
             }
 
@@ -198,10 +201,17 @@
                     id: item.tbname + 'menu' + i,
                     direction: 'right',
                     color: '#1890ff',
+                    type: 'dice-mind-map-leaf',
                     param: _param
                   })
                 }
               })
+            }
+
+            if (cell.children.length > 5 && length > 1) {
+              cell.collapsed = true
+            } else if (cell.children.length === 0) {
+              cell.collable = false
             }
 
             data.children.push(cell)
@@ -284,12 +294,12 @@
           const stroke = cfg.style.stroke || '#096dd9';
     
           return `
-          <group>
-            <rect draggable="true" style={{width: ${width}, height: 30, stroke: ${stroke}, radius: 4}} keyshape>
-              <text style={{ fontSize: 14, marginLeft: 6, marginTop: 6 }}>${cfg.label}</text>
-            </rect>
-          </group>
-        `;
+            <group>
+              <rect draggable="true" style={{width: ${width}, height: 30, stroke: ${stroke}, radius: 4}} keyshape>
+                <text style={{ fontSize: 14, marginLeft: 6, marginTop: 6 }}>${cfg.label}</text>
+              </rect>
+            </group>
+          `;
         },
         getAnchorPoints() {
           return [
@@ -308,13 +318,13 @@
           const color = cfg.color;
     
           return `
-          <group>
-            <rect draggable="true" style={{width: ${width}, height: 26, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, fill: 'transparent' }}>
-              <text style={{ fontSize: 12, fill: ${cfg.fontcolor ? cfg.fontcolor : 'black'}, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, marginLeft: 12, marginTop: 6 }}>${cfg.label}</text>
-            </rect>
-            <rect style={{ fill: ${color}, width: ${width}, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, height: 2, x: 0, y: 32 }} />
-          </group>
-        `;
+            <group>
+              <rect draggable="true" style={{width: ${width}, height: 26, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, fill: 'transparent' }}>
+                <text style={{ fontSize: 12, fill: ${cfg.fontcolor ? cfg.fontcolor : 'black'}, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, marginLeft: 12, marginTop: 6 }}>${cfg.label} ${cfg.collable ? '+' : ''}</text>
+              </rect>
+              <rect style={{ fill: ${color}, width: ${width}, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, height: 2, x: 0, y: 32 }} />
+            </group>
+          `;
         },
         getAnchorPoints() {
           return [
@@ -406,7 +416,7 @@
           data.color = color;
         }
     
-        if (d.children) {
+        if (d.children && !d.collapsed) {
           data.children = d.children.map((child) => changeData(child, level + 1, data.color));
         }
         return data;
@@ -447,9 +457,21 @@
           lineWidth: 2,
         },
       },
-      minZoom: 0.5,
+      minZoom: 0.3,
       modes: {
-        default: ['drag-canvas', 'zoom-canvas', 'dice-mindmap'],
+        default: [
+          {
+            type: 'collapse-expand',
+            trigger: 'click',
+            shouldBegin: (e, self) => {
+              if (e.item && e.item.getModel().collable) return true;
+              return false;
+            },
+          },
+          'drag-canvas',
+          'zoom-canvas',
+          'dice-mindmap'
+        ],
       },
     });
     
@@ -483,6 +505,7 @@
           </div>
           <div className="footer">
             <Button key="cancel" onClick={() => { this.setState({ visible: false })}}>鍏抽棴</Button>
+            <span className="tip">娉細鐐瑰嚮琛ㄥ悕鍙睍寮�/鏀惰捣鑿滃崟</span>
           </div>
         </Modal>
       </div>
diff --git a/src/menu/tablenodes/index.scss b/src/menu/tablenodes/index.scss
index 6cd97eb..f07caf4 100644
--- a/src/menu/tablenodes/index.scss
+++ b/src/menu/tablenodes/index.scss
@@ -42,7 +42,16 @@
   }
 
   .footer {
+    position: relative;
     text-align: center;
+
+    .tip {
+      position: absolute;
+      font-size: 12px;
+      color: #1890ff;
+      right: 10px;
+      top: 20px;
+    }
   }
   .tb-search {
     position: absolute;
diff --git a/src/mob/components/menubar/common-menubar/index.scss b/src/mob/components/menubar/common-menubar/index.scss
index d28f371..be019c0 100644
--- a/src/mob/components/menubar/common-menubar/index.scss
+++ b/src/mob/components/menubar/common-menubar/index.scss
@@ -6,17 +6,7 @@
   background-repeat: no-repeat;
   background-size: cover;
   min-height: 20px;
-  
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
+
   >.anticon-tool {
     position: absolute;
     z-index: 2;
diff --git a/src/mob/components/menubar/normal-menubar/index.scss b/src/mob/components/menubar/normal-menubar/index.scss
index e8b3434..6cfe56f 100644
--- a/src/mob/components/menubar/normal-menubar/index.scss
+++ b/src/mob/components/menubar/normal-menubar/index.scss
@@ -7,16 +7,6 @@
   background-size: cover;
   min-height: 20px;
   
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
   >.anticon-tool {
     position: absolute;
     z-index: 2;
diff --git a/src/mob/header/index.jsx b/src/mob/header/index.jsx
index 5bf90ea..38c5863 100644
--- a/src/mob/header/index.jsx
+++ b/src/mob/header/index.jsx
@@ -1,5 +1,4 @@
 import React, {Component} from 'react'
-import { Radio } from 'antd'
 
 import avatar from '@/assets/img/avatar.jpg'
 import MainLogo from '@/assets/img/main-logo.png'
@@ -8,26 +7,13 @@
 class MobHeader extends Component {
   state = {
     avatar: sessionStorage.getItem('CloudAvatar') || avatar,
-    userName: sessionStorage.getItem('CloudUserName'),
-    typename: sessionStorage.getItem('typename')
-  }
-
-  changeView = (e) => {
-    let val = e.target.value
-    this.props.changeView(val)
+    userName: sessionStorage.getItem('CloudUserName')
   }
 
   render () {
-    const { typename } = this.state
     return (
       <header className="mob-header-container">
         <div className="header-logo"><img src={MainLogo} alt=""/></div>
-        {typename === 'pad' ? <div className="change-view">
-          <Radio.Group defaultValue="vertical" onChange={this.changeView}>
-            <Radio value="vertical">绔栧睆</Radio>
-            <Radio value="horizontal">妯睆</Radio>
-          </Radio.Group>
-        </div> : null}
         <div className="header-user">
           <img src={this.state.avatar} alt=""/>
           <span>
diff --git a/src/mob/mobshell/index.jsx b/src/mob/mobshell/index.jsx
index 028e209..0063894 100644
--- a/src/mob/mobshell/index.jsx
+++ b/src/mob/mobshell/index.jsx
@@ -143,6 +143,7 @@
         timeline: '鏃堕棿杞�',
         officialAccount: '鍏虫敞鍏紬鍙�',
         sharecode: '鍒嗕韩鐮�',
+        iframe: 'iframe',
         login: '鐧诲綍'
       }
       let i = 1
diff --git a/src/pc/components/login/normal-login/index.scss b/src/pc/components/login/normal-login/index.scss
index e1b347c..037a7f7 100644
--- a/src/pc/components/login/normal-login/index.scss
+++ b/src/pc/components/login/normal-login/index.scss
@@ -8,18 +8,8 @@
   background-size: cover;
   min-height: 100px;
   max-width: 100%;
-  
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
-  .anticon-tool {
+
+  >.anticon-tool {
     position: absolute;
     z-index: 2;
     font-size: 16px;
diff --git a/src/pc/components/login/normal-login/loginform.jsx b/src/pc/components/login/normal-login/loginform.jsx
index 51a1189..fff2af3 100644
--- a/src/pc/components/login/normal-login/loginform.jsx
+++ b/src/pc/components/login/normal-login/loginform.jsx
@@ -139,9 +139,14 @@
     const { wrap } = this.props
     const { activeWay, loginWays, scanWay } = this.state
 
+    let style = {}
+    if (wrap.borderRadius) {
+      style.borderRadius = wrap.borderRadius
+    }
+
     return (
       <Form className="login-edit-form">
-        <div className="login-way-title">{activeWay.label}</div>
+        {wrap.topTip !== 'hidden' ? <div className="login-way-title">{activeWay.label}</div> : null}
         {scanWay && activeWay.type !== 'app_scan' ? <div className="scan-icon" onClick={() => this.onChangeTab(scanWay)}><QrcodeOutlined /></div> : null}
         {activeWay.type === 'uname_pwd' ? <div className={'form-item-wrap ' + (activeWay.shortcut === 'none' ? 'no-short' : '')}>
           <Form.Item>
@@ -161,7 +166,7 @@
             <Checkbox>鑷姩鐧诲綍</Checkbox>
           </Form.Item> : null}
           <Form.Item className="btn-login">
-            <Button type="primary" onDoubleClick={() => this.changeMenu()} className="login-form-button">
+            <Button type="primary" style={style} onDoubleClick={() => this.changeMenu()} className="login-form-button">
               鐧诲綍
             </Button>
           </Form.Item>
@@ -185,7 +190,7 @@
             />
           </Form.Item>
           <Form.Item className="btn-login">
-            <Button type="primary" onDoubleClick={() => this.changeMenu()} className="login-form-button">
+            <Button type="primary" style={style} onDoubleClick={() => this.changeMenu()} className="login-form-button">
               鐧诲綍
             </Button>
           </Form.Item>
diff --git a/src/pc/components/login/normal-login/options.jsx b/src/pc/components/login/normal-login/options.jsx
index 9731b8e..054fd0a 100644
--- a/src/pc/components/login/normal-login/options.jsx
+++ b/src/pc/components/login/normal-login/options.jsx
@@ -81,6 +81,27 @@
     },
     {
       type: 'radio',
+      field: 'topTip',
+      label: '椤堕儴鎻愮ず',
+      initval: wrap.topTip || 'show',
+      tooltip: '鐧诲綍鎴栨敞鍐屾柟寮忔彁绀轰俊鎭��',
+      required: false,
+      options: [
+        {value: 'show', label: '鏄剧ず'},
+        {value: 'hidden', label: '闅愯棌'}
+      ]
+    },
+    {
+      type: 'styleInput',
+      field: 'borderRadius',
+      label: '鍦嗚',
+      initval: wrap.borderRadius || '',
+      tooltip: '鐧诲綍鎴栨敞鍐屾椂锛岀‘瀹氭寜閽殑鍦嗚銆�',
+      required: false,
+      options: ['px', 'vh', 'vw', '%']
+    },
+    {
+      type: 'radio',
       field: 'classify',
       label: '缁勪欢绫诲瀷',
       initval: wrap.classify || 'login',
diff --git a/src/pc/components/login/normal-login/signform.jsx b/src/pc/components/login/normal-login/signform.jsx
index 9410986..4d3d42d 100644
--- a/src/pc/components/login/normal-login/signform.jsx
+++ b/src/pc/components/login/normal-login/signform.jsx
@@ -133,9 +133,14 @@
     const { wrap } = this.props
     const { activeWay, signWays, appType } = this.state
 
+    let style = {}
+    if (wrap.borderRadius) {
+      style.borderRadius = wrap.borderRadius
+    }
+
     return (
       <Form className="login-edit-form">
-        {appType === 'pc' ? <div className="login-way-title">{activeWay.label}</div> : null}
+        {appType === 'pc' && wrap.topTip !== 'hidden' ? <div className="login-way-title">{activeWay.label}</div> : null}
         {activeWay.type === 'uname_pwd' ? <div className="form-item-wrap">
           <Form.Item>
             <Input
@@ -151,7 +156,7 @@
             <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 type="primary" style={style} onDoubleClick={() => this.changeMenu()} className="sign-form-button">
             娉ㄥ唽
             </Button>
           </Form.Item>
@@ -178,7 +183,7 @@
             <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 type="primary" style={style} onDoubleClick={() => this.changeMenu()} className="sign-form-button">
               娉ㄥ唽
             </Button>
           </Form.Item>
diff --git a/src/pc/components/navbar/normal-navbar/index.scss b/src/pc/components/navbar/normal-navbar/index.scss
index ea0f488..3c9d934 100644
--- a/src/pc/components/navbar/normal-navbar/index.scss
+++ b/src/pc/components/navbar/normal-navbar/index.scss
@@ -58,17 +58,8 @@
       }
     }
   }
-  .card-control {
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    .anticon-tool {
-      right: auto;
-      left: 1px;
-      padding: 1px;
-    }
-  }
-  .anticon-tool {
+
+  >.anticon-tool {
     position: absolute;
     z-index: 2;
     font-size: 16px;
diff --git a/src/pc/menushell/index.jsx b/src/pc/menushell/index.jsx
index 64d7e2f..3bd54a3 100644
--- a/src/pc/menushell/index.jsx
+++ b/src/pc/menushell/index.jsx
@@ -114,7 +114,8 @@
         balcony: '娴姩鍗�',
         timeline: '鏃堕棿杞�',
         antvG6: '鏍戝浘',
-        login: '鐧诲綍'
+        login: '鐧诲綍',
+        iframe: 'iframe'
       }
       let i = 1
       
diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx
index bc4830a..0c35281 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, Typography } from 'antd'
+import { Col, Tooltip, notification, Typography, message } from 'antd'
 import moment from 'moment'
 
 import Api from '@/api'
@@ -768,6 +768,51 @@
             </div>
           </Col>
         )
+      } else if (card.eleType === 'color') {
+        let color = ''
+  
+        if (card.datatype === 'static') {
+          color = card.value
+        } else {
+          color = data[card.field] || ''
+        }
+  
+        if (color === '' && card.noValue === 'hide') { // 绌哄�奸殣钘�
+          return null
+        }
+
+        let _bgstyle = {backgroundColor: color}
+  
+        if (PicRadio[card.lenWidRadio]) {
+          _bgstyle.paddingTop = PicRadio[card.lenWidRadio]
+        } else {
+          _bgstyle.paddingTop = '100%'
+        }
+
+        if (card.copyable === 'true') {
+          _bgstyle.cursor = 'pointer'
+        }
+
+        contents.push(
+          <Col key={card.uuid} style={_style_} span={card.width}>
+            <div className="ant-mk-color" style={card.style}>
+              <div style={_bgstyle} onClick={(e) => {
+                if (card.copyable === 'true') {
+                  e.stopPropagation()
+
+                  let oInput = document.createElement('input')
+                  oInput.value = color
+                  document.body.appendChild(oInput)
+                  oInput.select()
+                  document.execCommand('Copy')
+                  document.body.removeChild(oInput)
+
+                  message.success('澶嶅埗鎴愬姛銆�')
+                }
+              }}></div>
+            </div>
+          </Col>
+        )
       } else if (card.eleType === 'button') {
         let _disabled = data.$disabled
         if (card.control === 'hidden') {
@@ -896,6 +941,7 @@
                   BData={data.$$BData || ''}
                   disabled={_disabled}
                   setting={cards.setting}
+                  columns={cards.columns}
                   selectedData={_data}
                 />
               </Col>
diff --git a/src/tabviews/custom/components/card/cardcellList/index.scss b/src/tabviews/custom/components/card/cardcellList/index.scss
index 587b487..1523314 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.scss
+++ b/src/tabviews/custom/components/card/cardcellList/index.scss
@@ -77,6 +77,11 @@
   .line10 {
     -webkit-line-clamp: 10;
   }
+  .ant-col:not(.mk-cell-btn) > div {
+    background-position: center center;
+    background-repeat: no-repeat;
+    background-size: cover;
+  }
   .mk-cell-btn {
     > div {width: 100%;max-width: 100%;}
     button:not(.ant-switch) {
@@ -158,6 +163,9 @@
     vertical-align: top;
     line-height: inherit;
   }
+  .ant-mk-color {
+    overflow: hidden;
+  }
   .ant-switch-large {
     min-width: 60px;
     height: 30px;
diff --git a/src/tabviews/custom/components/card/prop-card/index.jsx b/src/tabviews/custom/components/card/prop-card/index.jsx
index 14185b5..c6203d6 100644
--- a/src/tabviews/custom/components/card/prop-card/index.jsx
+++ b/src/tabviews/custom/components/card/prop-card/index.jsx
@@ -397,12 +397,18 @@
         data: _data,
         loading: false
       }, () => {
-        if (selected !== 'false') {
-          this.checkTopLine()
+        if (config.wrap.goback === 'true' && _data.$$empty) {
+          this.timer && this.timer.stop()
+
+          MKEmitter.emit('closeTabView', config.$pageId)
         } else {
-          this.transferLine()
+          if (selected !== 'false') {
+            this.checkTopLine()
+          } else {
+            this.transferLine()
+          }
+          this.autoExec()
         }
-        this.autoExec()
       })
 
       if (config.timer && config.clearField) {
diff --git a/src/tabviews/custom/components/chart/antv-G6/index.jsx b/src/tabviews/custom/components/chart/antv-G6/index.jsx
index 640f719..ab35200 100644
--- a/src/tabviews/custom/components/chart/antv-G6/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-G6/index.jsx
@@ -60,29 +60,7 @@
   },
   'single-node',
 )
-G6.registerNode(
-  'dice-mind-map-sub', {
-    jsx: (cfg) => {
-      const width = Util.getTextSize(cfg.label, 14)[0] + 24
 
-      return `
-        <group>
-          <rect style={{width: ${width}, height: 22, cursor: pointer}}>
-            <text style={{ fontSize: 14, fill: ${cfg.selected ? systemColor : '#000000'}, marginLeft: 12, marginTop: 6, cursor: pointer }}>${cfg.label}</text>
-          </rect>
-          <rect style={{ fill: ${cfg.color}, width: ${width}, height: 2, x: 0, y: 22, cursor: pointer }} />
-        </group>
-      `
-    },
-    getAnchorPoints() {
-      return [
-        [0, 0.965],
-        [1, 0.965]
-      ]
-    }
-  },
-  'single-node',
-)
 G6.registerNode(
   'dice-mind-map-leaf', {
     jsx: (cfg) => {
@@ -139,38 +117,6 @@
     ev.preventDefault()
   }
 })
-
-const dataMapTransform = (data) => {
-  const changeData = (d, level = 0, color) => {
-    const data = { ...d }
-
-    switch (level) {
-      case 0:
-        data.type = 'dice-mind-map-root'
-        break
-      case 1:
-        data.type = 'dice-mind-map-sub'
-        break
-      default:
-        data.type = 'dice-mind-map-leaf'
-        break
-    }
-
-    if (color) {
-      data.color = color
-    }
-
-    if (level === 1 && !d.direction) {
-      data.direction = 'right'
-    }
-
-    if (d.children) {
-      data.children = d.children.map((child) => changeData(child, level + 1, data.color))
-    }
-    return data
-  }
-  return changeData(data)
-}
 
 // 缂╄繘鏂囦欢鏍�
 G6.registerNode('indentedRoot', {
@@ -1223,6 +1169,8 @@
     root.children = root.children || []
 
     if (plot.subtype === 'mindmap') {
+      root.type = 'dice-mind-map-root'
+
       if (plot.dirField) {
         root.children = root.children.map(item => {
           item.direction = item[plot.dirField] === plot.dirSign ? 'left' : 'right'
@@ -1235,9 +1183,24 @@
         if (item.direction === 'left') {
           item.color = plot.leftColor || '#26C281'
         } else {
+          item.direction = 'right'
           item.color = plot.nodeColor || '#1890ff'
         }
       })
+
+      const collapse = (item) => {
+        if (!item.children) return
+
+        item.children.forEach(cell => {
+          cell.collapsed = plot.collapsed === 'true'
+          cell.direction = cell.direction || 'right'
+          cell.type = 'dice-mind-map-leaf'
+          cell.color = cell.color || item.color
+          collapse(cell)
+        })
+      }
+
+      collapse(root)
     } else if (plot.subtype === 'indentTree') {
       root.isRoot = true
       root.collapsed = false
@@ -1368,6 +1331,10 @@
     graph.data(data)
     graph.render()
     graph.fitView()
+
+    if (plot.collapsed === 'true') {
+      graph.zoomTo(1, { x: 0, y: plot.height / 2 })
+    }
   }
 
   indentrender = () => {
@@ -1437,10 +1404,16 @@
   ponitrender = () => {
     const { config, plot, chartId } = this.state
     const data = this.getdata()
+    const width = this.wrap.scrollWidth - 30
+    let modes = ['drag-canvas', 'zoom-canvas', config.uuid]
+
+    if (plot.collapsed === 'true') {
+      modes = [{ type: 'collapse-expand' }, 'drag-canvas', 'zoom-canvas', config.uuid]
+    }
 
     const tree = new G6.TreeGraph({
       container: chartId,
-      width: this.wrap.scrollWidth - 30,
+      width: width,
       height: plot.height,
       fitView: true,
       layout: {
@@ -1472,13 +1445,19 @@
       },
       minZoom: 0.5,
       modes: {
-        default: ['drag-canvas', 'zoom-canvas', config.uuid]
+        default: modes
       }
     })
 
-    tree.data(dataMapTransform(data))
+    tree.data(data)
 
     tree.render()
+
+    if (plot.collapsed === 'true' && plot.dirField) {
+      tree.zoomTo(1, { x: width / 2, y: plot.height / 2 })
+    } else if (plot.collapsed === 'true') {
+      tree.zoomTo(1, { x: 0, y: plot.height / 2 })
+    }
   }
 
   handleClick = (data = null) => {
diff --git a/src/tabviews/custom/components/iframe/index.jsx b/src/tabviews/custom/components/iframe/index.jsx
index e8d4fd5..62981a9 100644
--- a/src/tabviews/custom/components/iframe/index.jsx
+++ b/src/tabviews/custom/components/iframe/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Input, Modal, notification, Empty } from 'antd'
+import { Input, Modal, notification, Empty, Spin } from 'antd'
 
 import Api from '@/api'
 import UtilsDM from '@/utils/utils-datamanage.js'
@@ -82,8 +82,17 @@
   }
 
   componentDidMount () {
+    const { config } = this.state
+
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
+
+    if (config.wrap.linkType === 'input' && config.wrap.focus !== 'false') {
+      setTimeout(() => {
+        let node = document.getElementById(config.uuid)
+        node && node.select && node.select()
+      }, 200)
+    }
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -183,13 +192,9 @@
 
       this.setState({
         linkUrl: _data[config.wrap.linkField] || '',
-        data: _data,
-        loading: false
+        data: _data
       })
     } else {
-      this.setState({
-        loading: false
-      })
       if (result.ErrCode === 'N') {
         Modal.error({
           title: result.message,
@@ -215,30 +220,43 @@
     }
 
     if (submit) {
-      this.setState({linkUrl: val}, () => {
-        let node = document.getElementById(this.state.config.uuid)
-        node && node.select && node.select()
+      this.setState({linkUrl: '', loading: true}, () => {
+        this.setState({linkUrl: val})
       })
+
+      setTimeout(() => {
+        this.setState({loading: false}, () => {
+          let node = document.getElementById(this.state.config.uuid)
+          node && node.select && node.select()
+        })
+      }, 500)
     }
   }
 
   enterUrl = (val) => {
-    this.setState({linkUrl: val}, () => {
-      let node = document.getElementById(this.state.config.uuid)
-      node && node.select && node.select()
+    this.setState({linkUrl: '', loading: true}, () => {
+      this.setState({linkUrl: val})
     })
+
+    setTimeout(() => {
+      this.setState({loading: false}, () => {
+        let node = document.getElementById(this.state.config.uuid)
+        node && node.select && node.select()
+      })
+    }, 500)
   }
 
   render() {
-    const { config, linkUrl } = this.state
+    const { config, linkUrl, loading } = this.state
 
     return (
       <div className="menu-iframe-box" style={config.style}>
         {config.wrap.title || config.wrap.linkType === 'input' ? <div className="iframe-header" style={config.headerStyle}>
           <span className="title">{config.wrap.title}</span>
-          {config.wrap.linkType === 'input' ? <Search id={config.uuid} placeholder="璇疯緭鍏ュ湴鍧�" onChange={this.inputUrl} onSearch={this.enterUrl} enterButton="纭畾"/> : null}
+          {config.wrap.linkType === 'input' ? <Search id={config.uuid} disabled={loading} placeholder="璇疯緭鍏ュ湴鍧�" onChange={this.inputUrl} onSearch={this.enterUrl} enterButton="纭畾"/> : null}
         </div> : null}
         <div className="iframe-wrap" style={{height: config.wrap.height}}>
+          {loading ? <div className="mask"><Spin size="large" /></div> : null}
           {linkUrl ? <iframe title="mk" className="iframe" src={linkUrl} frameBorder="0"></iframe> : <Empty description={false}/>}
         </div>
       </div>
diff --git a/src/tabviews/custom/components/iframe/index.scss b/src/tabviews/custom/components/iframe/index.scss
index 9ca59f4..3e97448 100644
--- a/src/tabviews/custom/components/iframe/index.scss
+++ b/src/tabviews/custom/components/iframe/index.scss
@@ -33,9 +33,15 @@
 
     .ant-input-search {
       margin-top: 5px;
-      width: 40%;
-      max-width: 400px;
+      width: 65%;
       float: right;
+
+      .ant-btn[disabled] {
+        background-color: var(--mk-sys-color)!important;
+        border-color: var(--mk-sys-color)!important;
+        color: #ffffff!important;
+        opacity: 0.5;
+      }
     }
   }
 
@@ -57,5 +63,21 @@
       vertical-align: top;
       margin-top: 0px;
     }
+
+    .mask {
+      position: absolute;
+      width: 100%;
+      height: 100%;
+      left: 0px;
+      top: 0px;
+      background: #ffffff;
+      z-index: 1;
+
+      .ant-spin {
+        position: absolute;
+        left: calc(50% - 16px);
+        top: calc(50% - 16px);
+      }
+    }
   }
 }
diff --git a/src/tabviews/custom/components/module/account/index.jsx b/src/tabviews/custom/components/module/account/index.jsx
new file mode 100644
index 0000000..1a9a7b6
--- /dev/null
+++ b/src/tabviews/custom/components/module/account/index.jsx
@@ -0,0 +1,148 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { notification, Select, Divider } from 'antd'
+import { PlusOutlined } from '@ant-design/icons'
+
+import Api from '@/api'
+import MKEmitter from '@/utils/events.js'
+import './index.scss'
+
+const { Option } = Select
+
+class AccountModule extends Component {
+  static propTpyes = {
+    config: PropTypes.object
+  }
+
+  state = {
+    activeItem: null,
+    books: []
+  }
+
+  componentDidMount () {
+    this.loadData()
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  loadData = () => {
+    let param = {
+      func: 's_get_fcc_book_data'
+    }
+
+    Api.genericInterface(param).then(res => {
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        return
+      }
+
+      let books = res.book || []
+      let activeItem = null
+      let map = new Map()
+      books = books.filter(item => {
+        if (!item.id) return false
+        if (map.has(item.id)) return false
+        map.set(item.id, true)
+
+        if (item.selected === 'true' && !activeItem) {
+          activeItem = item
+        }
+        if (item.months) {
+          item.date = item.months.replace('-', '骞�') + '鏈�'
+        }
+        return true
+      })
+
+      if (!activeItem && books.length > 0) {
+        activeItem = books[0]
+      }
+
+      this.setState({books, activeItem})
+
+      if (activeItem) {
+        MKEmitter.emit('resetSelectLine', this.props.config.uuid, activeItem.id, activeItem)
+      }
+    })
+  }
+
+  changeBook = (value) => {
+    const { books } = this.state
+
+    let activeItem = books.filter(item => item.id === value)[0]
+
+    this.setState({activeItem})
+
+    if (activeItem) {
+      MKEmitter.emit('resetSelectLine', this.props.config.uuid, activeItem.id, activeItem)
+    }
+  }
+
+  addBook = () => {
+    const { config } = this.props
+
+    let menuId = config.wrap.MenuID
+    let menu = window.GLOB.mkThdMenus.filter(m => m.MenuID === menuId)[0]
+
+    if (!menu && config.wrap.MenuNo) {
+      menu = {
+        MenuID: menuId,
+        MenuName: config.wrap.MenuName,
+        MenuNo: config.wrap.MenuNo || '',
+        type: config.wrap.tabType
+      }
+    }
+
+    let newtab = {
+      ...menu,
+      param: {}
+    }
+
+    MKEmitter.emit('modifyTabs', newtab, true)
+  }
+
+  render() {
+    const { config } = this.props
+    const { activeItem, books } = this.state
+
+    return (
+      <div className="menu-account-wrap" style={config.style}>
+        {config.wrap.MenuID ? <Select value={activeItem ? activeItem.id : ''} placeholder="璇烽�夋嫨璐﹀" onChange={this.changeBook} dropdownRender={menu => (
+          <div>
+            {menu}
+            <Divider style={{ margin: '4px 0' }} />
+            <div className="mk-add-book" onMouseDown={this.addBook}>
+              <PlusOutlined /> 鐐瑰嚮鏂板璐﹀
+            </div>
+          </div>
+        )}>
+          {books.map(item => (
+            <Option key={item.id}>{item.account_name}</Option>
+          ))}
+        </Select> : <Select value={activeItem ? activeItem.id : ''} placeholder="璇烽�夋嫨璐﹀" onChange={this.changeBook}>
+          {books.map(item => (
+            <Option key={item.id}>{item.account_name}</Option>
+          ))}
+        </Select>}
+        {activeItem ? <span className="date">{activeItem.date}</span> : null}
+      </div>
+    )
+  }
+}
+
+export default AccountModule
\ No newline at end of file
diff --git a/src/tabviews/custom/components/module/account/index.scss b/src/tabviews/custom/components/module/account/index.scss
new file mode 100644
index 0000000..4b04107
--- /dev/null
+++ b/src/tabviews/custom/components/module/account/index.scss
@@ -0,0 +1,27 @@
+.menu-account-wrap {
+  position: relative;
+  box-sizing: border-box;
+  background: #ffffff;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-size: cover;
+  color: #000000;
+
+  .ant-select {
+    min-width: 250px;
+    max-width: 300px;
+    color: #000000;
+  }
+
+  .date {
+    margin-left: 15px;
+  }
+}
+
+.mk-add-book {
+  padding: 4px 8px 10px;
+  cursor: pointer;
+  text-align: center;
+  color: var(--mk-sys-color);
+}
+
diff --git a/src/tabviews/custom/components/module/voucher/index.jsx b/src/tabviews/custom/components/module/voucher/index.jsx
index bd053ab..e423749 100644
--- a/src/tabviews/custom/components/module/voucher/index.jsx
+++ b/src/tabviews/custom/components/module/voucher/index.jsx
@@ -1,11 +1,12 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Button, Select, Input, DatePicker } from 'antd'
-// import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
+import { Button, Select, Input, DatePicker, notification } from 'antd'
+import moment from 'moment'
 
+import Api from '@/api'
 import asyncComponent from '@/utils/asyncComponent'
-// import MKEmitter from '@/utils/events.js'
+import MKEmitter from '@/utils/events.js'
 import './index.scss'
 
 const VoucherTable = asyncComponent(() => import('./voucherTable'))
@@ -17,14 +18,13 @@
 
   state = {
     BID: '',
-    type: '',
     config: null,
     loading: false,
     data: null,
-    searchkey: null,
-    disableAdd: true,
-    disableSave: true,
-    typeOptions: []
+    disableAdd: false,
+    disableSave: false,
+    typeOptions: [],
+    book: null
   }
 
   UNSAFE_componentWillMount () {
@@ -33,8 +33,8 @@
     let BID = ''
     let BData = ''
 
-    if (config.setting.supModule) {
-      BData = window.GLOB.CacheData.get(config.setting.supModule)
+    if (config.wrap.supModule) {
+      BData = window.GLOB.CacheData.get(config.wrap.supModule)
     } else {
       BData = window.GLOB.CacheData.get(config.$pageId)
     }
@@ -45,14 +45,14 @@
     this.setState({
       config: fromJS(config).toJS(),
       BID: BID || '',
-      type: config.wrap.type
+      book: window.GLOB.CacheData.get(config.wrap.supBook) || null
     }, () => {
       this.loadData()
     })
   }
 
   componentDidMount () {
-
+    MKEmitter.addListener('resetSelectLine', this.resetParentParam)
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -66,10 +66,51 @@
     this.setState = () => {
       return
     }
+
+    MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
+  }
+
+  resetParentParam = (MenuID, id, data) => {
+    const { config } = this.state
+
+    if (config.wrap.supBook === MenuID) {
+      this.setState({ book: data }, () => {
+        this.loadData()
+      })
+      return
+    }
+
+    if (!config.wrap.supModule || config.wrap.supModule !== MenuID) return
+    if (id !== this.state.BID || id !== '') {
+      this.setState({ BID: id, BData: data }, () => {
+        this.loadData()
+      })
+    }
   }
 
   loadData = () => {
+    const { book } = this.state
 
+    if (!book) return
+
+    let param = {
+      func: 's_get_fcc_account_data',
+      account_code: book.account_code || '',
+      fcc_date: book.months ? book.months + '-01' : moment().format('YYYY-MM-DD')
+    }
+
+    Api.genericInterface(param).then(res => {
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        return
+      }
+
+      
+    })
   }
 
   triggeradd = () => {
@@ -85,21 +126,21 @@
   }
 
   render() {
-    const { config, disableSave, disableAdd, typeOptions, data, type } = this.state
+    const { config, disableSave, disableAdd, typeOptions, data } = this.state
 
     return (
       <div className="menu-voucher-wrap" style={config.style}>
         <div className="voucher-header">
-          <Button className="system-background header-btn" disabled={disableAdd} onClick={this.triggeradd}>鏂板</Button>
-          <Button className="system-background header-btn" disabled={disableSave} onClick={this.triggersave}>淇濆瓨</Button>
-          <Button className="system-background header-btn" disabled={disableSave} onClick={this.triggerprint}>鎵撳嵃</Button>
+          <Button className="add-background header-btn" disabled={disableAdd} onClick={this.triggeradd}>鏂板</Button>
+          <Button className="add-background header-btn" disabled={disableSave} onClick={this.triggersave}>淇濆瓨</Button>
+          <Button className="print-background header-btn" disabled={disableSave} onClick={this.triggerprint}>鎵撳嵃</Button>
           <Button className="system-background header-btn" disabled={disableSave} onClick={this.triggerprint}>瀵煎叆</Button>
-          <Button className="system-background header-btn" disabled={disableSave} onClick={this.triggerprint}>瀵煎嚭</Button>
+          <Button className="out-background header-btn" disabled={disableSave} onClick={this.triggerprint}>瀵煎嚭</Button>
         </div>
-        {type === 'edit' ? <div className="voucher-body">
+        {config.wrap.type === 'edit' ? <div className="voucher-body">
           <div className="pre-wrap">
             <div className="voucher-code">
-              <Select>
+              <Select dropdownClassName="mk-vcode-dropdown">
                 {typeOptions.map(option =>
                   <Select.Option value={option.value}>{option.label}</Select.Option>
                 )}
@@ -117,7 +158,7 @@
           </div>
           <VoucherTable config={config} data={data}/>
         </div> : null}
-        {type === 'check' ? <div className="voucher-body">
+        {config.wrap.type === 'check' ? <div className="voucher-body">
           <div className="pre-wrap">
             <div className="voucher-code">
               璁� 1 鍙�
diff --git a/src/tabviews/custom/components/module/voucher/index.scss b/src/tabviews/custom/components/module/voucher/index.scss
index 0137321..e3b1dd9 100644
--- a/src/tabviews/custom/components/module/voucher/index.scss
+++ b/src/tabviews/custom/components/module/voucher/index.scss
@@ -51,6 +51,35 @@
       }
     }
   }
+
+  .add-background {
+    background: #26C281;
+    border-color: #26C281;
+    color: #ffffff;
+  }
+  .print-background {
+    background-color: #8E44AD;
+    border-color: #8E44AD;
+    color: #ffffff;
+  }
+  .out-background {
+    background-color: rgb(50, 197, 210);
+    border-color: rgb(50, 197, 210);
+    color: #ffffff;
+  }
+
+  .system-background {
+    background: var(--mk-sys-color);
+    border-color: var(--mk-sys-color);
+    color: #ffffff;
+  }
 }
 
-
+.mk-vcode-dropdown {
+  .ant-empty-image svg {
+    max-width: 100%;
+  }
+  .ant-empty-description {
+    display: none;
+  }
+}
diff --git a/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx b/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
index d4bb231..2bcbd81 100644
--- a/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
+++ b/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
@@ -1,8 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Table, Modal, Input, InputNumber, notification, message } from 'antd'
-// import { EditOutlined } from '@ant-design/icons'
+import { Table, Modal, Input, InputNumber, notification, message, AutoComplete } from 'antd'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
@@ -120,6 +119,10 @@
     this.setState({value: val})
   }
 
+  complete = (key, option) => {
+    this.setState({value: option.props.value})
+  }
+
   render() {
     let { col, record, className } = this.props
     const { editing } = this.state
@@ -135,7 +138,19 @@
         colSpan = 2
       } else {
         if (editing) {
-          children = <Input.TextArea id={col.uuid + record.uuid} autoSize={false} defaultValue={val} onChange={(e) => this.onChange(e.target.value)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
+          let options = ['鐜伴噾', '鍙戠エ']
+          children = <AutoComplete
+            dataSource={options.map((cell, i) => <AutoComplete.Option value={cell} key={i}>
+              {cell}
+            </AutoComplete.Option>)}
+            filterOption={(input, option) => option.props.children.indexOf(input) > -1}
+            onSelect={this.complete}
+            defaultValue={val}
+            onChange={(val) => this.onChange(val)}
+            defaultOpen={true}
+          >
+            <Input.TextArea id={col.uuid + record.uuid} autoSize={false} defaultValue={val} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
+          </AutoComplete>
         } else {
           children = <div className="content-wrap" onClick={this.focus}>{val}</div>
         }
diff --git a/src/tabviews/custom/components/module/voucher/voucherTable/index.scss b/src/tabviews/custom/components/module/voucher/voucherTable/index.scss
index e8175c8..5114008 100644
--- a/src/tabviews/custom/components/module/voucher/voucherTable/index.scss
+++ b/src/tabviews/custom/components/module/voucher/voucherTable/index.scss
@@ -112,6 +112,18 @@
       }
     }
   }
+
+  .ant-select-auto-complete {
+    width: 100%;
+    .ant-input {
+      height: 60px;
+      border-radius: 0;
+      resize: none;
+    }
+    .ant-select-selection {
+      height: 60px;
+    }
+  }
   .ant-input {
     height: 60px;
     border-radius: 0;
@@ -169,91 +181,3 @@
     }
   }
 }
-.edit-custom-table.editable {
-  td {
-    background-color: #ffffff!important;
-  }
-  td.pointer .mk-mask {
-    display: block;
-  }
-  .mk-operation {
-    display: none;
-  }
-  .ant-table-placeholder {
-    display: none;
-  }
-}
-.edit-custom-table:not(.fixed-height) {
-  .ant-table-body::-webkit-scrollbar {
-    width: 8px;
-    height: 10px;
-  }
-  ::-webkit-scrollbar-thumb {
-    border-radius: 5px;
-    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
-    background: rgba(0, 0, 0, 0.13);
-  }
-  ::-webkit-scrollbar-track {/*婊氬姩鏉¢噷闈㈣建閬�*/
-    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
-    border-radius: 3px;
-    border: 1px solid rgba(0, 0, 0, 0.07);
-    background: rgba(0, 0, 0, 0);
-  }
-}
-.edit-custom-table.fixed-height {
-  .ant-table-body {
-    border-bottom: 1px solid rgba(0, 0, 0, .05);
-    .ant-table-fixed {
-      border-bottom: 0;
-    }
-  }
-}
-.edit-custom-table.hidden {
-  thead {
-    display: none;
-  }
-}
-.edit-custom-table.ghost {
-  .ant-table-thead > tr {
-    > th {
-      color: inherit;
-      background: transparent;
-      .ant-table-column-sorter .ant-table-column-sorter-inner {
-        color: inherit;
-      }
-    }
-    > th:hover {
-      background: transparent;
-    }
-  }
-  .ant-table-body {
-    overflow-x: auto;
-    tr {
-      td {
-        background: transparent!important;
-      }
-    }
-    tr:hover td {
-      background: transparent!important;
-    }
-  }
-}
-.image-scale-modal {
-  width: 70vw;
-  min-height: 80vh;
-  top: 10vh;
-  .ant-modal-body {
-    min-height: calc(80vh - 110px);
-    line-height: calc(80vh - 160px);
-    text-align: center;
-  }
-  .ant-modal-footer {
-    text-align: center;
-    span {
-      display: inline-block;
-      color: #1890ff;
-      padding: 5px 15px;
-      cursor: pointer;
-    }
-  }
-}
\ 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 34e9aad..7cb3013 100644
--- a/src/tabviews/custom/components/share/normalTable/index.jsx
+++ b/src/tabviews/custom/components/share/normalTable/index.jsx
@@ -385,7 +385,10 @@
         <CardCellComponent data={record} cards={config} elements={col.elements}/>
       )
     } else if (col.type === 'action') {
-      style.padding = '0px 5px'
+      style.padding = '0px'
+      if (col.style) {
+        style = {...style, ...col.style}
+      }
       resProps.children = (
         <CardCellComponent data={record} cards={config} elements={col.elements}/>
       )
@@ -960,7 +963,7 @@
     let height = setting.height || false
 
     return (
-      <div className={`normal-custom-table ${setting.tableHeader || ''} ${height ? 'fixed-height' : ''} ${setting.mode || ''}`} id={tableId}>
+      <div className={`normal-custom-table ${setting.tableHeader || ''} ${height ? 'fixed-height' : ''} ${setting.mode || ''} table-vertical-${setting.vertical || ''}`} id={tableId}>
         {(setting.tableType === 'radio' || setting.tableType === 'checkbox') && data && data.length > 0 ?
           <Switch title="鏀惰捣" className="main-pickup" checkedChildren="寮�" unCheckedChildren="鍏�" checked={pickup} onChange={this.pickupChange} /> : null
         }
diff --git a/src/tabviews/custom/components/share/normalTable/index.scss b/src/tabviews/custom/components/share/normalTable/index.scss
index a339616..e27e134 100644
--- a/src/tabviews/custom/components/share/normalTable/index.scss
+++ b/src/tabviews/custom/components/share/normalTable/index.scss
@@ -94,7 +94,7 @@
         // vertical-align: top;
 
         .card-cell-list {
-          color: rgba(0, 0, 0, 0.85);
+          color: inherit;
         }
         .ant-mk-picture {
           position: relative;
@@ -204,12 +204,10 @@
   }
   table tr {
     th .ant-table-column-title {
-      // color: var(--mk-table-color)!important;
       font-size: var(--mk-table-font-size)!important;
       font-weight: var(--mk-table-font-weight)!important;
     }
     td {
-      color: var(--mk-table-color)!important;
       font-size: var(--mk-table-font-size)!important;
       font-weight: var(--mk-table-font-weight)!important;
 
@@ -218,6 +216,9 @@
       }
     }
   }
+  table tbody tr {
+    color: var(--mk-table-color);
+  }
 }
 .normal-custom-table:not(.fixed-height) {
   .ant-table-body::-webkit-scrollbar {
diff --git a/src/tabviews/custom/components/table/base-table/index.scss b/src/tabviews/custom/components/table/base-table/index.scss
index dd90bb5..34f97b7 100644
--- a/src/tabviews/custom/components/table/base-table/index.scss
+++ b/src/tabviews/custom/components/table/base-table/index.scss
@@ -7,6 +7,7 @@
   }
   .top-search {
     border-bottom: 1px solid #efefef;
+    padding-top: 10px;
   }
   >.button-list.toolbar-button {
     min-height: 60px;
diff --git a/src/tabviews/custom/components/table/edit-table/index.scss b/src/tabviews/custom/components/table/edit-table/index.scss
index 686b44b..16ea698 100644
--- a/src/tabviews/custom/components/table/edit-table/index.scss
+++ b/src/tabviews/custom/components/table/edit-table/index.scss
@@ -7,6 +7,7 @@
   }
   .top-search {
     border-bottom: 1px solid #efefef;
+    padding-top: 10px;
   }
   >.button-list.toolbar-button {
     padding: 0;
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 19bf7e3..b2fdec6 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -507,7 +507,10 @@
         <CardCellComponent data={record} cards={config} elements={col.elements}/>
       )
     } else if (col.type === 'action') {
-      style.padding = '0px 5px'
+      style.padding = '0px'
+      if (col.style) {
+        style = {...style, ...col.style}
+      }
       children = (
         <CardCellComponent data={record} cards={config} elements={col.elements}/>
       )
@@ -1988,7 +1991,7 @@
           {!submit.hasAction && pickup ? <Button style={submit.style} onClick={() => setTimeout(() => {this.checkData()}, 10)} loading={loading} className="submit-table" type="link">鎻愪氦</Button> : null}
           <Switch title="缂栬緫" className="main-pickup" checkedChildren="寮�" unCheckedChildren="鍏�" disabled={loading || this.props.loading} checked={pickup} onChange={this.pickupChange} />
         </div>
-        <div className={`edit-custom-table ${pickup ? 'editable' : ''} ${setting.tableHeader || ''} ${setting.operType || ''} ${height ? 'fixed-height' : ''} ${setting.mode || ''}`} id={tableId}>
+        <div className={`edit-custom-table ${pickup ? 'editable' : ''} ${setting.tableHeader || ''} ${setting.operType || ''} ${height ? 'fixed-height' : ''} ${setting.mode || ''} table-vertical-${setting.vertical || ''}`} id={tableId}>
           <Table
             rowKey="$$uuid"
             components={components}
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 971228d..25f0089 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
@@ -72,7 +72,7 @@
         // vertical-align: top;
 
         .card-cell-list {
-          color: rgba(0, 0, 0, 0.85);
+          color: inherit;
         }
         .action-col {
           .ant-btn > .anticon + span {
@@ -292,12 +292,10 @@
   }
   table tr {
     th .ant-table-column-title, th .ant-table-column-title span:not(.anticon) {
-      // color: var(--mk-table-color)!important;
       font-size: var(--mk-table-font-size)!important;
       font-weight: var(--mk-table-font-weight)!important;
     }
     td {
-      color: var(--mk-table-color)!important;
       font-size: var(--mk-table-font-size)!important;
       font-weight: var(--mk-table-font-weight)!important;
 
@@ -306,6 +304,9 @@
       }
     }
   }
+  table tbody tr {
+    color: var(--mk-table-color);
+  }
 }
 .edit-custom-table.buoyMode {
   .ant-table-scroll {
diff --git a/src/tabviews/custom/components/table/normal-table/index.scss b/src/tabviews/custom/components/table/normal-table/index.scss
index c628e76..22eb16b 100644
--- a/src/tabviews/custom/components/table/normal-table/index.scss
+++ b/src/tabviews/custom/components/table/normal-table/index.scss
@@ -7,6 +7,7 @@
   }
   .top-search {
     border-bottom: 1px solid #efefef;
+    padding-top: 10px;
   }
   >.button-list.toolbar-button {
     min-height: 60px;
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index 3a28d2d..453c221 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -40,6 +40,7 @@
 const TimeLine = asyncComponent(() => import('./components/timeline/normal-timeline'))
 const AntvG6 = asyncComponent(() => import('./components/chart/antv-G6'))
 const Voucher = asyncComponent(() => import('./components/module/voucher'))
+const Account = asyncComponent(() => import('./components/module/account'))
 const Iframe = asyncComponent(() => import('./components/iframe'))
 const DebugTable = asyncComponent(() => import('@/tabviews/debugtable'))
 const TableNodes = asyncComponent(() => import('@/tabviews/zshare/tablenodes'))
@@ -838,6 +839,10 @@
 
       component.setting.useMSearch = component.setting.useMSearch === 'true'
 
+      if (component.wrap && component.wrap.goback === 'true') {
+        component.setting.sync = 'false'
+      }
+
       if (component.setting.interType !== 'system') { // 涓嶄娇鐢ㄧ郴缁熷嚱鏁版椂
         component.setting.sync = 'false'
         component.setting.laypage = component.setting.laypage === 'true'
@@ -1272,6 +1277,12 @@
             <Voucher config={item}/>
           </Col>
         )
+      } else if (item.type === 'module' && item.subtype === 'account') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <Account config={item}/>
+          </Col>
+        )
       } else if (item.type === 'iframe') {
         return (
           <Col span={item.width} style={style} key={item.uuid}>
diff --git a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
index f658b86..8dc3084 100644
--- a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -195,7 +195,7 @@
         })
         viewParam.arr_field = viewParam.arr_field.join(',')
 
-        viewParam.orderBy = btn.verify.order || viewParam.orderBy
+        viewParam.orderBy = btn.verify.order || ''
       }
     }
     if (btn.intertype === 'system' && btn.verify.enable === 'true') {
diff --git a/src/tabviews/zshare/actionList/index.jsx b/src/tabviews/zshare/actionList/index.jsx
index 7dd0d4b..911e141 100644
--- a/src/tabviews/zshare/actionList/index.jsx
+++ b/src/tabviews/zshare/actionList/index.jsx
@@ -1,7 +1,8 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Affix } from 'antd'
+import { Affix, Dropdown } from 'antd'
+import { DownOutlined } from '@ant-design/icons'
 
 import asyncComponent from './asyncButtonComponent'
 import './index.scss'
@@ -29,7 +30,25 @@
     setting: PropTypes.any,           // 椤甸潰閫氱敤璁剧疆
   }
 
-  state = {}
+  state = {
+    actions: [],
+    mores: null
+  }
+
+  UNSAFE_componentWillMount() {
+    const { setting, actions } = this.props
+
+    if (!setting.btnlimit || setting.btnlimit >= actions.length) {
+      this.setState({actions: actions})
+    } else {
+      let mores = fromJS(actions).toJS()
+      
+      this.setState({
+        actions: mores.splice(0, setting.btnlimit),
+        mores
+      })
+    }
+  }
 
   shouldComponentUpdate (nextProps, nextState) {
     return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
@@ -139,6 +158,7 @@
               btn={item}
               BData={BData}
               setting={setting}
+              columns={columns}
               selectedData={selectedData}
             />
           )
@@ -173,7 +193,8 @@
   }
 
   render() {
-    const { setting, MenuID, actions } = this.props
+    const { setting, MenuID } = this.props
+    const { actions, mores } = this.state
     let fixed = setting.actionfixed && setting.tabType === 'main' // 鎸夐挳鏄惁鍥哄畾鍦ㄥご閮�
 
     if (fixed && MenuID) {
@@ -181,6 +202,9 @@
         <Affix offsetTop={48}>
           <div className="button-list toolbar-button" id={fixed ? MenuID + 'mainaction' : ''}>
             {this.getButtonList(actions)}
+            {mores ? <Dropdown overlay={<div className="mk-button-dropdown-wrap">{this.getButtonList(mores)}</div>} trigger={['hover']}>
+              <div className="mk-more">鏇村<DownOutlined/></div>
+            </Dropdown> : null}
           </div>
         </Affix>
       )
@@ -188,6 +212,9 @@
       return (
         <div className="button-list toolbar-button" id={fixed ? MenuID + 'mainaction' : ''}>
           {this.getButtonList(actions)}
+          {mores ? <Dropdown overlay={<div className="mk-button-dropdown-wrap">{this.getButtonList(mores)}</div>} trigger={['hover']}>
+            <div className="mk-more">鏇村<DownOutlined/></div>
+          </Dropdown> : null}
         </div>
       )
     }
diff --git a/src/tabviews/zshare/actionList/index.scss b/src/tabviews/zshare/actionList/index.scss
index cd544eb..69b5302 100644
--- a/src/tabviews/zshare/actionList/index.scss
+++ b/src/tabviews/zshare/actionList/index.scss
@@ -26,3 +26,34 @@
     display: none;
   }
 }
+.mk-more {
+  display: inline-block;
+  height: 28px;
+  border: 1px solid #d8d8d8;
+  line-height: 28px;
+  padding: 0 10px 0px 20px;
+  border-radius: 4px;
+  cursor: pointer;
+  .anticon-down {
+    margin-left: 3px;
+  }
+}
+.mk-button-dropdown-wrap {
+  box-shadow: 0 0 2px #bcbcbc;
+  background: #ffffff;
+  min-width: 85px;
+  button {
+    display: block;
+    margin: 0!important;
+    width: 100%;
+    height: 34px;
+    border-radius: 0px;
+    padding-left: 15px!important;
+    .anticon {
+      display: none;
+    }
+    .anticon + span {
+      margin-left: 0px;
+    }
+  }
+}
diff --git a/src/tabviews/zshare/actionList/printbutton/index.jsx b/src/tabviews/zshare/actionList/printbutton/index.jsx
index 988c039..1f9b31a 100644
--- a/src/tabviews/zshare/actionList/printbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -27,6 +27,7 @@
     MenuID: PropTypes.string,         // 鑿滃崟ID
     btn: PropTypes.object,            // 鎸夐挳
     setting: PropTypes.any,           // 椤甸潰閫氱敤璁剧疆
+    columns: PropTypes.array,
     disabled: PropTypes.any,          // 琛屾寜閽鐢�
   }
 
@@ -190,6 +191,13 @@
         duration: 5
       })
       return
+    } else if (btn.intertype === 'system' && btn.verify.dataType === 'custom' && (!btn.verify.setting || btn.verify.columns.length === 0)) {
+      notification.warning({
+        top: 92,
+        message: '鑷畾涔夋墦鍗版暟鎹璁剧疆鏁版嵁婧愶紒',
+        duration: 5
+      })
+      return
     }
 
     this.setState({
@@ -244,70 +252,52 @@
   triggerNormalPrint = (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 _key = _data.key.toLowerCase()
+      formdata[_key] = _data.value
     })
 
     let printlist = []
     let templates = []
 
-    if (isNaN(baseCount) || baseCount < 1) {
-      baseCount = 1
-    }
-
     new Promise(resolve => {
-      if (btn.intertype === 'system') { // 浣跨敤绯荤粺鏃讹紝鐩存帴浠庤〃鏍兼垨琛ㄥ崟涓�夊彇鏁版嵁
+      if (btn.intertype === 'system' && btn.verify.dataType !== 'custom') { // 浣跨敤绯荤粺鏃讹紝鐩存帴浠庤〃鏍兼垨琛ㄥ崟涓�夊彇鏁版嵁
         if (btn.Ot === 'notRequired') {
           let printcell = {}
   
-          printcell.printType = baseType
-          printcell.printCount = baseCount
-          printcell.templateID = baseTemp
+          printcell.printType = formdata.printtype || ''
+          printcell.printCount = +(formdata.printcount || 1)
+          printcell.templateID = formdata.templateid || btn.verify.Template || ''
+
           printcell.data = [formdata]
+
+          if (isNaN(printcell.printCount) || printcell.printCount < 1) {
+            printcell.printCount = 1
+          }
 
           templates.push(printcell.templateID)
 
           printlist.push(printcell)
         } else {
           data.forEach(cell => {
-            let _cell = {...cell, ...formdata}
+            let _cell = {}
+
+            Object.keys(cell).forEach(key => {
+              let _key = key.toLowerCase()
+              _cell[_key] = cell[key]
+            })
+
+            _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]
-              }
-            })
+            printcell.printType = _cell.printtype || ''
+            printcell.printCount = +(_cell.printcount || 1)
+            printcell.templateID = _cell.templateid || btn.verify.Template || ''
 
             if (isNaN(printcell.printCount) || printcell.printCount < 1) {
-              printcell.printCount = baseCount
+              printcell.printCount = 1
             }
 
             templates.push(printcell.templateID)
@@ -316,58 +306,71 @@
           })
         }
 
-        resolve(true)
+        if (btn.verify.printMode === 'custom') {
+          this.execCustomPrint(printlist, formdata)
+          resolve(false)
+        } else {
+          resolve(true)
+        }
       } else {
         this.getprintdata(btn, data, formdata, formlist).then(result => {
-          if (result.next) {
-            result.list.forEach(cell => {
-              // 绯荤粺鎵撳嵃鏁版嵁锛屾牎楠宒ata瀛楁
-              if (btn.verify.printMode !== 'custom' && (!cell.data || cell.data.length === 0)) return
+          if (!result.next) {
+            resolve(false)
+            return
+          }
 
-              let templateID = baseTemp
-              let printType = baseType
-              let printCount = 0
+          // 鑷畾涔夋墦鍗�
+          if (btn.verify.printMode === 'custom') {
+            this.execCustomPrint(result.list, formdata)
+            resolve(false)
+            return
+          }
 
-              Object.keys(cell).forEach(key => {
-                if (!cell[key]) return
+          result.list.forEach(cell => {
+            // 绯荤粺鎵撳嵃鏁版嵁锛屾牎楠宒ata瀛楁
+            if (!cell.data || cell.data.length === 0) return
 
+            Object.keys(cell).forEach(key => {
+              let _key = key.toLowerCase()
+              if (['templateid', 'printtype', 'printcount'].includes(_key)) {
+                cell[_key] = cell[key]
+              }
+            })
+
+            cell.data.forEach(item => {
+              let _item = {...formdata}
+
+              _item.printtype = cell.printtype || ''
+              _item.printcount = cell.printcount || 1
+              _item.templateid = cell.templateid || ''
+
+              Object.keys(item).forEach(key => {
                 let _key = key.toLowerCase()
-
-                if (_key === 'templateid') {
-                  templateID = cell[key]
-                } else if (_key === 'printtype') {
-                  printType = cell[key]
-                } else if (_key === 'printcount') {
-                  printCount = +cell[key]
-                }
+                _item[_key] = item[key]
               })
 
-              cell.templateID = templateID
-              cell.printType = printType
-              cell.printCount = printCount
+              let printcell = {data: [_item]}
+  
+              printcell.printType = _item.printtype || ''
+              printcell.printCount = +(_item.printcount || 1)
+              printcell.templateID = _item.templateid || btn.verify.Template || ''
 
-              if (isNaN(cell.printCount) || cell.printCount < 1) {
-                cell.printCount = baseCount
+              if (isNaN(printcell.printCount) || printcell.printCount < 1) {
+                printcell.printCount = 1
               }
 
-              templates.push(cell.templateID)
+              templates.push(printcell.templateID)
 
-              printlist.push(cell)
+              printlist.push(printcell)
             })
-          }
+          })
           
-          resolve(result.next)
+          resolve(true)
         })
       }
     }).then(res => {
       // 鑾峰彇鎵撳嵃妯℃澘 getTemp
       if (!res) return false
-
-      if (btn.verify.printMode === 'custom') {
-        this.execCustomPrint(printlist, formdata)
-
-        return false
-      }
 
       templates = Array.from(new Set(templates)) // 鍘婚噸
 
@@ -447,10 +450,10 @@
               })
             }
 
-            this.execPrint(printlist, _temps, formdata)
+            this.execPrint(printlist, _temps)
           }, 500)
         } else {
-          this.execPrint(printlist, _temps, formdata)
+          this.execPrint(printlist, _temps)
         }
       } else {
         this.execError(errorMsg)
@@ -471,7 +474,7 @@
     })
 
     new Promise(resolve => {
-      if (btn.intertype === 'system') { // 浣跨敤绯荤粺鏃讹紝鐩存帴浠庤〃鏍兼垨琛ㄥ崟涓�夊彇鏁版嵁
+      if (btn.intertype === 'system' && btn.verify.dataType !== 'custom') { // 浣跨敤绯荤粺鏃讹紝鐩存帴浠庤〃鏍兼垨琛ㄥ崟涓�夊彇鏁版嵁
         if (btn.Ot === 'notRequired') {
           if (formlist.length > 0) {
             list = [formdata]
@@ -792,72 +795,124 @@
    * @description 鑾峰彇鎵撳嵃鏁版嵁
    */
   getprintdata = (btn, data, formdata, formlist) => {
-    const { setting } = this.props
+    const { setting, BID } = this.props
 
     let _list = []
     return new Promise(resolve => {
       let params = []
-      let param = {}
 
-      if (this.props.BID) {
-        param.BID = this.props.BID
-      }
-
-      if (btn.Ot === 'notRequired') {
-        let _param = { ...param, ...formdata }
-        params.push(_param)
-      } else if (btn.Ot === 'requiredSgl') {
-        if (setting.primaryKey) {
-          param[setting.primaryKey] = data[0][setting.primaryKey]
-        }
-
-        let _param = { ...param, ...formdata }
-
-        params.push(_param)
-      } else if (btn.Ot === 'requiredOnce') {
-        if (setting.primaryKey) {
-          let ids = data.map(d => { return d[setting.primaryKey]})
-          ids = ids.filter(Boolean)
-          ids = ids.join(',')
+      if (btn.intertype === 'system' && btn.verify.dataType === 'custom') {
+        if (btn.Ot === 'notRequired') {
+          let _param = this.getDefaultSql(formlist, null, '')
   
-          param[setting.primaryKey] = ids
-        }
-
-        let _param = { ...param, ...formdata }
-
-        params.push(_param)
-      } else if (btn.Ot === 'required') {
-        params = data.map((cell, index) => {
-          let _param = { ...param }
-          
+          params.push(_param)
+        } else if (btn.Ot === 'requiredSgl') {
+          let ID = ''
           if (setting.primaryKey) {
-            _param[setting.primaryKey] = cell[setting.primaryKey]
+            ID = data[0][setting.primaryKey] || ''
           }
 
-          let _cell = {}
-          if (index !== 0) {
-            Object.keys(cell).forEach(key => {
-              _cell[key.toLowerCase()] = cell[key]
-            })
+          let _param = this.getDefaultSql(formlist, data[0], ID)
+  
+          params.push(_param)
+        } else if (btn.Ot === 'requiredOnce') {
+          let ID = ''
+  
+          if (setting.primaryKey) {
+            let ids = data.map(d => { return d[setting.primaryKey]})
+            ids = ids.filter(Boolean)
+            ID = ids.join(',')
           }
 
-          formlist.forEach(_data => {
-            if (index !== 0 && _data.readin && _cell.hasOwnProperty(_data.key.toLowerCase())) {
-              _param[_data.key] = _cell[_data.key.toLowerCase()]
-            } else {
-              _param[_data.key] = _data.value
+          let _param = this.getDefaultSql(formlist, data[0], ID)
+  
+          params.push(_param)
+        } else if (btn.Ot === 'required') {
+          params = data.map(cell => {
+            let ID = ''
+            if (setting.primaryKey) {
+              ID = cell[setting.primaryKey] || ''
             }
+
+            return this.getDefaultSql(formlist, cell, ID)
           })
-          return _param
-        })
+        }
+      } else {
+        if (btn.Ot === 'notRequired') {
+          let _param = { ...formdata }
+  
+          if (BID) {
+            _param.BID = BID
+          }
+  
+          params.push(_param)
+        } else if (btn.Ot === 'requiredSgl') {
+          let _param = { ...formdata }
+  
+          if (setting.primaryKey) {
+            _param[setting.primaryKey] = data[0][setting.primaryKey]
+          }
+  
+          if (BID) {
+            _param.BID = BID
+          }
+  
+          params.push(_param)
+        } else if (btn.Ot === 'requiredOnce') {
+          let _param = { ...formdata }
+  
+          if (setting.primaryKey) {
+            let ids = data.map(d => { return d[setting.primaryKey]})
+            ids = ids.filter(Boolean)
+            ids = ids.join(',')
+    
+            _param[setting.primaryKey] = ids
+          }
+  
+          if (BID) {
+            _param.BID = BID
+          }
+  
+          params.push(_param)
+        } else if (btn.Ot === 'required') {
+          params = data.map((cell, index) => {
+            let _param = {}
+            
+            if (setting.primaryKey) {
+              _param[setting.primaryKey] = cell[setting.primaryKey]
+            }
+  
+            if (BID) {
+              _param.BID = BID
+            }
+  
+            let _cell = {}
+            if (index !== 0) {
+              Object.keys(cell).forEach(key => {
+                _cell[key.toLowerCase()] = cell[key]
+              })
+            }
+  
+            formlist.forEach(_data => {
+              if (index !== 0 && _data.readin && _cell.hasOwnProperty(_data.key.toLowerCase())) {
+                _param[_data.key] = _cell[_data.key.toLowerCase()]
+              } else {
+                _param[_data.key] = _data.value
+              }
+            })
+            return _param
+          })
+        }
       }
 
-      if (btn.intertype === 'inner') {
-        params = params.map(_param => {
-          _param.func = btn.innerFunc
-
-          return _param
-        })
+      if (btn.intertype === 'inner' || btn.intertype === 'system') {
+        if (btn.intertype === 'inner') {
+          params = params.map(_param => {
+            _param.func = btn.innerFunc
+  
+            return _param
+          })
+        }
 
         if (params.length <= 20) {
           let deffers = params.map(par => {
@@ -888,6 +943,233 @@
         this.printOuterLoopRequest(params, btn, _list, resolve)
       }
     })
+  }
+
+  /**
+   * @description 鑾峰彇榛樿瀛樺偍杩囩▼璇锋眰鍙傛暟
+   */
+  getDefaultSql = (formlist, data, ID) => {
+    const { BID, btn, columns } = this.props
+
+    let arrFields = btn.verify.columns.map(col => col.field).join(',')
+
+    let param = {
+      func: 'sPC_Get_TableData',
+      obj_name: 'data',
+      exec_type: 'y',
+      arr_field: arrFields,
+      default_sql: btn.verify.setting.defaultSql
+    }
+
+    if (BID) {
+      param.BID = BID
+    }
+    if (ID) {
+      param.ID = ID
+    }
+
+    let userName = sessionStorage.getItem('User_Name') || ''
+    let fullName = sessionStorage.getItem('Full_Name') || ''
+    let RoleID = sessionStorage.getItem('role_id') || ''
+    let departmentcode = sessionStorage.getItem('departmentcode') || ''
+    let organization = sessionStorage.getItem('organization') || ''
+    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+    let nation = sessionStorage.getItem('nation') || ''
+    let province = sessionStorage.getItem('province') || ''
+    let city = sessionStorage.getItem('city') || ''
+    let district = sessionStorage.getItem('district') || ''
+    let address = sessionStorage.getItem('address') || ''
+
+    let _dataresource = btn.verify.setting.dataresource
+    let _customScript = ''
+
+    btn.verify.scripts && btn.verify.scripts.forEach(script => {
+      if (script.status !== 'false') {
+        _customScript += `
+        ${script.sql}
+        `
+      }
+    })
+
+    if (btn.verify.setting.defaultSql === 'false') {
+      _dataresource = ''
+    }
+
+    if (/\s/.test(_dataresource)) {
+      _dataresource = '(' + _dataresource + ') tb'
+    }
+
+    if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
+      _dataresource = _dataresource.replace(/\$@/ig, '/*').replace(/@datam@/ig, '\'Y\'')
+      _dataresource = _dataresource.replace(/@\$/ig, '*/')
+      _customScript = _customScript.replace(/\$@/ig, '/*').replace(/@datam@/ig, '\'Y\'')
+      _customScript = _customScript.replace(/@\$/ig, '*/')
+    } else {
+      _dataresource = _dataresource.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
+      _customScript = _customScript.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
+    }
+
+    let initsql = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100)
+      Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
+    `
+
+    let _vars = []
+    let _initvars = []
+    let _declare = []
+    // 鑾峰彇瀛楁閿�煎
+    formlist.forEach(form => {
+      let _key = form.key.toLowerCase()
+
+      if (_vars.includes(_key)) return
+
+      _vars.push(_key)
+
+      if (form.type === 'number' || form.type === 'rate') {
+        let val = form.value
+        if (isNaN(val)) {
+          val = 0
+        }
+        _initvars.push(`@${_key}=${val}`)
+      } else if (['date', 'datemonth'].includes(form.type)) {
+        _initvars.push(`@${_key}='${form.value || '1949-10-01'}'`)
+      } else {
+        _initvars.push(`@${_key}='${form.value}'`)
+      }
+
+      if (form.fieldlen && form.fieldlen > 2048) {
+        form.fieldlen = 'max'
+      }
+
+      let _type = `nvarchar(${form.fieldlen})`
+
+      if (form.type.match(/date/ig)) {
+        _type = 'datetime'
+      } else if (form.type === 'number') {
+        _type = `decimal(18,${form.fieldlen})`
+      } else if (form.type === 'rate') {
+        _type = `decimal(18,2)`
+      }
+
+      _declare.push(`@${_key} ${_type}`)
+    })
+
+    if (_declare.length > 0) {
+      initsql += `/* 琛ㄥ崟鍙橀噺 */
+        Declare ${_declare.join(',')}
+        select ${_initvars.join(',')}
+      `
+
+      _declare = []
+      _initvars = []
+    }
+
+    if (data && columns && columns.length > 0) {
+      let datavars = {}
+
+      Object.keys(data).forEach(key => {
+        datavars[key.toLowerCase()] = data[key]
+      })
+  
+      columns.forEach(col => {
+        if (!col.field || !col.datatype) return
+
+        let _key = col.field.toLowerCase()
+
+        if (_vars.includes(_key)) return
+  
+        let _val = datavars.hasOwnProperty(_key) ? datavars[_key] : ''
+
+        if (/^date/ig.test(col.datatype) && !_val) {
+          _val = '1949-10-01'
+        }
+
+        _initvars.push(`@${_key}='${_val}'`)
+        _declare.push(`@${_key} ${col.datatype}`)
+      })
+    }
+
+    if (_declare.length > 0) {
+      initsql += `/* 鏄剧ず鍒楀彉閲� */
+        Declare ${_declare.join(',')}
+        select ${_initvars.join(',')}
+      `
+    }
+
+    
+    if (_customScript) {
+      _customScript = `${initsql}
+        ${_customScript}
+      `
+    }
+
+    _dataresource = _dataresource.replace(/@select\$|\$select@/ig, '')
+    _customScript = _customScript.replace(/@select\$|\$select@/ig, '')
+    _dataresource = _dataresource.replace(/\$sum@/ig, '/*')
+    _dataresource = _dataresource.replace(/@sum\$/ig, '*/')
+    _customScript = _customScript.replace(/\$sum@/ig, '/*')
+    _customScript = _customScript.replace(/@sum\$/ig, '*/')
+
+    _dataresource = _dataresource.replace(/@ID@/ig, `'${ID}'`)
+    _customScript = _customScript.replace(/@ID@/ig, `'${ID}'`)
+    _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 || ''}'`)
+
+
+    let LText = ''
+
+    if (_dataresource) {
+      LText = `/*system_query*/select ${arrFields} from (select ${arrFields} ,ROW_NUMBER() over(order by ${btn.verify.setting.order}) as rows from ${_dataresource}) tmptable order by tmptable.rows `
+    }
+
+    if (_customScript) {
+      if (LText) {
+        LText = `${LText}
+          aaa:
+          if @ErrorCode!=''
+            insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@ 
+        `
+      } else {
+        _customScript = `${_customScript}
+          aaa:
+          if @ErrorCode!=''
+            insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@ 
+        `
+      }
+    } else {
+      LText = `${initsql}
+        ${LText}
+      `
+    }
+
+    // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
+    if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
+      _customScript && console.info(`${btn.logLabel ? `/*${btn.logLabel} 鑷畾涔夎剼鏈�*/\n` : ''}${LText ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_customScript}`)
+      LText && console.info(`${btn.logLabel ? `/*${btn.logLabel} 鏁版嵁婧�*/\n` : ''}` + LText.replace(/\n\s{8}/ig, '\n'))
+    }
+
+    if (btn.logLabel) {
+      param.menuname = btn.logLabel
+    }
+
+    param.custom_script = Utils.formatOptions(_customScript)
+    param.LText = Utils.formatOptions(LText)
+
+    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    param.secretkey = Utils.encrypt('', param.timestamp)
+
+    if (window.GLOB.probation) {
+      param.s_debug_type = 'Y'
+    }
+
+    return param
   }
 
   /**
@@ -986,7 +1268,6 @@
 
         return Api.genericInterface(_callbackparam)
       } else if (response.status) {
-
         _list.push(response)
 
         // 涓�娆¤姹傛垚鍔燂紝杩涜涓嬩竴椤硅姹�
@@ -1072,7 +1353,7 @@
         }
 
         configParam.elements.forEach(element => {
-          let _field = element.field
+          let _field = element.field || ''
 
           if (_field === 'other_field') {
             _field = element.cusfield || ''
@@ -1082,7 +1363,7 @@
             Name: element.name || '',
             Type: element.type,
             Value: element.value || '',
-            Field: _field,
+            Field: _field.toLowerCase(),
             Left: element.left + offsetLeft,
             Top: element.top + offsetTop,
             Width: element.width,
@@ -1119,11 +1400,13 @@
             item.ImageWidth = element.imgWidth
             item.ImageHeight = element.imgHeight
             item.Trimming = ''
-            if (element.productValue && window.GLOB.systemType === 'production') {
-              item.Value = element.productValue
-              imgs.push(item.Value)
-            } else if (item.Value) {
-              imgs.push(item.Value)
+            if (!item.Field) {
+              if (element.productValue && window.GLOB.systemType === 'production') {
+                item.Value = element.productValue
+                imgs.push(item.Value)
+              } else if (item.Value) {
+                imgs.push(item.Value)
+              }
             }
           } else if (item.Type === 'text') {
             item.FontFamily = element.fontFamily
@@ -1190,8 +1473,8 @@
     return {
       error: error,
       config: _configparam,
-      fields: fields,
-      nonEFields: nonEFields,
+      fields: Array.from(new Set(fields)),
+      nonEFields: Array.from(new Set(nonEFields)),
       imgs: imgs
     }
   }
@@ -1339,7 +1622,7 @@
     })
   }
 
-  execPrint = (list, template, formdata) => {
+  execPrint = (list, template) => {
     const { btn } = this.props
     let _errors = []
 
@@ -1379,30 +1662,25 @@
         _datalist.forEach(res => {
           res.data.forEach(_cell => {
             for (let i = 0; i < res.printCount; i++) {
-              _data.push({...formdata, ..._cell})
+              _data.push(_cell)
             }
           })
         })
 
-        let _fields = Array.from(new Set(template[key].fields))
-        let _nonEFields = Array.from(new Set(template[key].nonEFields))
         let lacks = []
         let emptys = []
 
         _data.forEach(d => {
-          _fields.forEach(f => {
+          template[key].fields.forEach(f => {
             if (!d.hasOwnProperty(f)) {
               lacks.push(f)
-            } else if (_nonEFields.includes(f) && !d[f] && d[f] !== 0) {
+            } else if (template[key].nonEFields.includes(f) && !d[f] && d[f] !== 0) {
               emptys.push(f)
             }
           })
         })
 
         if (lacks.length > 0 || emptys.length > 0) {
-          lacks = Array.from(new Set(lacks))
-          emptys = Array.from(new Set(emptys))
-
           _errors.push({
             title: template[key].config.Title,
             lacks: lacks,
@@ -1490,49 +1768,29 @@
       return
     }
 
-    // let lackItems = printerList.filter(cell => cell.task.printer === 'lackprinter')[0]
-
     if (!socket || socket.readyState !== 1 || socket.url !== 'ws://' + btn.verify.linkUrl) {
       socket = new WebSocket('ws://' + btn.verify.linkUrl)
     } else {
-      // if (lackItems) {
-      //   let request  = {
-      //     requestID: '',
-      //     version: '',
-      //     cmd: 'getPrinters'
-      //   }
-      //   socket.send(JSON.stringify(request))
-      // } else {
-        this.syncMessageSend(printerList)
+      this.syncMessageSend(printerList)
 
-        this.execSuccess({
-          ErrCode: 'S',
-          message: '',
-          ErrMesg: '鎵撳嵃璇锋眰宸插彂鍑恒��',
-          status: true
-        })
-      // }
+      this.execSuccess({
+        ErrCode: 'S',
+        message: '',
+        ErrMesg: '鎵撳嵃璇锋眰宸插彂鍑恒��',
+        status: true
+      })
     }
 
     // 鎵撳紑Socket
     socket.onopen = () =>{
-      // if (lackItems) {
-      //   let request  = {
-      //     requestID: '',
-      //     version: '',
-      //     cmd: 'getPrinters'
-      //   }
-      //   socket.send(JSON.stringify(request))
-      // } else {
-        this.syncMessageSend(printerList)
+      this.syncMessageSend(printerList)
 
-        this.execSuccess({
-          ErrCode: 'S',
-          message: '',
-          ErrMesg: '鎵撳嵃璇锋眰宸插彂鍑恒��',
-          status: true
-        })
-      // }
+      this.execSuccess({
+        ErrCode: 'S',
+        message: '',
+        ErrMesg: '鎵撳嵃璇锋眰宸插彂鍑恒��',
+        status: true
+      })
     }
     // 鐩戝惉娑堟伅
     socket.onmessage = (event) => {
diff --git a/src/tabviews/zshare/cardcomponent/index.jsx b/src/tabviews/zshare/cardcomponent/index.jsx
index 3bcfd1a..9062213 100644
--- a/src/tabviews/zshare/cardcomponent/index.jsx
+++ b/src/tabviews/zshare/cardcomponent/index.jsx
@@ -208,6 +208,7 @@
               btn={item}
               BData={BData}
               setting={setting}
+              columns={columns}
               selectedData={[data]}
             />
           )
diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx
index 1f25c6c..48a20c1 100644
--- a/src/tabviews/zshare/mutilform/index.jsx
+++ b/src/tabviews/zshare/mutilform/index.jsx
@@ -301,7 +301,7 @@
             })
           } else if (item.regular === 'email') {
             _rules.push({
-              pattern: /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/,
+              pattern: /^([a-zA-Z0-9._-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/,
               message: item.regularText || '璇锋纭緭鍏ラ偖绠卞湴鍧�'
             })
           }
@@ -732,6 +732,12 @@
             _cell.$value = cell[item.cardValField]
             _cell = {..._cell, ...cell}
 
+            if (item.urlField) {
+              _cell.$url = cell[item.urlField] || ''
+            } else if (item.colorField) {
+              _cell.$color = cell[item.colorField] || ''
+            }
+
             if (map.has(_cell.ParentID + _cell.$value)) return
             
             map.set(_cell.ParentID + _cell.$value, 0)
diff --git a/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx b/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
index 74100ed..58acdce 100644
--- a/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
@@ -191,7 +191,7 @@
         }
 
         return <Col span={width} key={item.key}>
-          <div className={'card-color-cell' + (_active ? ' active' : '') + (item.$disabled ? ' disabled' : '')} style={{background: item.$value}} onClick={() => this.changeCard(item)}>
+          <div className={'card-color-cell' + (_active ? ' active' : '') + (item.$disabled ? ' disabled' : '')} style={{background: item.$color}} onClick={() => this.changeCard(item)}>
             {fields.map(col => {
               return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
             })}
diff --git a/src/tabviews/zshare/tablenodes/index.jsx b/src/tabviews/zshare/tablenodes/index.jsx
index 8a728df..df97bc4 100644
--- a/src/tabviews/zshare/tablenodes/index.jsx
+++ b/src/tabviews/zshare/tablenodes/index.jsx
@@ -155,11 +155,8 @@
         let { tbs, ptbs } = this.getTbs(config)
 
         ptbs = Array.from(new Set(ptbs))
+        ptbs = ptbs.filter(tb => tb.length > 1 && tb !== 'dbo')
         ptbs.sort()
-        if (ptbs.length && sessionStorage.getItem('mk_tb_names')) {
-          let names = sessionStorage.getItem('mk_tb_names')
-          ptbs = ptbs.filter(tb => names.indexOf(',' + tb.toLowerCase() + ',') > -1)
-        }
 
         if (ptbs.length) {
           ptbs.forEach((item, i) => {
@@ -184,6 +181,7 @@
 
         if (result.tb_list) {
           result.tb_list.sort((a, b) => a.tbname > b.tbname ? 1 : -1)
+          let length = result.tb_list.length
           result.tb_list.forEach((item, i) => {
             let cell = {
               label: item.tbname,
@@ -191,6 +189,8 @@
               id: 'table' + i,
               direction: 'right',
               color: '#1890ff',
+              collapsed: false,
+              collable: true,
               children: []
             }
 
@@ -209,10 +209,17 @@
                     id: item.tbname + 'menu' + i,
                     direction: 'right',
                     color: '#1890ff',
+                    type: 'dice-mind-map-leaf',
                     param: _param
                   })
                 }
               })
+            }
+
+            if (cell.children.length > 5 && length > 1) {
+              cell.collapsed = true
+            } else if (cell.children.length === 0) {
+              cell.collable = false
             }
 
             data.children.push(cell)
@@ -261,12 +268,12 @@
           const stroke = cfg.style.stroke || '#096dd9';
     
           return `
-          <group>
-            <rect draggable="true" style={{width: ${width}, height: 30, stroke: ${stroke}, radius: 4}} keyshape>
-              <text style={{ fontSize: 14, marginLeft: 6, marginTop: 6 }}>${cfg.label}</text>
-            </rect>
-          </group>
-        `;
+            <group>
+              <rect draggable="true" style={{width: ${width}, height: 30, stroke: ${stroke}, radius: 4}} keyshape>
+                <text style={{ fontSize: 14, marginLeft: 6, marginTop: 6 }}>${cfg.label}</text>
+              </rect>
+            </group>
+          `;
         },
         getAnchorPoints() {
           return [
@@ -285,13 +292,13 @@
           const color = cfg.color;
     
           return `
-          <group>
-            <rect draggable="true" style={{width: ${width}, height: 26, fill: 'transparent' }}>
-              <text style={{ fontSize: 12, fill: ${cfg.fontcolor ? cfg.fontcolor : 'black'}, marginLeft: 12, marginTop: 6 }}>${cfg.label}</text>
-            </rect>
-            <rect style={{ fill: ${color}, width: ${width}, height: 2, x: 0, y: 32 }} />
-          </group>
-        `;
+            <group>
+              <rect draggable="true" style={{width: ${width}, cursor: ${cfg.collable ? 'pointer' : 'default'}, height: 26, fill: 'transparent' }}>
+                <text style={{ fontSize: 12, fill: ${cfg.fontcolor ? cfg.fontcolor : 'black'}, cursor: ${cfg.collable ? 'pointer' : 'default'}, marginLeft: 12, marginTop: 6 }}>${cfg.label} ${cfg.collable ? '+' : ''}</text>
+              </rect>
+              <rect style={{ fill: ${color}, width: ${width}, cursor: ${cfg.collable ? 'pointer' : 'default'}, height: 2, x: 0, y: 32 }} />
+            </group>
+          `;
         },
         getAnchorPoints() {
           return [
@@ -302,6 +309,7 @@
       },
       'single-node',
     );
+
     G6.registerBehavior('scroll-canvas', {
       getEvents: function getEvents() {
         return {
@@ -358,9 +366,10 @@
           data.color = color;
         }
     
-        if (d.children) {
+        if (d.children && !d.collapsed) {
           data.children = d.children.map((child) => changeData(child, level + 1, data.color));
         }
+        
         return data;
       };
       return changeData(data);
@@ -399,9 +408,20 @@
           lineWidth: 2,
         },
       },
-      minZoom: 0.5,
+      minZoom: 0.3,
       modes: {
-        default: ['drag-canvas', 'zoom-canvas'],
+        default: [
+          {
+            type: 'collapse-expand',
+            trigger: 'click',
+            shouldBegin: (e, self) => {
+              if (e.item && e.item.getModel().collable) return true;
+              return false;
+            },
+          },
+          'drag-canvas',
+          'zoom-canvas'
+        ],
       },
     });
     
@@ -441,6 +461,7 @@
           </div>
           <div className="footer">
             <Button key="cancel" onClick={() => { this.setState({ visible: false })}}>鍏抽棴</Button>
+            <span className="tip">娉細鐐瑰嚮琛ㄥ悕鍙睍寮�/鏀惰捣鑿滃崟</span>
           </div>
         </Modal>
       </div>
diff --git a/src/tabviews/zshare/tablenodes/index.scss b/src/tabviews/zshare/tablenodes/index.scss
index e320023..5458306 100644
--- a/src/tabviews/zshare/tablenodes/index.scss
+++ b/src/tabviews/zshare/tablenodes/index.scss
@@ -62,7 +62,16 @@
   }
 
   .footer {
+    position: relative;
     text-align: center;
+
+    .tip {
+      position: absolute;
+      font-size: 12px;
+      color: var(--mk-sys-color);
+      right: 10px;
+      top: 20px;
+    }
   }
   .tb-search {
     position: absolute;
diff --git a/src/tabviews/zshare/topSearch/index.jsx b/src/tabviews/zshare/topSearch/index.jsx
index 47a2ae4..0b4ad56 100644
--- a/src/tabviews/zshare/topSearch/index.jsx
+++ b/src/tabviews/zshare/topSearch/index.jsx
@@ -423,6 +423,12 @@
             _item.$value = cell[item.cardValField]
             _item = {..._item, ...cell}
 
+            if (item.urlField) {
+              _item.$url = cell[item.urlField] || ''
+            } else if (item.colorField) {
+              _item.$color = cell[item.colorField] || ''
+            }
+
             if (map.has(_item.ParentID + _item.$value)) return
             
             map.set(_item.ParentID + _item.$value, 0)
diff --git a/src/templates/comtableconfig/updatetable/index.jsx b/src/templates/comtableconfig/updatetable/index.jsx
index d947713..8aaf83b 100644
--- a/src/templates/comtableconfig/updatetable/index.jsx
+++ b/src/templates/comtableconfig/updatetable/index.jsx
@@ -897,10 +897,12 @@
                 datatype: 'dynamic',
                 eleType: _cols[sub].type !== 'number' ? 'text' : 'number',
                 field: sub,
-                height: 1,
-                innerHeight: 21,
+                height: '',
+                innerHeight: 'auto',
                 marks: _cols[sub].marks || null,
                 noValue: 'show',
+                prefix: _cols[sub].prefix || '',
+                postfix: _cols[sub].postfix || '',
                 style: {},
                 width: 24,
                 uuid: Utils.getuuid()
diff --git a/src/templates/modalconfig/checkCard/index.jsx b/src/templates/modalconfig/checkCard/index.jsx
index 1766dd0..558e172 100644
--- a/src/templates/modalconfig/checkCard/index.jsx
+++ b/src/templates/modalconfig/checkCard/index.jsx
@@ -66,7 +66,7 @@
       }
       return _options.map(item => {
         return <Col span={width} key={item.key}>
-          <div className={'card-color-cell ' + cls} style={{background: item.$value}}>
+          <div className={'card-color-cell ' + cls} style={{background: item.$color}}>
             {_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>
             })}
diff --git a/src/templates/sharecomponent/actioncomponent/actionform/index.jsx b/src/templates/sharecomponent/actioncomponent/actionform/index.jsx
index a086d83..3c505eb 100644
--- a/src/templates/sharecomponent/actioncomponent/actionform/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/actionform/index.jsx
@@ -383,9 +383,11 @@
         
         _fieldval.label = '瀵煎叆Excel'
         _fieldval.class = 'dgreen'
+        _fieldval.execSuccess = 'grid'
         this.record.Ot = 'notRequired'
         this.record.label = '瀵煎叆Excel'
         this.record.class = 'dgreen'
+        this.record.execSuccess = 'grid'
       } else if (value === 'excelOut') {
         _fieldval.intertype = 'system'
         _fieldval.label = '瀵煎嚭Excel'
diff --git a/src/templates/sharecomponent/actioncomponent/index.jsx b/src/templates/sharecomponent/actioncomponent/index.jsx
index 024cfc7..06d1cf2 100644
--- a/src/templates/sharecomponent/actioncomponent/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/index.jsx
@@ -878,7 +878,8 @@
     } else if (card.OpenType === 'funcbutton' && card.funcType === 'print') {
       return <VerifyPrint
         card={card}
-        columns={config.columns}
+        columns={[]}
+        // columns={config.columns}
         wrappedComponentRef={(inst) => this.verifyRef = inst}
       />
     } else if (card.OpenType === 'funcbutton' && card.funcType === 'megvii') {
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
index 555ed77..947413b 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -239,8 +239,10 @@
 
   UNSAFE_componentWillMount() {
     const { card } = this.props
-    let _verify = fromJS(card.verify || {range: 1}).toJS()
+    let _verify = fromJS(card.verify || {}).toJS()
     let _columns = _verify.columns || []
+
+    delete _verify.dataresource
 
     // 鏃ф暟鎹吋瀹�
     _columns = _columns.map(col => {
@@ -260,6 +262,10 @@
       return col
     })
 
+    if (!_verify.hasOwnProperty('range')) {
+      _verify.range = 1
+    }
+
     this.setState({
       verify: {
         ..._verify,
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
index 8ba60e3..7e27b64 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
@@ -1,8 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Form, Row, Col, Button, notification, Modal, Tooltip, Radio, Select } from 'antd'
-import { QuestionCircleOutlined } from '@ant-design/icons'
+import { Form, Row, Col, Button, notification, Tooltip, Select } from 'antd'
 import moment from 'moment'
 
 import Api from '@/api'
@@ -12,39 +11,100 @@
 
 class CustomForm extends Component {
   static propTpyes = {
-    scripts: PropTypes.array,       // 鑷畾涔夎剼鏈垪琛�
-    usefulfields: PropTypes.any,    // 鍙敤瀛楁
-    systemScripts: PropTypes.array, // 绯荤粺鑴氭湰
-    scriptsChange: PropTypes.func   // 琛ㄥ崟
+    searches: PropTypes.any,        // 鎼滅储鏉′欢
+    linefields: PropTypes.any,
+    scriptsChange: PropTypes.func
   }
 
   state = {
     editItem: null,
+    systemScripts: [],
     usefulfields: null,
     loading: false,
-    verifySql: ''
   }
 
   UNSAFE_componentWillMount () {
-    this.resetfield(this.props.usefulfields)
+    this.resetfield(this.props.searches)
   }
 
-  UNSAFE_componentWillReceiveProps (nextProps) {
-    if (nextProps.usefulfields && !is(fromJS(this.props.usefulfields), fromJS(nextProps.usefulfields))) {
-      this.resetfield(nextProps.usefulfields)
+  UNSAFE_componentWillReceiveProps(nextProps) {
+    if (!is(fromJS(this.props.searches), fromJS(nextProps.searches))) {
+      this.resetfield(nextProps.searches)
     }
   }
 
-  resetfield = (columns) => {
-    columns = columns.filter(item => item.Column !== '$Index')
-    let fields = columns.map(item => item.Column)
+  componentDidMount () {
+    this.getsysScript()
+  }
 
-    let _sql = `Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@ErrorCode nvarchar(50), @retmsg nvarchar(4000)
-    `
+  getsysScript = () => {
+    if (sessionStorage.getItem('mk_sys_scripts')) {
+      this.setState({
+        systemScripts: JSON.parse(sessionStorage.getItem('mk_sys_scripts'))
+      })
+      return
+    }
     
+    let _scriptSql = `Select distinct func+Remark as funcname,longparam, s.Sort from聽 s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort`
+
+    _scriptSql = Utils.formatOptions(_scriptSql)
+
+    let _sParam = {
+      func: 'sPC_Get_SelectedList',
+      LText: _scriptSql,
+      obj_name: 'data',
+      arr_field: 'funcname,longparam'
+    }
+    
+    _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp)
+    _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 浜戠鏁版嵁楠岃瘉
+    
+    Api.getSystemConfig(_sParam).then(res => {
+      if (res.status) {
+        let _scripts = res.data.map(item => {
+          return {
+            name: item.funcname,
+            value: window.decodeURIComponent(window.atob(item.longparam))
+          }
+        })
+
+        sessionStorage.setItem('mk_sys_scripts', JSON.stringify(_scripts))
+
+        this.setState({
+          systemScripts: _scripts
+        })
+      } else {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  resetfield = (searches) => {
+    let _usefulFields = []
+    searches.forEach(item => {
+      if (!item.field) return
+
+      if (item.type === 'group') {
+        _usefulFields.push(item.field)
+        _usefulFields.push(item.datefield)
+        _usefulFields.push(item.datefield + '1')
+      } else if (['dateweek', 'datemonth', 'daterange'].includes(item.type)) {
+        _usefulFields.push(item.field)
+        _usefulFields.push(item.field + '1')
+      } else if (item.type === 'date' && _usefulFields.includes(item.field)) {
+        _usefulFields.push(item.field + '1')
+      } else {
+        _usefulFields.push(item.field)
+      }
+    })
+
     this.setState({
-      verifySql: _sql,
-      usefulfields: fields.join(', ')
+      usefulfields: _usefulFields.join(', ')
     })
   }
 
@@ -116,89 +176,22 @@
           return
         }
 
-        let tail = `
-          aaa:
-        `
-
-        let _initCustomScript = '' // 鍒濆鍖栬剼鏈�
-        let _prevCustomScript = '' // 榛樿sql鍓嶆墽琛岃剼鏈�
-        let _backCustomScript = '' // 榛樿sql鍚庢墽琛岃剼鏈�
-
-        this.props.scripts.forEach(item => {
-          if (item.status === 'false') return
-
-          if (item.position === 'init') {
-            _initCustomScript += `
-            /* 鍒濆鍖栬剼鏈� */
-            ${values.uuid === item.uuid ? values.sql : item.sql}
-            `
-          } else if (item.position === 'front') {
-            _prevCustomScript += `
-            /* 榛樿sql鍓嶈剼鏈� */
-            ${values.uuid === item.uuid ? values.sql : item.sql}
-            `
-          } else {
-            _backCustomScript += `
-            /* 榛樿sql鍚庤剼鏈� */
-            ${values.uuid === item.uuid ? values.sql : item.sql}
-            `
-          }
+        this.setState({
+          loading: true
         })
 
-        if (!values.uuid) {
-          if (values.position === 'init') {
-            _initCustomScript += `
-            /* 鍒濆鍖栬剼鏈� */
-            ${values.sql}
-            `
-          } else if (values.position === 'front') {
-            _prevCustomScript += `
-            /* 榛樿sql鍓嶈剼鏈� */
-            ${values.sql}
-            `
-          } else {
-            _backCustomScript += `
-            /* 榛樿sql鍚庤剼鏈� */
-            ${values.sql}
-            `
-          }
-        }
-
-        let param = {
-          func: 's_debug_sql',
-          exec_type: 'y',
-          LText: this.state.verifySql + _initCustomScript + _prevCustomScript + _backCustomScript + tail
-        }
-
-        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 = param.LText.replace(/\n/g, ' ')
-        
-        // 澶栬仈鏁版嵁搴撴浛鎹�
-        if (window.GLOB.externalDatabase !== null) {
-          param.LText = param.LText.replace(/@db@/ig, window.GLOB.externalDatabase)
-        }
-
-        param.LText = Utils.formatOptions(param.LText)
-        param.secretkey = Utils.encrypt('', param.timestamp)
-        
-        this.setState({loading: true})
-        Api.genericInterface(param).then(res => {
-          if (res.status) {
+        this.props.scriptsChange(values, (status) => {
+          if (status) {
             this.setState({
               loading: false,
               editItem: null
-            }, () => {
-              this.props.scriptsChange(values)
             })
             this.props.form.setFieldsValue({
               sql: ''
             })
           } else {
-            this.setState({loading: false})
-
-            Modal.error({
-              title: res.message
+            this.setState({
+              loading: false
             })
           }
         })
@@ -250,8 +243,8 @@
   }
 
   render() {
-    const { systemScripts, sheet } = this.props
-    const { usefulfields } = this.state
+    const { sheet, linefields } = this.props
+    const { usefulfields, systemScripts } = this.state
     const { getFieldDecorator } = this.props.form
     const formItemLayout = {
       labelCol: {
@@ -280,11 +273,12 @@
           <Col span={24} className="sqlfield">
             <Form.Item label={'鍙敤瀛楁'}>
               <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
-              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><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}
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address</span></Tooltip>
+              {usefulfields ? <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鎼滅储鏉′欢锛岃鎸夌収@xxx@鏍煎紡浣跨敤銆�'}>,&nbsp;{usefulfields}</Tooltip> : null}
+              {linefields ? <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'琛ㄥ崟鍙婅鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}>,&nbsp;{linefields}</Tooltip> : null}
             </Form.Item>
           </Col>
-          <Col span={8} style={{whiteSpace: 'nowrap'}}>
+          {/* <Col span={8} style={{whiteSpace: 'nowrap'}}>
             <Form.Item style={{marginBottom: 0}} label={
               <Tooltip placement="bottomLeft" title={'鑷畾涔夎剼鏈笌榛樿sql浣嶇疆鍏崇郴銆�'}>
                 <QuestionCircleOutlined className="mk-form-tip" />
@@ -301,8 +295,8 @@
                 </Radio.Group>
               )}
             </Form.Item>
-          </Col>
-          <Col span={10}>
+          </Col> */}
+          <Col span={8}>
             <Form.Item style={{marginBottom: 0}} label={'蹇嵎娣诲姞'}>
               <Select
                 showSearch
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/datasource/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/datasource/index.jsx
index cd970a6..557bf84 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/datasource/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/datasource/index.jsx
@@ -11,6 +11,7 @@
 
 class SettingForm extends Component {
   static propTpyes = {
+    btnType: PropTypes.any,
     setting: PropTypes.object,    // 鏁版嵁婧愰厤缃�
   }
 
@@ -20,10 +21,10 @@
   }
 
   UNSAFE_componentWillMount () {
-    const { setting } = this.props
+    const { setting, btnType } = this.props
 
     this.setState({
-      dataType: setting.dataType,
+      dataType: btnType === 'print' ? 'custom' : setting.dataType,
       defaultSql: setting.defaultSql || 'true'
     })
   }
@@ -104,7 +105,7 @@
   }
 
   render() {
-    const { setting } = this.props
+    const { setting, btnType } = this.props
     const { getFieldDecorator } = this.props.form
     const { dataType, defaultSql } = this.state
 
@@ -123,7 +124,7 @@
       <div className="excelout-datasource-wrap">
         <Form {...formItemLayout}>
           <Row gutter={24}>
-            <Col span={8}>
+            {btnType !== 'print' ? <Col span={8}>
               <Form.Item label="瀵煎嚭鏁版嵁">
                 {getFieldDecorator('dataType', {
                   initialValue: setting.dataType
@@ -134,7 +135,7 @@
                   </Radio.Group>
                 )}
               </Form.Item>
-            </Col>
+            </Col> : null}
             {dataType === 'custom' ? <Col className="short-label" span={8}>
               <Form.Item label="琛ㄥ悕">
                 {getFieldDecorator('tableName', {
@@ -198,12 +199,7 @@
               </Form.Item>
             </Col> : null}
             {dataType === 'custom' && defaultSql === 'true' ? <Col className="short-label" span={8}>
-              <Form.Item label={
-                <Tooltip placement="topLeft" title="鎺掑簭鏂瑰紡涓虹┖鏃讹紝浣跨敤琛ㄦ牸鎴栫粍浠朵腑鐨勬帓搴忔柟寮忋��">
-                  <QuestionCircleOutlined className="mk-form-tip" />
-                  鎺掑簭鏂瑰紡
-                </Tooltip>
-              }>
+              <Form.Item label="鎺掑簭鏂瑰紡">
                 {getFieldDecorator('order', {
                   initialValue: setting.order || '',
                   rules: [
@@ -215,9 +211,9 @@
                 })(<Input placeholder={'ID asc, UID desc'} autoComplete="off" />)}
               </Form.Item>
             </Col> : null}
-            {dataType === 'custom' ? <Col span={8}>
+            {dataType === 'custom' && btnType !== 'print' ? <Col span={8}>
               <Form.Item label={
-                <Tooltip placement="topLeft" title="涓嶄娇鐢ㄦ悳绱㈡潯浠舵椂锛屼笉浼氳繘琛屾悳绱㈡潯浠剁殑鎷兼帴涓庣浉鍏崇粺璁″瓧娈电殑鏇挎崲銆傛敞锛氳嚜瀹氫箟鏁版嵁鏉ユ簮鏃讹紝鍙娇鐢ㄥ唴閮ㄦ悳绱€��">
+                <Tooltip placement="topLeft" title="涓嶄娇鐢ㄦ悳绱㈡潯浠舵椂锛屼笉浼氳繘琛屾悳绱㈡潯浠剁殑鎷兼帴涓庣浉鍏崇粺璁″瓧娈电殑鏇挎崲銆�">
                   <QuestionCircleOutlined className="mk-form-tip" />
                   鎼滅储鏉′欢
                 </Tooltip>
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
index eb8ffeb..d3bc305 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -29,7 +29,6 @@
   state = {
     verify: {},
     activeKey: 'setting',
-    systemScripts: [],
     defaultscript: '', // 鑷畾涔夎剼鏈�
     excelColumns: [
       {
@@ -353,57 +352,6 @@
       searches: searches,
       activeKey: card.intertype === 'system' && _verify.dataType === 'custom' ? 'setting' : 'columns',
       defaultscript: defaultscript
-    })
-  }
-
-  componentDidMount () {
-    this.getsysScript()
-  }
-
-  getsysScript = () => {
-    if (sessionStorage.getItem('mk_sys_scripts')) {
-      this.setState({
-        systemScripts: JSON.parse(sessionStorage.getItem('mk_sys_scripts'))
-      })
-      return
-    }
-    
-    let _scriptSql = `Select distinct func+Remark as funcname,longparam, s.Sort from聽 s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort`
-
-    _scriptSql = Utils.formatOptions(_scriptSql)
-
-    let _sParam = {
-      func: 'sPC_Get_SelectedList',
-      LText: _scriptSql,
-      obj_name: 'data',
-      arr_field: 'funcname,longparam'
-    }
-    
-    _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-    _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp)
-    _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 浜戠鏁版嵁楠岃瘉
-    
-    Api.getSystemConfig(_sParam).then(res => {
-      if (res.status) {
-        let _scripts = res.data.map(item => {
-          return {
-            name: item.funcname,
-            value: window.decodeURIComponent(window.atob(item.longparam))
-          }
-        })
-
-        sessionStorage.setItem('mk_sys_scripts', JSON.stringify(_scripts))
-
-        this.setState({
-          systemScripts: _scripts
-        })
-      } else {
-        notification.warning({
-          top: 92,
-          message: res.message,
-          duration: 5
-        })
-      }
     })
   }
 
@@ -945,7 +893,7 @@
     }
   }
 
-  scriptsChange = (values) => {
+  scriptsChange = (values, callback) => {
     let verify = JSON.parse(JSON.stringify(this.state.verify))
 
     if (values.uuid) {
@@ -968,10 +916,12 @@
         loading: false,
         verify: verify
       })
+      callback(true)
     }, () => {             // 楠岃瘉澶辫触
       this.setState({
         loading: false
       })
+      callback(false)
     }, verify.scripts)
   }
 
@@ -984,7 +934,7 @@
     }
 
     let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-    let sql = SettingUtils.getDebugSql(verify, scripts, searches, Utils, timestamp)
+    let sql = SettingUtils.getDebugSql(verify, scripts, (verify.useSearch === 'true' ? searches : []), Utils, timestamp)
     let param = {
       func: 's_debug_sql',
       exec_type: 'y',
@@ -1012,7 +962,7 @@
 
   render() {
     const { card } = this.props
-    const { verify, excelColumns, defaultscript, scriptsColumns, activeKey, loading } = this.state
+    const { verify, excelColumns, defaultscript, scriptsColumns, activeKey, loading, searches } = this.state
     const { getFieldDecorator } = this.props.form
     const formItemLayout = {
       labelCol: {
@@ -1058,9 +1008,7 @@
             <CustomScript
               btn={card}
               sheet={verify.tableName}
-              usefulfields={verify.columns}
-              scripts={verify.scripts}
-              systemScripts={this.state.systemScripts}
+              searches={verify.useSearch === 'true' ? searches : []}
               scriptsChange={this.scriptsChange}
               wrappedComponentRef={(inst) => this.scriptsForm = inst}
             />
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx
index 72f7c39..306c80d 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx
@@ -23,6 +23,10 @@
     })
     arr_field = arr_field.join(',')
 
+    if (!arr_field) {
+      arr_field = '*'
+    }
+
     let _customScript = ''
     scripts && scripts.forEach(script => {
       if (script.status === 'false') return
@@ -39,14 +43,6 @@
 
     if (verify.defaultSql === 'false') {
       _dataresource = ''
-    }
-
-    if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-      window.GLOB.funcs.forEach(item => {
-        let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
-        _dataresource = _dataresource.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
-        _customScript = _customScript.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
-      })
     }
     
     _dataresource = _dataresource.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${timestamp}'`)
@@ -105,15 +101,15 @@
     }
 
     // 鏁版嵁婧愬鐞�, 瀛樺湪鏄剧ず鍒楁椂 
-    if (arr_field && _dataresource) {
+    if (_dataresource) {
       if (/\s/.test(_dataresource)) {
         _dataresource = '(' + _dataresource + ') tb'
       }
 
       if (verify.order) {
-        _dataresource = `select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${verify.order}) as rows from ${_dataresource} ${_search}) tmptable order by tmptable.rows`
+        _dataresource = `/*system_query*/select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${verify.order}) as rows from ${_dataresource} ${_search}) tmptable order by tmptable.rows`
       } else {
-        _dataresource = `select ${arr_field} from ${_dataresource} ${_search}`
+        _dataresource = `/*system_query*/select ${arr_field} from ${_dataresource} ${_search}`
       }
     }
 
diff --git a/src/templates/sharecomponent/actioncomponent/verifyprint/editable/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyprint/editable/index.jsx
index bf99d3c..9c93a48 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyprint/editable/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyprint/editable/index.jsx
@@ -1,4 +1,5 @@
 import React, {Component} from 'react'
+import { fromJS } from 'immutable'
 import { Table, Input, Popconfirm, Form } from 'antd'
 import { ArrowUpOutlined, ArrowDownOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons'
 import Utils from '@/utils/utils.js'
@@ -160,11 +161,14 @@
     this.setState({
       dataSource: _data
     })
+
+    this.props.onChange(fromJS(_data).toJS())
   }
 
   handleDelete = key => {
-    const dataSource = [...this.state.dataSource]
-    this.setState({ dataSource: dataSource.filter(item => item.key !== key) })
+    const dataSource = [...this.state.dataSource].filter(item => item.key !== key)
+    this.setState({ dataSource: dataSource })
+    this.props.onChange(fromJS(dataSource).toJS())
   }
 
   handleAdd = () => {
@@ -174,11 +178,13 @@
       Value: `${count}`,
       Text: `${count}`
     }
+    let list = [...dataSource, newData]
 
     this.setState({
-      dataSource: [...dataSource, newData],
+      dataSource: list,
       count: count + 1
     })
+    this.props.onChange(fromJS(list).toJS())
   }
 
   handleSave = row => {
@@ -190,10 +196,7 @@
       ...row
     })
     this.setState({ dataSource: newData })
-  }
-
-  UNSAFE_componentWillReceiveProps () {
-    
+    this.props.onChange(fromJS(newData).toJS())
   }
 
   render() {
diff --git a/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
index 324f63b..b7d47e3 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
@@ -1,16 +1,25 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Tabs, Row, Col, Button, notification, Modal, message, InputNumber, Input, Select, Radio, Tooltip } from 'antd'
-import { QuestionCircleOutlined } from '@ant-design/icons'
+import { fromJS } from 'immutable'
+import { Form, Tabs, Row, Col, Button, notification, Modal, message, InputNumber, Input, Select, Radio, Tooltip, Typography, Popconfirm, Spin } from 'antd'
+import { QuestionCircleOutlined, EditOutlined, StopOutlined, CheckCircleOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
+import SettingUtils from './utils.jsx'
 import CodeMirror from '@/templates/zshare/codemirror'
+import DataSource from '../verifyexcelout/datasource'
+import CustomScript from '../verifyexcelout/customscript'
+import asyncComponent from '@/utils/asyncComponent'
+import ColForm from '@/menu/datasource/verifycard/columnform'
 import EditTable from './editable'
 
 import './index.scss'
 
+const EditMTable = asyncComponent(() => import('@/templates/zshare/editTable'))
+const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
+const { Paragraph } = Typography
 const { TabPane } = Tabs
 
 class VerifyCard extends Component {
@@ -25,20 +34,239 @@
   state = {
     verify: {},
     templates: [],
+    loading: false,
+    activeKey: 'base',
     selectimg: '',
-    printMode: 'normal'
+    dataType: 'line',
+    printMode: 'normal',
+    usefulfields: '',
+    declareSql: '',
+    scriptsColumns: [
+      {
+        title: 'SQL',
+        dataIndex: 'sql',
+        width: '60%',
+        render: (text) => {
+          let title = text.match(/^\s*\/\*.+\*\//)
+          title = title && title[0] ? title[0] : ''
+          let _text = title ? text.replace(title, '') : text
+
+          return (
+            <div>
+              {title ? <span style={{color: '#a50'}}>{title}<span style={{fontSize: '12px', marginLeft: '5px'}}>{_text.length}</span></span> : null}
+              <Paragraph copyable={{ text: text }} ellipsis={{ rows: 4, expandable: true }}>{_text}</Paragraph>
+            </div>
+          )
+        }
+      },
+      {
+        title: '鎵ц浣嶇疆',
+        dataIndex: 'position',
+        width: '10%',
+        render: (text, record) => {
+          if (record.position === 'init') {
+            return <span style={{color: 'orange'}}>鍒濆鍖�</span>
+          } else if (record.position === 'front') {
+            return <span style={{color: '#26C281'}}>sql鍓�</span>
+          } else {
+            return <span style={{color: '#1890ff'}}>sql鍚�</span>
+          }
+        }
+      },
+      {
+        title: '鐘舵��',
+        dataIndex: 'status',
+        width: '10%',
+        render: (text, record) => record.status === 'false' ?
+          (
+            <div style={{color: '#ff4d4f'}}>
+              绂佺敤
+              <StopOutlined style={{marginLeft: '5px'}} />
+            </div>
+          ) :
+          (
+            <div style={{color: '#26C281'}}>
+              鍚敤
+              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
+            </div>
+          )
+      },
+      {
+        title: '鎿嶄綔',
+        align: 'center',
+        width: '140px',
+        dataIndex: 'operation',
+        render: (text, record) =>
+          (<div style={{textAlign: 'center'}}>
+            <span className="operation-btn" title="缂栬緫" onClick={() => this.handleEdit(record, 'scripts')} style={{color: '#1890ff'}}><EditOutlined /></span>
+            <span className="operation-btn" title="鐘舵�佸垏鎹�" onClick={() => this.handleStatus(record, 'scripts')} style={{color: '#8E44AD'}}><SwapOutlined /></span>
+            <Popconfirm
+              overlayClassName="popover-confirm"
+              title="纭畾鍒犻櫎鍚�?"
+              onConfirm={() => this.handleDelete(record, 'scripts')
+            }>
+              <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span>
+            </Popconfirm>
+          </div>)
+      }
+    ],
+    colColumns: [
+      {
+        title: '鍚嶇О',
+        dataIndex: 'label',
+        inputType: 'input',
+        editable: true,
+        width: '28%'
+      },
+      {
+        title: '瀛楁',
+        dataIndex: 'field',
+        inputType: 'input',
+        editable: true,
+        unique: true,
+        copy: true,
+        rules: [{
+          pattern: /^[\u4E00-\u9FA50-9a-zA-Z_]*$/ig,
+          message: '瀛楁鍚嶅彧鍏佽鍖呭惈鏁板瓧銆佸瓧姣嶃�佹眽瀛椾互鍙奯'
+        }],
+        width: '28%'
+      },
+      {
+        title: '鏁版嵁绫诲瀷',
+        dataIndex: 'datatype',
+        inputType: 'select',
+        options: [
+          { value: 'Nvarchar(10)', text: 'Nvarchar(10)' },
+          { value: 'Nvarchar(20)', text: 'Nvarchar(20)' },
+          { value: 'Nvarchar(50)', text: 'Nvarchar(50)' },
+          { value: 'Nvarchar(100)', text: 'Nvarchar(100)' },
+          { value: 'Nvarchar(256)', text: 'Nvarchar(256)' },
+          { value: 'Nvarchar(512)', text: 'Nvarchar(512)' },
+          { value: 'Nvarchar(1024)', text: 'Nvarchar(1024)' },
+          { value: 'Nvarchar(2048)', text: 'Nvarchar(2048)' },
+          { value: 'Nvarchar(max)', text: 'Nvarchar(max)' },
+          { value: 'Int', text: 'Int' },
+          { value: 'Decimal(18,0)', text: 'Decimal(18,0)' },
+          { value: 'Decimal(18,1)', text: 'Decimal(18,1)' },
+          { value: 'Decimal(18,2)', text: 'Decimal(18,2)' },
+          { value: 'Decimal(18,3)', text: 'Decimal(18,3)' },
+          { value: 'Decimal(18,4)', text: 'Decimal(18,4)' },
+          { value: 'Decimal(18,5)', text: 'Decimal(18,5)' },
+          { value: 'Decimal(18,6)', text: 'Decimal(18,6)' },
+          { value: 'Decimal(18,7)', text: 'Decimal(18,7)' },
+          { value: 'Decimal(18,8)', text: 'Decimal(18,8)' },
+          { value: 'Decimal(18,9)', text: 'Decimal(18,9)' },
+          { value: 'Decimal(18,10)', text: 'Decimal(18,10)' },
+          { value: 'Decimal(18,11)', text: 'Decimal(18,11)' },
+          { value: 'Decimal(18,12)', text: 'Decimal(18,12)' },
+          { value: 'Decimal(18,13)', text: 'Decimal(18,13)' },
+          { value: 'Decimal(18,14)', text: 'Decimal(18,14)' },
+          { value: 'Decimal(18,15)', text: 'Decimal(18,15)' },
+          { value: 'Decimal(18,16)', text: 'Decimal(18,16)' },
+          { value: 'Decimal(18,17)', text: 'Decimal(18,17)' },
+          { value: 'Decimal(18,18)', text: 'Decimal(18,18)' },
+          { value: 'date', text: 'date' },
+          { value: 'datetime', text: 'datetime' },
+        ],
+        editable: true,
+        width: '25%',
+      }
+    ]
   }
 
   UNSAFE_componentWillMount() {
-    let _verify = this.props.card.verify || {}
+    const { columns, card } = this.props
+    let _verify = fromJS(card.verify || {}).toJS()
 
     _verify.Template = _verify.Template || ''
     _verify.printerTypeList = _verify.printerTypeList || []
     _verify.linkType = _verify.linkType || 'system'
     _verify.printMode = _verify.printMode || 'normal'
+    _verify.scripts = _verify.scripts || []
+    _verify.columns = _verify.columns || []
+
+    let _usefulfields = []
+    let _declare = []
+    let _select = []
+    let fieldArr = []
+
+    let _sql = ''
+
+    if (card.execMode === 'pop' && card.modal && card.modal.fields) {
+      card.modal.fields.forEach(_f => {
+        if (!_f.field || fieldArr.includes(_f.field.toLowerCase())) return
+
+        fieldArr.push(_f.field.toLowerCase())
+
+        _usefulfields.push(_f.field)
+
+        let _fieldlen = _f.fieldlength || 50
+
+        if (_f.type === 'number') {
+          _fieldlen = _f.decimal ? _f.decimal : 0
+        }
+
+        if (_fieldlen > 2048) {
+          _fieldlen = 'max'
+        }
+
+        let _type = `nvarchar(${_fieldlen})`
+
+        if (_f.type.match(/date/ig)) {
+          _type = 'datetime'
+          _select.push(`@${_f.field}='1949-10-01'`)
+        } else if (_f.type === 'number') {
+          _type = `decimal(18,${_fieldlen})`
+          _select.push(`@${_f.field}=0`)
+        } else if (_f.type === 'rate') {
+          _type = `decimal(18,2)`
+          _select.push(`@${_f.field}=0`)
+        } else {
+          _select.push(`@${_f.field}=''`)
+        }
+
+        _declare.push(`@${_f.field} ${_type}`)
+      })
+
+      if (_declare.length > 0) {
+        _sql = `/* 琛ㄥ崟鍙橀噺 */
+          Declare ${_declare.join(', ')}
+          Select ${_select.join(', ')}
+        `
+      }
+      _declare = []
+      _select = []
+    }
+
+    if (columns && columns.length > 0 && card.Ot !== 'notRequired') {
+      columns.forEach(_f => {
+        if (!_f.field || fieldArr.includes(_f.field.toLowerCase()) || !_f.datatype) return
+
+        fieldArr.push(_f.field.toLowerCase())
+        _usefulfields.push(_f.field)
+
+        if (/decimal/ig.test(_f.datatype)) {
+          _select.push(`@${_f.field}=0`)
+        } else {
+          _select.push(`@${_f.field}=''`)
+        }
+
+        _declare.push(`@${_f.field} ${_f.datatype}`)
+      })
+
+      if (_declare.length > 0) {
+        _sql += `/* 鏄剧ず鍒楀彉閲� */
+          Declare ${_declare.join(', ')}
+          Select ${_select.join(', ')}
+        `
+      }
+    }
 
     this.setState({
       verify: _verify,
+      declareSql: _sql,
+      usefulfields: _usefulfields.join(', '),
+      dataType: _verify.dataType || 'line',
       linkType: _verify.linkType,
       printMode: _verify.printMode,
       printFunc: _verify.printFunc || '// Function(data, form, printer, notification) data-鎵撳嵃鏁版嵁鍒楄〃锛宖orm-琛ㄥ崟淇℃伅锛堜笉瀛樺湪鏃朵负{}锛夛紝printer-鎵撳嵃璁剧疆锛宯otification-淇℃伅鎻愮ず鎺т欢'
@@ -157,56 +385,67 @@
   }
 
   handleConfirm = () => {
-    const { verify } = this.state
+    const { verify, activeKey } = this.state
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     return new Promise((resolve, reject) => {
-      this.props.form.validateFieldsAndScroll((err, values) => {
-        if (!err) {
-          let _verify = {...verify, ...values}
-
-          if (this.refs.editTable && this.refs.editTable.state) {
-            let printTypes = this.refs.editTable.state.dataSource
+      if (activeKey === 'base') {
+        this.props.form.validateFieldsAndScroll((err, values) => {
+          if (err) return
   
-            let emptys = printTypes.filter(item => !item.Value || !item.Text)
-            let valMap = new Map()
-            let isvalid = true
+          resolve({...verify, ...values})
+        })
+      } else if (activeKey === 'print') {
+        if (verify.printerTypeList.length > 0) {
+          let printTypes = verify.printerTypeList.map(item => item.Value)
+          printTypes = Array.from(new Set(printTypes))
   
-            printTypes.forEach(item => {
-              if (valMap.has(item.Value)) {
-                isvalid = false
-              } else {
-                valMap.set(item.Value, item.Text)
-              }
+          if (verify.printerTypeList.length > printTypes.length) {
+            notification.warning({
+              top: 92,
+              message: '鎵撳嵃绫诲瀷涓璙alue瀛楁涓嶅彲閲嶅!',
+              duration: 5
             })
-  
-            if (emptys.length > 0) {
-              notification.warning({
-                top: 92,
-                message: '鎵撳嵃绫诲瀷琛ㄦ牸涓璙alue銆乀ext瀛楁涓嶅彲涓虹┖!',
-                duration: 5
-              })
-              return
-            } else if (!isvalid) {
-              notification.warning({
-                top: 92,
-                message: '鎵撳嵃绫诲瀷琛ㄦ牸涓璙alue瀛楁涓嶅彲閲嶅!',
-                duration: 5
-              })
-              return
-            }
-  
-            _verify.printerTypeList = printTypes
+            return
           }
-
-          resolve(_verify)
-        } else {
+        }
+        resolve(verify)
+      } else if (activeKey === 'setting') {
+        this.settingForm.handleConfirm().then(res => {
+          let _verify = {...verify, setting: res}
+          this.setState({
+            verify: _verify
+          }, () => {
+            this.setState({loading: true})
+            this.sqlverify(() => { // 楠岃瘉鎴愬姛
+              resolve(_verify)
+            }, () => {             // 楠岃瘉澶辫触
+              this.setState({
+                loading: false
+              })
+            }, _verify.scripts)
+          })
+        })
+      } else if (activeKey === 'scripts') {
+        if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) {
           notification.warning({
             top: 92,
-            message: '閾炬帴鍦板潃涓庢墦鍗版ā鏉夸笉鍙负绌�!',
+            message: '瀛樺湪鏈繚瀛樿剼鏈紝璇风偣鍑荤‘瀹氫繚瀛橈紝鎴栫偣鍑诲彇娑堟斁寮冧慨鏀癸紒',
             duration: 5
           })
+          return
         }
-      })
+  
+        this.setState({loading: true})
+        this.sqlverify(() => { // 楠岃瘉鎴愬姛
+          resolve(verify)
+        }, () => {             // 楠岃瘉澶辫触
+          this.setState({
+            loading: false
+          })
+        }, verify.scripts)
+      } else {
+        resolve(verify)
+      }
     })
   }
 
@@ -254,10 +493,182 @@
     })
   }
 
+  changeDataType = (e) => {
+    let value = e.target.value
+
+    this.setState({
+      dataType: value
+    })
+  }
+
+  // 鏍囩鍒囨崲
+  tabchange = (val) => {
+    const { activeKey, verify } = this.state
+
+    if (activeKey === 'base') {
+      this.props.form.validateFieldsAndScroll((err, values) => {
+        if (err) return
+
+        this.setState({
+          verify: {...verify, ...values},
+          activeKey: val
+        })
+      })
+    } else if (activeKey === 'print') {
+      if (verify.printerTypeList.length > 0) {
+        let printTypes = verify.printerTypeList.map(item => item.Value)
+        printTypes = Array.from(new Set(printTypes))
+
+        if (verify.printerTypeList.length > printTypes.length) {
+          notification.warning({
+            top: 92,
+            message: '鎵撳嵃绫诲瀷涓璙alue瀛楁涓嶅彲閲嶅!',
+            duration: 5
+          })
+          return
+        }
+      }
+      this.setState({
+        activeKey: val
+      })
+    } else if (activeKey === 'setting') {
+      this.settingForm.handleConfirm().then(res => {
+        this.setState({
+          verify: {...verify, setting: res}
+        }, () => {
+          this.setState({loading: true})
+          this.sqlverify(() => { // 楠岃瘉鎴愬姛
+            this.setState({
+              activeKey: val,
+              loading: false
+            })
+          }, () => {             // 楠岃瘉澶辫触
+            this.setState({
+              activeKey: val,
+              loading: false
+            })
+          }, verify.scripts)
+        })
+      })
+    } else if (activeKey === 'scripts') {
+      if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) {
+        notification.warning({
+          top: 92,
+          message: '瀛樺湪鏈繚瀛樿剼鏈紝璇风偣鍑荤‘瀹氫繚瀛橈紝鎴栫偣鍑诲彇娑堟斁寮冧慨鏀癸紒',
+          duration: 5
+        })
+        return
+      }
+
+      this.setState({loading: true})
+      this.sqlverify(() => { // 楠岃瘉鎴愬姛
+        this.setState({
+          activeKey: val,
+          loading: false
+        })
+      }, () => {             // 楠岃瘉澶辫触
+        this.setState({
+          activeKey: val,
+          loading: false
+        })
+      }, verify.scripts)
+    } else {
+      this.setState({
+        activeKey: val
+      })
+    }
+  }
+
+  scriptsChange = (values, callback) => {
+    let verify = JSON.parse(JSON.stringify(this.state.verify))
+
+    if (values.uuid) {
+      verify.scripts = verify.scripts.map(item => {
+        if (item.uuid === values.uuid) {
+          return values
+        } else {
+          return item
+        }
+      })
+    } else {
+      values.uuid = Utils.getuuid()
+      verify.scripts.push(values)
+    }
+
+    this.setState({loading: true})
+
+    this.sqlverify(() => { // 楠岃瘉鎴愬姛
+      this.setState({
+        loading: false,
+        verify: verify
+      })
+      callback(true)
+    }, () => {             // 楠岃瘉澶辫触
+      this.setState({
+        loading: false
+      })
+      callback(false)
+    }, verify.scripts)
+  }
+
+  sqlverify = (_resolve, _reject, scripts) => {
+    const { verify, declareSql } = this.state
+
+    let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    let sql = SettingUtils.getDebugSql(verify.setting || {}, verify.columns, scripts, declareSql, timestamp)
+    let param = {
+      func: 's_debug_sql',
+      exec_type: 'y',
+      LText: sql
+    }
+    param.LText = Utils.formatOptions(param.LText)
+    param.timestamp = timestamp
+    param.secretkey = Utils.encrypt('', timestamp)
+
+    Api.genericInterface(param).then(result => {
+      if (result.status) {
+        _resolve()
+      } else {
+        _reject()
+        Modal.error({
+          title: result.message
+        })
+      }
+    })
+  }
+
+  columnChange = (values, resolve) => {
+    let verify = fromJS(this.state.verify).toJS()
+
+    let fields = verify.columns.map(item => item.field.toLowerCase())
+    if (fields.includes(values.field.toLowerCase())) {
+      notification.warning({
+        top: 92,
+        message: '瀛楁宸插瓨鍦紒',
+        duration: 5
+      })
+      return
+    }
+
+    resolve()
+
+    values.uuid = Utils.getuuid()
+    verify.columns.push(values)
+
+    this.setState({verify})
+  }
+
+  updatefields = (columns) => {
+    let verify = fromJS(this.state.verify).toJS()
+    verify.columns = columns
+
+    this.setState({verify})
+  }
+
   render() {
     const { card } = this.props
     const { getFieldDecorator } = this.props.form
-    const { verify, linkType, printMode, printFunc } = this.state
+    const { verify, linkType, printMode, printFunc, scriptsColumns, dataType, loading, activeKey, usefulfields, colColumns } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -270,10 +681,11 @@
     }
 
     return (
-      <div>
+      <div className="verify-card-print-box">
         {card.label ? <div className="mk-com-name">{card.label} - 楠岃瘉淇℃伅</div> : null}
-        <Tabs defaultActiveKey="1" className="verify-card-print-box" onChange={this.tabchange}>
-          <TabPane tab="鎵撳嵃楠岃瘉" key="1">
+        {loading && <Spin size="large" />}
+        <Tabs activeKey={activeKey} onChange={this.tabchange}>
+          <TabPane tab="鎵撳嵃楠岃瘉" key="base">
             <Form {...formItemLayout}>
               <Row gutter={24}>
                 <Col span={8}>
@@ -339,6 +751,18 @@
                     })(<Input placeholder="" autoComplete="off" />)}
                   </Form.Item>
                 </Col>}
+                {card.intertype === 'system' ? <Col span={8}>
+                  <Form.Item label="鏁版嵁绫诲瀷">
+                    {getFieldDecorator('dataType', {
+                      initialValue: dataType || 'line'
+                    })(
+                      <Radio.Group onChange={this.changeDataType}>
+                        <Radio value="line">琛屾暟鎹�</Radio>
+                        <Radio value="custom">鑷畾涔�</Radio>
+                      </Radio.Group>
+                    )}
+                  </Form.Item>
+                </Col> : null}
                 {printMode === 'custom' ? <Col span={24}>
                   <Form.Item label={'澶勭悊鍑芥暟'} className="printFunc">
                     {getFieldDecorator('printFunc', {
@@ -433,7 +857,7 @@
                     )}
                   </Form.Item>
                 </Col> : null}
-                {printMode !== 'custom' ? <Col span={8} offset={printMode === 'RFID' ? 16 : 0}>
+                {printMode !== 'custom' ? <Col span={8} offset={16}>
                   <img className="legend" src={this.state.selectimg} alt=""/>
                 </Col> : null }
               </Row>
@@ -444,7 +868,7 @@
               鎵撳嵃绫诲瀷
               {verify.printerTypeList.length ? <span className="count-tip">{verify.printerTypeList.length}</span> : null}
             </span>
-          } disabled={printMode === 'RFID'} key="2">
+          } disabled={printMode === 'RFID'} key="print">
             <Form {...formItemLayout}>
               <Row gutter={24}>
                 <Col span={24} className="print-tip">
@@ -455,12 +879,45 @@
                   </Form.Item>
                 </Col>
                 <Col span={24}>
-                  <EditTable data={verify.printerTypeList} ref="editTable"/>
+                  <EditTable data={verify.printerTypeList} onChange={(list) => this.setState({verify: {...verify, printerTypeList: list}})}/>
                 </Col>
               </Row>
             </Form>
           </TabPane>
-          <TabPane tab="淇℃伅鎻愮ず" key="7">
+          {card.intertype === 'system' ? <TabPane tab="鏁版嵁婧�" disabled={dataType !== 'custom'} key="setting">
+            <DataSource setting={verify.setting || {}} btnType="print" wrappedComponentRef={(inst) => this.settingForm = inst}/>
+          </TabPane> : null}
+          {card.intertype === 'system' ? <TabPane tab={
+            <span>
+              瀛楁闆�
+              {verify.columns.length ? <span className="count-tip">{verify.columns.length}</span> : null}
+            </span>
+          } disabled={dataType !== 'custom'} key="columns">
+            <ColForm columnChange={this.columnChange}/>
+            <FieldsComponent
+              config={verify}
+              type="fields"
+              updatefield={this.updatefields}
+            />
+            <EditMTable actions={['edit', 'move', 'copy', 'del', 'clear']} type="datasourcefield" data={verify.columns} columns={colColumns} onChange={(columns) => this.setState({verify: {...verify, columns}})}/>
+          </TabPane> : null}
+          {card.intertype === 'system' ? <TabPane tab={
+            <span>
+              鑷畾涔夎剼鏈�
+              {verify.scripts.length ? <span className="count-tip">{verify.scripts.length}</span> : null}
+            </span>
+          } key="scripts" disabled={dataType !== 'custom'} id="mk-exout-script">
+            <CustomScript
+              btn={card}
+              sheet={verify.setting ? verify.setting.tableName : ''}
+              searches={[]}
+              linefields={usefulfields}
+              scriptsChange={this.scriptsChange}
+              wrappedComponentRef={(inst) => this.scriptsForm = inst}
+            />
+            <EditMTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/>
+          </TabPane> : null}
+          <TabPane tab="淇℃伅鎻愮ず" key="message">
             <div style={{textAlign: 'center', fontSize: '13px', marginBottom: '10px'}}>鎵撳嵃淇℃伅涓鏋滃瓨鍦ㄧ綉缁滆祫婧愶紙鍥剧墖锛夛紝璇风‘淇濊祫婧愬彲浠ユ甯歌闂紝璧勬簮涓嶅瓨鍦ㄦ椂浼氭姤鏁版嵁寮傚父銆�</div>
             <Form {...formItemLayout}>
               <Row gutter={24}>
diff --git a/src/templates/sharecomponent/actioncomponent/verifyprint/index.scss b/src/templates/sharecomponent/actioncomponent/verifyprint/index.scss
index 1da8ed1..7d406e1 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyprint/index.scss
+++ b/src/templates/sharecomponent/actioncomponent/verifyprint/index.scss
@@ -1,4 +1,5 @@
 .verify-card-print-box {
+  position: relative;
   .ant-tabs-nav-scroll {
     text-align: center;
   }
@@ -60,6 +61,56 @@
     color: #1890ff;
     font-size: 12px;
   }
+  .verify-form {
+    .sql {
+      .ant-col-sm-8 {
+        width: 10.5%;
+      }
+      .ant-col-sm-16 {
+        width: 89.5%;
+        padding-top: 4px;
+      }
+      .CodeMirror {
+        height: 350px;
+      }
+    }
+    .sqlfield {
+      .ant-form-item {
+        margin-bottom: 5px;
+      }
+      .ant-form-item-control {
+        line-height: 24px;
+      }
+      .ant-form-item-label {
+        line-height: 25px;
+      }
+      .ant-form-item-children {
+        line-height: 22px;
+      }
+      .ant-col-sm-8 {
+        width: 10.5%;
+      }
+      .ant-col-sm-16 {
+        width: 89.5%;
+      }
+    }
+    .add {
+      padding-top: 4px;
+    }
+  }
+  .ant-spin {
+    position: absolute;
+    top: calc(50% - 16px);
+    left: calc(50% - 16px);
+    z-index: 1;
+  }
+  .quickly-add {
+    position: absolute;
+    width: 100px;
+    right: 24px;
+    top: 5px;
+    z-index: 2;
+  }
 }
 .print-template-setting {
   .ant-select-dropdown-menu-item {
diff --git a/src/templates/sharecomponent/actioncomponent/verifyprint/utils.jsx b/src/templates/sharecomponent/actioncomponent/verifyprint/utils.jsx
new file mode 100644
index 0000000..0e8275c
--- /dev/null
+++ b/src/templates/sharecomponent/actioncomponent/verifyprint/utils.jsx
@@ -0,0 +1,77 @@
+
+export default class SettingUtils {
+  static getDebugSql (setting, columns, scripts, declareSql, timestamp) {
+    let sql = ''
+    let _dataresource = setting.dataresource || ''
+
+    let _customScript = ''
+    scripts && scripts.forEach(script => {
+      if (script.status === 'false') return
+      _customScript += `
+      ${script.sql}
+      `
+    })
+
+    if (_customScript) {
+      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
+        ${declareSql}
+        ${_customScript}
+      `
+    }
+
+    if (setting.defaultSql === 'false') {
+      _dataresource = ''
+    }
+    
+    _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, '')
+
+    // 澶栬仈鏁版嵁搴撴浛鎹�
+    if (window.GLOB.externalDatabase !== null) {
+      _dataresource = _dataresource.replace(/@db@/ig, window.GLOB.externalDatabase)
+      _customScript = _customScript.replace(/@db@/ig, window.GLOB.externalDatabase)
+    }
+
+    let arr_field = columns.map(col => col.field)
+    arr_field = arr_field.join(',')
+
+    if (!arr_field) {
+      arr_field = '*'
+    }
+
+    // 鏁版嵁婧愬鐞�, 瀛樺湪鏄剧ず鍒楁椂 
+    if (_dataresource) {
+      if (/\s/.test(_dataresource)) {
+        _dataresource = '(' + _dataresource + ') tb'
+      }
+
+      if (setting.order) {
+        _dataresource = `/*system_query*/select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${setting.order}) as rows from ${_dataresource}) tmptable order by tmptable.rows`
+      } else {
+        _dataresource = `/*system_query*/select ${arr_field} from ${_dataresource}`
+      }
+    }
+
+    if (_customScript) {
+      sql = `/* sql 楠岃瘉 */
+        ${_customScript}
+        ${_dataresource}
+        aaa:
+        if @ErrorCode!=''
+          insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@
+      `
+    } else {
+      sql = `/* sql 楠岃瘉 */
+        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
+        ${declareSql}
+        ${_dataresource}`
+    }
+    sql = sql.replace(/\n\s{8}/ig, '\n')
+    console.info(sql)
+    sql = sql.replace(/\n/g, ' ')
+
+    return sql
+  }
+}
\ No newline at end of file
diff --git a/src/templates/sharecomponent/searchcomponent/index.jsx b/src/templates/sharecomponent/searchcomponent/index.jsx
index 88b50ab..2951024 100644
--- a/src/templates/sharecomponent/searchcomponent/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/index.jsx
@@ -160,7 +160,6 @@
 
     this.searchFormRef.handleConfirm().then(res => {
       let fieldrepet = false // 瀛楁閲嶅
-      let labelrepet = false // 鎻愮ず鏂囧瓧閲嶅
 
       _searchlist = _searchlist.filter(item => !item.origin || item.uuid === res.uuid) // 鍘婚櫎绯荤粺椤�
 
@@ -188,8 +187,6 @@
 
           if (setFields.length < itemFields.length + resFields.length && (res.type !== 'date' || item.type !== 'date')) {
             fieldrepet = true
-          } else if (item.label === res.label) {
-            labelrepet = true
           }
         }
 
@@ -204,13 +201,6 @@
         notification.warning({
           top: 92,
           message: '瀛楁宸插瓨鍦�!',
-          duration: 5
-        })
-        return
-      } else if (labelrepet) {
-        notification.warning({
-          top: 92,
-          message: '鍚嶇О宸插瓨鍦�!',
           duration: 5
         })
         return
diff --git a/src/templates/sharecomponent/searchcomponent/index.scss b/src/templates/sharecomponent/searchcomponent/index.scss
index 4a4a374..9ba3f42 100644
--- a/src/templates/sharecomponent/searchcomponent/index.scss
+++ b/src/templates/sharecomponent/searchcomponent/index.scss
@@ -26,6 +26,9 @@
     vertical-align: top;
   }
   .mk-search-item-wrap.action {
+    .ant-form-item {
+      white-space: nowrap;
+    }
     .ant-form-item-label, .ant-form-item-control-wrapper {
       display: inline-block;
     }
diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
index c4365b3..3ad9a27 100644
--- a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -198,7 +198,7 @@
         if (this.record.resourceType === '0') {        // 鑷畾涔夎祫婧�
           shows.push('options', 'fields')
         } else if (this.record.resourceType === '1') { // 鏁版嵁婧�
-          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'database')
+          shows.push('dataSource', 'cardValField', 'colorField', 'fields', 'orderBy', 'orderType', 'database')
         }
       } else {
         reRequired.fields = true
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index ecbc867..b11d8ca 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -489,6 +489,13 @@
       required: true
     },
     {
+      type: 'text',
+      key: 'colorField',
+      label: '鑹插�煎瓧娈�',
+      initVal: card.colorField || '',
+      required: true
+    },
+    {
       type: 'radio',
       key: 'picratio',
       label: '鍥剧墖姣斾緥',
@@ -2693,6 +2700,13 @@
       readonly: false
     },
     {
+      type: 'text',
+      key: 'colorField',
+      label: '鑹插�煎瓧娈�',
+      initVal: card.colorField || '',
+      required: true
+    },
+    {
       type: 'radio',
       key: 'picratio',
       label: '鍥剧墖姣斾緥',
diff --git a/src/templates/zshare/modalform/datatable/index.jsx b/src/templates/zshare/modalform/datatable/index.jsx
index 7492418..7f13956 100644
--- a/src/templates/zshare/modalform/datatable/index.jsx
+++ b/src/templates/zshare/modalform/datatable/index.jsx
@@ -201,6 +201,17 @@
           return <span style={{display: 'block', width: '70px', height: '70px'}}><img style={{width: '100%', height: '100%'}} src={text} alt="" /></span>
         }
       })
+    } else if (display === 'color') {
+      columns.push({
+        title: 'Color',
+        dataIndex: '$color',
+        inputType: 'text',
+        editable: true,
+        render: (text) => {
+          if (!text) return ''
+          return <div style={{height: '20px', background: text}}></div>
+        }
+      })
     }
 
     fields.forEach(item => {
@@ -371,6 +382,8 @@
 
     if (display === 'picture') {
       item.$url = ''
+    } else if (display === 'color') {
+      item.$color = ''
     }
 
     fields.forEach(f => {
diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx
index b4354cc..2cd53c8 100644
--- a/src/templates/zshare/modalform/index.jsx
+++ b/src/templates/zshare/modalform/index.jsx
@@ -193,7 +193,7 @@
         if (this.record.resourceType === '0') {        // 鑷畾涔夎祫婧�
           shows.push('options', 'fields')
         } else if (this.record.resourceType === '1') { // 鏁版嵁婧�
-          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'database')
+          shows.push('dataSource', 'cardValField', 'colorField', 'fields', 'orderBy', 'orderType', 'database')
         }
       } else {
         reRequired.fields = true
diff --git a/src/templates/zshare/verifycard/index.jsx b/src/templates/zshare/verifycard/index.jsx
index 8b7680b..a8cbb97 100644
--- a/src/templates/zshare/verifycard/index.jsx
+++ b/src/templates/zshare/verifycard/index.jsx
@@ -626,7 +626,7 @@
           _fields.push(...group.sublist)
         })
         resolve(_fields)
-      } else if (card.modal) {
+      } else if (card.modal && (card.OpenType === 'pop' || !card.OpenType)) {
         _fields = card.modal.fields || []
         resolve(_fields)
       } else if (card.OpenType === 'pop') {
@@ -840,10 +840,10 @@
         let _arr = []
 
         _fields.forEach(item => {
-          if (!item.field || item.writein === 'false') return
+          if (!item.field || item.writein === 'false' || item.uuid === 'BID') return
 
           _arr.push(item.field.toLowerCase())
-          if (item.field.toLowerCase() === 'bid' && item.uuid === 'BID') {
+          if (item.field.toLowerCase() === 'bid') {
             _form.push(item.field + '=@BID@')
           } else {
             _form.push(item.field + '=@' + item.field)
diff --git a/src/utils/utils-custom.js b/src/utils/utils-custom.js
index a7a4398..1eaf2e9 100644
--- a/src/utils/utils-custom.js
+++ b/src/utils/utils-custom.js
@@ -896,7 +896,7 @@
 export function getTables (config, pops) {
   let tables = []
   let cuts = []
-  let cutreg = /(from|update|insert\s+into)\s+(@db@)?[a-z_]+/ig
+  let cutreg = /(from|update|insert\s+into)\s+(@db@)?[a-z0-9_]+/ig
   let trimreg = /(from|update|insert\s+into)\s+(@db@)?/ig
 
   if (config.setting && (!config.wrap || !config.wrap.datatype || config.wrap.datatype === 'dynamic')) {
@@ -943,6 +943,8 @@
         if (cell.eleType !== 'button') return
         if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
           action.push(cell)
+        } else if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) {
+          action.push(cell)
         } else if (cell.OpenType === 'popview') {
           if (pops) {
             pops.push({...cell, parentId: config.uuid})
@@ -956,6 +958,8 @@
         item.backElements.forEach(cell => {
           if (cell.eleType !== 'button') return
           if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
+            action.push(cell)
+          } else if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) {
             action.push(cell)
           } else if (cell.OpenType === 'popview') {
             if (pops) {
@@ -974,6 +978,8 @@
       col.elements.forEach(cell => {
         if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
           action.push(cell)
+        } else if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) {
+          action.push(cell)
         } else if (cell.OpenType === 'popview') {
           if (pops) {
             pops.push({...cell, parentId: config.uuid})
@@ -989,6 +995,8 @@
     if (cell.eleType !== 'button') return
     if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
       action.push(cell)
+    } else if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) {
+      action.push(cell)
     } else if (cell.OpenType === 'popview') {
       if (pops) {
         pops.push({...cell, parentId: config.uuid})
@@ -1000,6 +1008,8 @@
 
   config.action && config.action.forEach(cell => {
     if (['pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
+      action.push(cell)
+    } else if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) {
       action.push(cell)
     } else if (cell.OpenType === 'popview') {
       if (pops) {
@@ -1021,6 +1031,19 @@
       }
       if (btn.intertype === 'system' && btn.verify.scripts) {
         btn.verify.scripts.forEach(script => {
+          if (script.status === 'false') return
+          let tbs = script.sql.match(cutreg)
+          tbs && cuts.push(...tbs)
+        })
+      }
+    } else if (btn.OpenType === 'funcbutton') {
+      if (btn.intertype !== 'system' || !btn.verify || !btn.verify.setting) return
+      if (btn.verify.dataType === 'custom') {
+        if (btn.verify.setting.defaultSql !== 'false') {
+          let tbs = btn.verify.setting.dataresource.match(cutreg)
+          tbs && cuts.push(...tbs)
+        }
+        btn.verify.scripts && btn.verify.scripts.forEach(script => {
           if (script.status === 'false') return
           let tbs = script.sql.match(cutreg)
           tbs && cuts.push(...tbs)
@@ -1102,7 +1125,7 @@
 
   cuts = cuts.map(item => item.replace(trimreg, ''))
   tables.push(...cuts)
-  tables = tables.filter(Boolean)
+  tables = tables.filter(tb => tb && tb !== 'dbo' && tb.length > 1)
   tables = Array.from(new Set(tables))
 
   return tables
diff --git a/src/utils/utils.js b/src/utils/utils.js
index e92cda2..8616197 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -783,6 +783,8 @@
       arrfield.push(item.cardValField)
       if (item.urlField) {
         arrfield.push(item.urlField)
+      } else if (item.colorField) {
+        arrfield.push(item.colorField)
       }
     }
 
@@ -2566,9 +2568,9 @@
         @ErrorSeverity=ERROR_SEVERITY(),
         @ErrorState=ERROR_STATE();
         
-      RAISERROR(@ErrorMessage, /*-- Message text.*/
-        @ErrorSeverity, /*-- Severity.*/
-        @ErrorState  /*-- State.*/
+      RAISERROR(@ErrorMessage, /* Message text.*/
+        @ErrorSeverity, /* Severity.*/
+        @ErrorState  /* State.*/
       );
     END CATCH
     
@@ -2707,9 +2709,9 @@
         @ErrorSeverity=ERROR_SEVERITY(),
         @ErrorState=ERROR_STATE();
         
-      RAISERROR(@ErrorMessage, /*-- Message text.*/
-        @ErrorSeverity, /*-- Severity.*/
-        @ErrorState  /*-- State.*/
+      RAISERROR(@ErrorMessage, /* Message text.*/
+        @ErrorSeverity, /* Severity.*/
+        @ErrorState  /* State.*/
       );
     END CATCH
     
diff --git a/src/views/appmanage/index.jsx b/src/views/appmanage/index.jsx
index a3512bd..2861ae7 100644
--- a/src/views/appmanage/index.jsx
+++ b/src/views/appmanage/index.jsx
@@ -466,6 +466,7 @@
               cell.delay = _param.delay || 0
               cell.statusBarColor = _param.statusBarColor || 'black'
               cell.sysBgColor = _param.sysBgColor || '#ffffff'
+              cell.direction = _param.direction || 'vertical'
               cell.adapter = _param.adapter || ''
               cell.share = _param.share || 'false' // 鍒嗕韩
               cell.share_des = _param.share_des || '' // 鍒嗕韩鎻忚堪
@@ -650,7 +651,7 @@
     })
 
     // 瀛愬簲鐢↖D銆乼ypename銆佸簲鐢↖D銆丆loudUserID銆乤ppkey銆乴ogin_types(鏄惁闇�瑕佺櫥褰曪紝宸插純鐢�)銆乴ink_type(鏄惁浣跨敤鐭繛鎺ワ紝宸插純鐢�)銆乺ole_type(鏄惁浣跨敤瑙掕壊绠$悊)銆乴ang銆乧ss(鐨偆)銆乼itle(鏍囬)銆乫avicon(鍥炬爣)銆乽ser_binding(鐢ㄦ埛缁戝畾)銆乻ms_id(鐭俊妯℃澘ID)銆佽嚜瀹氫箟
-    param.LText = sublist.map(item => `select '${item.ID}','${item.typename}','${selectApp.ID}','${sessionStorage.getItem('CloudUserID') || ''}','${window.GLOB.appkey || ''}','false','false','${item.role_type || 'true'}','${item.lang || 'zh-CN'}','${item.css || ''}','${item.title || ''}','${item.favicon || ''}','${item.user_binding || 'false'}','','${window.btoa(window.encodeURIComponent(JSON.stringify({userbind: item.userbind || '', instantMessage: item.instantMessage || '', apptype: item.apptype || '', delay: item.delay || 0, statusBarColor: item.statusBarColor || 'black', sysBgColor: item.sysBgColor || '#ffffff', adapter: item.adapter || '', share: item.share || '', share_des: item.share_des || '', share_url: item.share_url || '', share_link: item.share_link || ''})))}'`)
+    param.LText = sublist.map(item => `select '${item.ID}','${item.typename}','${selectApp.ID}','${sessionStorage.getItem('CloudUserID') || ''}','${window.GLOB.appkey || ''}','false','false','${item.role_type || 'true'}','${item.lang || 'zh-CN'}','${item.css || ''}','${item.title || ''}','${item.favicon || ''}','${item.user_binding || 'false'}','','${window.btoa(window.encodeURIComponent(JSON.stringify({userbind: item.userbind || '', instantMessage: item.instantMessage || '', apptype: item.apptype || '', delay: item.delay || 0, statusBarColor: item.statusBarColor || 'black', sysBgColor: item.sysBgColor || '#ffffff', direction: item.direction || 'vertical', adapter: item.adapter || '', share: item.share || '', share_des: item.share_des || '', share_url: item.share_url || '', share_link: item.share_link || ''})))}'`)
     param.LText = param.LText.join(' union all ')
     param.LText = Utils.formatOptions(param.LText)
     
@@ -896,7 +897,7 @@
           return item
         })
 
-        param.LText = selectApp.sublist.map(item => `select '${item.ID}','${item.typename}','${selectApp.ID}','${sessionStorage.getItem('CloudUserID') || ''}','${window.GLOB.appkey || ''}','false','false','${item.role_type || 'true'}','${item.lang || 'zh-CN'}','${item.css || ''}','${item.title || ''}','${item.favicon || ''}','${item.user_binding || 'false'}','','${window.btoa(window.encodeURIComponent(JSON.stringify({userbind: item.userbind || '', instantMessage: item.instantMessage || '', apptype: item.apptype || '', delay: item.delay || 0, statusBarColor: item.statusBarColor || 'black', sysBgColor: item.sysBgColor || '#ffffff', adapter: item.adapter || '', share: item.share || '', share_des: item.share_des || '', share_url: item.share_url || '', share_link: item.share_link || ''})))}'`)
+        param.LText = selectApp.sublist.map(item => `select '${item.ID}','${item.typename}','${selectApp.ID}','${sessionStorage.getItem('CloudUserID') || ''}','${window.GLOB.appkey || ''}','false','false','${item.role_type || 'true'}','${item.lang || 'zh-CN'}','${item.css || ''}','${item.title || ''}','${item.favicon || ''}','${item.user_binding || 'false'}','','${window.btoa(window.encodeURIComponent(JSON.stringify({userbind: item.userbind || '', instantMessage: item.instantMessage || '', apptype: item.apptype || '', delay: item.delay || 0, statusBarColor: item.statusBarColor || 'black', sysBgColor: item.sysBgColor || '#ffffff', direction: item.direction || 'vertical', adapter: item.adapter || '', share: item.share || '', share_des: item.share_des || '', share_url: item.share_url || '', share_link: item.share_link || ''})))}'`)
         param.LText = param.LText.join(' union all ')
         param.LText = Utils.formatOptions(param.LText)
       }
@@ -989,7 +990,7 @@
         return item
       })
 
-      param.LText = sublist.map(item => `select '${item.ID}','${item.typename}','${selectApp.ID}','${sessionStorage.getItem('CloudUserID') || ''}','${window.GLOB.appkey || ''}','false','false','${item.role_type || 'true'}','${item.lang || 'zh-CN'}','${item.css || ''}','${item.title || ''}','${item.favicon || ''}','${item.user_binding || 'false'}','','${window.btoa(window.encodeURIComponent(JSON.stringify({userbind: item.userbind || '', instantMessage: item.instantMessage || '', apptype: item.apptype || '', delay: item.delay || 0, statusBarColor: item.statusBarColor || 'black', sysBgColor: item.sysBgColor || '#ffffff', adapter: item.adapter || '', share: item.share || '', share_des: item.share_des || '', share_url: item.share_url || '', share_link: item.share_link || ''})))}'`)
+      param.LText = sublist.map(item => `select '${item.ID}','${item.typename}','${selectApp.ID}','${sessionStorage.getItem('CloudUserID') || ''}','${window.GLOB.appkey || ''}','false','false','${item.role_type || 'true'}','${item.lang || 'zh-CN'}','${item.css || ''}','${item.title || ''}','${item.favicon || ''}','${item.user_binding || 'false'}','','${window.btoa(window.encodeURIComponent(JSON.stringify({userbind: item.userbind || '', instantMessage: item.instantMessage || '', apptype: item.apptype || '', delay: item.delay || 0, statusBarColor: item.statusBarColor || 'black', sysBgColor: item.sysBgColor || '#ffffff', direction: item.direction || 'vertical', adapter: item.adapter || '', share: item.share || '', share_des: item.share_des || '', share_url: item.share_url || '', share_link: item.share_link || ''})))}'`)
       param.LText = param.LText.join(' union all ')
       param.LText = Utils.formatOptions(param.LText)
 
diff --git a/src/views/appmanage/submutilform/index.jsx b/src/views/appmanage/submutilform/index.jsx
index 18265b2..5c1b1d8 100644
--- a/src/views/appmanage/submutilform/index.jsx
+++ b/src/views/appmanage/submutilform/index.jsx
@@ -322,6 +322,23 @@
               )}
             </Form.Item>
           </Col>
+          {typename === 'pad' ? <Col span={12}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="绯荤粺榛樿灞忓箷鏂瑰悜锛屽崟涓〉闈㈡柟鍚戣鍦ㄩ〉闈腑閰嶇疆銆�">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                灞忓箷鏂瑰悜
+              </Tooltip>
+            }>
+              {getFieldDecorator('direction', {
+                initialValue: card ? card.direction || 'vertical' : 'vertical'
+              })(
+                <Radio.Group>
+                  <Radio value="vertical">绔栧睆</Radio>
+                  <Radio value="horizontal">妯睆</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col> : null}
         </Row>
       </Form>
     )
diff --git a/src/views/design/index.jsx b/src/views/design/index.jsx
index 0c565d0..9c1ea4c 100644
--- a/src/views/design/index.jsx
+++ b/src/views/design/index.jsx
@@ -23,7 +23,7 @@
   
   render () {
     return (
-      <div className="mk-main-view mk-design-view">
+      <div className="mk-main-view">
         <ConfigProvider locale={_locale}>
           <Sidemenu key="sidemenu"/>
           <Header key="header"/>
diff --git a/src/views/design/index.scss b/src/views/design/index.scss
index 037cdcb..2dd743a 100644
--- a/src/views/design/index.scss
+++ b/src/views/design/index.scss
@@ -1,24 +1,6 @@
 .mk-main-view {
-  display: flex;
-  flex: auto;
-  min-height: 100%;
-
   .mk-save-menu[disabled] {
     background: #ffffff!important;
-  }
-}
-.mk-design-view {
-  #mk-tabview-wrap {
-    z-index: unset;
-    >.content-header {
-      >.ant-tabs {
-        z-index: 21;
-        background: #ffffff;
-      }
-    }
-  }
-  #mk-tabview-wrap.hastab + .sys-header-container .app-prod-entrance {
-    display: none;
   }
 }
 .mk-popover-control-wrap {
diff --git a/src/views/design/sidemenu/index.scss b/src/views/design/sidemenu/index.scss
index 22cc2fa..bc55c66 100644
--- a/src/views/design/sidemenu/index.scss
+++ b/src/views/design/sidemenu/index.scss
@@ -1,4 +1,4 @@
-@import '../../../assets/css/iconfont.css';
+// @import '../../../assets/css/iconfont.css';
 
 .mk-sys-side-menu {
   flex: 0 0 235px;
diff --git a/src/views/login/index.scss b/src/views/login/index.scss
index 608a846..5447f5a 100644
--- a/src/views/login/index.scss
+++ b/src/views/login/index.scss
@@ -1,7 +1,7 @@
 .login-container {
   height: 100vh;
   min-height: 600px;
-  background-color: #000000;
+  background-color: var(--mk-sys-background);
   background-size: cover;
   background-repeat: no-repeat;
   background-position: center center;
@@ -10,13 +10,13 @@
     height: 100px;
     padding-top: 30px;
     line-height: 80px;
-    border-bottom: 2px solid #1890ff;
+    border-bottom: 2px solid var(--mk-sys-color);
     img {
       max-height: 100%;
     }
     .plat-name {
       position: absolute;
-      color: #ffffff;
+      color: var(--mk-sys-font-color);
       line-height: 30px;
       font-size: 30px;
       font-weight: 600;
@@ -32,7 +32,22 @@
     min-height: 420px;
     background-size: cover;
     background-position: center center;
-    border-bottom: 2px solid #1890ff;
+    border-bottom: 2px solid var(--mk-sys-color);
+
+    .login-form-button {
+      background-color: var(--mk-sys-color);
+      border-color: var(--mk-sys-color);
+    }
+    .login-form-button[disabled] {
+      background-color: var(--mk-sys-color5);
+      border-color: var(--mk-sys-color5);
+    }
+
+    .login-way-wrap {
+      .login-way.active, .login-way:hover {
+        color: var(--mk-sys-color);
+      }
+    }
 
     .login-form {
       position: relative;
@@ -167,6 +182,7 @@
       }
       button.vercode {
         border: 0;
+        color: var(--mk-sys-color);
       }
       button:not(.vercode) {
         width: 100%;
@@ -198,7 +214,7 @@
         font-size: 18px;
       }
       .anticon-eye {
-        color: #1890ff;
+        color: var(--mk-sys-color);
       }
     }
     .login-sync-button {
@@ -209,7 +225,7 @@
   }
   .login-bottom {
     text-align: center;
-    color: #ffffff;
+    color: var(--mk-sys-font-color);
     padding-top: 20px;
     p span.split {
       margin-right: 15px;
@@ -217,7 +233,7 @@
     a {
       display: inline-block;
       margin-bottom: 5px;
-      color: #ffffff;
+      color: var(--mk-sys-font-color);
     }
   }
   .ant-btn-primary[disabled] {
diff --git a/src/views/main/index.jsx b/src/views/main/index.jsx
index 5626c5c..8dd7821 100644
--- a/src/views/main/index.jsx
+++ b/src/views/main/index.jsx
@@ -10,7 +10,7 @@
 import QueryLog from '@/components/querylog'
 import ImgScale from '@/components/imgScale'
 
-import './index.scss'
+// import './index.scss'
 
 const Tabview = asyncComponent(() => import('@/components/tabview'))
 const Breadview = asyncComponent(() => import('@/components/breadview'))
diff --git a/src/views/main/index.scss b/src/views/main/index.scss
index c14dc8e..e69de29 100644
--- a/src/views/main/index.scss
+++ b/src/views/main/index.scss
@@ -1,5 +0,0 @@
-.mk-main-view {
-  display: flex;
-  flex: auto;
-  min-height: 100%;
-}
\ No newline at end of file
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index 687d793..67ee9a7 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -1043,7 +1043,8 @@
       }
       let subforbid = {
         editable: '鍙紪杈戣〃鏍�',
-        voucher: '鍑瘉'
+        voucher: '鍑瘉',
+        account: '璐﹀'
       }
 
       config.components.forEach(item => {
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index b2df487..a3f934b 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -68,7 +68,6 @@
     menuloading: false,
     oriConfig: null,
     config: null,
-    direction: 'vertical',
     settingshow: true,
     controlshow: true,
     comloading: false,
@@ -91,6 +90,7 @@
         sessionStorage.setItem('typename', param.typename || 'mob')
         sessionStorage.setItem('adapter', param.adapter || '')
         sessionStorage.setItem('sysBgColor', param.sysBgColor || '#ffffff')
+        sessionStorage.setItem('direction', param.direction || 'vertical')
         sessionStorage.setItem('userbind', param.userbind || '')
         sessionStorage.setItem('instantMessage', param.instantMessage || '')
 
@@ -100,13 +100,6 @@
         window.GLOB.winHeight = 738
         window.GLOB.shellWidth = 376
         window.GLOB.shellHeight = 680
-
-        if (sessionStorage.getItem('typename') === 'pad') {
-          window.GLOB.winWidth = 736
-          window.GLOB.winHeight = 945
-          window.GLOB.shellWidth = 640
-          window.GLOB.shellHeight = 853
-        }
 
         let adapters = sessionStorage.getItem('adapter')
         if (adapters) {
@@ -498,7 +491,22 @@
         config.uuid = MenuId
         config.MenuID = MenuId
         config.open_edition = result.open_edition || ''
+        config.direction = config.direction || sessionStorage.getItem('direction') || 'vertical'
         window.GLOB.urlFields = config.urlFields || []
+
+        if (sessionStorage.getItem('typename') === 'pad') {
+          if (config.direction !== 'vertical') {
+            window.GLOB.winWidth = 992
+            window.GLOB.winHeight = 690
+            window.GLOB.shellWidth = 853
+            window.GLOB.shellHeight = 640
+          } else {
+            window.GLOB.winWidth = 736
+            window.GLOB.winHeight = 945
+            window.GLOB.shellWidth = 640
+            window.GLOB.shellHeight = 853
+          }
+        }
 
         if (config.version !== 2.0) {
           config.components = this.collectTB(config.components)
@@ -739,6 +747,21 @@
       config.MenuName = urlParam.MenuName || ''
       // config.MenuNo = urlParam.MenuNo || ''
       config.MenuNo = ''
+      config.direction = config.direction || sessionStorage.getItem('direction') || 'vertical'
+
+      if (sessionStorage.getItem('typename') === 'pad') {
+        if (config.direction !== 'vertical') {
+          window.GLOB.winWidth = 992
+          window.GLOB.winHeight = 690
+          window.GLOB.shellWidth = 853
+          window.GLOB.shellHeight = 640
+        } else {
+          window.GLOB.winWidth = 736
+          window.GLOB.winHeight = 945
+          window.GLOB.shellWidth = 640
+          window.GLOB.shellHeight = 853
+        }
+      }
 
       let navItem = null
       config.components.forEach(item => {
@@ -1809,6 +1832,8 @@
   }
 
   changeView = (val) => {
+    if (sessionStorage.getItem('typename') !== 'pad') return
+    
     if (val !== 'vertical') {
       window.GLOB.winWidth = 992
       window.GLOB.winHeight = 690
@@ -1822,7 +1847,6 @@
     }
 
     this.setState({
-      direction: val,
       comloading: true
     }, () => {
       this.setState({ comloading: false })
@@ -1849,7 +1873,7 @@
     return (
       <ConfigProvider locale={antdZhCN}>
         <div className={'mk-mob-view ' + viewType} id="mk-mob-design-view">
-          <Header changeView={this.changeView}/>
+          <Header/>
           {loading ? <Spin className="view-spin" size="large" /> : null}
           <DndProvider backend={HTML5Backend}>
             <div className={'menu-setting ' + (!settingshow ? 'hidden' : '')}>
@@ -1866,12 +1890,18 @@
                       config={config}
                       MenuId={MenuId}
                       adapters={adapters}
-                      updateConfig={this.updateConfig}
+                      updateConfig={(con) => {
+                        this.updateConfig(con)
+                        if (con.direction !== config.direction) {
+                          this.changeView(con.direction)
+                        }
+                      }}
                     /> : null}
                     {config ? <UrlFieldComponent config={config} updateConfig={this.updateConfig}/> : null}
                     {/* 琛ㄥ悕娣诲姞 */}
                     {config ? <TableComponent config={config} updatetable={this.updateConfig}/> : null}
                     {config ? <Paragraph style={{padding: '15px 0px 0px 18px'}} copyable={{ text: MenuId }}>鑿滃崟ID</Paragraph> : null}
+                    {config ? <Paragraph style={{padding: '10px 0px 0px 18px'}} copyable={{ text:  `${window.GLOB.baseurl}mob/index.html#/index/${sessionStorage.getItem('kei_no')}/${sessionStorage.getItem('typename')}/${sessionStorage.getItem('lang')}/${MenuId}/@BID@` }}>鑿滃崟閾炬帴</Paragraph> : null}
                   </Panel>
                   {/* 缁勪欢娣诲姞 */}
                   <Panel header="缁勪欢" className="component" key="component">
diff --git a/src/views/mobdesign/menuform/index.jsx b/src/views/mobdesign/menuform/index.jsx
index 14fae1f..ba65de4 100644
--- a/src/views/mobdesign/menuform/index.jsx
+++ b/src/views/mobdesign/menuform/index.jsx
@@ -185,6 +185,18 @@
               )}
             </Form.Item>
           </Col>
+          <Col span={24}>
+            <Form.Item label="灞忓箷鏂瑰悜">
+              {getFieldDecorator('direction', {
+                initialValue: config.direction || 'vertical'
+              })(
+                <Radio.Group onChange={(e) => {this.selectChange('direction', e.target.value)}}>
+                  <Radio value="vertical">绔栧睆</Radio>
+                  <Radio value="horizontal">妯睆</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
           {adapters.includes('app') || adapters.includes('wxmini') ? <Col span={24}>
             <Form.Item className="status-bar" label={
               <Tooltip placement="topLeft" title="鍦ㄦ槑绉戜簯APP鎴栧皬绋嬪簭涓紝鐘舵�佹爮鐨勮儗鏅壊銆�">
diff --git a/src/views/systemfunc/index.jsx b/src/views/systemfunc/index.jsx
index 26ae9c0..c0ef10e 100644
--- a/src/views/systemfunc/index.jsx
+++ b/src/views/systemfunc/index.jsx
@@ -6,12 +6,13 @@
 import Header from './header'
 import Sidemenu from './sidemenu'
 
-import './index.scss'
+// import './index.scss'
 
 const Tabview = asyncComponent(() => import('@/components/tabview'))
 
 class Design extends Component {
   UNSAFE_componentWillMount() {
+    document.body.className = 'mk-blue-black'
     sessionStorage.setItem('isEditState', 'true')
     window.GLOB.mkHS = true
 
@@ -27,7 +28,7 @@
   
   render () {
     return (
-      <div className="mk-hs-view">
+      <div className="mk-main-view">
         <ConfigProvider locale={zhCN}>
           <Sidemenu key="sidemenu"/>
           <Tabview key="tabview"/>
diff --git a/src/views/systemfunc/index.scss b/src/views/systemfunc/index.scss
index 8f5e059..8b13789 100644
--- a/src/views/systemfunc/index.scss
+++ b/src/views/systemfunc/index.scss
@@ -1,5 +1 @@
-.mk-hs-view {
-  display: flex;
-  flex: auto;
-  min-height: 100%;
-}
+
diff --git a/src/views/systemproc/proc/index.jsx b/src/views/systemproc/proc/index.jsx
index 56bc51f..6f13864 100644
--- a/src/views/systemproc/proc/index.jsx
+++ b/src/views/systemproc/proc/index.jsx
@@ -1,5 +1,6 @@
 import React, {Component} from 'react'
-import { Input, notification } from 'antd'
+import { Input, notification, Button, Form, Modal, Empty } from 'antd'
+import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import Utils from '@/utils/utils.js'
@@ -7,17 +8,52 @@
 import CodeMirror from '@/templates/zshare/codemirror'
 import './index.scss'
 
+const { confirm } = Modal
 const { Search } = Input
 
 class ProcControl extends Component {
   state = {
     procName: '',
-    content: null,
-    loading: false
+    content: '',
+    loading: false,
+    visible: false,
+    searchable: false,
+    inputing: false,
+    procList: [],
+    permFuncs: []
   }
 
   componentDidMount () {
+    if (sessionStorage.getItem('permFuncField')) {
+      this.setState({permFuncs: JSON.parse(sessionStorage.getItem('permFuncField'))})
+    } else {
+      Api.getCloudConfig({func: 'sPC_Get_Roles_sModular'}).then(res => {
+        if (res.status) {
+          let _permFuncs = []
+  
+          if (res.sModular && res.sModular.length > 0) {
+            res.sModular.forEach(field => {
+              if (field.ModularNo) {
+                _permFuncs.push(field.ModularNo)
+              }
+            })
+            _permFuncs = _permFuncs.sort()
+          }
+
+          if (_permFuncs.length) {
+            this.setState({permFuncs: _permFuncs})
     
+            sessionStorage.setItem('permFuncField', JSON.stringify(_permFuncs))
+          }
+        } else {
+          notification.warning({
+            top: 92,
+            message: res.message,
+            duration: 5
+          })
+        }
+      })
+    }
   }
 
   search = (value) => {
@@ -47,31 +83,330 @@
         })
         this.setState({content: '', procName: '', loading: false})
         return
+      } else if (!res.Ltext) {
+        this.setState({content: '', procName: '', loading: false})
+      } else {
+        this.setState({content: res.Ltext.replace(/mchr13k/ig, '\n'), procName: proc, loading: false})
+      }
+    })
+  }
+
+  save = (type) => {
+    const { content, procName, permFuncs } = this.state
+    let value = content.replace(/^(\s*)|(\s*)$/ig, '')
+
+    if (!value) {
+      notification.warning({
+        top: 92,
+        message: '瀛樺偍杩囩▼涓嶅彲涓虹┖',
+        duration: 5
+      })
+      return
+    } else {
+      let chars = [
+        {key: 'drop', reg: /(^|\s)drop\s/ig},
+        {key: 'alter', reg: /(^|\s)alter\s/ig},
+        {key: 'object', reg: /(^|\s)object(\s|\()/ig},
+        {key: 'kill', reg: /(^|\s)kill\s/ig},
+        {key: '--', reg: /--/ig}
+      ]
+
+      let error = ''
+
+      if (!/create(\s+)proc/ig.test(value)) {
+        error = '鑴氭湰涓繀椤讳娇鐢╟reate proc'
+      }
+    
+      chars.forEach(char => {
+        if (!error && char.reg.test(value)) {
+          error = '涓嶅彲浣跨敤' + char.key
+        }
+      })
+  
+      if (error) {
+        notification.warning({
+          top: 92,
+          message: error,
+          duration: 5
+        })
+        return
+      }
+    }
+
+    if (!procName) {
+      if (permFuncs.length > 0) {
+        this.setState({visible: true})
+      } else {
+        notification.warning({
+          top: 92,
+          message: '鏈幏鍙栧埌鎺堟潈缂栫爜涓嶅彲鏂板缓锛�',
+          duration: 5
+        })
+      }
+      return
+    }
+
+    let dropfunc = `IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('${procName}') AND type in (N'P', N'PC'))  mdrpk PROCEDURE ${procName}`
+    let createfunc = value.replace(/\n/ig, 'mchr13k')
+
+    let dropParam = {
+      func: 'sPC_TableData_InUpDe',
+      LText: Utils.formatOptions(dropfunc),
+      TypeCharOne: 'proc' // 鍒犻櫎瀛樺偍杩囩▼
+    }
+
+    dropParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    dropParam.secretkey = Utils.encrypt(dropParam.LText, dropParam.timestamp)
+    dropParam.open_key = Utils.encryptOpenKey(dropParam.secretkey, dropParam.timestamp)
+
+
+    let createParam = {
+      func: 'sPC_TableData_InUpDe',
+      LText: Utils.formatOptions(createfunc),
+      TypeCharOne: 'proc' // 鍒涘缓瀛樺偍杩囩▼
+    }
+
+    createParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    createParam.secretkey = Utils.encrypt(createParam.LText, createParam.timestamp)
+    createParam.open_key = Utils.encryptOpenKey(createParam.secretkey, createParam.timestamp)
+
+    let saveParam = {
+      func: 's_proc_save',
+      sql_script: window.btoa(window.encodeURIComponent(createfunc)),
+      proc_name: procName,
+      save_type: type !== 'prev' ? 'auto' : '' // 'auto' 鏃� 浼氭竻y鐨勬暟鎹�
+    }
+
+    this.setState({loading: true})
+    
+    Api.genericInterface(dropParam).then(res => {
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        this.setState({loading: false})
+        return
       }
 
-      this.setState({content: res.Ltext.replace(/mchr13k/ig, '\n'), procName: proc, loading: false})
+      Api.genericInterface(createParam).then(result => {
+        if (!result.status) {
+          notification.warning({
+            top: 92,
+            message: result.message,
+            duration: 5
+          })
+          this.setState({loading: false})
+          return
+        }
+
+        Api.genericInterface(saveParam).then(response => {
+          this.setState({loading: false})
+          if (!response.status) {
+            notification.warning({
+              top: 92,
+              message: response.message,
+              duration: 5
+            })
+          } else {
+            notification.success({
+              top: 92,
+              message: '淇濆瓨鎴愬姛銆�',
+              duration: 5
+            })
+          }
+        })
+      })
+    })
+  }
+
+  prev = () => {
+    const { procName } = this.state
+    const that = this
+
+    let saveParam = {
+      func: 's_proc_ctrl_z',
+      proc_name: procName
+    }
+
+    confirm({
+      title: '纭畾鍒囨崲涓婁竴鐗堟湰鍚楋紵',
+      content: '',
+      onOk() {
+        that.setState({loading: true})
+  
+        Api.genericInterface(saveParam).then(res => {
+          that.setState({loading: false})
+          if (!res.status || !res.Ltext) {
+            notification.warning({
+              top: 92,
+              message: !res.status ? res.message : '娌℃湁鍙互鍚庨��鐨勭増鏈�',
+              duration: 5
+            })
+            return
+          }
+
+          let value = window.decodeURIComponent(window.atob(res.Ltext))
+          value  = value.replace(/mchr13k/ig, '\n')
+
+          that.setState({content: value}, () => {
+            that.save('prev')
+          })
+        })
+      },
+      onCancel() {}
+    })
+  }
+
+  next = () => {
+    const { procName } = this.state
+    const that = this
+
+    let saveParam = {
+      func: 's_proc_ctrl_y',
+      proc_name: procName
+    }
+
+    confirm({
+      title: '纭畾鍒囨崲涓嬩竴鐗堟湰鍚楋紵',
+      content: '',
+      onOk() {
+        that.setState({loading: true})
+  
+        Api.genericInterface(saveParam).then(res => {
+          that.setState({loading: false})
+          if (!res.status || !res.Ltext) {
+            notification.warning({
+              top: 92,
+              message: !res.status ? res.message : '娌℃湁鍙互鎾ら攢鍚庨��鐨勭増鏈�',
+              duration: 5
+            })
+            return
+          }
+
+          let value = window.decodeURIComponent(window.atob(res.Ltext))
+          value  = value.replace(/mchr13k/ig, '\n')
+
+          that.setState({content: value}, () => {
+            that.save()
+          })
+        })
+      },
+      onCancel() {}
+    })
+  }
+
+  handleConfirm = () => {
+    this.props.form.validateFieldsAndScroll((err, values) => {
+      if (err) return
+
+      this.setState({procName: values.name}, () => {
+        this.save()
+      })
+    })
+  }
+
+  searchAll = (value) => {
+    let param = {
+      func: 's_proc_search',
+      proc_name: value || ''
+    }
+
+    this.setState({loading: true})
+
+    Api.genericInterface(param).then(res => {
+      this.setState({loading: false})
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        return
+      }
+
+      this.setState({procList: res.data || []})
+    })
+  }
+
+  changeProc = (name) => {
+    const { loading } = this.state
+
+    if (loading) {
+      notification.warning({
+        top: 92,
+        message: '鏌ヨ涓绋嶅悗銆�',
+        duration: 5
+      })
+      return
+    }
+    
+    this.setState({inputing: true, procName: name}, () => {
+      this.setState({inputing: false})
+      this.search(name)
     })
   }
 
   render () {
-    const { loading, content } = this.state
+    const { getFieldDecorator } = this.props.form
+    const { loading, content, procName, visible, permFuncs, searchable, procList, inputing } = this.state
+
+    let _patten = permFuncs.length ? new RegExp('^(' + permFuncs.join('|') + ')[0-9a-zA-Z_]*$', 'g') : ''
 
     return (
       <div className="mk-proc-wrap">
-        <div className="control-wrap">
-          <div className="search-wrap">
-            <Search placeholder="璇疯緭鍏ュ瓨鍌ㄨ繃绋嬪悕绉�" disabled={loading} enterButton="纭畾" onSearch={this.search}/>
-          </div>
-          <div className="action-wrap">
-
+        <div className={'searh-list' + (searchable ? ' open' : '')}>
+          <Search placeholder="瀛樺偍杩囩▼鍚嶇О鏌ヨ" disabled={loading} onSearch={this.searchAll}/>
+          <div className="proc-list">
+            {procList.map((item, index) => (<div className="proc-item" onClick={() => this.changeProc(item.proc_name)} key={index}>{item.proc_name}</div>))}
+            {procList.length === 0 ? <Empty /> : null}
           </div>
         </div>
-        <div className="edit-wrap">
-          <CodeMirror value={content} onChange={(val) => this.setState({content: val})}/>
+        <div className="proc-wrap">
+          <div className="control-wrap">
+            <div className="search-wrap">
+              {searchable ? <MenuUnfoldOutlined onClick={() => this.setState({searchable: !searchable})}/> : <MenuFoldOutlined onClick={() => this.setState({searchable: !searchable})}/>}
+              {!inputing ? <Search placeholder="璇疯緭鍏ュ瓨鍌ㄨ繃绋嬪悕绉�" defaultValue={procName} disabled={loading} enterButton="纭畾" onSearch={this.search}/> : null}
+            </div>
+            <div className="action-wrap">
+              <Button key="save" className="mk-btn mk-green" disabled={loading} onClick={() => this.save()}>淇濆瓨</Button>
+              <Button key="prev" className="mk-btn mk-primary" disabled={!procName || loading} onClick={this.prev}>涓婁竴鐗堟湰</Button>
+              <Button key="next" className="mk-btn mk-primary" disabled={!procName || loading} onClick={this.next}>涓嬩竴鐗堟湰</Button>
+            </div>
+          </div>
+          <div className="edit-wrap">
+            <CodeMirror value={content} onChange={(val) => this.setState({content: val})}/>
+          </div>
         </div>
+        <Modal
+          title="鏂板缓"
+          wrapClassName="mk-create-func"
+          visible={visible}
+          onOk={this.handleConfirm}
+          width={540}
+          onCancel={() => {this.setState({ visible: false })}}
+          destroyOnClose
+        >
+          <Form.Item label="瀛樺偍杩囩▼鍚嶇О">
+            {getFieldDecorator('name', {
+              initialValue: '',
+              rules: [
+                {
+                  required: true,
+                  message: '璇疯緭鍏ュ瓨鍌ㄨ繃绋嬪悕绉�!'
+                },
+                {
+                  pattern: _patten,
+                  message: `鍙厑璁稿寘鍚暟瀛椼�佸瓧姣嶅拰涓嬪垝绾匡紝涓斾互${permFuncs.join(', ')}绛夊瓧绗﹀紑濮嬨�俙
+                }
+              ]
+            })(<Input placeholder="" autoComplete="off" />)}
+          </Form.Item>
+        </Modal>
       </div>
     )
   }
 }
 
-export default ProcControl
\ No newline at end of file
+export default Form.create()(ProcControl)
\ No newline at end of file
diff --git a/src/views/systemproc/proc/index.scss b/src/views/systemproc/proc/index.scss
index d8d5749..653bc5c 100644
--- a/src/views/systemproc/proc/index.scss
+++ b/src/views/systemproc/proc/index.scss
@@ -1,12 +1,89 @@
 .mk-proc-wrap {
   position: relative;
   padding: 65px 20px 0px;
+  display: flex;
   
+  .searh-list {
+    width: 0px;
+    margin-right: 15px;
+    overflow: hidden;
+    transition: width 0.2s;
+
+    .ant-input-search {
+      width: 300px;
+    }
+    .proc-list {
+      width: 300px;
+      height: calc(100vh - 128px);
+      overflow-y: auto;
+      overflow-x: hidden;
+      margin-top: 10px;
+      border: 1px solid #e8e8e8;
+
+      .proc-item {
+        padding: 5px;
+        margin: 5px;
+        word-break: break-all;
+        cursor: pointer;
+      }
+      .ant-empty {
+        margin-top: 50px;
+      }
+    }
+    .proc-list::-webkit-scrollbar {
+      width: 7px;
+      height: 7px;
+    }
+    .proc-list::-webkit-scrollbar-thumb {
+      border-radius: 5px;
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+      background: rgba(0, 0, 0, 0.13);
+    }
+    .proc-list::-webkit-scrollbar-track {
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+      border-radius: 3px;
+      border: 1px solid rgba(0, 0, 0, 0.07);
+      background: rgba(0, 0, 0, 0);
+    }
+  }
+  .searh-list.open {
+    width: 300px;
+  }
+  .proc-wrap {
+    flex: 1;
+  }
   .control-wrap {
     display: flex;
 
     .search-wrap {
-      width: 300px;
+      width: 360px;
+      display: flex;
+
+      .ant-btn[disabled] {
+        background-color: #1890ff!important;
+        border-color: #1890ff!important;
+        color: #ffffff!important;
+        opacity: 0.5;
+      }
+      .ant-input {
+        border-radius: 0;
+      }
+      >.anticon {
+        line-height: 30px;
+        width: 35px;
+        border: 1px solid #e8e8e8;
+        cursor: pointer;
+        border-top-left-radius: 4px;
+        border-bottom-left-radius: 4px;
+      }
+    }
+    .action-wrap {
+      text-align: right;
+      flex: 1;
+
+      .ant-btn {
+        margin-left: 20px;
+      }
 
       .ant-btn[disabled] {
         background-color: #1890ff!important;
@@ -33,3 +110,15 @@
     }
   }
 }
+
+.mk-create-func {
+  .ant-modal-body {
+    min-height: 180px;
+  }
+  .ant-form-item {
+    display: flex;
+    .ant-form-item-control-wrapper {
+      flex: 1;
+    }
+  }
+}

--
Gitblit v1.8.0