king
2020-12-31 32b84012bb8e2f05295c4237d17224700b149c8f
merge 2020-12-31
75个文件已修改
7个文件已添加
1554 ■■■■ 已修改文件
src/assets/css/viewstyle.scss 424 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mobimg/group.png 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/index.scss 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tabview/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tabview/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/dragaction/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/index.jsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/settingform/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.scss 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/wrapsetting/settingform/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/prop-card/index.jsx 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/prop-card/index.scss 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/table-card/cardcomponent/index.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/table-card/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/table-card/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.scss 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/index.scss 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/copycomponent/index.jsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/copycomponent/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/normalheader/index.scss 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/pastecomponent/index.jsx 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/pastecomponent/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/index.jsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/index.scss 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/wrapsetting/settingform/index.jsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/wrapsetting/settingform/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/index.jsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/index.scss 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/utils.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modelsource/option.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/pastecontroller/index.jsx 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/pastecontroller/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/popview/index.jsx 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/popview/menuform/index.jsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/options.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/reducer.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardItem/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardItem/index.scss 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/data-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/data-card/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/prop-card/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/prop-card/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.jsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/normal-table/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/index.jsx 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/normalbutton/index.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/printbutton/index.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/customSwitch/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/normalTable/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/utils.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editcomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/pasteform/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/customform/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/customscript/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/billprint/index.jsx 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/billprint/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.scss 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/main/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.scss 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/viewstyle.scss
@@ -1,80 +1,434 @@
.mk-white {
  > .flex-container {
    > .header-container {
      background: #ffffff;
      color: #000000;
      box-shadow: 0 2px 8px #f0f1f2;
// bg1     主背景色
// bg2     次背景色
// font1   主字体颜色
// color1  1阶色 - 底色
// color2  2阶色
// color3  3阶色
// color4  4阶色
// color5  5阶色
// color6  6阶色 - 主色系
// color7  7阶色
// 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: transparent;
      .plat-name {
        color: $font1;
      }
    }
    .login-middle {
      border-color: transparent;
      .login-form-button {
        background-color: $color6;
        border-color: $color6;
      }
      .login-form-button[disabled] {
        background-color: $color5;
        border-color: $color5;
      }
      button.vercode {
        color: $color6;
      }
      .ant-tabs {
        .ant-tabs-tab.ant-tabs-tab-active {
          color: $color6;
        }
        .ant-tabs-tab:hover {
          color: $color6;
        }
      }
    }
    .login-bottom {
      color: $font1;
      a {
        color: $font1;
      }
    }
  }
  #root > .main-view {
    > .header-container {
      background: $bg1;
      color: $font1;
      box-shadow: 0 1px 1px #d9d9d9;
      .header-setting span {
        color: $font1;
      }
      > .header-collapse i {
        color: #000000;
        color: $font1;
      }
      > .header-menu {
        li {
          span {
            color: #000000;
            color: $font1;
          }
    
          &:hover {
            span {
              color: #1890ff;
              border-bottom: 4px solid #1890ff;
              color: $color6;
              border-bottom: 4px solid $color6;
            }
          }
          &.active {
            span {
              color: #1890ff;
              border-bottom: 4px solid #1890ff;
              color: $color6;
              border-bottom: 4px solid $color6;
            }
          }
        }
      }
      > .header-setting span {
        color: #000000;
      }
      > .header-edit-box .dragdashboard {
        background: #ffffff;
      }
    }
    > .side-menu {
      border-right: 1px solid #d9d9d9;
      background: #ffffff;
      background: $bg1;
      > .ant-menu {
        background: #ffffff;
        background: $bg1;
        > .ant-menu-submenu {
          color: #000000;
          background: #ffffff;
          color: $font1;
          background: transparent;
          > .ant-menu-submenu-title {
            background: #ffffff;
            &:hover {
              color: #1890ff;
              color: $font1;
            }
            > .ant-menu-submenu-arrow:before {
              background: #000000;
              background: $font1;
            }
            > .ant-menu-submenu-arrow:after {
              background: #000000;
              background: $font1;
            }
          }
          > .ant-menu-sub {
            background: #ffffff;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25) inset;
            background: transparent;
            box-shadow: none;
            .ant-menu-item {
              border-bottom: 1px solid #d9d9d9;
              // background-color: #c4ebfd;
              a {
                color: #000000;
                color: $font2;
              }
            }
          }
        }
        > .ant-menu-submenu.ant-menu-submenu-open {
          color: #1890ff;
          > .ant-menu-submenu-title {
            background: $bg2;
        }
      }
      // .ant-menu-inline.ant-menu-sub {
      //   background: #ffffff;
      //   color: #000000;
      }
    }
    > .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;
              }
            }
          }
        }
      }
    }
    >.content-box {
      >.content-header {
        >.ant-tabs {
          >.ant-tabs-bar {
            .ant-tabs-tab:hover {
              color: $color5;
            }
            .ant-tabs-tab.ant-tabs-tab-active {
              color: $color6;
            }
            .ant-tabs-ink-bar {
              background-color: $color6;
            }
          }
        }
      }
      .normal-data-table, .normal-custom-table {
        table {
          .ant-table-tbody {
            > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td {
              background-color: $color1;
            }
            > tr.ant-table-row-selected:not(.background) td {
              background-color: $color1;
            }
            > tr.ant-table-row-selected:not(.background):hover .ant-table-column-sort {
              background-color: $color1;
            }
            > tr.mk-row-active:not(.background) td {
              background-color: $color3;
            }
            > tr.ant-table-row-selected.mk-row-active:not(.background):hover .ant-table-column-sort {
              background-color: $color3;
            }
          }
        }
      }
      .top-search {
        >.ant-row {
          .ant-col.search-button {
            .ant-btn:not(.ant-btn-primary):active, .ant-btn:not(.ant-btn-primary).active, .ant-btn:not(.ant-btn-primary):hover, .ant-btn:not(.ant-btn-primary):focus {
              color: $color7;
              border-color: $color7;
            }
            .ant-btn-primary {
              background-color: $color6;
              border-color: $color6;
            }
          }
        }
      }
      .ant-tabs-nav .ant-tabs-tab-active {
        color: $color6;
      }
      .ant-tabs-nav .ant-tabs-ink-bar {
        background-color: $color6;
      }
      .ant-tabs-nav .ant-tabs-tab:active {
        color: $color7;
      }
      .ant-tabs-nav .ant-tabs-tab:hover {
        color: $color5;
      }
      .ant-pagination {
        .ant-pagination-item-active {
          border-color: $color6;
          a {
            color: $color6;
          }
        }
        .ant-pagination-item:hover a {
          color: $color6;
        }
        .ant-pagination-prev:hover .ant-pagination-item-link {
          color: $color6;
        }
        .ant-pagination-next:hover .ant-pagination-item-link {
          color: $color6;
        }
      }
    }
  }
  .custom-data-card-box, .custom-prop-card-box {
    .data-zoom.radio .card-row-list > .ant-col:not(.active):not(.selected):hover > .card-item-box, .data-zoom.checkbox .card-row-list > .ant-col:not(.active):not(.selected):hover > .card-item-box {
      border-color: $color4 !important;
      box-shadow: 0 0 4px $color4 !important;
    }
    .card-row-list.radio, .card-row-list.checkbox {
      >.ant-col:not(.active):not(.selected):hover {
        >.card-item-box {
          border-color: $color4!important;
          box-shadow: 0 0 4px $color4!important;
        }
      }
    }
    .card-row-list {
      >.active >.card-item-box {
        border-color: $color6!important;
        box-shadow: 0 0 4px $color6;
      }
      >.selected >.card-item-box {
        border-color: $color4!important;
        box-shadow: 0 0 4px $color4;
      }
    }
  }
  // 系统样式修改
  // .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled) {
  //   background-color: $color1;
  // }
  // .ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled) {
  //   background-color: $color1;
  // }
  // // 复选框
  // .ant-checkbox-checked .ant-checkbox-inner {
  //   background-color: $color6;
  //   border-color: $color6;
  // }
  // .ant-checkbox-checked::after {
  //   border: 1px solid $color6;
  // }
  // .ant-checkbox-indeterminate .ant-checkbox-inner::after {
  //   background-color: $color6;
  // }
  // .ant-checkbox-wrapper:hover .ant-checkbox-inner, .ant-checkbox:hover .ant-checkbox-inner, .ant-checkbox-input:focus + .ant-checkbox-inner {
  //   border-color: $color6;
  // }
  // // 下拉框
  // .ant-select-selection:hover {
  //   border-color: $color5;
  // }
  // .ant-select-focused .ant-select-selection, .ant-select-selection:focus, .ant-select-selection:active {
  //   border-color: $color5;
  //   box-shadow: 0 0 0 2px $color2;
  // }
  // // 切换
  // .ant-switch-checked {
  //   background-color: $color6;
  // }
  // // 输入框
  // .ant-input:hover {
  //   border-color: $color5;
  // }
  // .ant-input:focus, .ant-input:active {
  //   border-color: $color5;
  //   box-shadow: 0 0 0 2px $color2;
  // }
  // .ant-input-number-focused {
  //   border-color: $color5;
  //   box-shadow: 0 0 0 2px $color2;
  // }
  // .ant-input-number:hover, .ant-input-number:focus, .ant-input-number:active, .ant-input-number-input:hover, .ant-input-number-input:focus, .ant-input-number-input:active, .ant-input-number-focused:hover, .ant-input-number-focused:focus, .ant-input-number-focused:active {
  //   border-color: $color5;
  // }
  // .ant-input-number:focus, .ant-input-number:active {
  //   box-shadow: 0 0 0 2px $color2;
  // }
  // // 日历
  // .ant-calendar-picker:hover .ant-calendar-picker-input:not(.ant-input-disabled) {
  //   border-color: $color5;
      // }
    }
@mixin bgblack() {
  #root > .main-view {
    > .header-container {
      box-shadow: none;
      > .header-menu {
        li {
          &:hover, &.active {
            span {
              color: #ffffff;
  }
}
        }
      }
    }
  }
}
body.mk-blue-black {
  --antd-wave-shadow-color: #1890ff;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65), #e6f7ff, #bae7ff, #91d5ff, #69c0ff, #40a9ff, #1890ff, #096dd9, #0050b3, #003a8c, #002766);
  @include bgblack();
}
body.mk-blue-white {
  --antd-wave-shadow-color: #1890ff;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #e6f7ff, #bae7ff, #91d5ff, #69c0ff, #40a9ff, #1890ff, #096dd9, #0050b3, #003a8c, #002766);
}
body.mk-red-black {
  --antd-wave-shadow-color: #f5222d;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65), #fff1f0, #ffccc7, #ffa39e, #ff7875, #ff4d4f, #f5222d, #cf1322, #a8071a, #820014, #5c0011);
  @include bgblack();
}
body.mk-red-white {
  --antd-wave-shadow-color: #f5222d;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff1f0, #ffccc7, #ffa39e, #ff7875, #ff4d4f, #f5222d, #cf1322, #a8071a, #820014, #5c0011);
}
body.mk-orange-red-black {
  --antd-wave-shadow-color: #fa541c;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65), #fff2e8, #ffd8bf, #ffbb96, #ff9c6e, #ff7a45, #fa541c, #d4380d, #ad2102, #871400, #610b00);
  @include bgblack();
}
body.mk-orange-red-white {
  --antd-wave-shadow-color: #fa541c;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff2e8, #ffd8bf, #ffbb96, #ff9c6e, #ff7a45, #fa541c, #d4380d, #ad2102, #871400, #610b00);
}
body.mk-orange-black {
  --antd-wave-shadow-color: #fa8c16;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65), #fff7e6, #ffe7ba, #ffd591, #ffc069, #ffa940, #fa8c16, #d46b08, #ad4e00, #873800, #612500);
  @include bgblack();
}
body.mk-orange-white {
  --antd-wave-shadow-color: #fa8c16;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff7e6, #ffe7ba, #ffd591, #ffc069, #ffa940, #fa8c16, #d46b08, #ad4e00, #873800, #612500);
}
body.mk-orange-yellow-black {
  --antd-wave-shadow-color: #faad14;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#fffbe6, #fff1b8, #ffe58f, #ffd666, #ffc53d, #faad14, #d48806, #ad6800, #874d00, #613400);
  @include bgblack();
}
body.mk-orange-yellow-white {
  --antd-wave-shadow-color: #faad14;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fffbe6, #fff1b8, #ffe58f, #ffd666, #ffc53d, #faad14, #d48806, #ad6800, #874d00, #613400);
}
body.mk-yellow-black {
  --antd-wave-shadow-color: #fadb14;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#feffe6, #ffffb8, #fffb8f, #fff566, #ffec3d, #fadb14, #d4b106, #ad8b00, #876800, #614700);
  @include bgblack();
}
body.mk-yellow-white {
  --antd-wave-shadow-color: #fadb14;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #feffe6, #ffffb8, #fffb8f, #fff566, #ffec3d, #fadb14, #d4b106, #ad8b00, #876800, #614700);
}
body.mk-yellow-green-black {
  --antd-wave-shadow-color: #a0d911;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#fcffe6, #f4ffb8, #eaff8f, #d3f261, #bae637, #a0d911, #7cb305, #5b8c00, #3f6600, #254000);
  @include bgblack();
}
body.mk-yellow-green-white {
  --antd-wave-shadow-color: #a0d911;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fcffe6, #f4ffb8, #eaff8f, #d3f261, #bae637, #a0d911, #7cb305, #5b8c00, #3f6600, #254000);
}
body.mk-green-black {
  --antd-wave-shadow-color: #52c41a;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#f6ffed, #d9f7be, #b7eb8f, #95de64, #73d13d, #52c41a, #389e0d, #237804, #135200, #092b00);
  @include bgblack();
}
body.mk-green-white {
  --antd-wave-shadow-color: #52c41a;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #f6ffed, #d9f7be, #b7eb8f, #95de64, #73d13d, #52c41a, #389e0d, #237804, #135200, #092b00);
}
body.mk-cyan-black {
  --antd-wave-shadow-color: #13c2c2;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#e6fffb, #b5f5ec, #87e8de, #5cdbd3, #36cfc9, #13c2c2, #08979c, #006d75, #00474f, #002329);
  @include bgblack();
}
body.mk-cyan-white {
  --antd-wave-shadow-color: #13c2c2;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #e6fffb, #b5f5ec, #87e8de, #5cdbd3, #36cfc9, #13c2c2, #08979c, #006d75, #00474f, #002329);
}
body.mk-blue-purple-black {
  --antd-wave-shadow-color: #2f54eb;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#f0f5ff, #d6e4ff, #adc6ff, #85a5ff, #597ef7, #2f54eb, #1d39c4, #10239e, #061178, #030852);
  @include bgblack();
}
body.mk-blue-purple-white {
  --antd-wave-shadow-color: #2f54eb;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #f0f5ff, #d6e4ff, #adc6ff, #85a5ff, #597ef7, #2f54eb, #1d39c4, #10239e, #061178, #030852);
}
body.mk-purple-black {
  --antd-wave-shadow-color: #722ed1;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#f9f0ff, #efdbff, #d3adf7, #b37feb, #9254de, #722ed1, #531dab, #391085, #22075e, #120338);
  @include bgblack();
}
body.mk-purple-white {
  --antd-wave-shadow-color: #722ed1;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #f9f0ff, #efdbff, #d3adf7, #b37feb, #9254de, #722ed1, #531dab, #391085, #22075e, #120338);
}
body.mk-magenta-black {
  --antd-wave-shadow-color: #eb2f96;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#fff0f6, #ffd6e7, #ffadd2, #ff85c0, #f759ab, #eb2f96, #c41d7f, #9e1068, #780650, #520339);
  @include bgblack();
}
body.mk-magenta-white {
  --antd-wave-shadow-color: #eb2f96;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff0f6, #ffd6e7, #ffadd2, #ff85c0, #f759ab, #eb2f96, #c41d7f, #9e1068, #780650, #520339);
}
body.mk-grass-green-black {
  --antd-wave-shadow-color: #aeb303;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#f2efda, #e6de97, #d9d26c, #ccc845, #bfbf22, #aeb303, #838c00, #5c6600, #374000, #151a00);
  @include bgblack();
}
body.mk-grass-green-white {
  --antd-wave-shadow-color: #aeb303;
  @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);
}
src/assets/mobimg/group.png
src/components/sidemenu/index.scss
@@ -16,11 +16,11 @@
  .ant-menu-sub.ant-menu-inline {
    position: relative;
  }
  .ant-menu-sub.ant-menu-inline > .ant-menu-item { // 重置三级菜单行高
  .ant-menu-sub.ant-menu-inline > .ant-menu-item {
    height: 38px;
    line-height: 38px;
    margin: 0px;
    border-bottom: 1px solid #000c17;
    // border-bottom: 1px solid #000c17;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
@@ -31,10 +31,10 @@
      top: -5px;
    }
  }
  .ant-menu-sub.ant-menu-inline > .ant-menu-item.ant-menu-item-active { // 重置三级菜单行高
  .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 { // 重置三级菜单行高
  .ant-menu-sub.ant-menu-inline > .ant-menu-item.ant-menu-item-selected {
    background: #06b4f7;
  }
  .ant-menu-inline .ant-menu-item {
src/components/tabview/index.jsx
@@ -237,7 +237,7 @@
                  <Tabs.TabPane
                    tab={
                      <span className="tab-control">
                        {['CommonTable', 'FormTab', 'TreePage', 'CalendarPage', 'CustomPage'].includes(view.type) ?
                        {['CommonTable', 'FormTab', 'TreePage', 'CalendarPage', 'CustomPage', 'ManageTable', 'VerupTable'].includes(view.type) ?
                          <Icon type="redo" onClick={(e) => {this.refreshTabview(e, view)}}/> : null
                        }
                        <span className="tab-name" onClick={(e) => {this.changeTab(e, view)}}>
src/components/tabview/index.scss
@@ -25,7 +25,7 @@
          }
          span.tab-control i.anticon-redo {
            position: absolute;
            left: -5px;
            left: -3px;
            top: 18px;
            font-size: 14px;
            margin: 0px;
src/index.js
@@ -81,9 +81,10 @@
    GLOB.filter = config.filter || ''
    if (config.externalDatabase !== false && config.externalDatabase !== 'false' && config.externalDatabase !== undefined) {
      GLOB.externalDatabase = config.externalDatabase || ''
      GLOB.externalDatabase = config.externalDatabase ? `[${config.externalDatabase}]..` : ''
    } else {
      GLOB.externalDatabase = null
    }
    // 只有业务系统才可以设置为正式系统
@@ -169,6 +170,9 @@
          link.href = GLOB.favicon
          document.getElementsByTagName('head')[0].appendChild(link)
        }
        if (GLOB.style && options.styles[GLOB.style]) {
          document.body.className = options.styles[GLOB.style]
        }
      } catch {
        console.warn('Parse Failure')
      }
src/menu/components/card/cardcellcomponent/dragaction/index.jsx
@@ -34,8 +34,9 @@
  }
  const copyCard = id => {
    const { card, index: overIndex } = findCard(id)
    const { card } = findCard(id)
    let copycard = fromJS(card).toJS()
    let _cards = fromJS(cards).toJS()
    copycard.uuid = Utils.getuuid()
    copycard.copyType = 'customCardElement'
@@ -59,7 +60,7 @@
      document.body.removeChild(oInput)
    }
    const _cards = update(cards, { $splice: [[overIndex + 1, 0, copycard]] })
    _cards.push(copycard)
    handleList(_cards)
    handleMenu(copycard)
src/menu/components/card/cardcomponent/index.jsx
@@ -4,6 +4,7 @@
import { Modal, Popover, Icon, Switch, Col } from 'antd'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import SettingForm from './settingform'
@@ -13,12 +14,14 @@
import './index.scss'
const CardCellComponent = asyncComponent(() => import('../cardcellcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
class CardBoxComponent extends Component {
  static propTpyes = {
    offset: PropTypes.any,           // 偏移量
    cards: PropTypes.object,         // 卡片行配置信息
    card: PropTypes.object,          // 卡片配置信息
    move: PropTypes.func,            // 卡片移动
    deleteElement: PropTypes.func,   // 卡片删除
    updateElement: PropTypes.func    // 菜单配置更新
  }
@@ -214,7 +217,14 @@
    }
    
    if (side === 'back') {
      _style = {...card.backStyle, height: card.style.height}
      _style = {
        ...card.backStyle,
        height: card.style.height,
        marginBottom: card.style.marginBottom,
        marginLeft: card.style.marginLeft,
        marginRight: card.style.marginRight,
        marginTop: card.style.marginTop
      }
    }
    return (
@@ -226,8 +236,17 @@
              <div className="mk-popover-control">
                <Icon className="plus" title="添加元素" onClick={this.addElement} type="plus" />
                <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" />
                <Icon className="edit" type="edit" onClick={() => this.setState({settingVisible: true})} />
                <Icon className="edit" title="编辑" type="edit" onClick={() => this.setState({settingVisible: true})} />
                <CopyComponent type="cardcell" card={card}/>
                <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
                {cards.subtype === 'propcard' ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
                  <div className="mk-popover-control">
                    <Icon className="plus" title="左移" type="arrow-left" onClick={() => this.props.move(card, 'left')} />
                    <Icon className="close" title="右移" type="arrow-right" onClick={() => this.props.move(card, 'right')} />
                  </div>
                } trigger="hover" getPopupContainer={() => document.getElementById(card.uuid)}>
                  <Icon type="swap" id={card.uuid}/>
                </Popover> : null}
                {cards.subtype === 'propcard' ? <Icon className="close" title="删除卡片" type="delete" onClick={() => this.props.deleteElement(card)} /> : null}
                {card.setting.type === 'multi' ? <Switch size="small" onClick={this.changeSide} defaultChecked /> : null}
              </div>
src/menu/components/card/cardcomponent/settingform/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Radio, Tooltip, Icon, Input, InputNumber } from 'antd'
import { Form, Row, Col, Radio, Tooltip, Icon, Input, InputNumber, Select } from 'antd'
import './index.scss'
@@ -101,10 +101,16 @@
                {getFieldDecorator('transform', {
                  initialValue: setting.transform || 'up'
                })(
                  <Radio.Group>
                    <Radio value="up">向上滑动</Radio>
                    <Radio value="down">向下滑动</Radio>
                  </Radio.Group>
                  <Select>
                    <Select.Option value="up">向上滑动</Select.Option>
                    <Select.Option value="down">向下滑动</Select.Option>
                    <Select.Option value="left">向左滑动</Select.Option>
                    <Select.Option value="right">向右滑动</Select.Option>
                    <Select.Option value="scale">缩放</Select.Option>
                    <Select.Option value="opacity">透明度</Select.Option>
                    <Select.Option value="rotateX">纵向展开</Select.Option>
                    <Select.Option value="rotateY">横向展开</Select.Option>
                  </Select>
                )}
              </Form.Item>
            </Col> : null}
src/menu/components/card/data-card/index.jsx
@@ -17,6 +17,8 @@
const WrapComponent = asyncIconComponent(() => import('./wrapsetting'))
const CardComponent = asyncComponent(() => import('../cardcomponent'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent'))
@@ -374,13 +376,15 @@
    }
    return (
      <div className="menu-data-card-edit-box" style={{...card.style, minHeight: card.wrap.minHeight}}>
      <div className="menu-data-card-edit-box" style={{...card.style}}>
        <NormalHeader defaultshow="hidden" config={card} updateComponent={this.updateComponent}/>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" />
            <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" />
            <WrapComponent config={card} updateConfig={this.updateComponent} />
            <CopyComponent type="datacard" card={card}/>
            <PasteComponent config={card} options={['action', 'search', 'form']} updateConfig={this.updateComponent} />
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
            <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
src/menu/components/card/data-card/index.scss
@@ -5,7 +5,7 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 100px;
  min-height: 20px;
  
  .card-control {
    position: absolute;
@@ -39,7 +39,7 @@
  }
  
  .card-item:hover {
    box-shadow: 0px 0px 2px #e8e8e8;
    box-shadow: 0px 0px 2px #1890ff;
  }
  .model-menu-card-cell-list .card-detail-row > .anticon-plus {
@@ -82,5 +82,6 @@
  clear: both;
}
.menu-data-card-edit-box:hover {
  box-shadow: 0px 0px 2px #e8e8e8;
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/card/data-card/wrapsetting/settingform/index.jsx
@@ -197,18 +197,6 @@
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype !== 'tablecard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="卡片外边框的最小高度,控制数据加载时组件的占位。">
                  <Icon type="question-circle" />
                  最小高度
                </Tooltip>
              }>
                {getFieldDecorator('minHeight', {
                  initialValue: wrap.minHeight || 100
                })(<InputNumber min={20} max={2000} precision={0} onPressEnter={this.handleSubmit} />)}
              </Form.Item>
            </Col> : null}
            {config.subtype === 'tablecard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="表格高度,超出时滚动,高度为空时根据内容自适应。">
src/menu/components/card/prop-card/index.jsx
@@ -16,6 +16,8 @@
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const WrapComponent = asyncIconComponent(() => import('../data-card/wrapsetting'))
const CardComponent = asyncComponent(() => import('../cardcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
@@ -304,8 +306,27 @@
    }
  }
  move = (item, direction) => {
    let card = fromJS(this.state.card).toJS()
    let dragIndex = card.subcards.findIndex(c => c.uuid === item.uuid)
    let hoverIndex = null
    if (direction === 'left') {
      hoverIndex = dragIndex - 1
    } else {
      hoverIndex = dragIndex + 1
    }
    if (hoverIndex === -1 || hoverIndex === card.subcards.length) return
    card.subcards.splice(hoverIndex, 0, ...card.subcards.splice(dragIndex, 1))
    this.setState({card})
    this.props.updateConfig(card)
  }
  render() {
    const { menu } = this.props
    const { card } = this.state
    let offset = 0
@@ -321,12 +342,14 @@
    }
    return (
      <div className="menu-prop-card-edit-box" style={{...card.style, minHeight: card.wrap.minHeight}}>
      <div className="menu-prop-card-edit-box" style={{...card.style}}>
        <NormalHeader defaultshow="hidden" config={card} updateComponent={this.updateComponent}/>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <Icon className="plus" title="添加卡片" onClick={this.addCard} type="plus" />
            {menu ? <WrapComponent config={card} MenuType={menu.MenuType} updateConfig={this.updateComponent} /> : null}
            <WrapComponent config={card} updateConfig={this.updateComponent} />
            <CopyComponent type="propcard" card={card}/>
            <PasteComponent config={card} options={['cardcell']} updateConfig={this.updateComponent} />
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
            <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
@@ -336,7 +359,7 @@
        } trigger="hover">
          <Icon type="tool" />
        </Popover>
        {card.subcards.map((subcard, index) => (<CardComponent key={subcard.uuid} offset={!index ? offset : 0} MenuType={menu ? menu.MenuType : ''} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        {card.subcards.map((subcard, index) => (<CardComponent key={subcard.uuid} offset={!index ? offset : 0} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
      </div>
    )
  }
src/menu/components/card/prop-card/index.scss
@@ -5,7 +5,7 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 100px;
  min-height: 20px;
  
  .card-control {
    position: absolute;
@@ -39,7 +39,7 @@
  }
  
  .card-item:hover {
    box-shadow: 0px 0px 2px #e8e8e8;
    box-shadow: 0px 0px 2px #1890ff;
  }
  .model-menu-card-cell-list .card-detail-row > .anticon-plus {
@@ -72,5 +72,6 @@
  clear: both;
}
.menu-prop-card-edit-box:hover {
  box-shadow: 0px 0px 2px #e8e8e8;
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/card/table-card/cardcomponent/index.jsx
@@ -4,6 +4,7 @@
import { Modal, Popover, Icon } from 'antd'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import SettingForm from './settingform'
@@ -13,6 +14,7 @@
import './index.scss'
const CardCellComponent = asyncComponent(() => import('../../cardcellcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
class CardBoxComponent extends Component {
  static propTpyes = {
@@ -171,7 +173,8 @@
              <div className="mk-popover-control">
                <Icon className="plus" title="添加元素" onClick={this.addElement} type="plus" />
                <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" />
                <Icon className="edit" type="edit" onClick={() => this.setState({settingVisible: true})} />
                <Icon className="edit" title="编辑" type="edit" onClick={() => this.setState({settingVisible: true})} />
                <CopyComponent type="cardcell" card={card}/>
                <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
                <Icon className="close" title="删除卡片" type="delete" onClick={() => this.props.deleteElement(card)} />
              </div>
src/menu/components/card/table-card/index.jsx
@@ -16,6 +16,8 @@
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const WrapComponent = asyncIconComponent(() => import('../data-card/wrapsetting'))
const CardComponent = asyncComponent(() => import('./cardcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
@@ -308,7 +310,6 @@
  }
  render() {
    const { menu } = this.props
    const { card } = this.state
    return (
@@ -318,7 +319,9 @@
          <div className="mk-popover-control">
            <Icon className="plus" title="添加卡片" onClick={this.addCard} type="plus" />
            <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" />
            {menu ? <WrapComponent config={card} MenuType={menu.MenuType} updateConfig={this.updateComponent} /> : null}
            <WrapComponent config={card} updateConfig={this.updateComponent} />
            <CopyComponent type="tablecard" card={card}/>
            <PasteComponent config={card} options={['cardcell', 'search', 'form']} updateConfig={this.updateComponent} />
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
            <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
@@ -328,7 +331,7 @@
          <Icon type="tool" />
        </Popover>
        <div style={{minHeight: card.wrap.height - 90}}>
          {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} MenuType={menu ? menu.MenuType : ''} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
          {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        </div>
        {card.setting.laypage === 'true' ? <Pagination size="small" total={50} /> : null}
      </div>
src/menu/components/card/table-card/index.scss
@@ -55,7 +55,7 @@
  }
  
  .card-item:hover {
    box-shadow: 0px 0px 2px #e8e8e8;
    box-shadow: 0px 0px 2px #1890ff;
  }
  .model-menu-card-cell-list .card-detail-row > .anticon-plus {
@@ -91,5 +91,6 @@
  clear: both;
}
.menu-table-card-edit-box:hover {
  box-shadow: 0px 0px 2px #e8e8e8;
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/chart/antv-bar/index.jsx
@@ -19,6 +19,8 @@
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const ChartCompileForm = asyncIconComponent(() => import('./chartcompile'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent'))
@@ -861,6 +863,8 @@
            <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" />
            <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" />
            <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
            <CopyComponent type="line" card={card}/>
            <PasteComponent config={card} options={['action', 'search', 'form']} updateConfig={this.updateComponent} />
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
            <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
src/menu/components/chart/antv-bar/index.scss
@@ -60,5 +60,6 @@
  }
}
.menu-line-chart-edit-box:hover {
  box-shadow: 0px 0px 2px #e8e8e8;
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/chart/antv-pie/index.jsx
@@ -17,6 +17,8 @@
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const ChartCompileForm = asyncIconComponent(() => import('./chartcompile'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
@@ -432,6 +434,8 @@
          <div className="mk-popover-control">
            <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" />
            <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
            <CopyComponent type="pie" card={card}/>
            <PasteComponent config={card} options={['search', 'form']} updateConfig={this.updateComponent} />
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
            <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
src/menu/components/chart/antv-pie/index.scss
@@ -40,6 +40,7 @@
    }
  }
}
.menu-line-chart-edit-box:hover {
  box-shadow: 0px 0px 2px #e8e8e8;
.menu-pie-chart-edit-box:hover {
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/search/main-search/index.jsx
@@ -20,6 +20,8 @@
const { confirm } = Modal
const WrapComponent = asyncIconComponent(() => import('./wrapsetting'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
class MainSearchComponent extends Component {
  static propTpyes = {
@@ -353,6 +355,8 @@
          <div className="mk-popover-control">
            <Icon className="plus" title="添加" onClick={this.addSearch} type="plus" />
            <WrapComponent config={card} updateConfig={this.updateComponent}/>
            <CopyComponent type="mainsearch" card={card}/>
            <PasteComponent config={card} options={['search', 'form']} updateConfig={this.updateComponent} />
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
          </div>
src/menu/components/search/main-search/index.scss
@@ -97,5 +97,6 @@
  clear: both;
}
.main-search-edit-list:hover {
  box-shadow: 0px 0px 2px #e8e8e8;
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/share/copycomponent/index.jsx
New file
@@ -0,0 +1,46 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Icon, message } from 'antd'
import './index.scss'
class CopyComponent extends Component {
  static propTpyes = {
    btnlog: PropTypes.array,
    handlelog: PropTypes.func
  }
  trigger = () => {
    const { card, type } = this.props
    let copycard = fromJS(card).toJS()
    copycard.copyType = type
    let _val = ''
    try {
      _val = window.btoa(window.encodeURIComponent(JSON.stringify(copycard)))
    } catch {
      message.warning('复制失败,请重试!')
      _val = ''
    }
    if (_val) {
      let oInput = document.createElement('input')
      oInput.value = _val
      document.body.appendChild(oInput)
      oInput.select()
      document.execCommand('Copy')
      document.body.removeChild(oInput)
      message.success('复制成功。')
    }
  }
  render () {
    return (
      <Icon type="copy" title="复制" style={{color: '#26C281'}} onClick={this.trigger} />
    )
  }
}
export default CopyComponent
src/menu/components/share/copycomponent/index.scss
src/menu/components/share/normalheader/index.scss
@@ -13,6 +13,8 @@
    margin-left: 10px;
    position: relative;
    z-index: 1;
    min-height: 45px;
    min-width: 30px;
  }
}
.normal-header.hidden {
src/menu/components/share/pastecomponent/index.jsx
New file
@@ -0,0 +1,175 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Icon, Modal, notification } from 'antd'
import Utils from '@/utils/utils.js'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform'))
class PasteController extends Component {
  static propTpyes = {
    config: PropTypes.object,        // 组件配置
    updateConfig: PropTypes.func
  }
  state = {
    visible: false
  }
  handleMenuClick = () => {
    this.setState({visible: true})
  }
  resetconfig = (item) => {
    item.uuid = Utils.getuuid()
    if (item.copyType === 'cardcell') {
      item.setting = item.setting || {}
      item.setting.width = item.setting.width || 6
      if (item.elements) {
        item.elements = item.elements.map(cell => {
          cell.uuid = Utils.getuuid()
          return cell
        })
      }
      if (item.backElements) {
        item.backElements = item.backElements.map(cell => {
          cell.uuid = Utils.getuuid()
          return cell
        })
      }
    } else if (item.copyType === 'table') {
      let loopCol = (col) => {
        col.subcols = col.subcols.map(c => {
          c.uuid = Utils.getuuid()
          if (c.type === 'colspan' && c.subcols) {
            c = loopCol(c)
          } else if (c.type === 'custom' && c.elements) {
            c.elements = c.elements.map(cell => {
              cell.uuid = Utils.getuuid()
              return cell
            })
          } else if (c.type === 'action' && c.elements) {
            c.elements = c.elements.map(cell => {
              cell.uuid = Utils.getuuid()
              return cell
            })
          }
          return c
        })
        return col
      }
      if (item.type === 'colspan' && item.subcols) {
        item = loopCol(item)
      } else if (item.type === 'custom' && item.elements) {
        item.elements = item.elements.map(cell => {
          cell.uuid = Utils.getuuid()
          return cell
        })
      } else if (item.type === 'action' && item.elements) {
        item.elements = item.elements.map(cell => {
          cell.uuid = Utils.getuuid()
          return cell
        })
      }
    }
    return item
  }
  pasteSubmit = () => {
    const { options } = this.props
    this.pasteFormRef.handleConfirm().then(res => {
      if (!options.includes(res.copyType)) {
        notification.warning({
          top: 92,
          message: '配置信息格式错误!',
          duration: 5
        })
        return
      }
      let type = res.copyType
      let config = fromJS(this.props.config).toJS()
      res = this.resetconfig(res)
      delete res.copyType
      if (type === 'action') {
        config.action = config.action || []
        config.action = config.action.filter(item => !item.origin)
        config.action.push(res)
      } else if (type === 'search' || type === 'form') {
        config.search = config.search || []
        config.search = config.search.filter(item => !item.origin)
        let keys = config.search.map(item => item.field.toLowerCase())
        if (type === 'form') {
          if (['number', 'switch', 'textarea', 'checkcard', 'fileupload', 'hint', 'color', 'funcvar'].includes(res.type)) {
            res.type = 'text'
          } else if (res.type === 'radio') {
            res.type = 'select'
          } else if (res.type === 'checkbox') {
            res.type = 'multiselect'
          } else if (res.type === 'datetime') {
            res.type = 'date'
          }
        }
        if (res.field && keys.includes(res.field.toLowerCase())) {
          notification.warning({
            top: 92,
            message: '搜索字段已存在!',
            duration: 5
          })
          return
        }
        config.search.push(res)
      } else if (type === 'cardcell') {
        config.subcards.push(res)
      }
      this.props.updateConfig(config)
      this.setState({visible: false})
      notification.success({
        top: 92,
        message: '粘贴成功!',
        duration: 2
      })
    })
  }
  render() {
    const { visible } = this.state
    return (
      <div style={{display: 'inline-block'}}>
        <Icon type="snippets" style={{color: 'purple'}} onClick={() => {this.setState({visible: true})}} />
        <Modal
          title="粘贴"
          visible={visible}
          width={600}
          maskClosable={false}
          onOk={this.pasteSubmit}
          onCancel={() => {this.setState({visible: false})}}
          destroyOnClose
        >
          <PasteForm wrappedComponentRef={(inst) => this.pasteFormRef = inst} inputSubmit={this.pasteSubmit}/>
        </Modal>
      </div>
    )
  }
}
export default PasteController
src/menu/components/share/pastecomponent/index.scss
src/menu/components/table/normal-table/columns/index.jsx
@@ -176,6 +176,7 @@
  state = {
    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    tableId: '',
    data: [{uuid: Utils.getuuid()}],
    refresh: false,    // 强制刷新
    columns: [],
@@ -186,7 +187,24 @@
  UNSAFE_componentWillMount () {
    const { config } = this.props
    let tableId = (() => {
      let uuid = []
      let _options = 'abcdefghigklmnopqrstuv'
      for (let i = 0; i < 19; i++) {
        uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1))
      }
      return uuid.join('')
    }) ()
    if (config.wrap && config.wrap.borderColor) { // 边框颜色
      let style = `#${tableId} table, #${tableId} tr, #${tableId} th, #${tableId} td {border-color: ${config.wrap.borderColor}}`
      let ele = document.createElement('style')
      ele.innerHTML = style
      document.getElementsByTagName('head')[0].appendChild(ele)
    }
    this.setState({
      tableId,
      columns: fromJS(config.cols).toJS(),
      fields: fromJS(config.columns).toJS(),
      lineMarks: config.lineMarks ? fromJS(config.lineMarks).toJS() : []
@@ -203,6 +221,11 @@
      }
    } else if (!is(fromJS(this.state.fields), fromJS(nextProps.config.columns))) {
      this.setState({fields: fromJS(nextProps.config.columns).toJS()})
    } else if (this.props.config.wrap.borderColor !== nextProps.config.wrap.borderColor) {
      let style = `#${this.state.tableId} table, #${this.state.tableId} tr, #${this.state.tableId} th, #${this.state.tableId} td {border-color: ${nextProps.config.wrap.borderColor}}`
      let ele = document.createElement('style')
      ele.innerHTML = style
      document.getElementsByTagName('head')[0].appendChild(ele)
    }
  }
@@ -459,7 +482,7 @@
  render() {
    const { config } = this.props
    const { fields, card, lineMarks, dict } = this.state
    const { fields, card, lineMarks, dict, tableId } = this.state
    const components = {
      header: {
        cell: DragableHeaderCol
@@ -472,7 +495,7 @@
    const columns = this.handlecolumns(this.state.columns, fields, config)
    return (
      <div className={`normal-table-columns ${config.setting.laypage} ${config.wrap.tableType}`}>
      <div className={`normal-table-columns ${config.setting.laypage} ${config.wrap.tableType}`} id={tableId}>
        <div className="col-control">
          <Icon title="复制" type="copy" onClick={this.copycolumn} />
          <MarkColumn columns={fields} type="line" marks={lineMarks} onSubmit={this.updateLineMarks} />
src/menu/components/table/normal-table/index.jsx
@@ -18,6 +18,8 @@
const SearchComponent = asyncComponent(() => import('@/templates/sharecomponent/searchcomponent'))
const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const ColumnComponent = asyncComponent(() => import('./columns'))
const WrapComponent = asyncIconComponent(() => import('./wrapsetting'))
@@ -328,6 +330,8 @@
            <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" />
            <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" />
            <WrapComponent config={card} updateConfig={this.updateComponent} />
            <CopyComponent type="normaltable" card={card}/>
            <PasteComponent config={card} options={['action', 'search', 'form']} updateConfig={this.updateComponent} />
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
            <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
src/menu/components/table/normal-table/index.scss
@@ -60,5 +60,6 @@
  clear: both;
}
.menu-normal-table-edit-box:hover {
  box-shadow: 0px 0px 2px #e8e8e8;
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/table/normal-table/wrapsetting/settingform/index.jsx
@@ -2,6 +2,7 @@
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Radio, Tooltip, Icon, InputNumber, Select } from 'antd'
import ColorSketch from '@/mob/colorsketch'
import './index.scss'
class SettingForm extends Component {
@@ -116,13 +117,39 @@
                  initialValue: wrap.bordered || 'true'
                })(
                  <Radio.Group style={{whiteSpace: 'nowrap'}}>
                    <Radio key="true" value={'true'}> 有 </Radio>
                    <Radio key="false" value={'false'}> 无 </Radio>
                    <Radio key="true" value="true"> 有 </Radio>
                    <Radio key="false" value="false"> 无 </Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label="表头">
                {getFieldDecorator('tableHeader', {
                  initialValue: wrap.tableHeader || 'show'
                })(
                  <Radio.Group style={{whiteSpace: 'nowrap'}}>
                    <Radio key="show" value="show"> 显示 </Radio>
                    <Radio key="hidden" value="hidden"> 隐藏 </Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="默认值 #e8e8e8。">
                  <Icon type="question-circle" />
                  边框颜色
                </Tooltip>
              }>
                {getFieldDecorator('borderColor', {
                  initialValue: wrap.borderColor || '#e8e8e8'
                })(
                  <ColorSketch />
                )}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="栅格布局,每行等分为24列。">
                  <Icon type="question-circle" />
src/menu/components/table/normal-table/wrapsetting/settingform/index.scss
@@ -8,4 +8,8 @@
  .ant-input-number {
    width: 100%;
  }
  .color-sketch-block {
    position: relative;
    top: 7px;
  }
}
src/menu/components/tabs/antv-tabs/index.jsx
@@ -15,6 +15,8 @@
import './index.scss'
const SettingComponent = asyncIconComponent(() => import('../tabsetting'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
const TabLabelComponent = asyncComponent(() => import('../tablabelform'))
const TabComponents = asyncComponent(() => import('../tabcomponents'))
@@ -238,6 +240,19 @@
    this.props.updateConfig(tabs)
  }
  insert = (item, tab) => {
    let tabs = fromJS(this.state.tabs).toJS()
    tabs.subtabs.forEach(stab => {
      if (stab.uuid === tab.uuid) {
        stab.components.push(item)
      }
    })
    this.setState({tabs})
    this.props.updateConfig(tabs)
  }
  render() {
    const { tabs, dict, labelvisible, editab } = this.state
@@ -249,6 +264,7 @@
              <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
                <div className="mk-popover-control">
                  <Icon className="edit" title="edit" type="edit" onClick={() => this.editTab(tab)} />
                  <PasteController type="tab" Tab={tab} insert={this.insert} />
                  <Icon className="close" title="delete" type="close" onClick={() => this.delTab(tab)} />
                </div>
              } trigger="hover">
@@ -263,6 +279,7 @@
              <div className="mk-popover-control">
                <Icon className="plus" title="添加标签" type="plus" onClick={this.tabAdd} />
                <SettingComponent config={tabs} updateConfig={this.updateComponent} />
                <CopyComponent type="tabs" card={tabs}/>
                <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
                <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(tabs.uuid)} />
              </div>
src/menu/components/tabs/antv-tabs/index.scss
@@ -96,5 +96,6 @@
  }
}
.menu-tabs-edit-box:hover {
  box-shadow: 0px 0px 2px #e8e8e8;
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/datasource/verifycard/utils.jsx
@@ -23,15 +23,11 @@
    }
    if (setting.interType === 'system' && setting.execute !== 'false') {
      _dataresource = setting.dataresource
      _dataresource = setting.dataresource || ''
    }
    
    if (_dataresource) {
      _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
    }
    if (_customScript) {
      _customScript = _customScript.replace(/@\$|\$@/ig, '')
    }
    if (_customScript) {
      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50) select @ErrorCode='',@retmsg =''
@@ -39,6 +35,12 @@
      `
    }
    
    // 外联数据库替换
    if (window.GLOB.externalDatabase !== null) {
      _dataresource = _dataresource.replace(/@db@/ig, window.GLOB.externalDatabase)
      _customScript = _customScript.replace(/@db@/ig, window.GLOB.externalDatabase)
    }
    // 正则替换
    let _regoptions = []
    let _fields = []
src/menu/modalconfig/index.jsx
@@ -199,7 +199,7 @@
      _formfields = config.fields
    }
    _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'color')
    _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color')
    _tabfields = _formfields.filter(item => card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type))
    _tabfields.unshift({field: '', text: '原表单'})
src/menu/modelsource/option.jsx
@@ -1,10 +1,9 @@
// import zhCN from '@/locales/zh-CN/mob.js'
// import enUS from '@/locales/en-US/mob.js'
import bar from '@/assets/mobimg/bar.png'
import bar1 from '@/assets/mobimg/bar1.png'
import line from '@/assets/mobimg/line.png'
import line1 from '@/assets/mobimg/line1.png'
import tabs from '@/assets/mobimg/tabs.png'
import group from '@/assets/mobimg/group.png'
import card1 from '@/assets/mobimg/card1.png'
import card2 from '@/assets/mobimg/card2.png'
import TableCard from '@/assets/mobimg/table-card.png'
@@ -14,11 +13,10 @@
import Pie2 from '@/assets/mobimg/nightingale.png'
import Mainsearch from '@/assets/mobimg/mainsearch.png'
// const _dict =  sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
// 组件配置信息
export const menuOptions = [
  { type: 'menu', url: tabs, component: 'tabs', subtype: 'tabs', title: '标签页', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: group, component: 'group', subtype: 'group', title: '分组', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: Mainsearch, component: 'search', subtype: 'mainsearch', title: '搜索条件', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '数据卡', config: `[{"uuid":"160135809128212dm7i29fim9ksto9od","setting":{"width":6},"style":{"paddingTop":"15px","marginTop":"4px","paddingRight":"15px","marginRight":"8px","marginLeft":"8px","backgroundColor":"rgba(255, 255, 255, 1)","borderColor":"#e8e8e8","paddingLeft":"15px","marginBottom":"4px","borderWidth":"1px","paddingBottom":"10px"},"backStyle":{},"elements":[{"datatype":"static","width":12,"marks":null,"height":1,"value":"关单","style":{},"prefix":"","postfix":"","format":"","eleType":"text","uuid":"160231860159931untbea62sgokunc5s"},{"datatype":"static","width":12,"marks":null,"style":{"color":"rgba(250, 219, 20, 1)","textAlign":"right"},"btnstyle":{},"eleType":"icon","icon":"question-circle","field":"","uuid":"1602318768361nv8ql4t47sgcsn88b0u"},{"datatype":"static","width":24,"marks":null,"height":1,"innerHeight":36,"value":"100","style":{"fontSize":"24px","fontWeight":"500","color":"rgba(0, 0, 0, 1)"},"prefix":"","btnstyle":{},"postfix":"","format":"","eleType":"text","uuid":"1602318817884v70gtgb65ubnm8mbcvv"},{"color":"#1890ff","width":24,"marks":null,"maxValue":100,"style":{"color":"rgba(250, 140, 22, 1)","paddingTop":"20px","paddingBottom":"10px"},"btnstyle":{},"eleType":"slider","field":"int1","uuid":"16023188871233rkktuvpp1h077igrsu"},{"eleType":"splitline","width":24,"color":"#e8e8e8","uuid":"1602320017038n31bk9o831ggug0tu0b","marks":null,"style":{"marginTop":"10px","marginBottom":"10px"},"btnstyle":{}},{"datatype":"static","width":12,"marks":null,"height":1,"value":"100","style":{"marginTop":"6px"},"prefix":"关单","btnstyle":{},"postfix":"","format":"","eleType":"text","uuid":"1602320061243drd7lf3agvn04kgr175"}],"backElements":[]}]` },
  { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '属性卡', config: `[{"uuid":"1603681387259qaqf1127f72esmtchge","setting":{"width":6,"type":"simple"},"style":{"paddingTop":"15px","marginTop":"8px","paddingRight":"15px","marginRight":"8px","marginLeft":"8px","borderColor":"#e8e8e8","paddingLeft":"15px","marginBottom":"8px","borderWidth":"1px","paddingBottom":"15px"},"backStyle":{},"elements":[{"datatype":"static","width":12,"marks":null,"height":1,"value":"超时工单","style":{"color":"rgba(67, 67, 67, 0.51)"},"prefix":"","postfix":"","format":"","eleType":"text","uuid":"1603681402945qnkgm7q8cng65evn5ev"},{"eleType":"icon","datatype":"static","width":12,"icon":"question-circle","tooltip":"超时工单","uuid":"1603681473384i2crkbtofg4pu76k06a","marks":null,"style":{"textAlign":"right","color":"rgba(250, 219, 20, 1)"}},{"datatype":"static","width":24,"marks":null,"height":1,"innerHeight":36,"value":"100","style":{"fontSize":"24px","color":"rgba(0, 0, 0, 1)"},"prefix":"","postfix":"","format":"","eleType":"number","uuid":"1603681539870d704ufqf98kc6t7537t"},{"color":"rgba(250, 219, 20, 1)","datatype":"static","width":24,"marks":null,"maxValue":100,"value":50,"style":{"paddingTop":"10px","paddingBottom":"10px"},"eleType":"slider","uuid":"1603683067556mvupau0odvrtv45u7o8"},{"eleType":"splitline","width":24,"color":"#e8e8e8","uuid":"1603683117981t9k55k8an430fuppmci","marks":null,"style":{"paddingTop":"5px","paddingBottom":"5px"}},{"datatype":"static","width":12,"marks":null,"height":1,"value":"100","style":{"color":"rgba(0, 0, 0, 0.65)","marginTop":"10px"},"prefix":"超时工单  ","postfix":"","format":"","eleType":"text","uuid":"1603683136553uvsmkfohkft9idbfkhu"}],"backElements":[]}]` },
src/menu/pastecontroller/index.jsx
New file
@@ -0,0 +1,193 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Icon, Modal, Button, notification } from 'antd'
import Utils from '@/utils/utils.js'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform'))
class PasteController extends Component {
  static propTpyes = {
    type: PropTypes.any,        // 组件类型
    Tab: PropTypes.any,         // 标签,添加菜单组件时为空
    insert: PropTypes.func
  }
  state = {
    visible: false
  }
  handleMenuClick = () => {
    this.setState({visible: true})
  }
  resetconfig = (item, Tab) => {
    item.uuid = Utils.getuuid()
    item.floor = Tab ? (Tab.floor + 1) : 1
    if (Tab) {
      item.tabId = Tab.uuid
      item.parentId = Tab.parentId
    }
    if (item.type === 'tabs') {
      item.subtabs.forEach(tab => {
        tab.uuid = Utils.getuuid()
        tab.parentId = item.uuid
        if (item.floor >= 3) {
          tab.components = tab.components.filter(cell => cell.type !== 'tabs')
        }
        tab.components = tab.components.map(cell => {
          cell = this.resetconfig(cell, tab)
          return cell
        })
      })
    } else if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) {
      item.subcards.forEach(card => {
        card.uuid = Utils.getuuid()
        if (card.elements) {
          card.elements = card.elements.map(cell => {
            cell.uuid = Utils.getuuid()
            return cell
          })
        }
        if (card.backElements) {
          card.backElements = card.backElements.map(cell => {
            cell.uuid = Utils.getuuid()
            return cell
          })
        }
      })
    } else if (item.type === 'table' && item.subtype === 'normaltable' && item.cols) {
      let loopCol = (col) => {
        col.subcols = col.subcols.map(c => {
          c.uuid = Utils.getuuid()
          if (c.type === 'colspan' && c.subcols) {
            c = loopCol(c)
          } else if (c.type === 'custom' && c.elements) {
            c.elements = c.elements.map(cell => {
              cell.uuid = Utils.getuuid()
              return cell
            })
          } else if (c.type === 'action' && c.elements) {
            c.elements = c.elements.map(cell => {
              cell.uuid = Utils.getuuid()
              return cell
            })
          }
          return c
        })
        return col
      }
      item.cols = item.cols.map(col => {
        col.uuid = Utils.getuuid()
        if (col.type === 'colspan' && col.subcols) {
          col = loopCol(col)
        } else if (col.type === 'custom' && col.elements) {
          col.elements = col.elements.map(cell => {
            cell.uuid = Utils.getuuid()
            return cell
          })
        } else if (col.type === 'action' && col.elements) {
          col.elements = col.elements.map(cell => {
            cell.uuid = Utils.getuuid()
            return cell
          })
        }
        return col
      })
    }
    if (item.btnlog) {
      item.btnlog = []
    }
    if (item.action) {
      item.action = item.action.map(cell => {
        cell.uuid = Utils.getuuid()
        return cell
      })
    }
    if (item.search) {
      item.search = item.search.map(cell => {
        cell.uuid = Utils.getuuid()
        return cell
      })
    }
    if (item.columns) {
      item.columns = item.columns.map(cell => {
        cell.uuid = Utils.getuuid()
        return cell
      })
    }
    return item
  }
  pasteSubmit = () => {
    const { Tab } = this.props
    this.pasteFormRef.handleConfirm().then(res => {
      if (!['tabs', 'datacard', 'propcard', 'mainsearch', 'normaltable', 'tablecard', 'line', 'bar', 'pie'].includes(res.copyType)) {
        notification.warning({
          top: 92,
          message: '配置信息格式错误!',
          duration: 5
        })
        return
      } else if (Tab && Tab.floor === 3 && res.type === 'tabs') {
        notification.warning({
          top: 92,
          message: '标签页最多为三重结构!',
          duration: 5
        })
        return
      }
      res = this.resetconfig(res, Tab)
      delete res.copyType
      this.props.insert(res, Tab)
      this.setState({visible: false})
      notification.success({
        top: 92,
        message: '粘贴成功!',
        duration: 2
      })
    })
  }
  render() {
    const { type } = this.props
    const { visible } = this.state
    return (
      <div style={{display: 'inline-block'}}>
        {type !== 'menu' ? <Icon type="snippets" style={{color: 'purple'}} onClick={() => {this.setState({visible: true})}} /> : null}
        {type === 'menu' ? <Button type="link" style={{padding: '5px'}} icon="snippets" onClick={() => {this.setState({visible: true})}}>粘贴</Button> : null}
        <Modal
          title="粘贴"
          visible={visible}
          width={600}
          maskClosable={false}
          onOk={this.pasteSubmit}
          onCancel={() => {this.setState({visible: false})}}
          destroyOnClose
        >
          <PasteForm wrappedComponentRef={(inst) => this.pasteFormRef = inst} inputSubmit={this.pasteSubmit}/>
        </Modal>
      </div>
    )
  }
}
export default PasteController
src/menu/pastecontroller/index.scss
src/menu/popview/index.jsx
@@ -11,6 +11,7 @@
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/mob.js'
import enUS from '@/locales/en-US/mob.js'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import { modifyCustomMenu } from '@/store/action'
@@ -58,6 +59,10 @@
    })
  }
  componentDidMount () {
    MKEmitter.addListener('delButtons', this.delButtons)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
@@ -69,6 +74,11 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('delButtons', this.delButtons)
  }
  delButtons = (items) => {
    this.setState({delButtons: [...this.state.delButtons, ...items]})
  }
  closeView = () => {
@@ -98,7 +108,8 @@
  }
  getMenuParam = () => {
    const { MenuId, MenuType } = this.state
    const { btn } = this.props
    const { MenuId } = this.state
    let param = {
      func: 'sPC_Get_LongParam',
@@ -123,18 +134,19 @@
            MenuID: MenuId,
            Template: 'CustomPage',
            enabled: false,
            MenuName: btn.config.MenuName + '-' + btn.label,
            MenuNo: '',
            tables: [],
            components: [],
            viewType: 'popview',
            style: {
              backgroundColor: '#ffffff', backgroundImage: '',
              paddingTop: '16px', paddingBottom: '80px', paddingLeft: '16px', paddingRight: '16px'
            },
            MenuType: MenuType
          }
        } else {
          config.uuid = MenuId
          config.MenuID = MenuId
          config.MenuType = config.MenuType || MenuType
        }
        this.setState({
@@ -225,11 +237,10 @@
  }
  submitConfig = () => {
    // const { btn } = this.props
    const { openEdition, delButtons } = this.state
    let config = fromJS(this.state.config).toJS()
    if (config.cacheUseful === 'true' && !config.cacheTime) {
    if ((config.cacheUseful === 'true' && !config.cacheTime) || !config.MenuNo || !config.MenuName) {
      notification.warning({
        top: 92,
        message: '请完善菜单基本信息!',
@@ -250,9 +261,9 @@
    let param = {
      func: 'sPC_Tab_AddUpt',
      MenuID: _config.uuid,
      MenuNo: _config.tabNo,
      MenuNo: _config.MenuNo,
      Template: 'CustomPage',
      MenuName: _config.tabName,
      MenuName: _config.MenuName,
      Remark: '',
      Sort: 0,
      PageParam: JSON.stringify({Template: 'CustomPage'}),
@@ -265,7 +276,7 @@
    let btnParam = {             // 添加菜单按钮
      func: 'sPC_Button_AddUpt',
      Type: 40,                  // 添加菜单下的按钮type为40,按钮下的按钮type为60
      Type: 60,                  // 添加菜单下的按钮type为40,按钮下的按钮type为60
      ParentID: _config.uuid,
      MenuNo: _config.MenuNo,
      Template: 'CustomPage',
src/menu/popview/menuform/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Radio, Icon, Tooltip, InputNumber } from 'antd'
import { Form, Row, Col, Radio, Icon, Input, Tooltip, InputNumber } from 'antd'
import './index.scss'
@@ -10,6 +10,16 @@
    btn: PropTypes.object,
    config: PropTypes.object,
    updateConfig: PropTypes.func
  }
  // 菜单名称
  changeName = (e) => {
    this.props.updateConfig({...this.props.config, MenuName: e.target.value})
  }
  // 菜单参数
  changeNo = (e) => {
    this.props.updateConfig({...this.props.config, MenuNo: e.target.value})
  }
  changeCacheDay = (val) => {
@@ -47,6 +57,32 @@
      <Form {...formItemLayout} className="custom-menu-form">
        <Row>
          <Col span={24}>
            <Form.Item label={dict['mob.menu'] + dict['mob.name']}>
              {getFieldDecorator('MenuName', {
                initialValue: config.MenuName,
                rules: [
                  {
                    required: true,
                    message: dict['mob.required.input'] + dict['mob.menu'] + dict['mob.name'] + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" onChange={this.changeName}/>)}
            </Form.Item>
          </Col>
          <Col span={24}>
            <Form.Item label={dict['mob.menu'] + dict['mob.param']}>
              {getFieldDecorator('MenuNo', {
                initialValue: config.MenuNo,
                rules: [
                  {
                    required: true,
                    message: dict['mob.required.input'] + dict['mob.menu'] + dict['mob.param'] + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" onChange={this.changeNo}/>)}
            </Form.Item>
          </Col>
          <Col span={24}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="对于不经常性变动的信息,缓存数据有助于提高查询效率。">
                <Icon type="question-circle" />
src/store/options.js
@@ -5,6 +5,31 @@
  cakey: 'MjAyMDAxMTYxMjQwMDQ2NDM$mk2N0QzODE2MjExNUI0MTc4OTVDMQ==',
  cdomain: 'aHR0cDovL2Nsb3VkLnBv$mkc2l0ZWNncm91cC5jb206ODA4MA==', // window.btoa('') 域名 不带 /; baoshide ( aHR0cDovL2Nsb3VkLnBv$mkc2l0ZWNncm91cC5jb206ODA4MA== )
  styles: {
    white: 'mk-white'
    bg_black_style_blue: 'mk-blue-black',
    bg_white_style_blue: 'mk-blue-white',
    bg_black_style_red: 'mk-red-black',
    bg_white_style_red: 'mk-red-white',
    bg_black_style_orange_red: 'mk-orange-red-black',
    bg_white_style_orange_red: 'mk-orange-red-white',
    bg_black_style_orange: 'mk-orange-black',
    bg_white_style_orange: 'mk-orange-white',
    bg_black_style_orange_yellow: 'mk-orange-yellow-black',
    bg_white_style_orange_yellow: 'mk-orange-yellow-white',
    bg_black_style_yellow: 'mk-yellow-black',
    bg_white_style_yellow: 'mk-yellow-white',
    bg_black_style_yellow_green: 'mk-yellow-green-black',
    bg_white_style_yellow_green: 'mk-yellow-green-white',
    bg_black_style_green: 'mk-green-black',
    bg_white_style_green: 'mk-green-white',
    bg_black_style_cyan: 'mk-cyan-black',
    bg_white_style_cyan: 'mk-cyan-white',
    bg_black_style_blue_purple: 'mk-blue-purple-black',
    bg_white_style_blue_purple: 'mk-blue-purple-white',
    bg_black_style_purple: 'mk-purple-black',
    bg_white_style_purple: 'mk-purple-white',
    bg_black_style_magenta: 'mk-magenta-black',
    bg_white_style_magenta: 'mk-magenta-white',
    bg_black_style_grass_green: 'mk-grass-green-black',
    bg_white_style_grass_green: 'mk-grass-green-white',
  }
}
src/store/reducer.js
@@ -81,6 +81,7 @@
      }
    case Type.RESET_EDITSTATE:
    // 重置编辑状态
      document.body.className = ''
      return {
        ...state,
        tabviews: [],
src/tabviews/custom/components/card/cardItem/index.jsx
@@ -49,6 +49,9 @@
    return (
      <div className="card-item-box" style={card.style}>
        <CardCellComponent data={data} cards={cards} cardCell={card} elements={card.elements} updateStatus={this.props.updateStatus}/>
        {card.setting.type === 'multi' ? <div className={'back-side ' + card.setting.transform} style={card.backStyle}>
          <CardCellComponent data={data} cards={cards} cardCell={card} elements={card.backElements} updateStatus={this.props.updateStatus}/>
        </div> : null}
      </div>
    )
  }
src/tabviews/custom/components/card/cardItem/index.scss
@@ -1,3 +1,58 @@
.card-item-box {
  position: relative;
  overflow: hidden;
  .back-side {
    position: absolute;
    top: 0px;
    left: 0px;
    right: 0px;
    bottom: 0px;
    background-color: #ffffff;
    transition: all 0.3s;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
  }
  .back-side.up {
    transform: translate(0, 100%);
  }
  .back-side.down {
    transform: translate(0, -100%);
  }
  .back-side.left {
    transform: translate(100%, 0);
  }
  .back-side.right {
    transform: translate(-100%, 0);
  }
  .back-side.opacity {
    opacity: 0;
  }
  .back-side.rotateX {
    transform: rotateX(90deg);
  }
  .back-side.rotateY {
    transform: rotateY(90deg);
  }
  .back-side.scale {
    transform: scale(0, 0);
  }
}
.card-item-box:hover {
  .back-side.up, .back-side.down, .back-side.left, .back-side.right {
    transform: translate(0, 0);
  }
  .back-side.opacity {
    opacity: 1;
  }
  .back-side.rotateX {
    transform: rotateX(0deg);
  }
  .back-side.rotateY {
    transform: rotateY(0deg);
  }
  .back-side.scale {
    transform: scale(1, 1);
  }
}
src/tabviews/custom/components/card/data-card/index.jsx
@@ -373,7 +373,7 @@
            ))}
          </div> : null}
          {switchable ? <div className={'prev-page ' + (total <= _total ? 'disabled' : '')} onClick={this.nextPage}><div><div><img src={nextImg} alt=""/></div></div></div> : null}
          {data && data.length === 0 ? <Empty description={false}/> : null}
          {!data || data.length === 0 ? <Empty description={false}/> : null}
        </div>
        {config.wrap.pagestyle !== 'switch' && config.setting.laypage && data ? <Pagination size="small" total={total} showTotal={t => `共 ${t} 条`} pageSize={config.setting.pageSize} onChange={this.changePageIndex} current={pageIndex}/> : null}
      </div>
src/tabviews/custom/components/card/data-card/index.scss
@@ -3,7 +3,7 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 100px;
  min-height: 20px;
  >.button-list.toolbar-button {
    padding: 0;
src/tabviews/custom/components/card/prop-card/index.jsx
@@ -42,15 +42,15 @@
      _sync = _config.setting.sync === 'true'
      if (_sync && data) {
        _data = data[_config.dataName]
        _data = data[_config.dataName] || {}
        if (_data && Array.isArray(_data)) {
          _data = _data[0]
          _data = _data[0] || {}
        }
        _sync = false
      } else if (_sync && initdata) {
        _data = initdata
        _data = initdata || {}
        if (_data && Array.isArray(_data)) {
          _data = _data[0]
          _data = _data[0] || {}
        }
        _sync = false
      }
src/tabviews/custom/components/card/prop-card/index.scss
@@ -3,7 +3,7 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 100px;
  min-height: 20px;
  position: relative;
  .card-row-list::after {
src/tabviews/custom/components/share/normalTable/index.jsx
@@ -381,6 +381,7 @@
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    tableId: '',          // 表格ID
    selectedRowKeys: [],  // 表格中选中行
    pageIndex: 1,         // 初始页面索引
    pageSize: 10,         // 每页数据条数
@@ -457,9 +458,26 @@
      rowspans = null
    }
    let tableId = (() => {
      let uuid = []
      let _options = 'abcdefghigklmnopqrstuv'
      for (let i = 0; i < 19; i++) {
        uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1))
      }
      return uuid.join('')
    }) ()
    if (setting.borderColor) { // 边框颜色
      let style = `#${tableId} table, #${tableId} tr, #${tableId} th, #${tableId} td {border-color: ${setting.borderColor}}`
      let ele = document.createElement('style')
      ele.innerHTML = style
      document.getElementsByTagName('head')[0].appendChild(ele)
    }
    this.setState({
      columns: _columns,
      rowspans,
      tableId,
      orderfields
    })
  }
@@ -733,7 +751,7 @@
  render() {
    const { setting, statFValue, lineMarks, data } = this.props
    const { selectedRowKeys, activeIndex, pickup } = this.state
    const { selectedRowKeys, activeIndex, pickup, tableId } = this.state
    // 设置表格选择属性:单选、多选、不可选
    let rowSelection = null
@@ -780,7 +798,7 @@
    }
    return (
      <div className="normal-custom-table">
      <div className={'normal-custom-table ' + setting.tableHeader} id={tableId}>
        {(setting.tableType === 'radio' || setting.tableType === 'checkbox') && data && data.length > 0 ?
          <Switch title="收起" className="main-pickup" checkedChildren="开" unCheckedChildren="关" defaultChecked={pickup} onChange={this.pickupChange} /> : null
        }
src/tabviews/custom/components/share/normalTable/index.scss
@@ -157,6 +157,11 @@
    }
  }
}
.normal-custom-table.hidden {
  thead {
    display: none;
  }
}
.image-scale-modal {
  width: 70vw;
  min-height: 80vh;
src/tabviews/custom/components/table/normal-table/index.scss
@@ -51,7 +51,4 @@
      line-height: 150px!important;
    }
  }
  .normal-data-table {
    padding: 0;
  }
}
src/tabviews/custom/index.jsx
@@ -242,6 +242,8 @@
        if (item.action && item.action.length > 0) {
          item.action = item.action.filter(cell => {
            cell.logLabel = item.name + '-' + cell.label
            cell.ContainerId = this.state.ContainerId
            return permAction[cell.uuid]
          })
        }
@@ -258,15 +260,18 @@
              if (cell.eleType === 'button') {
                cell.logLabel = item.name + '-' + cell.label
                cell.Ot = 'requiredSgl'
                cell.ContainerId = this.state.ContainerId
              } else if (['text', 'number', 'link'].includes(cell.eleType) && !cell.height && _hasheight) {
                cell.innerHeight = 'auto'
              }
              return cell.eleType !== 'button' || permAction[cell.uuid]
            })
            card.backElements = card.backElements.filter(cell => {
              if (cell.eleType === 'button') {
                cell.logLabel = item.name + '-' + cell.label
                cell.Ot = 'requiredSgl'
                cell.ContainerId = this.state.ContainerId
              } else if (['text', 'number', 'link'].includes(cell.eleType) && !cell.height && _hasheight) {
                cell.innerHeight = 'auto'
              }
@@ -280,6 +285,7 @@
              if (cell.eleType === 'button') {
                cell.logLabel = item.name + '-' + cell.label
                cell.Ot = 'requiredSgl'
                cell.ContainerId = this.state.ContainerId
              } else if (['text', 'number', 'link'].includes(cell.eleType) && !cell.height && _hasheight) {
                cell.innerHeight = 'auto'
              }
@@ -292,6 +298,7 @@
            col.elements = col.elements.filter(cell => {
              cell.logLabel = item.name + '-' + cell.label
              cell.Ot = 'requiredSgl'
              cell.ContainerId = this.state.ContainerId
              return permAction[cell.uuid]
            })
            return col.elements.length !== 0
src/tabviews/verupmanage/index.jsx
@@ -421,6 +421,14 @@
    })
  }
  reloadMenuView = (menuId) => {
    const { MenuID } = this.props
    if (MenuID !== menuId) return
    this.reloadview()
  }
  UNSAFE_componentWillMount () {
    // 组件加载时,获取菜单数据
    this.loadconfig()
@@ -430,6 +438,10 @@
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  componentDidMount () {
    MKEmitter.addListener('reloadMenuView', this.reloadMenuView)
  }
  /**
   * @description 组件销毁,清除state更新
   */
@@ -437,6 +449,7 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('reloadMenuView', this.reloadMenuView)
  }
  render() {
@@ -483,8 +496,8 @@
            chgSelectData={this.changeSelectedData}
          />
        </div>
        <Tabs defaultActiveKey="0">
          {config.tabs && config.tabs.map((_tab, index) => {
        {config.tabs ? <Tabs defaultActiveKey="0">
          {config.tabs.map((_tab, index) => {
            return (
              <TabPane tab={
                <span>
@@ -506,7 +519,7 @@
              </TabPane>
            )
          })}
        </Tabs>
        </Tabs> : null}
      </div>
    )
  }
src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -943,7 +943,7 @@
                  }
                  // 外联数据库替换
                  if (window.GLOB.externalDatabase !== null) {
                    _option.sql = _option.sql.replace(/@db@/ig, `[${window.GLOB.externalDatabase}]..`)
                    _option.sql = _option.sql.replace(/@db@/ig, window.GLOB.externalDatabase)
                  }
                  cell.data_sql = Utils.formatOptions(_option.sql)
@@ -1100,7 +1100,7 @@
   * @description 显示模态框
   */
  getModels = () => {
    const { setting, BID } = this.props
    const { setting, BID, btn } = this.props
    const { btnconfig } = this.state
    if (!this.state.visible || !btnconfig || !btnconfig.setting) return null
@@ -1110,9 +1110,12 @@
    let clickouter = false
    let container = document.body
    if (setting.tabType === 'main' && btnconfig.setting.container === 'tab' && this.props.ContainerId) {
    if (
      (setting.tabType === 'main' && btnconfig.setting.container === 'tab' && this.props.ContainerId) ||
      (btnconfig.setting.container === 'tab' && btn.ContainerId)
    ) {
      width = btnconfig.setting.width + '%'
      container = () => document.getElementById(this.props.ContainerId)
      container = () => document.getElementById(this.props.ContainerId || btn.ContainerId)
    }
    if (btnconfig.setting.clickouter === 'close') {
src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -1069,7 +1069,7 @@
                  }
                  // 外联数据库替换
                  if (window.GLOB.externalDatabase !== null) {
                    _option.sql = _option.sql.replace(/@db@/ig, `[${window.GLOB.externalDatabase}]..`)
                    _option.sql = _option.sql.replace(/@db@/ig, window.GLOB.externalDatabase)
                  }
                  cell.data_sql = Utils.formatOptions(_option.sql)
@@ -1218,7 +1218,7 @@
   * @description 显示模态框
   */
  getModels = () => {
    const { setting, BID } = this.props
    const { setting, BID, btn } = this.props
    const { btnconfig } = this.state
    if (!this.state.visible || !btnconfig || !btnconfig.setting) return null
@@ -1228,9 +1228,12 @@
    let clickouter = false
    let container = document.body
    if (setting.tabType === 'main' && btnconfig.setting.container === 'tab' && this.props.ContainerId) {
    if (
      (setting.tabType === 'main' && btnconfig.setting.container === 'tab' && this.props.ContainerId) ||
      (btnconfig.setting.container === 'tab' && btn.ContainerId)
    ) {
      width = btnconfig.setting.width + '%'
      container = () => document.getElementById(this.props.ContainerId)
      container = () => document.getElementById(this.props.ContainerId || btn.ContainerId)
    }
    if (btnconfig.setting.clickouter === 'close') {
src/tabviews/zshare/mutilform/customSwitch/index.jsx
@@ -33,10 +33,11 @@
  }
  render() {
    const { Item } = this.props
    const { defaultChecked } = this.state
    return (
      <Switch defaultChecked={defaultChecked} onChange={this.onChange}/>
      <Switch checkedChildren={Item.openText || ''} unCheckedChildren={Item.closeText || ''} defaultChecked={defaultChecked} onChange={this.onChange}/>
    )
  }
}
src/tabviews/zshare/mutilform/index.jsx
@@ -95,8 +95,11 @@
    formlist.forEach(item => {
      if (item.type === 'text' || item.type === 'number') {                // 用于过滤下拉菜单关联表单
        _inputfields.push(item.field)
      } else if (item.type === 'textarea' && item.encryption === 'true') { // 加密字段
      } else if (item.type === 'textarea') {
        _inputfields.push(item.field)
        if (item.encryption === 'true') {                                // 加密字段
        encrypts.push(item.field)
        }
      } else if (item.type === 'link') {
        linkFields[item.linkField] = linkFields[item.linkField] || []
        linkFields[item.linkField].push(item.field)
@@ -120,6 +123,7 @@
        _fieldlen = item.fieldlength || 512
      } else if (item.type === 'number') {
        _fieldlen = item.decimal ? item.decimal : 0
        item.initval = item.initval || 0
      }
      datatype[item.field] = item.type
@@ -800,7 +804,6 @@
          </Col>
        )
      } else if (item.type === 'number') { // 数字
        let _initval = item.initval
        let precision = (item.decimal || item.decimal === 0) ? item.decimal : null
        fields.push(
@@ -812,7 +815,7 @@
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.field, {
                initialValue: _initval,
                initialValue: item.initval,
                rules: [
                  {
                    required: true,
src/tabviews/zshare/normalTable/index.scss
@@ -22,9 +22,6 @@
      tr {
        th {
          position: relative;
          // .ant-table-column-title {
          //   white-space: nowrap;
          // }
        }
      }
    }
@@ -54,7 +51,6 @@
  }
  .ant-table-body {
    overflow-x: auto!important;
    // min-height: 90px;
    table {
      .ant-table-tbody > tr > td {
        vertical-align: top;
src/tabviews/zshare/topSearch/index.jsx
@@ -25,6 +25,7 @@
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    oriId: Utils.getuuid(),  // 搜索表单Id
    formId: '',              // 搜索表单Id
    match: null,             // 搜索条件匹配规则
    style: null,             // 搜索条件类型
@@ -111,7 +112,7 @@
          } else { // 合并请求,区分本地及系统
            // 外联数据库替换
            if (window.GLOB.externalDatabase !== null) {
              _option.sql = _option.sql.replace(/@db@/ig, `[${window.GLOB.externalDatabase}]..`)
              _option.sql = _option.sql.replace(/@db@/ig, window.GLOB.externalDatabase)
            }
            if (item.database === 'sso') {
              mainItems.push(`select '${item.field}' as obj_name,'${_option.field}' as arr_field,'${window.btoa(window.encodeURIComponent(_option.sql))}' as LText`)
@@ -641,7 +642,7 @@
    if (showButton) {
      fields.push(
        <Col span={6} style={{ whiteSpace: 'nowrap' }} key="actions">
        <Col span={6} style={{ whiteSpace: 'nowrap' }} className="search-button" key="actions">
          <Form.Item label={' '} colon={false} style={{ minHeight: '40px' }}>
            <Button type="primary" onClick={this.handleSearch}>
              {dict['main.search']}
@@ -813,7 +814,7 @@
    }
    return (
      <Form {...formItemLayout} className={`top-search ${float}`} style={searchStyle} id={this.state.formId}>
      <Form {...formItemLayout} className={`top-search ${float}`} style={searchStyle} id={this.state.formId || this.state.oriId}>
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
    )
src/templates/formtabconfig/index.jsx
@@ -439,7 +439,7 @@
      _formfields = [..._formfields, ...group.sublist]
    })
    _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'color')
    _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color')
    _tabfields = _formfields.filter(item => card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type))
    _tabfields.unshift({field: '', text: '原表单'})
    
src/templates/modalconfig/dragelement/card.jsx
@@ -104,7 +104,7 @@
  } else if (card.type === 'linkMain') {
    formItem = (<Input style={{marginTop: '4px'}} />)
  } else if (card.type === 'switch') {
    formItem = (<Switch style={{marginTop: '8px'}} checked={card.initval}/>)
    formItem = (<Switch checkedChildren={card.openText || ''} unCheckedChildren={card.closeText || ''} style={{marginTop: '8px'}} checked={card.initval}/>)
  } else if (card.type === 'radio') {
    formItem = card.options && card.options.length > 0 ? (<Radio.Group value={card.initval}>
      {card.options.map(cell => <Radio key={cell.key} value={cell.Value}>{cell.Text}</Radio>)}
src/templates/modalconfig/index.jsx
@@ -276,7 +276,7 @@
      _formfields = config.fields
    }
    _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'color')
    _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color')
    _tabfields = _formfields.filter(item => card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type))
    _tabfields.unshift({field: '', text: '原表单'})
src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
@@ -139,6 +139,11 @@
        param.LText = param.LText.replace(/@\$|\$@/ig, '')
        // 外联数据库替换
        if (window.GLOB.externalDatabase !== null) {
          param.LText = param.LText.replace(/@db@/ig, window.GLOB.externalDatabase)
        }
        param.LText = Utils.formatOptions(param.LText)
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx
@@ -38,6 +38,12 @@
      _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 _regoptions = []
    let _search = ''
src/templates/sharecomponent/settingcomponent/settingform/utils.jsx
@@ -9,7 +9,7 @@
   */
  static getDebugSql (setting, scripts, arr_field, regoptions, search) {
    let sql = ''
    let _dataresource = setting.dataresource
    let _dataresource = setting.dataresource || ''
    let _customScript = ''
    scripts && scripts.forEach(script => {
      _customScript += `
@@ -33,6 +33,11 @@
    if (_customScript) {
      _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 _regoptions = regoptions.map(item => {
src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx
@@ -29,6 +29,12 @@
    
    _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 _regoptions = [
src/templates/zshare/editcomponent/index.jsx
@@ -312,7 +312,7 @@
          onCancel={() => {this.setState({pasteVisible: false})}}
          destroyOnClose
        >
          <PasteForm dict={dict} wrappedComponentRef={(inst) => this.pasteFormRef = inst}/>
          <PasteForm wrappedComponentRef={(inst) => this.pasteFormRef = inst}/>
        </Modal>
      </div>
    )
src/templates/zshare/formconfig.jsx
@@ -1963,6 +1963,20 @@
      required: true
    },
    {
      type: 'text',
      key: 'openText',
      label: '开启提示',
      initVal: card.openText || '',
      required: false
    },
    {
      type: 'text',
      key: 'closeText',
      label: '关闭提示',
      initVal: card.closeText || '',
      required: false
    },
    {
      type: 'radio',
      key: 'resourceType',
      label: Formdict['header.form.resourceType'],
src/templates/zshare/modalform/index.jsx
@@ -23,7 +23,7 @@
  multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'entireLine', 'tooltip'],
  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'entireLine', 'tooltip', 'emptyText', 'enter'],
  fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'entireLine', 'tooltip'],
  switch: ['initval', 'openVal', 'closeVal', 'readonly', 'hidden', 'readin', 'entireLine', 'tooltip'],
  switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'entireLine', 'tooltip'],
  date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'],
  datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'],
  datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'],
@@ -691,8 +691,9 @@
            }
          } else if (values.type === 'funcvar') { // 函数变量为只读元素
            values.readonly = 'true'
          } else if (values.type === 'number' && (values.min || values.min === 0) && (values.max || values.max === 0)) { // 数值型验证最小最大值
            if (values.min > values.max) {
          } else if (values.type === 'number') {  // 数值型验证最小最大值
            values.required = 'true'
            if ((values.min || values.min === 0) && (values.max || values.max === 0) && values.min > values.max) {
              notification.warning({
                top: 92,
                message: '最小值不可大于最大值!',
src/templates/zshare/pasteform/index.jsx
@@ -1,14 +1,13 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, notification } from 'antd'
import Utils from '@/utils/utils.js'
import './index.scss'
const { TextArea } = Input
class MainSearch extends Component {
  static propTpyes = {
    dict: PropTypes.object     // 字典项
    inputSubmit: PropTypes.func // 回车事件
  }
  componentDidMount () {
@@ -38,10 +37,6 @@
              duration: 5
            })
            _config = ''
          }
          if (_config && _config.uuid) { // 每次粘贴时更新ID,防止重复粘贴时id重复
            _config.uuid = Utils.getuuid()
          }
          if (_config) {
@@ -76,10 +71,10 @@
                rules: [
                  {
                    required: true,
                    message: this.props.dict['form.required.input'] + '配置信息!'
                    message: '请输入配置信息!'
                  }
                ]
              })(<TextArea autoSize={{ minRows: 6, maxRows: 6 }} />)}
              })(<TextArea autoSize={{ minRows: 6, maxRows: 6 }} onPressEnter={() => this.props.inputSubmit && this.props.inputSubmit()}/>)}
            </Form.Item>
          </Col>
        </Row>
src/templates/zshare/verifycard/customform/index.jsx
@@ -103,6 +103,11 @@
        // 数据权限
        param.LText = param.LText.replace(/@\$|\$@/ig, '')
        // 外联数据库替换
        if (window.GLOB.externalDatabase !== null) {
          param.LText = param.LText.replace(/@db@/ig, window.GLOB.externalDatabase)
        }
        param.LText = Utils.formatOptions(param.LText)
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
src/templates/zshare/verifycard/customscript/index.jsx
@@ -106,6 +106,11 @@
        // 数据权限
        param.LText = param.LText.replace(/@\$|\$@/ig, '')
        // 外联数据库替换
        if (window.GLOB.externalDatabase !== null) {
          param.LText = param.LText.replace(/@db@/ig, window.GLOB.externalDatabase)
        }
        console.info(`/* sql 验证 */\n${param.LText.replace(/\n\s{6,20}/ig, '\n')}`)
        param.LText = Utils.formatOptions(param.LText)
src/utils/utils.js
@@ -168,7 +168,7 @@
    value = value.replace(/%/ig, ' mpercent ')
    // 外联数据库替换
    if (window.GLOB.externalDatabase !== null) {
      value = value.replace(/@db@/ig, `[${window.GLOB.externalDatabase}]..`)
      value = value.replace(/@db@/ig, window.GLOB.externalDatabase)
    }
    // encode编码(中文字符超出base64加密范围)
    value = window.btoa(window.encodeURIComponent(value))
@@ -239,7 +239,7 @@
    value = value.replace(/%/ig, ' mpercent ')
    // 外联数据库替换
    if (window.GLOB.externalDatabase !== null) {
      value = value.replace(/@db@/ig, `[${window.GLOB.externalDatabase}]..`)
      value = value.replace(/@db@/ig, window.GLOB.externalDatabase)
    }
    let encodesql = (val) => {
src/views/billprint/index.jsx
@@ -19,6 +19,8 @@
const AntvPie = asyncComponent(() => import('@/tabviews/custom/components/chart/antv-pie'))
const DataCard = asyncComponent(() => import('@/tabviews/custom/components/card/data-card'))
const PropCard = asyncComponent(() => import('@/tabviews/custom/components/card/prop-card'))
const TableCard = asyncComponent(() => import('@/tabviews/custom/components/card/table-card'))
const NormalTable = asyncComponent(() => import('@/tabviews/custom/components/table/normal-table'))
class BillPrint extends Component {
  state = {
@@ -145,7 +147,7 @@
        let params = []
        let _pars = []
        config.components = config.components.filter(item => !['tabs', 'search'].includes(item.type) && item.subtype !== 'tablecard')
        config.components = config.components.filter(item => !['tabs', 'search'].includes(item.type))
        config.components = config.components.map(component => {
          if (component.action) component.action = []
          if (component.search) component.search = []
@@ -381,13 +383,17 @@
        comps.forEach((_item, index) => {
          let item = fromJS(_item).toJS()
          if (index + 1 >= length && !_pageover) {
            pagesover = true
          }
          if (item.wrap && item.wrap.printType === 'headerOrfooter') { // 页眉页脚
            page.push(item)
          } else if (_pageover) {
            return
          } else if (item.type === 'card' && item.subtype === 'datacard') {
            if (!_item.dataArray || _item.dataArray.length === 0) return
          } else if (item.subtype === 'datacard' || item.type === 'table') {
            if (_item.dataArray && _item.dataArray.length > 0) {
            item.data = []
            while (count < limit && _item.dataArray.length > 0) {
@@ -399,11 +405,12 @@
              _pageover = true
            }
            page.push(item)
            }
          } else {
            page.push(item)
          }
          if (index + 1 === length && !_pageover) {
          if (index + 1 >= length && !_pageover) {
            pagesover = true
          }
        })
@@ -430,9 +437,8 @@
              page.push(item)
            } else if (_pageover) {
              return
            } else if (item.type === 'card' && item.subtype === 'datacard') {
              if (!_item.dataArray || _item.dataArray.length === 0) return
            } else if (item.subtype === 'datacard' || item.type === 'table') {
              if (_item.dataArray && _item.dataArray.length > 0) {
              item.data = []
  
              while (count < limit && _item.dataArray.length > 0) {
@@ -444,6 +450,7 @@
                _pageover = true
              }
              page.push(item)
              }
            } else {
              page.push(item)
            }
@@ -457,7 +464,7 @@
        pages.push(page)
        pageIndex++
        if (pageIndex >= 2000 || pagesover) {
        if (pageIndex >= 200 || pagesover) {
          over = true
        }
      }
@@ -537,6 +544,18 @@
            <PropCard config={item} initdata={item.data} mainSearch={[]} menuType="" />
          </Col>
        )
      } else if (item.type === 'table' && item.subtype === 'tablecard') {
        return (
          <Col span={item.width} key={item.uuid}>
            <TableCard config={item} initdata={item.data} mainSearch={[]} menuType="" />
          </Col>
        )
      } else if (item.type === 'table' && item.subtype === 'normaltable') {
        return (
          <Col span={item.width} key={item.uuid}>
            <NormalTable config={item} initdata={item.data} mainSearch={[]} menuType="" />
          </Col>
        )
      } else {
        return null
      }
src/views/billprint/index.scss
@@ -22,3 +22,7 @@
    top: calc(40vh + 70px);
  }
}
.normal-custom-table .main-pickup {
  display: none!important;
}
src/views/login/index.jsx
@@ -374,7 +374,7 @@
            window.GLOB.style = systemMsg.style
        
            if (window.GLOB.style && options.styles[window.GLOB.style]) {
              document.getElementById('root').className = options.styles[window.GLOB.style]
              document.body.className = options.styles[window.GLOB.style]
            }
            if (res.titlelogo && window.GLOB.favicon !== res.titlelogo) {
src/views/login/index.scss
@@ -55,6 +55,13 @@
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
        border-top: 0;
      }
      .ant-tabs-tab:first-child {
        border-left: 0;
      }
      .ant-tabs-tab:last-child {
        border-right: 0;
      }
      .ant-tabs-tab.ant-tabs-tab-active {
        cursor: default;
@@ -92,6 +99,7 @@
      min-width: 300px;
      border-radius: 5px;
      overflow: hidden;
      border: 1px solid #e8e8e8;
      .form-item-wrap {
        padding: 0.6vw 1.6vw 1.6vw;
@@ -190,8 +198,8 @@
      }
      .login-form-button {
        border-radius: 0;
        background: #6fb3e9;
        border: 1px solid #6fb3e9;
        background: #6fb3e9!important;
        border: 1px solid #6fb3e9!important;
      }
    }
    .login-sync-button {
@@ -215,11 +223,11 @@
      font: 12px/150% Arial,Verdana,"\5b8b\4f53";
    }
  }
  .ant-btn-primary[disabled] {
    color: #fff;
    background-color: #40a9ff;
    border-color: #40a9ff;
  }
  // .ant-btn-primary[disabled] {
  //   color: #fff;
  //   background-color: #40a9ff;
  //   border-color: #40a9ff;
  // }
}
.sync-cloud-application {
  .ant-modal-body {
src/views/main/index.jsx
@@ -13,7 +13,7 @@
class Main extends Component {
  render () {
    return (
      <div className="flex-container">
      <div className="flex-container main-view">
        <ConfigProvider locale={_locale}>
          <Header key="header"/>
          <Sidemenu key="sidemenu"/>
src/views/menudesign/index.jsx
@@ -30,6 +30,7 @@
const SourceWrap = asyncComponent(() => import('@/menu/modelsource'))
const MenuShell = asyncComponent(() => import('@/menu/menushell'))
const BgController = asyncComponent(() => import('@/menu/bgcontroller'))
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
const PaddingController = asyncComponent(() => import('@/menu/padcontroller'))
const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller'))
@@ -48,6 +49,7 @@
    MenuNo: '',
    tableFields: [],
    delButtons: [],
    copyButtons: [],
    activeKey: 'basedata',
    menuloading: false,
    oriConfig: null,
@@ -85,6 +87,7 @@
  componentDidMount () {
    MKEmitter.addListener('delButtons', this.delButtons)
    MKEmitter.addListener('copyButtons', this.copyButtons)
    MKEmitter.addListener('changePopview', this.initPopview)
  }
@@ -96,11 +99,15 @@
      return
    }
    MKEmitter.removeListener('delButtons', this.delButtons)
    MKEmitter.removeListener('copyButtons', this.copyButtons)
    MKEmitter.removeListener('changePopview', this.initPopview)
  }
  delButtons = (items) => {
    this.setState({delButtons: [...this.state.delButtons, ...items]})
  }
  copyButtons = (items) => {
    this.setState({copyButtons: [...this.state.copyButtons, ...items]})
  }
  initPopview = (card, btn) => {
@@ -187,6 +194,7 @@
            MenuNo: MenuNo,
            tables: [],
            components: [],
            viewType: 'menu',
            style: {
              backgroundColor: '#ffffff', backgroundImage: '',
              paddingTop: '16px', paddingBottom: '80px', paddingLeft: '16px', paddingRight: '16px'
@@ -607,6 +615,15 @@
    this.props.modifyCustomMenu(config)
  }
  insert = (item) => {
    let config = fromJS(this.state.config).toJS()
    config.components.push(item)
    this.setState({config})
    this.props.modifyCustomMenu(config)
  }
  /**
   * @description 更新常用表信息,快捷添加后更新配置信息
   */
@@ -676,6 +693,7 @@
                  <div> {config && config.MenuName} </div>
                } bordered={false} extra={
                  <div>
                    <PasteController type="menu" Tab={null} insert={this.insert} />
                    {config ? <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                    <Button type="primary" onClick={this.submitConfig} loading={menuloading}>{dict['mob.save']}</Button>
                    <Button type="default" onClick={this.closeView}>{dict['mob.return']}</Button>
src/views/menudesign/index.scss
@@ -9,7 +9,14 @@
    background: #ffffff;
    padding: 50px 0px 0px 0px;
    // .menu-setting::before {
    //   content: ' ';
    //   position: absolute;
    //   width: 300px;
    //   height: 100%;
    //   left: 0;
    //   top: 0;
    // }
    .menu-setting {
      position: fixed;
      left: 0;