king
2023-05-15 8d7c3eed8bdac1e77c8de90a3227d801708c358e
2023-05-15
121个文件已修改
9个文件已添加
6483 ■■■■■ 已修改文件
package-lock.json 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/viewstyle.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/breadview/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/mkPicture/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/balcony/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/elementform/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/formconfig.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/options.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/double-data-card/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/double-data-card/options.jsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx 356 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-X6/chartcompile/index.jsx 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-X6/chartcompile/index.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-X6/index.jsx 1449 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-X6/index.scss 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/code/sandbox/codecontent/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/code/sandbox/options.jsx 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/step-form/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/tab-form/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/module/voucher/voucherTable/index.scss 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/dragsearch/card.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/actionform/index.jsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/formconfig.jsx 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/index.jsx 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/searchcomponent/dragsearch/card.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/editColumn/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/index.scss 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/options.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/editColumn/index.jsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/editColumn/index.scss 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/index.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/index.scss 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/index.jsx 83 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/uniqueform/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/options.jsx 156 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/index.jsx 86 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/index.scss 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/index.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/index.scss 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/options.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.scss 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/replaceField/index.jsx 110 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/formdragelement/card.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modalconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/linksetting/linkform/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/calendar/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardcellList/index.jsx 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/data-card/index.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/double-data-card/index.jsx 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/double-data-card/index.scss 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/code/sand-box/index.jsx 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/group/normal-group/index.jsx 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/index.jsx 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/voucherTable/index.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.scss 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalheader/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/tabtransfer/index.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/base-table/index.scss 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/index.jsx 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/index.scss 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/normalTable/index.jsx 969 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/normalTable/index.scss 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/normal-table/index.jsx 75 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/normal-table/index.scss 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/tabs/antv-tabs/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/tree/antd-tree/index.scss 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/popview/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtable/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtabtable/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/editLine/index.jsx 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/editLine/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/excelInbutton/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/index.jsx 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/index.scss 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/newpagebutton/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/normalbutton/index.jsx 111 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/popupbutton/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/printbutton/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/tabbutton/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkCheck/index.jsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkCheck/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/normalTable/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/index.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/calendarconfig/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/calendarconfig/source.jsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/source.jsx 230 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/card.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/index.scss 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/actionform/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/index.jsx 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/uniqueform/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/index.jsx 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/fieldscomponent/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/searchform/index.jsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/source.jsx 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.jsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/modaleditable/index.jsx 84 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/pasteform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/callbackcustomscript/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/customform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/customscript/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/option.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-custom.js 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -624,24 +624,28 @@
      }
    },
    "@antv/x6": {
      "version": "1.33.0",
      "resolved": "https://registry.npmjs.org/@antv/x6/-/x6-1.33.0.tgz",
      "integrity": "sha512-B9KkOZJrhgjwDfwUBl58YAGcnD3lpebVaGPGxFMtLcBWmM7K6aDu+TK0CbcdoTS99OyqUQkzNI4O4RFwrw+SRA==",
      "version": "2.10.1",
      "resolved": "https://registry.npmjs.org/@antv/x6/-/x6-2.10.1.tgz",
      "integrity": "sha512-38Fi9Qgnp+ylTrnRnhrGsc2cxsDosULbN6toVs9GjVpOguzq3oxRUblzO6dcnJhbzXfZxIcB/IuQt3pYpXJBKA==",
      "requires": {
        "csstype": "^3.0.3",
        "jquery": "^3.5.1",
        "jquery-mousewheel": "^3.1.13",
        "lodash-es": "^4.17.15",
        "mousetrap": "^1.6.5",
        "@antv/x6-common": "^2.0.12",
        "@antv/x6-geometry": "^2.0.5",
        "utility-types": "^3.10.0"
      },
      "dependencies": {
        "csstype": {
          "version": "3.1.0",
          "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz",
          "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA=="
        }
      }
    },
    "@antv/x6-common": {
      "version": "2.0.12",
      "resolved": "https://registry.npmjs.org/@antv/x6-common/-/x6-common-2.0.12.tgz",
      "integrity": "sha512-7PcvHGJ2UhrBEtsLI6MaHw6BCMhy22leCH8vCaMvmF32EEQ/491v6DKVPhcpp0dYZNERpfqvAB1w407Aw+bwLA==",
      "requires": {
        "lodash-es": "^4.17.15",
        "utility-types": "^3.10.0"
      }
    },
    "@antv/x6-geometry": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/@antv/x6-geometry/-/x6-geometry-2.0.5.tgz",
      "integrity": "sha512-MId6riEQkxphBpVeTcL4ZNXL4lScyvDEPLyIafvWMcWNTGK0jgkK7N20XSzqt8ltJb0mGUso5s56mrk8ysHu2A=="
    },
    "@antv/x6-react-components": {
      "version": "1.1.15",
@@ -795,6 +799,24 @@
            "d3-force": "^2.0.1",
            "ml-matrix": "^6.5.0"
          }
        },
        "@antv/x6": {
          "version": "1.34.13",
          "resolved": "https://registry.npmjs.org/@antv/x6/-/x6-1.34.13.tgz",
          "integrity": "sha512-gYFxh9Sd1UXPO0aO9LHclASacT6HKkG7AP9XQqRuuCcJYWQiZVRmTN1mYQf3lTZDdybdI6IisZp6zFoGjmFxig==",
          "requires": {
            "csstype": "^3.0.3",
            "jquery": "^3.5.1",
            "jquery-mousewheel": "^3.1.13",
            "lodash-es": "^4.17.15",
            "mousetrap": "^1.6.5",
            "utility-types": "^3.10.0"
          }
        },
        "csstype": {
          "version": "3.1.2",
          "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
          "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
        }
      }
    },
@@ -12591,9 +12613,9 @@
      "integrity": "sha512-JNAkmPeB/GS2tCRqUzRPsTOHpGDah7xP18vGJfIjZC+W2sxEHbxgJxetIjIqhjQ3yYbYNEELkM/spKLtwoOSUQ=="
    },
    "jquery": {
      "version": "3.6.0",
      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
      "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
      "version": "3.7.0",
      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz",
      "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ=="
    },
    "jquery-mousewheel": {
      "version": "3.1.13",
package.json
@@ -8,6 +8,7 @@
    "@antv/g2": "^4.1.34",
    "@antv/g6": "^4.6.4",
    "@antv/util": "^2.0.17",
    "@antv/x6": "^2.10.1",
    "@antv/xflow": "^1.0.50",
    "@babel/core": "7.5.5",
    "@svgr/webpack": "4.3.2",
src/assets/css/viewstyle.scss
@@ -112,7 +112,7 @@
    }
  }
  // 搜索栏
  .top-search {
  .mk-search-wrap {
    >.ant-row {
      .ant-col.search-button {
        .ant-btn:not(.ant-btn-primary):not(.ant-btn-link):active, .ant-btn:not(.ant-btn-primary):not(.ant-btn-link).active, .ant-btn:not(.ant-btn-primary):not(.ant-btn-link):hover, .ant-btn:not(.ant-btn-primary):not(.ant-btn-link):focus {
@@ -135,7 +135,7 @@
    }
  }
  // 表格
  .normal-data-table, .normal-custom-table {
  .normal-data-table, .normal-custom-table, .edit-custom-table {
    table {
      .ant-table-tbody {
        > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td {
src/components/breadview/index.scss
@@ -22,7 +22,7 @@
    padding-right: 15px;
  }
  >.commontable, >.calendar-page {
    > .top-search {
    > .mk-search-wrap {
      padding-left: 0;
      padding-right: 0;
      margin: 0 24px;
src/components/header/index.jsx
@@ -11,7 +11,8 @@
  modifyMainMenu,
  logout
} from '@/store/action'
import asyncComponent from '@/utils/asyncSpinComponent'
import asyncSpinComponent from '@/utils/asyncSpinComponent'
import asyncComponent from '@/utils/asyncComponent'
import Api from '@/api'
import MKEmitter from '@/utils/events.js'
import options from '@/store/options.js'
@@ -22,7 +23,7 @@
const { confirm } = Modal
const { Search } = Input
const Resetpwd = asyncComponent(() => import('@/components/resetPassword'))
const LoginForm = asyncComponent(() => import('./loginform'))
const LoginForm = asyncSpinComponent(() => import('./loginform'))
class Header extends Component {
  static propTpyes = {
src/components/mkPicture/index.jsx
@@ -44,7 +44,18 @@
  checkUrl = (url) => {
    let img = new Image()
    img.addEventListener('error', this.loadHandler)
    img.src = url
    if (/^https/.test(window.location.protocol)) { // https转换
      if (/^http:/.test(url)) {
        img.src = url.replace(/^http:/, 'https:')
      } else if (/^\/\//.test(url)) {
        img.src = 'https:' + url
      } else {
        img.src = url
      }
    } else {
      img.src = url
    }
  }
  loadHandler = (e) => {
src/index.js
@@ -147,6 +147,10 @@
        } else if (!/webapi\/dostars$/ig.test(systemApi)) {
          systemApi = systemApi.replace(/\/?$/, '/webapi/dostars')
        }
        if (/^https/.test(window.location.protocol) && /^http:/.test(systemApi) && !GLOB.transfer) {
          systemApi = systemApi.replace(/^http:/, 'https:')
        }
      
        GLOB.mainSystemApi = systemApi
      }
src/menu/components/card/balcony/index.jsx
@@ -175,6 +175,10 @@
    newcard.datatype = 'dynamic'
    newcard.height = 1
    if (card.wrap.datatype === 'static') {
      newcard.datatype = 'static'
    }
    // 注册事件-添加元素
    MKEmitter.emit('cardAddElement', card.uuid, newcard)
  }
src/menu/components/card/cardcellcomponent/elementform/index.jsx
@@ -289,6 +289,11 @@
        return item
      })
      let _field = ''
      if (value === 'formula') {
        _field = this.props.form.getFieldValue('field') || ''
      }
      this.setState({
        link: '',
        eleType: value,
@@ -303,6 +308,8 @@
          this.props.form.setFieldsValue({color: '#000000'})
        } else if (value === 'text' || value === 'number') {
          this.props.form.setFieldsValue({format: ''})
        } else if (value === 'formula' && _field) {
          this.props.form.setFieldsValue({formula: '@' + _field + '@'})
        }
        if (value === 'text' || value === 'picture') {
          this.props.form.setFieldsValue({link: ''})
src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -512,6 +512,7 @@
      options: [
        { value: 'tel', text: '电话' },
        { value: 'email', text: '邮箱' },
        { value: 'qywx', text: '企业微信' },
        { value: 'other', text: '其他' }
      ]
    },
src/menu/components/card/cardcomponent/index.jsx
@@ -121,6 +121,7 @@
  }
  
  addElement = () => {
    const { cards } = this.props
    const { card } = this.state
    let newcard = {}
@@ -133,6 +134,8 @@
    if (card.$cardType === 'extendCard' && card.setting.cardRole === 'header') {
      newcard.datatype = 'static'
    } else if (cards.subtype === 'propcard' && cards.wrap.datatype === 'static') {
      newcard.datatype = 'static'
    }
    // 注册事件-添加元素
src/menu/components/card/data-card/index.jsx
@@ -204,6 +204,9 @@
    if (btn) {
      card.action = card.action.filter(item => item.uuid !== btn.uuid)
      setTimeout(() => {
        MKEmitter.emit('revertBtn', card.uuid)
      }, 200)
    }
    this.updateComponent(card)
src/menu/components/card/data-card/options.jsx
@@ -397,6 +397,7 @@
      controlFields: [
        {field: 'jumpField', values: ['menu', 'link']},
        {field: 'joint', values: ['menu', 'link']},
        {field: 'open', values: ['menu', 'link']},
        {field: 'menu', values: ['menu']},
        {field: 'link', values: ['link']},
      ],
@@ -445,6 +446,18 @@
    },
    {
      type: 'radio',
      field: 'open',
      label: '打开方式',
      initval: wrap.open || 'blank',
      required: false,
      options: [
        {value: 'blank', label: '新窗口'},
        {value: 'self', label: '当前窗口'},
      ],
      forbid: subtype !== 'propcard' || appType !== 'mob'
    },
    {
      type: 'radio',
      field: 'supKey',
      label: '上级主键',
      initval: wrap.supKey || 'true',
src/menu/components/card/double-data-card/index.jsx
@@ -197,6 +197,10 @@
    if (btn) {
      card.action = card.action.filter(item => item.uuid !== btn.uuid)
      setTimeout(() => {
        MKEmitter.emit('revertBtn', card.uuid)
      }, 200)
    }
    this.updateComponent(card)
src/menu/components/card/double-data-card/options.jsx
@@ -210,6 +210,26 @@
      required: false
    },
    {
      type: 'number',
      field: 'zHeight',
      label: '高度',
      min: 10,
      max: 5000,
      precision: 0,
      initval: wrap.zHeight,
      tooltip: '卡片区域高度,内容超出时纵向滚动。注:小于等于100时为高度的百分比,第一个扩展属性卡将定位在顶部。',
      required: false,
      forbid: appType === 'mob'
    },
    {
      type: 'color',
      field: 'zBColor',
      label: '边框颜色',
      initval: wrap.zBColor || 'transparent',
      tooltip: '卡片区域设置高度或最小宽度时,滚动区域边框的颜色。',
      required: false
    },
    {
      type: 'radio',
      field: 'permission',
      label: '权限验证',
src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx
New file
@@ -0,0 +1,356 @@
/**
 * @description 获取图表视图配置表单
 * @param {object} card       // 图表对象
 */
export function getBaseForm (card, columns) {
  let appType = sessionStorage.getItem('appType')
  let roleList = sessionStorage.getItem('sysRoles')
  if (roleList) {
    try {
      roleList = JSON.parse(roleList)
    } catch (e) {
      roleList = []
    }
  } else {
    roleList = []
  }
  let menulist = []
  if (appType === 'pc') {
    menulist = sessionStorage.getItem('appMenus')
    if (menulist) {
      try {
        menulist = JSON.parse(menulist)
      } catch (e) {
        menulist = []
      }
    } else {
      menulist = []
    }
  } else if (appType === '') {
    menulist = sessionStorage.getItem('fstMenuList')
    if (menulist) {
      try {
        menulist = JSON.parse(menulist)
      } catch (e) {
        menulist = []
      }
    } else {
      menulist = []
    }
  }
  return [
    {
      type: 'text',
      field: 'title',
      label: '标题',
      initval: card.title,
      required: false
    },
    {
      type: 'text',
      field: 'name',
      label: '组件名称',
      initval: card.name,
      tooltip: '用于组件间的区分。',
      required: true
    },
    {
      type: 'number',
      field: 'width',
      label: '宽度',
      initval: card.width,
      tooltip: '栅格布局,每行等分为24列。',
      min: 1,
      max: 24,
      decimal: 0,
      required: true
    },
    {
      type: 'styleInput',
      field: 'height',
      label: '图表高度',
      initval: card.height,
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'radio',
      field: 'permission',
      label: '权限验证',
      initval: card.permission || 'false',
      required: false,
      options: [
        {value: 'true', label: '启用'},
        {value: 'false', label: '禁用'},
      ],
      forbid: !appType || sessionStorage.getItem('editMenuType') === 'popview'
    },
    {
      type: 'multiselect',
      field: 'blacklist',
      label: '黑名单',
      initval: card.blacklist || [],
      required: false,
      options: roleList,
      forbid: !!appType
    },
    {
      type: 'radio',
      field: 'click',
      label: '点击事件',
      initval: card.click || '',
      tooltip: '点击节点时触发的事件。',
      required: false,
      options: [
        {value: '', label: '数据切换'},
        {value: 'menu', label: '菜单'},
        {value: 'menus', label: '菜单组'}
      ],
      controlFields: [
        {field: 'menu', values: ['menu']},
        {field: 'menus', values: ['menus']},
        {field: 'menuType', values: ['menus']},
        {field: 'open', values: ['menu', 'menus']},
        {field: 'joint', values: ['menu', 'menus']},
      ]
    },
    {
      type: appType === '' ? 'cascader' : 'select',
      field: 'menu',
      label: '关联菜单',
      initval: card.menu || (appType === '' ? [] : ''),
      required: true,
      extendName: 'MenuNo',
      options: menulist
    },
    {
      type: 'select',
      field: 'menuType',
      label: '菜单类型',
      initval: card.menuType || '',
      required: true,
      options: columns
    },
    {
      type: 'radio',
      field: 'open',
      label: '打开方式',
      initval: card.open || 'blank',
      required: false,
      options: [
        {value: 'blank', label: '新窗口'},
        {value: 'self', label: '当前窗口'},
      ],
      forbid: appType !== 'pc'
    },
    {
      type: 'radio',
      field: 'joint',
      label: '参数拼接',
      initval: card.joint || 'true',
      required: false,
      options: [
        {value: 'true', label: '是'},
        {value: 'false', label: '否'},
      ],
    },
    {
      type: 'table',
      field: 'menus',
      label: '菜单组',
      initval: card.menus || [],
      required: true,
      span: 24,
      actions: appType === 'pc' ? ['view'] : [],
      columns: [
        {
          title: '标识',
          dataIndex: 'sign',
          inputType: 'input',
          editable: true,
          unique: true,
          required: false,
          width: '35%'
        },
        {
          title: '菜单',
          dataIndex: 'menu',
          inputType: !appType ? 'cascader' : 'select',
          editable: true,
          required: true,
          extends: !appType ? 'Menu' : [{key: 'label', value: 'label'}],
          width: '35%',
          render: (text, record) => record.label,
          options: menulist
        }
      ]
    }
  ]
}
/**
 * @description 获取图表视图配置表单
 * @param {object} card       // 图表对象
 * @param {Array}  columns    // 显示列
 */
export function getOptionForm (card, columns) {
  return [
    {
      type: 'select',
      field: 'subtype',
      label: '类型',
      initval: card.subtype || 'mindmap',
      required: true,
      options: [{
        value: 'mindmap',
        label: '思维导图'
      }, {
        value: 'indentTree',
        label: '缩进文件树'
      }, {
        value: 'kapmap',
        label: '知识图谱树'
      }],
      controlFields: [
        {field: 'dirField', values: ['mindmap']},
        {field: 'nodeColor', values: ['mindmap']},
        // {field: 'collapsed', values: ['indentTree', 'kapmap']},
      ]
    },
    {
      type: 'radio',
      field: 'rootType',
      label: '根节点取值',
      initval: card.rootType || 'fixed',
      tooltip: '选择上级时,请填写根节点的文本和值的字段名',
      required: true,
      options: [{
        value: 'fixed',
        label: '固定值'
      }, {
        value: 'supvalue',
        label: '上级组件'
      }, {
        value: 'line',
        label: '行'
      }],
      controlFields: [
        {field: 'rootLabel', values: ['fixed', 'supvalue']},
        {field: 'rootValue', values: ['fixed', 'supvalue']},
        {field: 'mark', values: ['line']},
      ]
    },
    {
      type: 'text',
      field: 'rootValue',
      label: '根节点值',
      initval: card.rootValue || '',
      required: true
    },
    {
      type: 'text',
      field: 'rootLabel',
      label: '根节点文本',
      initval: card.rootLabel || '',
      required: true
    },
    {
      type: 'select',
      field: 'valueField',
      label: '值字段',
      initval: card.valueField || '',
      required: true,
      options: columns
    },
    {
      type: 'select',
      field: 'labelField',
      label: '文本字段',
      initval: card.labelField || '',
      required: true,
      options: columns
    },
    {
      type: 'select',
      field: 'parentField',
      label: '上级字段',
      initval: card.parentField || '',
      required: true,
      options: columns
    },
    {
      type: 'text',
      field: 'mark',
      label: '顶级标识',
      initval: card.mark || '',
      tooltip: '上级字段值与顶级标识相同时,视为根节点。',
      required: true
    },
    {
      type: 'select',
      field: 'dirField',
      label: '方向控制',
      initval: card.dirField || '',
      required: false,
      options: columns,
      controlFields: [
        {field: 'dirSign', notNull: true},
        {field: 'leftColor', notNull: true},
      ]
    },
    {
      type: 'text',
      field: 'dirSign',
      label: '左向标记',
      initval: card.dirSign || '',
      tooltip: '当节点值与标记相同时节点信息位于节点左侧,多个值请用逗号分隔。',
      required: false
    },
    {
      type: 'color',
      field: 'nodeColor',
      label: '节点颜色',
      initval: card.nodeColor || '#1890ff',
      tooltip: '右侧节点的标记颜色。',
      colorType: 'hex',
      required: false
    },
    {
      type: 'color',
      field: 'leftColor',
      label: '左节点颜色',
      initval: card.leftColor || '#26C281',
      tooltip: '左侧节点的标记颜色。',
      colorType: 'hex',
      required: false
    },
    {
      type: 'radio',
      field: 'empty',
      label: '空值隐藏',
      initval: card.empty || 'show',
      tooltip: '当查询数据为空时,隐藏该组件。',
      required: false,
      options: [
        {value: 'show', label: '否'},
        {value: 'hidden', label: '是'},
      ],
    },
    {
      type: 'radio',
      field: 'collapsed',
      label: '节点合并',
      initval: card.collapsed || 'false',
      tooltip: '一级节点是否合并。',
      required: false,
      options: [
        {value: 'false', label: '否'},
        {value: 'true', label: '是'},
      ],
    },
  ]
}
src/menu/components/chart/antv-X6/chartcompile/index.jsx
New file
@@ -0,0 +1,179 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Modal, Form, Tabs } from 'antd'
import { EditOutlined } from '@ant-design/icons'
import { getBaseForm, getOptionForm } from './formconfig'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
const { TabPane } = Tabs
const NormalForm = asyncComponent(() => import('@/components/normalform/modalform'))
class LineChartDrawerForm extends Component {
  static propTpyes = {
    plot: PropTypes.object,
    config: PropTypes.object,
    plotchange: PropTypes.func
  }
  state = {
    view: 'normal',
    visible: false,
    plot: null,
    formlist: null,
    baseFormlist: null
  }
  showDrawer = () => {
    const { config } = this.props
    this.setState({
      visible: true,
      view: 'normal',
      plot: fromJS(config.plot).toJS(),
      baseFormlist: getBaseForm(config.plot, config.columns),
      formlist: getOptionForm(config.plot, config.columns)
    })
  }
  onSubmit = () => {
    const { config } = this.props
    const { plot, view } = this.state
    if (view === 'normal') {
      this.norRef.handleConfirm().then(res => {
        let _plot = {...plot, ...res}
        if (_plot.click !== 'menus') {
          delete _plot.menus
        }
        if (_plot.click !== 'menu') {
          delete _plot.menu
          delete _plot.MenuID
          delete _plot.MenuName
          delete _plot.MenuNo
          delete _plot.tabType
        } else if (sessionStorage.getItem('appType') === '' && _plot.menu) {
          let list = null
          try {
            list = JSON.parse(sessionStorage.getItem('thdMenuList')) || []
          } catch (e) {
            list = []
          }
          let id = _plot.menu[_plot.menu.length - 1]
          list.forEach(item => {
            if (item.MenuID === id) {
              _plot.MenuID = id
              _plot.MenuName = item.MenuName
              _plot.MenuNo = item.MenuNo
              _plot.tabType = item.type
            }
          })
        }
        this.setState({
          plot: _plot,
          visible: false
        })
        this.props.plotchange({...config, plot: _plot})
      })
    } else if (view === 'base') {
      this.baseRef.handleConfirm().then(res => {
        let _plot = {...plot, ...res}
        if (_plot.click !== 'menus') {
          delete _plot.menus
        }
        if (_plot.click !== 'menu') {
          delete _plot.menu
          delete _plot.MenuID
          delete _plot.MenuName
          delete _plot.MenuNo
          delete _plot.tabType
        } else if (sessionStorage.getItem('appType') === '' && _plot.menu) {
          let list = null
          try {
            list = JSON.parse(sessionStorage.getItem('thdMenuList')) || []
          } catch (e) {
            list = []
          }
          let id = _plot.menu[_plot.menu.length - 1]
          list.forEach(item => {
            if (item.MenuID === id) {
              _plot.MenuID = id
              _plot.MenuName = item.MenuName
              _plot.MenuNo = item.MenuNo
              _plot.tabType = item.type
            }
          })
        }
        this.setState({
          plot: _plot,
          visible: false
        })
        this.props.plotchange({...config, plot: _plot})
      })
    }
  }
  changeTab = (tab) => {
    const { plot, view } = this.state
    if (view === 'normal') {
      this.norRef.handleConfirm().then(res => {
        this.setState({
          plot: {...plot, ...res},
          view: tab
        })
      })
    } else if (view === 'base') {
      this.baseRef.handleConfirm().then(res => {
        this.setState({
          plot: {...plot, ...res},
          view: tab
        })
      })
    }
  }
  render() {
    const { config } = this.props
    const { view, visible, baseFormlist, formlist } = this.state
    return (
      <div className="line-chart-drawer-form">
        <EditOutlined title="编辑" onClick={this.showDrawer} />
        <Modal
          wrapClassName="mk-pop-modal"
          visible={visible}
          width={850}
          maskClosable={false}
          onOk={this.onSubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          {config.name ? <div className="mk-com-name">{config.name} - 编辑</div> : null}
          <Tabs activeKey={view} onChange={this.changeTab}>
            <TabPane tab="组件设置" key="base">
              <NormalForm formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
            </TabPane>
            <TabPane tab="图表设置" key="normal">
              <NormalForm formlist={formlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.norRef = inst}/>
            </TabPane>
          </Tabs>
        </Modal>
      </div>
    );
  }
}
export default Form.create()(LineChartDrawerForm)
src/menu/components/chart/antv-X6/chartcompile/index.scss
New file
@@ -0,0 +1,6 @@
.line-chart-drawer-form {
  display: inline-block;
  > .anticon-edit {
    color: #1890ff;
  }
}
src/menu/components/chart/antv-X6/index.jsx
New file
@@ -0,0 +1,1449 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, message } from 'antd'
import { ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import G6 from '@antv/g6'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle, getTables, getHeight, checkComponent } from '@/utils/utils-custom.js'
import './index.scss'
const { Util } = G6
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const ChartCompileForm = asyncIconComponent(() => import('./chartcompile'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
const MindData = [
  'Modeling Methods',
  [
    'Classification',
    ['Logistic regression', 'Linear discriminant analysis', 'Rules', 'Decision trees', 'Naive Bayes', 'K nearest neighbor', 'Probabilistic neural network', 'Support vector machine']
  ],
  [
    'Consensus',
    [
      'Models diversity',
      ['Different initializations', 'Different parameter choices', 'Different architectures', 'Different modeling methods', 'Different training sets', 'Different feature sets']
    ],
    [
      'Methods',
      ['Classifier selection', 'Classifier fusion']
    ],
    [
      'Common',
      ['Bagging', 'Boosting', 'AdaBoost']
    ]
  ],
  [
    'Regression',
    ['Multiple linear regression', 'Partial least squares', 'Multi-layer feedforward neural network', 'General regression neural network', 'Support vector regression']
  ]
]
const styles = {
  blue: '#1890ff',
  red: '#f5222d',
  orange_red: '#fa541c',
  orange: '#fa8c16',
  orange_yellow: '#faad14',
  yellow: '#fadb14',
  yellow_green: '#a0d911',
  green: '#52c41a',
  cyan: '#13c2c2',
  blue_purple: '#2f54eb',
  purple: '#722ed1',
  magenta: '#eb2f96',
  grass_green: '#aeb303',
  deep_red: '#c32539',
  deep_blue: '#1d3661'
}
let systemColor = '#1890ff'
if (window.GLOB.style) {
  let type = window.GLOB.style.replace(/bg_black_style_|bg_white_style_/, '')
  systemColor = styles[type] || '#1890ff'
}
const COLORS = ['#5B8FF9', '#F6BD16', '#5AD8A6', '#945FB9', '#E86452', '#6DC8EC', '#FF99C3', '#1E9493', '#FF9845', '#5D7092']
// 思维导图
G6.registerNode(
  'dice-mind-map-root', {
    jsx: (cfg) => {
      const width = Util.getTextSize(cfg.label, 16)[0] + 24
      return `
        <group>
          <rect style={{width: ${width}, height: 42, stroke: ${systemColor}, radius: 4}} keyshape>
            <text style={{ fontSize: 16, marginLeft: 6, marginTop: 12 }}>${cfg.label}</text>
          </rect>
        </group>
      `
    },
    getAnchorPoints() {
      return [
        [0, 0.5],
        [1, 0.5]
      ]
    }
  },
  'single-node',
)
G6.registerNode(
  'dice-mind-map-leaf', {
    jsx: (cfg) => {
      const width = Util.getTextSize(cfg.label, 12)[0] + 24
      return `
        <group>
          <rect style={{width: ${width}, height: 26, fill: 'transparent', cursor: pointer }}>
            <text style={{ fontSize: 12, fill: ${cfg.selected ? systemColor : '#000000'}, marginLeft: 12, marginTop: 6, cursor: pointer }}>${cfg.label}</text>
          </rect>
          <rect style={{ fill: ${cfg.color}, width: ${width}, height: 2, x: 0, y: 32, cursor: pointer }} />
        </group>
      `
    },
    getAnchorPoints() {
      return [
        [0, 0.965],
        [1, 0.965]
      ]
    }
  },
  'single-node',
)
G6.registerBehavior('dice-mindmap', {
  getEvents() {
    return {
      'node:click': 'editNode',
      'canvas:click': 'onCanvasClick'
    }
  },
  editNode(evt) {
    const item = evt.item
    const model = item.get('model')
    this.graph.getNodes().forEach(node => {
      let _model = node.get('model')
      if (_model.selected) {
        _model.selected = false
        this.graph.updateItem(node, _model, false)
      }
    })
    model.selected = true
    this.graph.updateItem(item, model, false)
  },
  onCanvasClick(e) {
    this.graph.getNodes().forEach(node => {
      let _model = node.get('model')
      if (_model.selected) {
        _model.selected = false
        this.graph.updateItem(node, _model, false)
      }
    })
  }
})
G6.registerBehavior('scroll-canvas', {
  getEvents: function getEvents() {
    return {
      wheel: 'onWheel'
    }
  },
  onWheel: function onWheel(ev) {
    const { graph } = this
    if (!graph) {
      return
    }
    if (ev.ctrlKey) {
      const canvas = graph.get('canvas')
      const point = canvas.getPointByClient(ev.clientX, ev.clientY)
      let ratio = graph.getZoom()
      if (ev.wheelDelta > 0) {
        ratio += ratio * 0.05
      } else {
        ratio *= ratio * 0.05
      }
      graph.zoomTo(ratio, {
        x: point.x,
        y: point.y
      })
    } else {
      const x = ev.deltaX || ev.movementX
      const y = ev.deltaY || ev.movementY || (-ev.wheelDelta * 125) / 3
      graph.translate(-x, -y)
    }
    ev.preventDefault()
  }
})
// 缩进文件树
G6.registerNode('indentedRoot', {
  draw(model, group) {
    const keyShape = group.addShape('rect', {
      attrs: {
        x: -46,
        y: -16,
        width: 92,
        height: 32,
        fill: systemColor,
        radius: 2,
        stroke: '#5B8FF9',
        lineWidth: 0
      },
      name: 'key-shape'
    })
    const text = group.addShape('text', {
      attrs: {
        text: model.label || 'root',
        fill: "#fff",
        fontSize: 12,
        x: 0,
        y: 0,
        textAlign: 'center',
        textBaseline: 'middle'
      },
      name: 'root-text-shape'
    })
    const textBBox = text.getBBox()
    const width = textBBox.width + 24
    const height = textBBox.height + 12
    keyShape.attr({
      x: -width / 2,
      y: -height / 2,
      width,
      height
    })
    return keyShape
  },
  getAnchorPoints() {
    return [
      [0.5, 1]
    ]
  },
  update: undefined
})
G6.registerNode('indentedNode', {
  addChildCount(group, tag, props) {
    const { collapsed, branchColor, count } = props
    let clickCircleY = 10
    // 子类数量 icon,绘制圆点在节点正下方
    if (tag) {
      const childCountGroup = group.addGroup({
        name: 'child-count-group'
      })
      childCountGroup.setMatrix([1, 0, 0, 0, 1, 0, 0, clickCircleY, 1])
      const countBackWidth = collapsed ? 26 : 12
      childCountGroup.addShape('rect', {
        attrs: {
          width: countBackWidth,
          height: 12,
          radius: 6,
          stroke: branchColor,
          lineWidth: 2,
          fill: collapsed ? branchColor : '#fff',
          x: -countBackWidth / 2,
          y: -6,
          cursor: 'pointer',
        },
        name: 'child-count-rect-shape'
      })
      const childCountText = childCountGroup.addShape('text', {
        attrs: {
          text: count,
          fill: '#fff',
          x: 0,
          y: 0,
          fontSize: 10,
          textAlign: 'center',
          textBaseline: 'middle',
          cursor: 'pointer',
        },
        name: 'child-count-text-shape'
      })
      const childHoverIcon = childCountGroup.addShape('path', {
        attrs: {
          stroke: '#fff',
          lineWidth: 1,
          cursor: 'pointer',
          path: [['M', -3, 2], ['L', 0, -2], ['L', 3, 2]]
        },
        name: 'child-count-expand-icon',
        capture: false
      })
      childHoverIcon.hide()
      // 连接 count 的线段
      const countLink = group.addShape('path', {
        attrs: {
          path: [['M', 0, 0], ['L', 0, 11]],
          stroke: branchColor,
          lineWidth: 2,
        },
        name: 'count-link'
      })
      countLink.toBack()
      if (collapsed) {
        childCountGroup.show()
        childCountText.show()
        countLink.show()
      }
      else {
        childCountGroup.hide()
        childCountText.hide()
        countLink.hide()
      }
      clickCircleY += 16
    }
  },
  addBottomLine(group, props) {
    const { x, width, stroke, lineWidth } = props
    return group.addShape('path', {
      attrs: {
        path: [
          ['M', x - 1, 0],
          ['L', width, 0],
        ],
        stroke,
        lineWidth,
      },
      name: 'node-path-shape'
    })
  },
  addName(group, props) {
    const { label, x = 0, y, fill } = props
    return group.addShape('text', {
      attrs: {
        text: label,
        x,
        y,
        textAlign: 'start',
        textBaseline: 'top',
        fill,
        fontSize: 14,
        fontFamily: 'PingFangSC-Regular',
        cursor: 'pointer',
      },
      name: 'not-root-text-shape'
    })
  },
  draw(model, group) {
    const { collapsed, depth, label, children, selected } = model
    // 是否为根节点
    const rootNode = depth === 0
    // 子节点数量
    const childCount = children ? children.length : 0
    let width = 0
    const height = 24
    const x = 0
    const y = -height / 2
    const borderRadius = 4
    // 名称文本
    const text = this.addName(group, { label, x, y })
    let textWidth = text.getBBox().width
    width = textWidth + 20
    const keyShapeAttrs = {
      x,
      y,
      width,
      height,
      radius: borderRadius,
      fill: undefined,
      stroke: undefined,
    }
    const keyShape = group.addShape('rect', {
      attrs: keyShapeAttrs,
      name: 'root-key-shape-rect-shape'
    })
    // 底部横线
    const bottomLine = this.addBottomLine(group, {
      stroke: model.branchColor || '#AAB7C4',
      lineWidth: 3,
      x,
      width
    })
    let nameColor = 'rgba(0, 0, 0, 0.85)'
    if (selected) {
      nameColor = systemColor
    }
    // 名称
    text.attr({
      y: y - 12,
      fill: nameColor
    })
    text.toFront()
    textWidth = text.getBBox().width
    if (bottomLine) bottomLine.toFront()
    this.addChildCount(group, childCount && !rootNode, {
      collapsed,
      branchColor: model.branchColor,
      count: childCount ? `${childCount}` : undefined
    })
    const bbox = group.getBBox()
    const backContainer = group.addShape('path', {
      attrs: {
        path: childCount ? [
          ['M', bbox.minX, bbox.minY],
          ['L', bbox.maxX, bbox.minY],
          ['L', bbox.maxX, bbox.maxY],
          ['L', bbox.minX + 20, bbox.maxY],
          ['L', bbox.minX + 20, bbox.maxY + 20],
          ['L', bbox.minX, bbox.maxY + 20],
          ['Z']
        ] : [
          ['M', bbox.minX, bbox.minY],
          ['L', bbox.maxX, bbox.minY],
          ['L', bbox.maxX, bbox.maxY],
          ['L', bbox.minX, bbox.maxY],
          ['Z']
        ],
        fill: '#fff',
        opacity: 0
      }
    })
    backContainer.toBack()
    return keyShape
  }
})
G6.registerEdge('indentedEdge', {
  afterDraw: (cfg, group) => {
    const sourceNode = cfg.sourceNode && cfg.sourceNode.getModel()
    const targetNode = cfg.targetNode && cfg.targetNode.getModel()
    const color = sourceNode.branchColor || targetNode.branchColor || cfg.color || '#000'
    const keyShape = group.get('children')[0]
    keyShape.attr({
      stroke: color,
      lineWidth: 3 // branchThick
    })
    group.toBack()
  },
  getControlPoints: (cfg) => {
    const startPoint = cfg.startPoint
    const endPoint = cfg.endPoint
    return [
      startPoint,
      {
        x: startPoint.x,
        y: endPoint.y,
      },
      endPoint
    ]
  },
  update: undefined
}, 'polyline')
G6.registerBehavior('wheel-scroll', {
  getDefaultCfg() {
    return {
      direction: 'y',
      zoomKey: 'ctrl',
      sensitivity: 3,
      scalableRange: -64
    }
  },
  getEvents() {
    return {
      wheel: 'onWheel'
    }
  },
  onWheel(ev) {
    const graph = this.graph
    let keyDown = ev[`${this.zoomKey}Key`]
    if (this.zoomKey === 'control') keyDown = ev.ctrlKey
    if (keyDown) {
      const sensitivity = this.get('sensitivity')
      const canvas = graph.get('canvas')
      const point = canvas.getPointByClient(ev.clientX, ev.clientY)
      let ratio = graph.getZoom()
      if (ev.wheelDelta > 0) {
        ratio *= (1 + 0.01 * sensitivity)
      } else {
        ratio *= (1 - 0.01 * sensitivity)
      }
      graph.zoomTo(ratio, {
        x: point.x,
        y: point.y
      })
      graph.emit('wheelzoom', ev)
    } else {
      let dx = ev.deltaX || ev.movementX
      let dy = ev.deltaY || ev.movementY
      if (!dy && navigator.userAgent.indexOf('Firefox') > -1) dy = (-ev.wheelDelta * 125) / 3
      const width = this.graph.get('width')
      const height = this.graph.get('height')
      const graphCanvasBBox = this.graph.get('group').getCanvasBBox()
      let expandWidth = this.scalableRange
      let expandHeight = this.scalableRange
      // 若 scalableRange 是 0~1 的小数,则作为比例考虑
      if (expandWidth < 1 && expandWidth > -1) {
        expandWidth = width * expandWidth
        expandHeight = height * expandHeight
      }
      const { minX, maxX, minY, maxY } = graphCanvasBBox
      if (dx > 0) {
        if (maxX < -expandWidth) {
          dx = 0
        } else if (maxX - dx < -expandWidth) {
          dx = maxX + expandWidth
        }
      } else if (dx < 0) {
        if (minX > width + expandWidth) {
          dx = 0
        } else if (minX - dx > width + expandWidth) {
          dx = minX - (width + expandWidth)
        }
      }
      if (dy > 0) {
        if (maxY < -expandHeight) {
          dy = 0
        } else if (maxY - dy < -expandHeight) {
          dy = maxY + expandHeight
        }
      } else if (dy < 0) {
        if (minY > height + expandHeight) {
          dy = 0
        } else if (minY - dy > height + expandHeight) {
          dy = minY - (height + expandHeight)
        }
      }
      if (this.get('direction') === 'x') {
        dy = 0
      } else if (this.get('direction') === 'y') {
        dx = 0
      }
      graph.translate(-dx, -dy)
    }
    ev.preventDefault()
  }
})
G6.registerBehavior('hover-node', {
  getEvents() {
    return {
      'node:mouseover': 'onNodeMouseOver',
      'node:mouseleave': 'onNodeMouseLeave',
      'node:mouseenter': 'onNodeMouseEnter'
    }
  },
  onNodeMouseEnter(ev) {
    const { item } = ev
    if (!item || item.get('destroyed')) return
    item.toFront()
    const model = item.getModel()
    const { collapsed, depth } = model
    const rootNode = depth === 0 || model.isRoot
    const group = item.getContainer()
    if (rootNode) return
    // 控制子节点个数标记
    if (!collapsed) {
      const childCountGroup = group.find(e => e.get('name') === 'child-count-group')
      if (childCountGroup) {
        childCountGroup.show()
      }
    }
  },
  onNodeMouseOver(ev) {
    const shape = ev.target
    // tooltip显示、隐藏
    this.graph.emit('tooltip: show', ev)
    // expand 状态下,若 hover 到子节点个数标记,填充背景+显示收起 icon
    const { item } = ev
    const group = item.getContainer()
    const model = item.getModel()
    if (!model.collapsed) {
      const childCountGroup = group.find(e => e.get('name') === 'child-count-group')
      if (childCountGroup) {
        childCountGroup.show()
        const back = childCountGroup.find(e => e.get('name') === 'child-count-rect-shape')
        const expandIcon = childCountGroup.find(e => e.get('name') === 'child-count-expand-icon')
        const rootNode = model.depth === 0 || model.isRoot
        const branchColor = rootNode ? '#576286' : model.branchColor
        if (shape.get('parent').get('name') === 'child-count-group') {
          if (back) {
            back.attr('fill', branchColor || '#fff')
          }
          if (expandIcon) {
            expandIcon.show()
          }
        } else {
          if (back) {
            back.attr('fill', '#fff')
          }
          if (expandIcon) {
            expandIcon.hide()
          }
        }
      }
    }
  },
  onNodeMouseLeave(ev) {
    const { item } = ev
    const model = item.getModel()
    const group = item.getContainer()
    const { collapsed } = model
    if (!collapsed) {
      const childCountGroup = group.find(e => e.get('name') === 'child-count-group')
      if (childCountGroup) {
        childCountGroup.hide()
      }
      const iconsLinkPath = group.find(e => e.get('name') === 'icons-link-path')
      if (iconsLinkPath) {
        iconsLinkPath.hide()
      }
    }
    this.graph.emit('tooltip: hide', ev)
  }
})
G6.registerBehavior('click-node', {
  getEvents() {
    return {
      'node:click': 'onNodeClick',
      'canvas:click': 'onCanvasClick'
    }
  },
  onNodeClick(e) {
    const { item, target } = e
    const shape = target
    const shapeName = shape.cfg.name
    let model = item.getModel()
    // 点击收起/展开 icon
    if (shapeName === 'child-count-rect-shape' || shapeName === 'child-count-text-shape') {
      const updatedCollapsed = !model.collapsed
      this.graph.updateItem(item, { collapsed: updatedCollapsed })
      this.graph.layout()
      return
    }
    // 选中节点
    this.graph.getNodes().forEach(node => {
      let _model = node.get('model')
      if (_model.selected) {
        _model.selected = false
        this.graph.updateItem(node, _model, false)
      }
    })
    model.selected = true
    this.graph.updateItem(item, model, false)
    return
  },
  onCanvasClick(e) {
    this.graph.getNodes().forEach(node => {
      let _model = node.get('model')
      if (_model.selected) {
        _model.selected = false
        this.graph.updateItem(node, _model, false)
      }
    })
  }
})
const dataIndTransform = (data) => {
  const changeData = (d) => {
    let data = { ...d }
    data.type = data.isRoot ? 'indentedRoot' : 'indentedNode'
    if (d.children) {
      data.children = d.children.map((child) => changeData(child))
    }
    // 给定 branchColor 和 0-2 层节点 depth
    if (data.children && data.children.length) {
      data.depth = 0
      data.children.forEach((subtree, i) => {
        subtree.branchColor = COLORS[i % COLORS.length]
        // dfs
        let currentDepth = 1
        subtree.depth = currentDepth
        Util.traverseTree(subtree, child => {
          child.branchColor = COLORS[i % COLORS.length]
          if (!child.depth) {
            child.depth = currentDepth + 1
          }
          else currentDepth = subtree.depth
          if (child.children) {
            child.children.forEach(subChild => {
              subChild.depth = child.depth + 1
            })
          }
          if (!data.isRoot) {
            child.collapsed = data.collapsed || false
          }
          return true
        })
      })
    }
    return data
  }
  return changeData(data)
}
// 知识图谱树
G6.registerNode('treeNode', {
  draw: (cfg, group) => {
    const { label, selected, children, isRoot } = cfg
    const rootNode = !!isRoot
    const hasChildren = children && children.length !== 0
    let width = 0
    const height = 28
    const x = 0
    const y = -height / 2
    // 名称文本
    const text = group.addShape('text', {
      attrs: {
        text: label,
        x: x * 2,
        y,
        textAlign: 'left',
        textBaseline: 'top',
        fontFamily: 'PingFangSC-Regular',
      },
      cursor: 'pointer',
      name: 'name-text-shape',
    })
    const textWidth = text.getBBox().width
    width = textWidth + 20
    width = width < 60 ? 60 : width
    if (!rootNode && hasChildren) {
      width += 22
    }
    const keyShapeAttrs = {
      x,
      y,
      width,
      height,
      radius: 4
    }
    const keyShape = group.addShape('rect', {
      attrs: keyShapeAttrs,
      name: 'root-key-shape-rect-shape'
    })
    if (!rootNode) {
      // 底部横线
      group.addShape('path', {
        attrs: {
          path: [
            ['M', x - 1, 0],
            ['L', width, 0],
          ],
          stroke: '#AAB7C4',
          lineWidth: 1,
        },
        name: 'node-path-shape'
      })
    }
    const mainX = x - 10
    const mainY = -height + 15
    if (rootNode) {
      group.addShape('rect', {
        attrs: {
          x: mainX,
          y: mainY,
          width: width + 12,
          height,
          radius: 14,
          fill: systemColor,
          cursor: 'pointer',
        },
        name: 'main-shape'
      })
    }
    let nameColor = 'rgba(0, 0, 0, 0.85)'
    if (selected) {
      nameColor = systemColor
    }
    // 名称
    if (rootNode) {
      group.addShape('text', {
        attrs: {
          text: label,
          x: mainX + 18,
          y: 1,
          textAlign: 'left',
          textBaseline: 'middle',
          fill: '#ffffff',
          fontSize: 12,
          fontFamily: 'PingFangSC-Regular',
          cursor: 'pointer',
        },
        name: 'root-text-shape'
      })
    } else {
      group.addShape('text', {
        attrs: {
          text: label,
          x: mainX + 6,
          y: y - 5,
          textAlign: 'start',
          textBaseline: 'top',
          fill: nameColor,
          fontSize: 12,
          fontFamily: 'PingFangSC-Regular',
          cursor: 'pointer',
        },
        name: 'not-root-text-shape'
      })
    }
    // 子类数量
    if (hasChildren && !rootNode) {
      const childCountHeight = 12
      const childCountX = width - 22
      const childCountY = -childCountHeight / 2
      group.addShape('rect', {
        attrs: {
          width: 22,
          height: 12,
          stroke: systemColor,
          fill: '#fff',
          x: childCountX,
          y: childCountY,
          radius: 6,
          cursor: 'pointer',
        },
        name: 'child-count-rect-shape',
      })
      group.addShape('text', {
        attrs: {
          text: `${children.length}`,
          fill: 'rgba(0, 0, 0, .65)',
          x: childCountX + 11,
          y: childCountY + 12,
          fontSize: 10,
          width: 22,
          textAlign: 'center',
          cursor: 'pointer',
        },
        name: 'child-count-text-shape'
      })
    }
    return keyShape
  }
})
G6.registerEdge('smooth', {
  draw(cfg, group) {
    const { startPoint, endPoint } = cfg
    const hgap = Math.abs(endPoint.x - startPoint.x)
    const path = [
      ['M', startPoint.x, startPoint.y],
      [
        'C',
        startPoint.x + hgap / 4,
        startPoint.y,
        endPoint.x - hgap / 2,
        endPoint.y,
        endPoint.x,
        endPoint.y,
      ],
    ]
    const shape = group.addShape('path', {
      attrs: {
        stroke: '#AAB7C4',
        path,
      },
      name: 'smooth-path-shape',
    })
    return shape
  },
})
G6.registerBehavior('click-item', {
  getEvents() {
    return {
      'node:click': 'onNodeClick',
      'canvas:click': 'onCanvasClick'
    }
  },
  onNodeClick(e) {
    const { item } = e
    let model = item.getModel()
    if (model.children) return
    // 选中节点
    this.graph.getNodes().forEach(node => {
      let _model = node.get('model')
      if (_model.selected) {
        _model.selected = false
        this.graph.updateItem(node, _model, false)
      }
    })
    model.selected = true
    this.graph.updateItem(item, model, false)
    return
  },
  onCanvasClick(e) {
    this.graph.getNodes().forEach(node => {
      let _model = node.get('model')
      if (_model.selected) {
        _model.selected = false
        this.graph.updateItem(node, _model, false)
      }
    })
  }
})
class antvG6Chart extends Component {
  static propTpyes = {
    card: PropTypes.object,
    updateConfig: PropTypes.func,
    deletecomponent: PropTypes.func,
  }
  state = {
    card: null,
    eventListener: null
  }
  UNSAFE_componentWillMount () {
    const { card } = this.props
    if (card.isNew) {
      let _plot = {
        width: card.width || 24,
        height: 400,
        subtype: card.subtype,
        name: card.name
      }
      let _card = {
        uuid: card.uuid,
        type: card.type,
        format: 'array',   // 组件属性 - 数据格式
        pageable: false,   // 组件属性 - 是否可分页
        switchable: true,  // 组件属性 - 数据是否可切换
        width: _plot.width,
        name: _plot.name,
        subtype: card.subtype,
        setting: { interType: 'system' },
        style: {
          borderWidth: '1px', borderColor: 'rgb(217, 217, 217)',
          marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px'
        },
        headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
        columns: [],
        scripts: [],
        search: [],
        action: [],
        plot: _plot,
      }
      if (card.config) {
        let config = fromJS(card.config).toJS()
        _card.plot = config.plot
        _card.plot.name = card.name
        _card.style = config.style
        _card.headerStyle = config.headerStyle
        _card.setting = config.setting
        _card.columns = config.columns
        _card.scripts = config.scripts
      }
      this.updateComponent(_card)
    } else {
      this.setState({
        card: fromJS(card).toJS()
      })
    }
  }
  componentDidMount () {
    MKEmitter.addListener('tabsChange', this.handleTabsChange)
    setTimeout(() => {
      this.viewrender()
    }, 1000)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('tabsChange', this.handleTabsChange)
  }
  handleTabsChange = (parentId) => {
    const { card } = this.state
    if (parentId.indexOf(card.uuid) > -1 || parentId === 'all') {
      let _element = document.getElementById(card.uuid + 'canvas')
      if (_element) {
        _element.innerHTML = ''
      }
      this.$timer && clearTimeout(this.$timer)
      this.$timer = setTimeout(this.viewrender, 100)
    }
  }
  getdata = () => {
    const { card } = this.state
    const setData = (list) => {
      let item = {
        label: list[0],
        id: list[0],
        children: []
      }
      if (!list[1]) {
        delete item.children
        return item
      } else if (!Array.isArray(list[1])) {
        return list.map(m => ({label: m, id: m}))
      }
      for (let i = 1; i < list.length; i++) {
        let cell = setData(list[i])
        if (Array.isArray(cell)) {
          item.children.push(...cell)
        } else {
          item.children.push(cell)
        }
      }
      return item
    }
    let data = setData(MindData)
    if (card.plot.subtype === 'mindmap') {
      if (card.plot.dirField) {
        data.children[0].direction = 'left'
        data.children[2].direction = 'left'
      }
      data.children.forEach(item => {
        if (item.direction === 'left') {
          item.color = card.plot.leftColor || '#26C281'
        } else {
          item.direction = 'right'
          item.color = card.plot.nodeColor || '#1890ff'
        }
      })
      data.collapsed = false
      data.type = 'dice-mind-map-root'
      const collapse = (item) => {
        if (!item.children) return
        item.children.forEach(cell => {
          cell.collapsed = card.plot.collapsed === 'true'
          cell.direction = cell.direction || 'right'
          cell.type = 'dice-mind-map-leaf'
          cell.color = cell.color || item.color
          collapse(cell)
        })
      }
      collapse(data)
    } else if (card.plot.subtype === 'indentTree') {
      data.isRoot = true
      data.collapsed = false
      data.children.forEach(item => {
        item.collapsed = card.plot.collapsed === 'true'
      })
    } else if (card.plot.subtype === 'kapmap') {
      data.isRoot = true
      data.collapsed = false
      if (card.plot.collapsed === 'true') {
        const collapse = (item) => {
          if (!item.children) return
          item.children.forEach(cell => {
            cell.collapsed = true
            collapse(cell)
          })
        }
        collapse(data)
      }
    }
    return data
  }
  viewrender = () => {
    const { card } = this.state
    if (card.plot.subtype === 'mindmap') {
      this.ponitrender()
    } else if (card.plot.subtype === 'indentTree') {
      this.indentrender()
    } else if (card.plot.subtype === 'kapmap') {
      this.kapmaprender()
    }
  }
  kapmaprender = () => {
    const { card } = this.state
    const plot = card.plot
    const data = this.getdata()
    const height = getHeight(plot.height)
    const graph = new G6.TreeGraph({
      container: card.uuid + 'canvas',
      width: this.wrap.scrollWidth - 30,
      height: height,
      modes: {
        default: [
          {
            type: 'collapse-expand',
          },
          'drag-canvas',
          'zoom-canvas',
          'click-item'
        ],
      },
      defaultNode: {
        type: 'treeNode',
        anchorPoints: [
          [0, 0.5],
          [1, 0.5],
        ],
      },
      defaultEdge: {
        type: 'smooth',
      },
      layout: {
        type: 'compactBox',
        direction: 'LR',
        getId: function getId(d) {
          return d.id
        },
        getHeight: function getHeight() {
          return 16
        },
        getWidth: function getWidth(d) {
          const labelWidth = G6.Util.getTextSize(d.label, 12)[0]
          const width = 60 + labelWidth
          return width
        },
        getVGap: function getVGap() {
          return 15
        },
        getHGap: function getHGap() {
          return 30
        }
      }
    })
    graph.data(data)
    graph.render()
    graph.fitView()
    if (plot.collapsed === 'true') {
      graph.zoomTo(1, { x: 0, y: height / 2 })
    }
  }
  indentrender = () => {
    const { card } = this.state
    const plot = card.plot
    const data = this.getdata()
    const tree = new G6.TreeGraph({
      container: card.uuid + 'canvas',
      width: this.wrap.scrollWidth - 30,
      height: getHeight(plot.height),
      layout: {
        type: 'indented',
        direction: 'LR',
        isHorizontal: true,
        indent: 40,
        getHeight: (d) => {
          if (d.isRoot) {
            return 30
          }
          if (d.collapsed && d.children && d.children.length) {
            return 36
          }
          return 22
        },
        getVGap: () => {
          return 10
        },
      },
      defaultEdge: {
        type: 'indentedEdge',
        style: {
          lineWidth: 2,
          radius: 16
        }
      },
      minZoom: 0.5,
      modes: {
        default: [
          'drag-canvas',
          'wheel-scroll',
          'hover-node',
          'click-node'
        ]
      }
    })
    tree.on('afterrender', e => {
      tree.getEdges().forEach(edge => {
        const targetNode = edge.getTarget().getModel()
        const color = targetNode.branchColor
        tree.updateItem(edge, { color })
      })
      setTimeout(() => {
        tree.moveTo(32, 32)
        tree.zoomTo(0.7)
      }, 16)
    })
    tree.data(dataIndTransform(data))
    tree.render()
  }
  /**
   * @description 散点图
   */
  ponitrender = () => {
    const { card } = this.state
    const plot = card.plot
    const data = this.getdata()
    const width = this.wrap.scrollWidth - 30
    const height = getHeight(plot.height)
    let modes = ['drag-canvas', 'zoom-canvas', 'dice-mindmap']
    if (plot.collapsed === 'true') {
      modes = [{ type: 'collapse-expand' },'drag-canvas', 'zoom-canvas', 'dice-mindmap']
    }
    const tree = new G6.TreeGraph({
      container: card.uuid + 'canvas',
      width: width,
      height: height,
      fitView: true,
      layout: {
        type: 'mindmap',
        direction: 'H',
        getHeight: () => {
          return 16
        },
        getWidth: (node) => {
          return node.level === 0 ?
            Util.getTextSize(node.label, 16)[0] + 12 :
            Util.getTextSize(node.label, 12)[0]
        },
        getVGap: () => {
          return 10
        },
        getHGap: () => {
          return 60
        },
        getSide: (node) => {
          return node.data.direction
        }
      },
      defaultEdge: {
        type: 'cubic-horizontal',
        style: {
          lineWidth: 2
        }
      },
      minZoom: 0.5,
      modes: {
        default: modes
      }
    })
    tree.data(data)
    tree.render()
    if (plot.collapsed === 'true' && plot.dirField) {
      tree.zoomTo(1, { x: width / 2, y: height / 2 })
    } else if (plot.collapsed === 'true') {
      tree.zoomTo(1, { x: 0, y: height / 2 })
    }
  }
  updateComponent = (card) => {
    if (this.state.card && (!is(fromJS(card.plot), fromJS(this.state.card.plot)) || !is(fromJS(card.style), fromJS(this.state.card.style)))) {
      let _element = document.getElementById(card.uuid + 'canvas')
      if (_element) {
        _element.innerHTML = ''
      }
      this.$timer && clearTimeout(this.$timer)
      this.$timer = setTimeout(() => {
        this.viewrender()
      }, 150)
    }
    card.width = card.plot.width
    card.name = card.plot.name
    card.subtype = card.plot.subtype
    card.$c_ds = true
    card.errors = checkComponent(card)
    if (card.errors.length === 0) {
      card.$tables = getTables(card)
    }
    if (!card.plot.valueField) {
      card.errors.push({ level: 0, detail: '图表信息尚未设置!'})
    } else {
      let columns = card.columns.map(c => c.field)
      if (!columns.includes(card.plot.valueField)) {
        card.errors.push({ level: 0, detail: '值字段在字段集中不存在'})
      } else if (!columns.includes(card.plot.labelField)) {
        card.errors.push({ level: 0, detail: '文本字段在字段集中不存在'})
      } else if (!columns.includes(card.plot.parentField)) {
        card.errors.push({ level: 0, detail: '上级字段在字段集中不存在'})
      }
    }
    this.setState({
      card: card
    })
    this.props.updateConfig(card)
  }
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    this.updateComponent(_card)
  }
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.updateComponent(_card)
      })
    }
  }
  render() {
    const { card } = this.state
    let _style = resetStyle(card.style)
    return (
      <div className="menu-scatter-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <ChartCompileForm config={card} plotchange={this.updateComponent}/>
            <CopyComponent type="antvG6" card={card}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(card.uuid)}/>
            <SettingComponent config={card} updateConfig={this.updateComponent}/>
          </div>
        } trigger="hover">
          <ToolOutlined/>
        </Popover>
        <NormalHeader config={card} updateComponent={this.updateComponent}/>
        <div className="canvas" style={{minHeight: card.plot.height}} id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
        <div className="component-name">
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
              document.body.removeChild(oInput)
              message.success('复制成功。')
            }}>{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
}
export default antvG6Chart
src/menu/components/chart/antv-X6/index.scss
New file
@@ -0,0 +1,68 @@
.menu-scatter-chart-edit-box {
  position: relative;
  box-sizing: border-box;
  background: #ffffff;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  .canvas {
    margin: 0px;
    padding: 15px;
    letter-spacing: 0px;
  }
  .chart-header {
    position: relative;
    height: 45px;
    border-bottom: 1px solid #e8e8e8;
    overflow: hidden;
    padding-right: 35px;
    .chart-title {
      text-decoration: inherit;
      font-weight: inherit;
      font-style: inherit;
      float: left;
      line-height: 45px;
      margin-left: 10px;
      position: relative;
      z-index: 1;
    }
  }
  >.anticon-tool {
    position: absolute;
    right: 1px;
    top: 1px;
    z-index: 3;
    font-size: 16px;
    padding: 5px;
    cursor: pointer;
    color: rgba(0, 0, 0, 0.85);
    background: rgba(255, 255, 255, 0.55);
  }
  .model-menu-action-list {
    position: absolute;
    right: 0px;
    top: 30px;
    z-index: 4;
    font-size: 16px;
    .ant-row .anticon-plus {
      float: right;
    }
    .page-card {
      float: right;
    }
  }
  .normal-header + .canvas + .model-menu-action-list {
    top: 45px;
  }
}
.menu-scatter-chart-edit-box:hover {
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/code/sandbox/codecontent/index.jsx
@@ -27,10 +27,13 @@
  componentDidMount () {
    const { config } = this.props
    if (config.js && config.wrap.compileMode !== 'custom') {
    if (config.js) {
      try {
        // eslint-disable-next-line no-eval
        eval(config.js)
        // eval(config.js)
        // eslint-disable-next-line
        let evalfunc = eval('(true && function (data) {' + config.js + '})')
        evalfunc([])
      } catch (e) {
        message.warning(config.name + 'JS 执行失败!')
        console.warn(config.name + e)
@@ -53,10 +56,11 @@
      }
    }
    if (config.html !== nextProps.config.html || config.js !== nextProps.config.js) {
      if (nextProps.config.js && nextProps.config.wrap.compileMode !== 'custom') {
      if (nextProps.config.js) {
        try {
          // eslint-disable-next-line no-eval
          eval(nextProps.config.js)
          let evalfunc = eval('(true && function (data) {' + nextProps.config.js + '})')
          evalfunc([])
        } catch (e) {
          message.warning(config.name + 'JS 执行失败!')
          console.warn(config.name + e)
src/menu/components/code/sandbox/options.jsx
@@ -46,21 +46,21 @@
        {value: 'dynamic', label: '动态'},
        {value: 'static', label: '静态'},
      ],
      controlFields: [
        {field: 'compileMode', values: ['dynamic']}
      ]
      // controlFields: [
      //   {field: 'compileMode', values: ['dynamic']}
      // ]
    },
    {
      type: 'radio',
      field: 'compileMode',
      label: '编译方式',
      initval: wrap.compileMode || 'replace',
      required: false,
      options: [
        {value: 'replace', label: '字段替换'},
        {value: 'custom', label: '自定义'},
      ]
    },
    // {
    //   type: 'radio',
    //   field: 'compileMode',
    //   label: '编译方式',
    //   initval: wrap.compileMode || 'replace',
    //   required: false,
    //   options: [
    //     {value: 'replace', label: '字段替换'},
    //     {value: 'custom', label: '自定义'},
    //   ]
    // },
    {
      type: 'radio',
      field: 'permission',
src/menu/components/form/simple-form/index.jsx
@@ -357,7 +357,7 @@
        })
      }
      if (item.type === 'switch') {
      if (item.type === 'switch' || item.type === 'check') {
        _linksupFields.push({
          field: item.field,
          label: item.label
src/menu/components/form/step-form/index.jsx
@@ -459,7 +459,7 @@
        })
      }
      if (item.type === 'switch') {
      if (item.type === 'switch' || item.type === 'check') {
        _linksupFields.push({
          field: item.field,
          label: item.label
src/menu/components/form/tab-form/index.jsx
@@ -464,7 +464,7 @@
        })
      }
      if (item.type === 'switch') {
      if (item.type === 'switch' || item.type === 'check') {
        _linksupFields.push({
          field: item.field,
          label: item.label
src/menu/components/module/voucher/voucherTable/index.scss
@@ -159,103 +159,4 @@
  td.pointer {
    position: relative;
  }
  td.pointer {
    .mk-mask {
      display: none;
      cursor: pointer;
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
    }
  }
}
.edit-custom-table.editable {
  td {
    background-color: #ffffff!important;
  }
  td.pointer .mk-mask {
    display: block;
  }
  .mk-operation {
    display: none;
  }
  .ant-table-placeholder {
    display: none;
  }
}
.edit-custom-table:not(.fixed-height) {
  .ant-table-body::-webkit-scrollbar {
    width: 8px;
    height: 10px;
  }
  ::-webkit-scrollbar-thumb {
    border-radius: 5px;
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
    background: rgba(0, 0, 0, 0.13);
  }
  ::-webkit-scrollbar-track {/*滚动条里面轨道*/
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
    border-radius: 3px;
    border: 1px solid rgba(0, 0, 0, 0.07);
    background: rgba(0, 0, 0, 0);
  }
}
.edit-custom-table.fixed-height {
  .ant-table-body {
    border-bottom: 1px solid rgba(0, 0, 0, .05);
    .ant-table-fixed {
      border-bottom: 0;
    }
  }
}
.edit-custom-table.hidden {
  thead {
    display: none;
  }
}
.edit-custom-table.ghost {
  .ant-table-thead > tr {
    > th {
      color: inherit;
      background: transparent;
      .ant-table-column-sorter .ant-table-column-sorter-inner {
        color: inherit;
      }
    }
    > th:hover {
      background: transparent;
    }
  }
  .ant-table-body {
    overflow-x: auto;
    tr {
      td {
        background: transparent!important;
      }
    }
    tr:hover td {
      background: transparent!important;
    }
  }
}
.image-scale-modal {
  width: 70vw;
  min-height: 80vh;
  top: 10vh;
  .ant-modal-body {
    min-height: calc(80vh - 110px);
    line-height: calc(80vh - 160px);
    text-align: center;
  }
  .ant-modal-footer {
    text-align: center;
    span {
      display: inline-block;
      color: #1890ff;
      padding: 5px 15px;
      cursor: pointer;
    }
  }
}
src/menu/components/search/main-search/dragsearch/card.jsx
@@ -1,6 +1,6 @@
import React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { Select, DatePicker, Input, Popover, Form } from 'antd'
import { Select, DatePicker, Input, Popover, Form, Switch, Checkbox } from 'antd'
import { CopyOutlined, EditOutlined, CloseOutlined } from '@ant-design/icons'
import moment from 'moment'
@@ -109,6 +109,10 @@
    formItem = (<DateGroup card={card} />)
  } else if (card.type === 'checkcard') {
    formItem = <CheckCard config={card} />
  } else if (card.type === 'switch') {
    formItem = (<Switch checkedChildren={card.openText || ''} unCheckedChildren={card.closeText || ''} style={{marginTop: '8px'}} checked={card.initval === card.openVal}/>)
  } else if (card.type === 'check') {
    formItem = <Checkbox style={{lineHeight: '36px'}} checked={card.initval === card.openVal}>{card.checkTip || ''}</Checkbox>
  }
  return (
src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -206,6 +206,9 @@
        }
      } else if (intertype === 'inner') {
        shows.push('innerFunc', 'output')
        if (Ot === 'requiredOnce') { // 前置函数
          shows.push('preFunc')
        }
        reRequired.innerFunc = true
      } else {
        shows.push('sql', 'sqlType', 'output')
@@ -763,7 +766,7 @@
            { pattern: /^[a-zA-Z0-9@_]+$/, message: '表名只可使用字母、数字以及_' },
            { max: formRule.func.max, message: formRule.func.maxMessage }
          )
        } else if (item.key === 'outerFunc' || item.key === 'callbackFunc') {
        } else if (item.key === 'outerFunc' || item.key === 'callbackFunc' || item.key === 'preFunc') {
          rules.push(
            { pattern: formRule.func.pattern, message: formRule.func.message },
            { max: formRule.func.max, message: formRule.func.maxMessage }
@@ -921,6 +924,59 @@
          values.modal = card.modal || null
          values.config = card.config || null
          if (card.OpenType === 'excelOut' && values.OpenType === 'excelIn') {
            if (values.verify && values.verify.columns && values.verify.columns.length > 0) {
              values.verify.columns = values.verify.columns.map(col => {
                col.required = col.required || 'true'
                col.type = col.type || 'Nvarchar(50)'
                col.import = col.import || 'true'
                if (col.type === 'text' || col.type === 'image') {
                  col.type = 'Nvarchar(50)'
                } else if (col.type === 'number') {
                  col.type = 'Decimal(18,2)'
                }
                if (/^Nvarchar/ig.test(col.type)) {
                  col.limit = col.type.match(/\d+/)[0]
                } else if (/^Decimal/ig.test(col.type)) {
                  col.limit = col.type.match(/\d+/ig)[1]
                } else {
                  col.limit = ''
                }
                delete col.output
                delete col.abs
                delete col.Width
                return col
              })
              values.verify.sheet = values.verify.sheet || 'Sheet1'
            }
          } else if (card.OpenType === 'excelIn' && values.OpenType === 'excelOut') {
            if (values.verify && values.verify.columns && values.verify.columns.length > 0) {
              values.verify.columns = values.verify.columns.map(col => {
                col.type = col.type || 'text'
                col.output = col.output || 'true'
                col.required = col.required || 'false'
                col.Width = 20
                if (!['text', 'image', 'number'].includes(col.type)) {
                  if (/^Decimal/ig.test(col.type)) {
                    col.type = 'number'
                  } else {
                    col.type = 'text'
                  }
                }
                delete col.import
                return col
              })
            }
          }
          if (values.OpenType === 'form') {
            if (values.formType !== 'scan') {
              if (/^(0|[1-9]\d*)$/.test(values.openVal) && /^(0|[1-9]\d*)$/.test(values.closeVal)) {
src/menu/components/share/actioncomponent/formconfig.jsx
@@ -97,7 +97,6 @@
    { value: 'print', text: '标签打印' },
    { value: 'refund', text: '退款' },
    { value: 'closetab', text: '标签关闭' },
    { value: 'changeuser', text: '切换用户' },
    { value: 'megvii', text: '旷视面板机' },
    { value: 'filezip', text: '文件压缩包' },
  ]
@@ -150,7 +149,6 @@
    opentypes = opentypes.filter(item => item.value !== 'tab')
    funTypes = [
      { value: 'print', text: '标签打印' },
      { value: 'changeuser', text: '切换用户' },
    ]
    pageTemps = [
      { value: 'linkpage', text: '关联菜单' },
@@ -165,6 +163,19 @@
      pageTemps.unshift({ value: 'billprintTemp', text: '单据打印模板' })
    }
  }
  if (card.funcType === 'changeuser') { // 原类型支持
    funTypes.unshift({ value: 'changeuser', text: '切换用户' })
  }
  if (config.subtype === 'editable') { // 编辑表的添加、删除
    funTypes.push(
      { value: 'addline', text: '增加行(编辑表)' },
      { value: 'delline', text: '删除行(编辑表)' }
    )
  } else if (card.funcType === 'addline' || card.funcType === 'delline') {
    card.funcType = ''
  }
  
  if (type === 'chart' && appType !== 'mob') {
    opentypes = opentypes.filter(item => item.value === 'excelIn' || item.value === 'excelOut')
@@ -176,7 +187,10 @@
  let refresh = []
  if (viewType === 'popview') { // 弹窗标签
    opentypes = opentypes.filter(item => item.value !== 'popview' && item.value !== 'funcbutton')
    opentypes = opentypes.filter(item => item.value !== 'popview')
    funTypes = funTypes.filter(item => item.value !== 'print')
    refresh.push({
      value: 'closepoptab', // 关闭弹窗标签
      text: '关闭弹窗'
@@ -960,6 +974,15 @@
      }]
    },
    {
      type: 'text',
      key: 'preFunc',
      label: '前置函数',
      initVal: card.preFunc || '',
      tooltip: '前置函数执行完成后,结果会传入内部函数中,此时内部函数会异步执行;当前置函数返回中ErrCode等于-1时,将不再执行内部函数。',
      required: false,
      forbid: appType === 'mob'
    },
    {
      type: 'radio',
      key: 'control',
      label: '按钮控制',
@@ -1213,10 +1236,13 @@
    { value: 'print', text: '标签打印' },
    { value: 'refund', text: '退款' },
    { value: 'closetab', text: '标签关闭' },
    { value: 'changeuser', text: '切换用户' },
    { value: 'megvii', text: '旷视面板机' },
    { value: 'filezip', text: '文件压缩包' },
  ]
  if (card.funcType === 'changeuser') { // 原类型支持
    funTypes.unshift({ value: 'changeuser', text: '切换用户' })
  }
  let menulist = sessionStorage.getItem('fstMenuList')
  if (menulist) {
@@ -1231,7 +1257,10 @@
  let refresh = []
  if (viewType === 'popview') { // 弹窗标签
    opentypes = opentypes.filter(item => item.value !== 'popview' && item.value !== 'funcbutton')
    opentypes = opentypes.filter(item => item.value !== 'popview')
    funTypes = funTypes.filter(item => item.value !== 'print')
    refresh.push({
      value: 'closepoptab', // 关闭弹窗标签
      text: '关闭弹窗'
@@ -1804,6 +1833,14 @@
      }]
    },
    {
      type: 'text',
      key: 'preFunc',
      label: '前置函数',
      initVal: card.preFunc || '',
      tooltip: '前置函数执行完成后,结果会传入内部函数中,此时内部函数会异步执行;当前置函数返回中ErrCode等于-1时,将不再执行内部函数。',
      required: false
    },
    {
      type: 'radio',
      key: 'control',
      label: '按钮控制',
src/menu/components/share/actioncomponent/index.jsx
@@ -60,7 +60,7 @@
  }
  componentDidMount () {
    MKEmitter.addListener('revert', this.revert)
    MKEmitter.addListener('revertBtn', this.revertBtn)
    MKEmitter.addListener('addButton', this.addButton)
    MKEmitter.addListener('submitModal', this.handleSave)
  }
@@ -76,12 +76,12 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('revert', this.revert)
    MKEmitter.removeListener('revertBtn', this.revertBtn)
    MKEmitter.removeListener('addButton', this.addButton)
    MKEmitter.removeListener('submitModal', this.handleSave)
  }
  revert = (id) => {
  revertBtn = (id) => {
    if (id && id !== this.props.config.uuid) return
    this.setState({
@@ -609,6 +609,24 @@
          return item.uuid !== id
        })
      })
    } else if (config.type === 'card' && config.subcards) {
      config.subcards.forEach(scard => {
        scard.elements = scard.elements.filter(item => {
          if (item.uuid === id) {
            btn = item
            _col = scard
          }
          return item.uuid !== id
        })
        scard.backElements = scard.backElements.filter(item => {
          if (item.uuid === id) {
            btn = item
            _col = scard
          }
          return item.uuid !== id
        })
        return scard
      })
    }
    if (!btn) return
src/menu/components/share/searchcomponent/dragsearch/card.jsx
@@ -1,6 +1,6 @@
import React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { Select, DatePicker, Input, Popover, Form } from 'antd'
import { Select, DatePicker, Input, Popover, Form, Switch, Checkbox } from 'antd'
import { EditOutlined, CopyOutlined, CloseOutlined } from '@ant-design/icons'
import moment from 'moment'
@@ -107,6 +107,10 @@
    />
  } else if (card.type === 'group') {
    formItem = <DateGroup card={card} />
  } else if (card.type === 'switch') {
    formItem = (<Switch checkedChildren={card.openText || ''} unCheckedChildren={card.closeText || ''} style={{marginTop: '8px'}} checked={card.initval === card.openVal}/>)
  } else if (card.type === 'check') {
    formItem = <Checkbox style={{lineHeight: '36px'}} checked={card.initval === card.openVal}>{card.checkTip || ''}</Checkbox>
  }
  let labelwidth = card.labelwidth || 33.3
src/menu/components/table/base-table/columns/editColumn/index.jsx
@@ -96,8 +96,12 @@
          this.props.form.setFieldsValue({IsSort: 'false'})
        } else if (value === 'text' || value === 'number') {
          this.props.form.setFieldsValue({perspective: ''})
        } else if (value === 'action' || value === 'colspan') {
        } else if (value === 'colspan') {
          this.props.form.setFieldsValue({Align: 'center'})
        } else if (value === 'action') {
          this.props.form.setFieldsValue({Align: 'center', label: '操作'})
        } else if (value === 'index') {
          this.props.form.setFieldsValue({label: '序号'})
        }
      })
    } else if (key === 'field') {
src/menu/components/table/base-table/columns/index.jsx
@@ -46,7 +46,8 @@
    return !is(fromJS(this.props.column), fromJS(nextProps.column)) ||
      !is(fromJS(this.props.fields), fromJS(nextProps.fields)) ||
      this.props.index !== nextProps.index
      this.props.index !== nextProps.index ||
      window.GLOB.columnId === nextProps.column.uuid || window.GLOB.precolumnId === nextProps.column.uuid
  }
  render() {
@@ -57,6 +58,10 @@
      if (column.Width) {
        style.width = column.Width
        style.minWidth = column.Width
      }
      if (window.GLOB.columnId === column.uuid) {
        style.color = '#1890ff'
      }
      return connectDragSource(
@@ -83,6 +88,11 @@
        style.width = column.Width
        style.minWidth = column.Width
      }
      if (window.GLOB.columnId === column.uuid) {
        style.color = '#1890ff'
      }
      return (
        <th {...restProps} style={style} key={column.uuid} onDoubleClick={() => this.props.editColumn(column)}>
          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
@@ -354,7 +364,7 @@
        config.action = config.action.filter(item => item.uuid !== btn.uuid)
        setTimeout(() => {
          MKEmitter.emit('revert', config.uuid)
          MKEmitter.emit('revertBtn', config.uuid)
        }, 200)
      }
@@ -453,6 +463,9 @@
      }
    }
    window.GLOB.precolumnId = window.GLOB.columnId || ''
    window.GLOB.columnId = col.uuid
    this.setState({card: null})
    this.updateCol(col)
  }
src/menu/components/table/base-table/columns/index.scss
@@ -102,8 +102,11 @@
  .ant-table-small > .ant-table-content .ant-table-thead > tr > th {
    background-color: #fafafa!important;
  }
  .ant-table-small.ant-table-bordered {
    border-right: 1px solid #e8e8e8;
  }
  table, tr, th, td {
  table, tr, th, td, .ant-table-small {
    border-color: var(--mk-table-border-color)!important;
  }
  table tr {
src/menu/components/table/base-table/index.jsx
@@ -142,7 +142,9 @@
      item.cols = item.cols.filter(a => !a.origin)
      delete item.isNew
      this.setState({card: item}, () => { MKEmitter.emit('revert') })
      this.setState({card: null}, () => {
        this.setState({card: item})
      })
    }
  }
@@ -346,6 +348,8 @@
    const { card } = this.state
    let options = ['action', 'search', 'form', 'cols']
    if (!card) return null
    return (
      <div className="menu-base-table-edit-box" style={card.style} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
src/menu/components/table/base-table/options.jsx
@@ -153,7 +153,7 @@
      field: 'height',
      label: '表格高度',
      initval: wrap.height || '',
      tooltip: '表格高度,空值时高度自适应。',
      tooltip: '表格高度,空值时高度自适应。注:小于等于100时为高度的百分比。',
      min: 10,
      max: 3000,
      precision: 0,
@@ -171,6 +171,16 @@
    },
    {
      type: 'select',
      field: 'tipField',
      label: '信息提示',
      initval: wrap.tipField || '',
      tooltip: '鼠标悬浮于行上方时的提示信息。',
      required: false,
      allowClear: true,
      options: columns
    },
    {
      type: 'select',
      field: 'controlField',
      label: '禁用字段',
      initval: wrap.controlField || '',
src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
@@ -163,21 +163,21 @@
        text: '右对齐'
      }]
    },
    {
      type: 'radio',
      key: 'sum',
      label: '显示合计',
      initVal: card.sum || 'false',
      tooltip: '合计信息只在使用系统数据源时有效。',
      required: false,
      options: [{
        value: 'true',
        text: '是'
      }, {
        value: 'false',
        text: '否'
      }]
    },
    // {
    //   type: 'radio',
    //   key: 'sum',
    //   label: '显示合计',
    //   initVal: card.sum || 'false',
    //   tooltip: '合计信息只在使用系统数据源时有效。',
    //   required: false,
    //   options: [{
    //     value: 'true',
    //     text: '是'
    //   }, {
    //     value: 'false',
    //     text: '否'
    //   }]
    // },
    {
      type: 'radio',
      key: 'editable',
@@ -259,16 +259,16 @@
        text: '数据源'
      }]
    },
    {
      type: 'select',
      key: 'editField',
      label: '编辑字段',
      initVal: card.editField || '',
      tooltip: '当值与提示文字不同时,可额外添加编辑字段,作为实际值的录入字段。',
      allowClear: true,
      required: false,
      options: fields
    },
    // {
    //   type: 'select',
    //   key: 'editField',
    //   label: '编辑字段',
    //   initVal: card.editField || '',
    //   tooltip: '当值与提示文字不同时,可额外添加编辑字段,作为实际值的录入字段。',
    //   allowClear: true,
    //   required: false,
    //   options: fields
    // },
    {
      type: 'options',
      key: 'options',
@@ -370,7 +370,7 @@
      type: 'select',
      key: 'enter',
      label: '回车切换',
      initVal: card.enter || '$next',
      initVal: card.enter || '$noAct',
      tooltip: '包括文本或数值回车事件、下拉菜单选中事件、开关切换事件。',
      options: editCols
    },
@@ -519,6 +519,21 @@
      options: fields
    },
    {
      type: 'radio',
      key: 'noValue',
      label: '空值',
      initVal: card.noValue || 'show',
      tooltip: '当值为0时是否显示',
      required: false,
      options: [{
        value: 'show',
        text: '显示'
      }, {
        value: 'hide',
        text: '隐藏'
      }]
    },
    {
      type: 'multiselect',
      key: 'blacklist',
      label: '黑名单',
src/menu/components/table/edit-table/columns/editColumn/index.jsx
@@ -1,9 +1,12 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Form, Row, Col, Input, Select, InputNumber, Radio, Tooltip, Modal, notification } from 'antd'
import { Form, Row, Col, Input, Select, InputNumber, Radio, Tooltip, Modal, notification, Popover } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons'
import moment from 'moment'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import { getColumnForm } from './formconfig'
import { formRule } from '@/utils/option.js'
import CodeMirror from '@/templates/zshare/codemirror'
@@ -14,12 +17,12 @@
const { TextArea } = Input
const columnTypeOptions = {
  text: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'textFormat', 'editable', 'initval', 'blacklist'],
  number: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'decimal', 'format', 'prefix', 'postfix', 'editable', 'initval', 'sum', 'blacklist'],
  number: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'decimal', 'format', 'prefix', 'postfix', 'editable', 'initval', 'sum', 'blacklist', 'noValue'],
  textarea: ['label', 'field', 'type', 'Align', 'Hide', 'Width', 'prefix', 'initval', 'postfix', 'blacklist'],
  custom: ['label', 'type', 'Align', 'Width', 'blacklist'],
  colspan: ['label', 'type', 'Align', 'Hide', 'blacklist'],
  action: ['label', 'type', 'Align', 'Width'],
  formula: ['label', 'type', 'Align', 'Hide', 'Width', 'prefix', 'postfix', 'eval', 'formula', 'blacklist'],
  formula: ['label', 'type', 'Align', 'Hide', 'Width', 'prefix', 'postfix', 'eval', 'formula', 'blacklist', 'noValue'],
  index: ['label', 'type', 'Align', 'Width']
}
@@ -35,6 +38,7 @@
  state = {
    visible: false,
    loading: false,
    formlist: null,
    transfield: {}
  }
@@ -107,6 +111,11 @@
      formlist: formlist.map(item => {
        item.hidden = !_options.includes(item.key)
        if (item.key === 'formula') {
          item.fields = this.props.fields.map(col => col.field)
          item.fields = item.fields.join(', ')
        }
        return item
      })
    })
@@ -128,6 +137,11 @@
    if (key === 'type') {
      let _options = this.getOptions()
      let _field = ''
      if (value === 'formula') {
        _field = this.props.form.getFieldValue('field') || ''
      }
      this.setState({
        formlist: this.state.formlist.map(item => {
          item.initVal = this.column[item.key] || item.initVal
@@ -136,8 +150,14 @@
          return item
        })
      }, () => {
        if (value === 'action' || value === 'colspan') {
        if (value === 'colspan') {
          this.props.form.setFieldsValue({Align: 'center'})
        } else if (value === 'formula' && _field) {
          this.props.form.setFieldsValue({formula: '@' + _field + '@'})
        } else if (value === 'action') {
          this.props.form.setFieldsValue({Align: 'center', label: '操作'})
        } else if (value === 'index') {
          this.props.form.setFieldsValue({label: '序号'})
        }
      })
    } else if (key === 'field') {
@@ -314,6 +334,28 @@
          { required: item.required, message: '请输入' + item.label + '!' }
        ]
        if (item.key === 'formula') {
          fields.push(
            <Col span={span} key={index}>
              <Form.Item className={className} extra={extra} label={item.tooltip ?
                <Tooltip placement="topLeft" title={item.tooltip}>
                  <QuestionCircleOutlined className="mk-form-tip" />
                  {item.label}
                </Tooltip> : item.label
              }>
                {getFieldDecorator(item.key, {
                  initialValue: initVal,
                  rules: rules
                })(<TextArea rows={item.rows || 2}/>)}
              </Form.Item>
              <Popover overlayClassName="formula-fields" placement="topLeft" title="" content={<div>{item.fields}</div>} trigger="click">
                <span className="formula-icon">字段集</span>
              </Popover>
            </Col>
          )
          return
        }
        content = <TextArea rows={item.rows || 2}/>
      } else if (item.type === 'codemirror') {
        rules = [
@@ -367,22 +409,70 @@
            return
          }
        }
        this.setState({visible: false, formlist: null})
        this.props.submitCol(values)
        this.column = null
        if (values.dataSource && /\s/.test(values.dataSource)) {
          let error = Utils.verifySql(values.dataSource)
          if (error) {
            notification.warning({
              top: 92,
              message: '数据源中不可使用' + error,
              duration: 5
            })
            return
          }
          this.setState({
            loading: true
          })
          let param = {
            func: 's_debug_sql',
            exec_type: 'y',
            LText: `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)
              ${values.dataSource}`
          }
          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
          param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
          param.LText = param.LText.replace(/\n/g, ' ')
          param.LText = Utils.formatOptions(param.LText)
          param.secretkey = Utils.encrypt('', param.timestamp)
          if (window.GLOB.mainSystemApi && values.database === 'sso') {
            param.rduri = window.GLOB.mainSystemApi
          }
          Api.genericInterface(param).then(result => {
            if (result.status) {
              this.setState({visible: false, loading: false, formlist: null})
              this.props.submitCol(values)
              this.column = null
            } else {
              this.setState({loading: false})
              Modal.error({
                title: result.message
              })
            }
          })
        } else {
          this.setState({visible: false, formlist: null})
          this.props.submitCol(values)
          this.column = null
        }
      }
    })
  }
  editModalCancel = () => {
    this.setState({visible: false, formlist: null})
    this.setState({visible: false, loading: false, formlist: null})
    this.props.cancelCol()
  }
  render() {
    const { visible } = this.state
    const { visible, loading } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -403,6 +493,7 @@
          maskClosable={false}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          confirmLoading={loading}
          destroyOnClose
        >
          <Form {...formItemLayout} className="commontable-column-form" id="edit-table-column-winter">
src/menu/components/table/edit-table/columns/editColumn/index.scss
@@ -17,6 +17,14 @@
      height: 150px;
    }
  }
  .formula-icon {
    position: absolute;
    bottom: 5px;
    right: 15px;
    cursor: pointer;
    font-size: 12px;
    color: #1890ff;
  }
  .ant-form-extra {
    padding-top: 0px;
    min-height: 0px;
@@ -35,3 +43,13 @@
    float: none;
  }
}
.formula-fields {
  z-index: 1200!important;
  .ant-popover-inner-content {
    div {
      max-width: 750px;
      word-break: break-all;
    }
  }
}
src/menu/components/table/edit-table/columns/index.jsx
@@ -47,7 +47,8 @@
    return !is(fromJS(this.props.column), fromJS(nextProps.column)) ||
      !is(fromJS(this.props.fields), fromJS(nextProps.fields)) ||
      this.props.index !== nextProps.index
      this.props.index !== nextProps.index ||
      window.GLOB.columnId === nextProps.column.uuid || window.GLOB.precolumnId === nextProps.column.uuid
  }
  render() {
@@ -64,6 +65,10 @@
      if (column.Width) {
        style.width = column.Width
        style.minWidth = column.Width
      }
      if (window.GLOB.columnId === column.uuid) {
        style.color = '#1890ff'
      }
      return connectDragSource(
@@ -90,6 +95,9 @@
      if (column.Width) {
        style.width = column.Width
        style.minWidth = column.Width
      }
      if (window.GLOB.columnId === column.uuid) {
        style.color = '#1890ff'
      }
      return (
@@ -339,7 +347,7 @@
        config.action = config.action.filter(item => item.uuid !== btn.uuid)
        setTimeout(() => {
          MKEmitter.emit('revert', config.uuid)
          MKEmitter.emit('revertBtn', config.uuid)
        }, 200)
      }
@@ -415,6 +423,9 @@
      col.style = card.style || {}
      col.elements = card.type === 'action' ? (card.elements || []) : []
    }
    window.GLOB.precolumnId = window.GLOB.columnId || ''
    window.GLOB.columnId = col.uuid
    this.setState({card: null})
    this.updateCol(col)
@@ -538,7 +549,6 @@
      } else {
        cell.type = 'number'
        cell.format = 'none'
        cell.sum = 'false'
        cell.decimal = item.decimal || 0
        cell.Width = 80
      }
src/menu/components/table/edit-table/columns/index.scss
@@ -15,11 +15,14 @@
    max-width: 60px;
  }
  .submit-btn {
    min-height: 24px;
    min-height: 28px;
    min-width: 65px;
    height: auto;
    margin-right: 10px;
    margin-bottom: 10px!important;
    background-color: #1890ff;
    border-width: 0;
    top: -2px;
  }
  .ant-table-thead > tr > th .ant-table-header-column .ant-table-column-sorters > .ant-table-column-title {
    position: unset;
@@ -131,8 +134,11 @@
  .ant-table-small > .ant-table-content .ant-table-thead > tr > th {
    background-color: #fafafa!important;
  }
  .ant-table-small.ant-table-bordered {
    border-right: 1px solid #e8e8e8;
  }
  table, tr, th, td {
  table, tr, th, td, .ant-table-small {
    border-color: var(--mk-table-border-color)!important;
  }
  table tr {
src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx
@@ -197,7 +197,7 @@
              this.props.scriptsChange(values)
            })
            this.props.form.setFieldsValue({
              sql: ''
              sql: ' '
            })
          } else {
            this.setState({loading: false})
@@ -243,6 +243,9 @@
    }
    let _sql = this.props.form.getFieldValue('sql')
    if (/^\s+$/.test(_sql)) {
      _sql = ''
    }
    if (_sql) {
      _sql = _sql + ` 
src/menu/components/table/edit-table/columns/tableIn/index.jsx
@@ -1,8 +1,8 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Form, Tabs, Row, Col, Input, Button, Table, Popconfirm, notification, Modal, message, InputNumber, Radio, Typography } from 'antd'
import { StopTwoTone, CheckCircleTwoTone, EditOutlined, ArrowUpOutlined, ArrowDownOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
import { Form, Tabs, Row, Col, Input, Button, Popconfirm, notification, Modal, message, InputNumber, Radio, Typography } from 'antd'
import { StopTwoTone, CheckCircleTwoTone, EditOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
import moment from 'moment'
import Api from '@/api'
@@ -47,7 +47,7 @@
      {
        title: '报错编码',
        dataIndex: 'errorCode',
        width: '12%',
        width: '10%',
        editable: true,
        inputType: 'select',
        options: [
@@ -60,13 +60,24 @@
      {
        title: '验证类型',
        dataIndex: 'verifyType',
        width: '12%',
        render: (text, record) => record.verifyType === 'logic' ? '逻辑验证' : '物理验证',
        width: '14%',
        render: (text, record) => {
          let names = {
            physical: '物理验证(全量验证)',
            logic: '逻辑验证(全量验证)',
            physical_temp: '物理验证(仅临时表)',
            logic_temp: '逻辑验证(仅临时表)',
          }
          return names[text] || '物理验证(全量验证)'
        },
        inputType: 'select',
        editable: true,
        options: [
          { value: 'physical', text: '物理验证' },
          { value: 'logic', text: '逻辑验证' }
          { value: 'physical', text: '物理验证(全量验证)' },
          { value: 'logic', text: '逻辑验证(全量验证)' },
          { value: 'physical_temp', text: '物理验证(仅临时表)' },
          { value: 'logic_temp', text: '逻辑验证(仅临时表)' }
        ]
      },
      {
@@ -149,10 +160,8 @@
        width: '20%',
        dataIndex: 'operation',
        render: (text, record) =>
          (<div>
          (<div style={{textAlign: 'center'}}>
            <span className="operation-btn" onClick={() => this.handleEdit(record, 'scripts')} style={{color: '#1890ff'}}><EditOutlined /></span>
            <span className="operation-btn" onClick={() => this.handleUpDown(record, 'scripts', 'up')} style={{color: '#1890ff'}}><ArrowUpOutlined /></span>
            <span className="operation-btn" onClick={() => this.handleUpDown(record, 'scripts', 'down')} style={{color: '#ff4d4f'}}><ArrowDownOutlined /></span>
            <span className="operation-btn" title="状态切换" onClick={() => this.handleStatus(record, 'scripts')} style={{color: '#8E44AD'}}><SwapOutlined /></span>
            <Popconfirm
              overlayClassName="popover-confirm"
@@ -378,51 +387,6 @@
    })
  }
  handleUpDown = (record, type, direction) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
    let index = 0
    if (type === 'unique') {
      verify.uniques = verify.uniques.filter((item, i) => {
        if (item.uuid === record.uuid) {
          index = i
        }
        return item.uuid !== record.uuid
      })
      if ((index === 0 && direction === 'up') || (index === verify.uniques.length && direction === 'down')) {
        return
      }
      if (direction === 'up') {
        verify.uniques.splice(index - 1, 0, record)
      } else {
        verify.uniques.splice(index + 1, 0, record)
      }
    } else if (type === 'scripts') {
      verify.scripts = verify.scripts.filter((item, i) => {
        if (item.uuid === record.uuid) {
          index = i
        }
        return item.uuid !== record.uuid
      })
      if ((index === 0 && direction === 'up') || (index === verify.scripts.length && direction === 'down')) {
        return
      }
      if (direction === 'up') {
        verify.scripts.splice(index - 1, 0, record)
      } else {
        verify.scripts.splice(index + 1, 0, record)
      }
    }
    this.setState({
      verify: verify
    })
  }
  handleConfirm = () => {
    const { verify } = this.state
    
@@ -623,14 +587,7 @@
              scriptsChange={this.scriptsChange}
              wrappedComponentRef={(inst) => this.scriptsForm = inst}
            />
            <Table
              bordered
              rowKey="uuid"
              className="custom-table"
              dataSource={verify.scripts}
              columns={scriptsColumns}
              pagination={false}
            />
            <EditTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/>
          </TabPane>
          <TabPane tab="信息提示" key="tip">
            <Form {...formItemLayout}>
src/menu/components/table/edit-table/columns/tableIn/uniqueform/index.jsx
@@ -108,8 +108,10 @@
                ]
              })(
                <Select>
                  <Select.Option value="physical"> 物理验证 </Select.Option>
                  <Select.Option value="logic"> 逻辑验证 </Select.Option>
                  <Select.Option value="physical"> 物理验证(全量验证) </Select.Option>
                  <Select.Option value="logic"> 逻辑验证(全量验证) </Select.Option>
                  <Select.Option value="physical_temp"> 物理验证(仅临时表) </Select.Option>
                  <Select.Option value="logic_temp"> 逻辑验证(仅临时表)  </Select.Option>
                </Select>
              )}
            </Form.Item>
src/menu/components/table/edit-table/index.jsx
@@ -141,7 +141,9 @@
      delete item.isNew
      this.setState({card: item})
      this.setState({card: null}, () => {
        this.setState({card: item})
      })
    }
  }
@@ -158,6 +160,10 @@
      card.$c_cl = true
      
      card.errors = checkComponent(card)
      if (!card.submit.sheet) {
        card.errors.push({ level: 0, detail: '提交按钮未设置!'})
      }
      if (card.errors.length === 0) {
        card.$tables = getTables(card)
@@ -273,9 +279,9 @@
  }
  getWrapForms = () => {
    const { wrap, action } = this.state.card
    const { wrap, columns } = this.state.card
    return getWrapForm(wrap, action)
    return getWrapForm(wrap, columns)
  }
  updateWrap = (res) => {
@@ -343,8 +349,11 @@
  render() {
    const { card, appType } = this.state
    if (!card) return null
    let _style = resetStyle(card.style)
    return (
      <div className="menu-editable-table-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
src/menu/components/table/edit-table/options.jsx
@@ -1,7 +1,7 @@
/**
 * @description Wrap表单配置信息
 */
export default function (wrap, action = []) {
export default function (wrap, columns = []) {
  let roleList = sessionStorage.getItem('sysRoles')
  let appType = sessionStorage.getItem('appType')
@@ -47,59 +47,59 @@
      field: 'height',
      label: '高度',
      initval: wrap.height || '',
      tooltip: '表格高度,空值时高度自适应。',
      tooltip: '表格高度,空值时高度自适应。注:小于等于100时为高度的百分比。',
      min: 10,
      max: 3000,
      precision: 0,
      required: false
    },
    {
      type: 'radio',
      field: 'editable',
      label: '初始化',
      initval: wrap.editable || 'false',
      required: false,
      options: [
        {value: 'true', label: '可编辑'},
        {value: 'false', label: '不可编辑'},
      ],
      controlFields: [
        {field: 'switchable', values: ['true']},
      ]
    },
    {
      type: 'radio',
      field: 'submittal',
      label: '提交后',
      initval: wrap.submittal || 'false',
      required: false,
      options: [
        {value: 'true', label: '可编辑'},
        {value: 'false', label: '不可编辑'},
      ]
    },
    {
      type: 'radio',
      field: 'addable',
      label: '可新增',
      initval: wrap.addable || 'false',
      required: false,
      options: [
        {value: 'true', label: '是'},
        {value: 'false', label: '否'},
      ]
    },
    {
      type: 'radio',
      field: 'delable',
      label: '可删除',
      initval: wrap.delable || 'true',
      required: false,
      options: [
        {value: 'true', label: '是'},
        {value: 'false', label: '否'},
      ]
    },
    // {
    //   type: 'radio',
    //   field: 'editable',
    //   label: '初始化',
    //   initval: wrap.editable || 'false',
    //   required: false,
    //   options: [
    //     {value: 'true', label: '可编辑'},
    //     {value: 'false', label: '不可编辑'},
    //   ],
    //   controlFields: [
    //     {field: 'switchable', values: ['true']},
    //   ]
    // },
    // {
    //   type: 'radio',
    //   field: 'submittal',
    //   label: '提交后',
    //   initval: wrap.submittal || 'false',
    //   required: false,
    //   options: [
    //     {value: 'true', label: '可编辑'},
    //     {value: 'false', label: '不可编辑'},
    //   ]
    // },
    // {
    //   type: 'radio',
    //   field: 'addable',
    //   label: '可新增',
    //   initval: wrap.addable || 'false',
    //   required: false,
    //   options: [
    //     {value: 'true', label: '是'},
    //     {value: 'false', label: '否'},
    //   ]
    // },
    // {
    //   type: 'radio',
    //   field: 'delable',
    //   label: '可删除',
    //   initval: wrap.delable || 'false',
    //   required: false,
    //   options: [
    //     {value: 'true', label: '是'},
    //     {value: 'false', label: '否'},
    //   ]
    // },
    {
      type: 'radio',
      field: 'commit',
@@ -113,18 +113,18 @@
        {value: 'simple', label: '单项'},
      ]
    },
    {
      type: 'radio',
      field: 'operType',
      label: '编辑按钮',
      initval: wrap.operType || 'btnMode',
      tooltip: '编辑时的添加、删除按钮显示位置,注:使用浮标时表格横向滚动失效,表格设置高度时浮标无效。',
      required: false,
      options: [
        {value: 'btnMode', label: '按钮式'},
        {value: 'buoyMode', label: '浮标式'},
      ]
    },
    // {
    //   type: 'radio',
    //   field: 'operType',
    //   label: '编辑按钮',
    //   initval: wrap.operType || 'btnMode',
    //   tooltip: '编辑时的添加、删除按钮显示位置,注:使用浮标时表格横向滚动失效,表格设置高度时浮标无效。',
    //   required: false,
    //   options: [
    //     {value: 'btnMode', label: '按钮式'},
    //     {value: 'buoyMode', label: '浮标式'},
    //   ]
    // },
    {
      type: 'radio',
      field: 'editType',
@@ -282,18 +282,18 @@
      ],
      forbid: !appType || sessionStorage.getItem('editMenuType') === 'popview'
    },
    {
      type: 'radio',
      field: 'switchable',
      label: '状态切换',
      initval: wrap.switchable || 'true',
      tooltip: '是否可以在编辑和默认table状态间切换。',
      required: false,
      options: [
        {value: 'true', label: '启用'},
        {value: 'false', label: '禁用'},
      ]
    },
    // {
    //   type: 'radio',
    //   field: 'switchable',
    //   label: '状态切换',
    //   initval: wrap.switchable || 'true',
    //   tooltip: '是否可以在编辑和默认table状态间切换。',
    //   required: false,
    //   options: [
    //     {value: 'true', label: '启用'},
    //     {value: 'false', label: '禁用'},
    //   ]
    // },
    {
      type: 'radio',
      field: 'empty',
@@ -307,6 +307,16 @@
      ],
    },
    {
      type: 'select',
      field: 'tipField',
      label: '信息提示',
      initval: wrap.tipField || '',
      tooltip: '鼠标悬浮于行上方时的提示信息。',
      required: false,
      allowClear: true,
      options: columns
    },
    {
      type: 'multiselect',
      field: 'blacklist',
      label: '黑名单',
src/menu/components/table/normal-table/columns/editColumn/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Form, Row, Col, Input, Select, InputNumber, Radio, Tooltip, Cascader, Modal, Checkbox } from 'antd'
import { Form, Row, Col, Input, Select, InputNumber, Radio, Tooltip, Cascader, Modal, Checkbox, Popover } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons'
import { getColumnForm } from './formconfig'
@@ -65,6 +65,11 @@
      formlist: formlist.map(item => {
        item.hidden = !_options.includes(item.key)
        if (item.key === 'formula') {
          item.fields = this.props.fields.map(col => col.field)
          item.fields = item.fields.join(', ')
        }
        return item
      })
    })
@@ -84,6 +89,11 @@
    if (key === 'type') {
      let _options = fromJS(columnTypeOptions[value]).toJS()
      let _field = ''
      if (value === 'formula') {
        _field = this.props.form.getFieldValue('field') || ''
      }
      this.setState({
        type: value,
        formlist: this.state.formlist.map(item => {
@@ -96,8 +106,14 @@
          this.props.form.setFieldsValue({IsSort: 'false'})
        } else if (value === 'text' || value === 'number') {
          this.props.form.setFieldsValue({perspective: ''})
        } else if (value === 'action' || value === 'colspan') {
        } else if (value === 'colspan') {
          this.props.form.setFieldsValue({Align: 'center'})
        } else if (value === 'formula' && _field) {
          this.props.form.setFieldsValue({formula: '@' + _field + '@'})
        } else if (value === 'action') {
          this.props.form.setFieldsValue({Align: 'center', label: '操作'})
        } else if (value === 'index') {
          this.props.form.setFieldsValue({label: '序号'})
        }
      })
    } else if (key === 'field') {
@@ -338,26 +354,52 @@
          </Col>
        )
      } else if (item.type === 'textarea') {
        fields.push(
          <Col span={24} key={index} className="textarea">
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<TextArea rows={2} disabled={item.readonly} placeholder={item.placeholder || ''}/>)}
            </Form.Item>
          </Col>
        )
        if (item.key === 'formula') {
          fields.push(
            <Col span={24} className="textarea" key={index}>
              <Form.Item label={item.tooltip ?
                <Tooltip placement="topLeft" title={item.tooltip}>
                  <QuestionCircleOutlined className="mk-form-tip" />
                  {item.label}
                </Tooltip> : item.label
              }>
                {getFieldDecorator(item.key, {
                  initialValue: item.initVal || '',
                  rules: [
                    {
                      required: !!item.required,
                      message: '请输入' + item.label + '!'
                    }
                  ]
                })(<TextArea autoSize={{minRows: 2}} disabled={item.readonly} placeholder={item.placeholder || ''} />)}
              </Form.Item>
              <Popover overlayClassName="formula-fields" placement="topLeft" title="" content={<div>{item.fields}</div>} trigger="click">
                <span className="formula-icon">字段集</span>
              </Popover>
            </Col>
          )
        } else {
          fields.push(
            <Col span={24} key={index} className="textarea">
              <Form.Item label={item.tooltip ?
                <Tooltip placement="topLeft" title={item.tooltip}>
                  <QuestionCircleOutlined className="mk-form-tip" />
                  {item.label}
                </Tooltip> : item.label
              }>
                {getFieldDecorator(item.key, {
                  initialValue: item.initVal || '',
                  rules: [
                    {
                      required: !!item.required,
                      message: '请输入' + item.label + '!'
                    }
                  ]
                })(<TextArea rows={2} disabled={item.readonly} placeholder={item.placeholder || ''}/>)}
              </Form.Item>
            </Col>
          )
        }
      }
    })
    return fields
src/menu/components/table/normal-table/columns/editColumn/index.scss
@@ -14,9 +14,27 @@
      width: 88%;
    }
  }
  .formula-icon {
    position: absolute;
    bottom: 5px;
    right: 15px;
    cursor: pointer;
    font-size: 12px;
    color: #1890ff;
  }
  >.ant-row >.ant-col {
    display: inline-block;
    vertical-align: top;
    float: none;
  }
}
.formula-fields {
  z-index: 1200!important;
  .ant-popover-inner-content {
    div {
      max-width: 750px;
      word-break: break-all;
    }
  }
}
src/menu/components/table/normal-table/columns/index.jsx
@@ -47,7 +47,8 @@
    return !is(fromJS(this.props.column), fromJS(nextProps.column)) ||
      !is(fromJS(this.props.fields), fromJS(nextProps.fields)) ||
      this.props.index !== nextProps.index
      this.props.index !== nextProps.index ||
      window.GLOB.columnId === nextProps.column.uuid || window.GLOB.precolumnId === nextProps.column.uuid
  }
  render() {
@@ -58,6 +59,10 @@
      if (column.Width) {
        style.width = column.Width
        style.minWidth = column.Width
      }
      if (window.GLOB.columnId === column.uuid) {
        style.color = '#1890ff'
      }
      return connectDragSource(
@@ -84,6 +89,10 @@
      if (column.Width) {
        style.width = column.Width
        style.minWidth = column.Width
      }
      if (window.GLOB.columnId === column.uuid) {
        style.color = '#1890ff'
      }
      return (
@@ -330,7 +339,7 @@
        config.action = config.action.filter(item => item.uuid !== btn.uuid)
        setTimeout(() => {
          MKEmitter.emit('revert', config.uuid)
          MKEmitter.emit('revertBtn', config.uuid)
        }, 200)
      }
@@ -410,6 +419,9 @@
      col.elements = card.type === 'action' ? (card.elements || []) : []
    }
    window.GLOB.precolumnId = window.GLOB.columnId || ''
    window.GLOB.columnId = col.uuid
    this.setState({card: null})
    this.updateCol(col)
  }
src/menu/components/table/normal-table/columns/index.scss
@@ -119,8 +119,11 @@
  .ant-table-small > .ant-table-content > .ant-table-body {
    margin: 0;
  }
  .ant-table-small.ant-table-bordered {
    border-right: 1px solid #e8e8e8;
  }
  table, tr, th, td {
  table, tr, th, td, .ant-table-small {
    border-color: var(--mk-table-border-color)!important;
  }
  table tr {
src/menu/components/table/normal-table/index.jsx
@@ -166,7 +166,9 @@
      delete item.isNew
      this.setState({card: item}, () => { MKEmitter.emit('revert') })
      this.setState({card: null}, () => {
        this.setState({card: item})
      })
    }
  }
@@ -388,6 +390,9 @@
  render() {
    const { card, appType } = this.state
    if (!card) return null
    let options = ['action', 'search', 'form', 'cols']
    let _style = resetStyle(card.style)
    
src/menu/components/table/normal-table/options.jsx
@@ -47,7 +47,7 @@
      field: 'height',
      label: '高度',
      initval: wrap.height || '',
      tooltip: '表格高度,空值时高度自适应。',
      tooltip: '表格高度,空值时高度自适应。注:小于等于100时为高度的百分比。',
      min: 10,
      max: 3000,
      precision: 0,
@@ -212,6 +212,16 @@
    },
    {
      type: 'select',
      field: 'tipField',
      label: '信息提示',
      initval: wrap.tipField || '',
      tooltip: '鼠标悬浮于行上方时的提示信息。',
      required: false,
      allowClear: true,
      options: columns
    },
    {
      type: 'select',
      field: 'controlField',
      label: '禁用字段',
      initval: wrap.controlField || '',
src/menu/modalconfig/index.jsx
@@ -137,7 +137,7 @@
        })
      }
      if (item.type === 'switch') {
      if (item.type === 'switch' || item.type === 'check') {
        _linksupFields.push({
          field: item.field,
          label: item.label
src/menu/modalconfig/index.scss
@@ -93,20 +93,20 @@
      position: relative;
      padding: 0;
      .modal-fields-row.up_down {
        .ant-form-item {
          display: block!important;
          .ant-form-item-label {
            width: 100%!important;
            text-align: left;
            height: 24px;
            line-height: 28px;
          }
          .ant-form-item-control-wrapper {
            width: 100%!important;
          }
        }
      }
      // .modal-fields-row.up_down {
      //   .ant-form-item {
      //     display: block!important;
      //     .ant-form-item-label {
      //       width: 100%!important;
      //       text-align: left;
      //       height: 24px;
      //       line-height: 28px;
      //     }
      //     .ant-form-item-control-wrapper {
      //       width: 100%!important;
      //     }
      //   }
      // }
      .ant-modal-content {
        max-width: 95%;
src/menu/replaceField/index.jsx
@@ -9,7 +9,6 @@
import Utils from '@/utils/utils.js'
import SettingForm from './settingform'
import { queryTableSql } from '@/utils/option.js'
import MKEmitter from '@/utils/events.js'
import './index.scss'
class ReplaceField extends Component {
@@ -420,35 +419,35 @@
      }
      config.components = _replace(config.components)
    } else if (type === 'table') {
      config.columns = config.columns.map(col => {
        if (col.field && map[col.field.toLowerCase()]) {
          col.field = map[col.field.toLowerCase()].FieldName
        }
        return col
      })
    // } else if (type === 'table') {
    //   config.columns = config.columns.map(col => {
    //     if (col.field && map[col.field.toLowerCase()]) {
    //       col.field = map[col.field.toLowerCase()].FieldName
    //     }
    //     return col
    //   })
      config.search = config.search.map(col => {
        if (col.field && map[col.field.toLowerCase()]) {
          col.field = map[col.field.toLowerCase()].FieldName
        }
        if (col.datefield && map[col.datefield.toLowerCase()]) {
          col.datefield = map[col.datefield.toLowerCase()].FieldName
        }
        return col
      })
    //   config.search = config.search.map(col => {
    //     if (col.field && map[col.field.toLowerCase()]) {
    //       col.field = map[col.field.toLowerCase()].FieldName
    //     }
    //     if (col.datefield && map[col.datefield.toLowerCase()]) {
    //       col.datefield = map[col.datefield.toLowerCase()].FieldName
    //     }
    //     return col
    //   })
      config.action = config.action.map(m => {
        if (m.verify && m.verify.columns) {
          m.verify.columns = m.verify.columns.map(col => {
            if (col.Column && map[col.Column.toLowerCase()]) {
              col.Column = map[col.Column.toLowerCase()].FieldName
            }
            return col
          })
        }
        return m
      })
    //   config.action = config.action.map(m => {
    //     if (m.verify && m.verify.columns) {
    //       m.verify.columns = m.verify.columns.map(col => {
    //         if (col.Column && map[col.Column.toLowerCase()]) {
    //           col.Column = map[col.Column.toLowerCase()].FieldName
    //         }
    //         return col
    //       })
    //     }
    //     return m
    //   })
    } else if (type === 'form') {
      config.fields = config.fields.map(col => {
        if (col.field && map[col.field.toLowerCase()]) {
@@ -469,10 +468,6 @@
      duration: 3
    })
    this.props.updateConfig(config)
    setTimeout(() => {
      MKEmitter.emit('revert')
    }, 300)
  }
  // 依据字段替换名称
@@ -590,32 +585,32 @@
      }
      config.components = _replace(config.components)
    } else if (type === 'table') {
      config.columns = config.columns.map(col => {
        if (col.field && map[col.field.toLowerCase()]) {
          col.label = map[col.field.toLowerCase()].FieldDec
        }
        return col
      })
    // } else if (type === 'table') {
    //   config.columns = config.columns.map(col => {
    //     if (col.field && map[col.field.toLowerCase()]) {
    //       col.label = map[col.field.toLowerCase()].FieldDec
    //     }
    //     return col
    //   })
      
      config.search = config.search.map(col => {
        if (col.field && map[col.field.toLowerCase()]) {
          col.label = map[col.field.toLowerCase()].FieldDec
        }
        return col
      })
    //   config.search = config.search.map(col => {
    //     if (col.field && map[col.field.toLowerCase()]) {
    //       col.label = map[col.field.toLowerCase()].FieldDec
    //     }
    //     return col
    //   })
      config.action = config.action.map(m => {
        if (m.verify && m.verify.columns) {
          m.verify.columns = m.verify.columns.map(col => {
            if (col.Column && map[col.Column.toLowerCase()]) {
              col.Text = map[col.Column.toLowerCase()].FieldDec
            }
            return col
          })
        }
        return m
      })
    //   config.action = config.action.map(m => {
    //     if (m.verify && m.verify.columns) {
    //       m.verify.columns = m.verify.columns.map(col => {
    //         if (col.Column && map[col.Column.toLowerCase()]) {
    //           col.Text = map[col.Column.toLowerCase()].FieldDec
    //         }
    //         return col
    //       })
    //     }
    //     return m
    //   })
    } else if (type === 'form') {
      config.fields = config.fields.map(col => {
        if (col.field && map[col.field.toLowerCase()]) {
@@ -636,9 +631,6 @@
      duration: 3
    })
    this.props.updateConfig(config)
    setTimeout(() => {
      MKEmitter.emit('revert')
    }, 500)
  }
  render() {
src/mob/components/formdragelement/card.jsx
@@ -127,6 +127,8 @@
    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label">{card.label}</div><div className="am-input-control">{card.linkfield}</div></div></div>)
  } else if (card.type === 'switch') {
    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label">{card.label}</div><div className="am-list-switch"><Switch checked={card.initval}/></div></div></div>)
  } else if (card.type === 'check') {
    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label">{card.label}</div><div className="am-list-switch"><Checkbox checked={card.initval}>{card.checkTip}</Checkbox></div></div></div>)
  } else if (card.type === 'radio') {
    let options = null
    if (card.options && card.options.length > 0) {
@@ -247,7 +249,7 @@
            {formItem}
            <div></div>
            {showField && card.field ? <div className="field-name" style={card.writein === 'false' ? {color: 'orange'} : {}}>
              {card.field}{card.hidden === 'true' || card.type === 'funcvar' ? '(隐藏)' : ''}{card.readonly === 'true' ? '(只读)' : ''}{card.linkField ? <span style={{color: '#1890ff'}}>{`(关联${card.linkField})`}</span> : ''}{card.supField ? <span style={{color: '#8E44AD'}}>{`(上级${card.supField})`}</span> : ''}
              {card.field}{card.hidden === 'true' || card.type === 'funcvar' ? '(隐藏)' : ''}{card.readonly === 'true' ? '(只读)' : ''}{card.readin === 'false' ? '(未填充)' : ''}{card.linkField ? <span style={{color: '#1890ff'}}>{`(关联${card.linkField})`}</span> : ''}{card.supField ? <span style={{color: '#8E44AD'}}>{`(上级${card.supField})`}</span> : ''}
            </div> : ''}
          </Form.Item>
        </div>
src/mob/modalconfig/index.jsx
@@ -159,7 +159,7 @@
        })
      }
      if (item.type === 'switch') {
      if (item.type === 'switch' || item.type === 'check') {
        _linksupFields.push({
          field: item.field,
          label: item.label
src/pc/components/navbar/normal-navbar/index.jsx
@@ -121,7 +121,9 @@
  }
  changeMenu = (menu) => {
    if (menu.property === 'link') {
    if (menu.property === 'text') {
      return
    } else if (menu.property === 'link') {
      window.open(menu.link)
      return
    }
src/pc/components/navbar/normal-navbar/linksetting/linkform/index.jsx
@@ -109,11 +109,12 @@
                <Radio.Group onChange={this.changeProperty}>
                  <Radio value="link">链接</Radio>
                  <Radio value="linkmenu">关联菜单</Radio>
                  <Radio value="text">文本</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
          <Col span={22}>
          {property !== 'text' ? <Col span={22}>
            <Form.Item label="打开方式">
              {getFieldDecorator('open', {
                initialValue: menu.open || 'blank'
@@ -124,7 +125,7 @@
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
          </Col> : null}
          {property === 'link' ? <Col span={22}>
            <Form.Item label="链接地址">
              {getFieldDecorator('link', {
src/tabviews/calendar/index.scss
@@ -6,7 +6,7 @@
  .box404 {
    padding-top: 30px;
  }
  >.top-search {
  >.mk-search-wrap {
    padding: 0px 24px 5px;
    border-bottom: 1px solid #efefef;
  }
src/tabviews/commontable/index.scss
@@ -6,7 +6,7 @@
  .box404 {
    padding-top: 30px;
  }
  >.top-search {
  >.mk-search-wrap {
    padding: 0px 24px 5px;
    border-bottom: 1px solid #efefef;
  }
src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -24,6 +24,7 @@
const PrintButton = asyncComponent(() => import('@/tabviews/zshare/actionList/printbutton'))
const FuncMegvii = asyncComponent(() => import('@/tabviews/zshare/actionList/funcMegvii'))
const FuncZip = asyncComponent(() => import('@/tabviews/zshare/actionList/funczip'))
const EditLine = asyncComponent(() => import('@/tabviews/zshare/actionList/editLine'))
const BarCode = asyncElementComponent(() => import('@/components/barcode'))
const QrCode = asyncElementComponent(() => import('@/components/qrcode'))
const MkProgress = asyncElementComponent(() => import('@/components/mkProgress'))
@@ -131,6 +132,13 @@
        _url = _url + `?subject=来自${fullName}的邮件`
      }
      window.open(_url)
      return
    } else if (card.linkType === 'qywx') {
      notification.warning({
        top: 92,
        message: 'PC不支持打开企业微信!',
        duration: 5
      })
      return
    }
@@ -316,7 +324,7 @@
          val = data[card.field]
        }
  
        if (val === '' && card.noValue === 'hide') { // 空值隐藏
        if (!val && card.noValue === 'hide') { // 空值隐藏
          return null
        }
  
@@ -406,6 +414,9 @@
              val = <Paragraph copyable={{ text: orival }}>{val}</Paragraph>
            }
          }
        } else if (card.fixStyle === 'alone') {
          let _s = {fontSize: card.fixSize, color: card.fixColor, marginLeft: card.fixLeft, marginRight: card.fixRight}
          val = <span style={_s}>{card.prefix || ''}{card.postfix || ''}</span>
        }
  
        let className = ''
@@ -485,6 +496,9 @@
          } else {
            val = `${card.prefix || ''}${val}${card.postfix || ''}`
          }
        } else if (card.fixStyle === 'alone') {
          let _s = {fontSize: card.fixSize, color: card.fixColor, marginLeft: card.fixLeft, marginRight: card.fixRight}
          val = <span style={_s}>{card.prefix || ''}{card.postfix || ''}</span>
        }
        
        let className = ''
@@ -640,7 +654,7 @@
          val = data[card.field] || ''
        }
  
        if (val === '' && card.noValue === 'hide') { // 空值隐藏
        if (!val && card.noValue === 'hide') { // 空值隐藏
          return null
        }
  
@@ -662,7 +676,7 @@
          url = data[card.field] || ''
        }
  
        if (url === '' && card.noValue === 'hide') { // 空值隐藏
        if (!url && card.noValue === 'hide') { // 空值隐藏
          return null
        }
  
@@ -694,7 +708,7 @@
          val = data[card.field] || ''
        }
  
        if (val === '' && card.noValue === 'hide') { // 空值隐藏
        if (!val && card.noValue === 'hide') { // 空值隐藏
          return null
        }
  
@@ -751,6 +765,8 @@
  
            val += _val
          })
        } else if (data && data.$$empty) {
          val = ''
        } else if (data) {
          let _val = card.formula
          Object.keys(data).forEach(key => {
@@ -770,7 +786,7 @@
          val = _val === undefined ? '' : _val
        }
        if (val === '' && card.noValue === 'hide') { // 空值隐藏
        if (!val && card.noValue === 'hide') { // 空值隐藏
          return null
        }
  
@@ -790,6 +806,9 @@
          } else {
            val = <>{card.prefix || ''}{val}{card.postfix || ''}</>
          }
        } else if (card.fixStyle === 'alone') {
          let _s = {fontSize: card.fixSize, color: card.fixColor, marginLeft: card.fixLeft, marginRight: card.fixRight}
          val = <span style={_s}>{card.prefix || ''}{card.postfix || ''}</span>
        }
        let className = ''
@@ -825,7 +844,7 @@
          color = data[card.field] || ''
        }
  
        if (color === '' && card.noValue === 'hide') { // 空值隐藏
        if (!color && card.noValue === 'hide') { // 空值隐藏
          return null
        }
@@ -1006,6 +1025,16 @@
                />
              </div>
            )
          } else if (card.funcType === 'addline' || card.funcType === 'delline') {
            contents.push(
              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
                <EditLine
                  btn={card}
                  disabled={_disabled}
                  selectedData={_data}
                />
              </div>
            )
          }
        }
      }
src/tabviews/custom/components/card/data-card/index.scss
@@ -6,15 +6,6 @@
  min-height: 20px;
  overflow-y: auto;
  .button-list.toolbar-button {
    padding: 0;
    line-height: 45px;
    button {
      margin-right: 0px;
      margin-bottom: 0px;
    }
  }
  .data-zoom {
    display: flex;
    position: relative;
src/tabviews/custom/components/card/double-data-card/index.jsx
@@ -156,6 +156,19 @@
      }
    }
    if (_config.wrap.zHeight) {
      _config.wrap.zHeight = _config.wrap.zHeight <= 100 ? _config.wrap.zHeight + 'vh' : _config.wrap.zHeight
    }
    if (_config.wrap.zHeight || _config.wrap.minWidth) {
      _config.wrap.zoomStyle = {
        border: `1px solid ${_config.wrap.zBColor || 'transparent'}`,
        height: _config.wrap.zHeight || 'auto'
      }
    } else {
      _config.wrap.zoomStyle = null
    }
    this.setState({
      pageSize: _config.setting.pageSize || 10,
      pageOptions,
@@ -562,9 +575,8 @@
      if (type === 'plus') {
        let _data = (this.state.data || []).concat(result.data || [])
        data = _data.map((item, index) => {
          let children = []
          if (item[config.setting.subdata]) {
            let children = []
            let _children = item[config.setting.subdata]
            delete item[config.setting.subdata]
@@ -581,9 +593,10 @@
                children.push(cell)
              }
            })
            item.children = children
          } else if (!item.children) {
            item.children = []
          }
          item.children = children
          item.key = index
          item.$$uuid = item[config.setting.primaryKey] || ''
@@ -944,7 +957,7 @@
            selectedData={selectedData}
          /> : null
        }
        <div className={config.wrap.minWidth ? 'data-zoom-box' : ''}>
        <div className={config.wrap.zoomStyle ? 'data-zoom-box' : ''} style={config.wrap.zoomStyle}>
          <div className={`data-zoom ${config.wrap.wrapClass}`} style={config.wrap.minWidth ? {minWidth: config.wrap.minWidth} : null}>
            <Row className={'card-row-list '}>
              {precards.map((item, index) => (
src/tabviews/custom/components/card/double-data-card/index.scss
@@ -6,15 +6,6 @@
  min-height: 20px;
  overflow-y: auto;
  .button-list.toolbar-button {
    padding: 0;
    line-height: 45px;
    button {
      margin-right: 0px;
      margin-bottom: 0px;
    }
  }
  .data-zoom {
    display: flex;
    position: relative;
@@ -298,10 +289,20 @@
  .data-zoom-box {
    width: 100%;
    overflow-x: auto;
    overflow-y: auto;
    padding-bottom: 10px;
    border: 1px solid #e8e8e8;
    border-radius: 4px;
    .extend-card:first-child {
      position: sticky;
      top: 0px;
      z-index: 2;
    }
  }
  .data-zoom-box::-webkit-scrollbar {
    height: 7px;
    height: 9px;
    width: 9px;
  }
  .data-zoom-box::-webkit-scrollbar-thumb {
    border-radius: 5px;
src/tabviews/custom/components/code/sand-box/index.jsx
@@ -20,7 +20,7 @@
    config: null,              // 图表配置信息
    loading: false,            // 数据加载状态
    sync: false,               // 是否统一请求数据
    data: {},                  // 数据
    data: [],                  // 数据
    html: '',
  }
@@ -30,7 +30,7 @@
    const { data, initdata } = this.props
    let _config = fromJS(this.props.config).toJS()
    let _data = {}
    let _data = []
    let _sync = false
    let BID = ''
@@ -49,7 +49,7 @@
      _sync = _config.setting.sync === 'true'
      if (_sync && data) {
        _data = data[_config.dataName] || {}
        _data = data[_config.dataName] || []
        _sync = false
        this.loaded = true
      } else if (_sync && initdata) {
@@ -122,7 +122,7 @@
    const { sync, config } = this.state
    if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) {
      let _data = {}
      let _data = []
      if (nextProps.data && nextProps.data[config.dataName]) {
        _data = nextProps.data[config.dataName]
      }
@@ -157,13 +157,13 @@
    if (config.wrap.datatype === 'static') {
      this.setState({
        data: {},
        data: [],
        loading: false
      })
      return
    } else if (config.setting.supModule && !BID) { // BID 不存在时,不做查询
      this.setState({
        data: {},
        data: [],
        loading: false
      })
      this.loaded = true
@@ -186,7 +186,7 @@
    let result = await Api.genericInterface(param)
    if (result.status) {
      let _data = result.data || {}
      let _data = result.data || []
      this.loaded = true
      if (config.$cache && config.setting.onload !== 'false') {
@@ -220,32 +220,35 @@
    const { html, js, wrap, columns } = this.state.config
    let _html = html
    if (_html && wrap.datatype !== 'static' && wrap.compileMode !== 'custom') {
      let _data = data
      if (Array.isArray(_data)) {
        _data = _data[0] || {}
      }
      columns.forEach(col => {
        if (col.field) {
          let val = (_data[col.field] || _data[col.field] === 0) ? _data[col.field] : ''
          let reg = new RegExp('@' + col.field + '@', 'ig')
    if (_html && wrap.datatype !== 'static') {
      if (/@[\u4E00-\u9FA50-9a-zA-Z_]+@/ig.test(_html)) {
        let _data = data[0] || {}
          _html = _html.replace(reg, val)
        }
      })
        columns.forEach(col => {
          if (col.field) {
            let val = _data[col.field] !== undefined ? _data[col.field] : ''
            let reg = new RegExp('@' + col.field + '@', 'ig')
            _html = _html.replace(reg, val)
          }
        })
      }
    }
    this.setState({html: _html}, () => {
      if (js) {
        try {
          if (wrap.compileMode !== 'custom') {
            // eslint-disable-next-line no-eval
            eval(js)
          } else {
            // eslint-disable-next-line
            let evalfunc = eval('(true && function (data) {' + js + '})')
            evalfunc(data)
          }
          // eslint-disable-next-line
          let evalfunc = eval('(true && function (data) {' + js + '})')
          evalfunc(data)
          // if (wrap.compileMode !== 'custom') {
          //   // eslint-disable-next-line no-eval
          //   eval(js)
          // } else {
          //   // eslint-disable-next-line
          //   let evalfunc = eval('(true && function (data) {' + js + '})')
          //   evalfunc(data)
          // }
        } catch (e) {
          console.warn(e)
        }
src/tabviews/custom/components/group/normal-group/index.jsx
@@ -296,101 +296,8 @@
    })
  }
  // canvasToImage(canvas) {
  //   let image = new Image()
  //   image.src = canvas.toDataURL('image/jpg')
  //   image.style = 'width:100%;height:100%;position:absolute;z-index:1;left:0px;top:0px;'
  //   return image
  // }
  // print = () => {
  //   const { config } = this.props
  //   const { printing } = this.state
  //   if (printing) return
  //   this.setState({printing: true})
  //   let qrcodes = document.getElementsByClassName('qrcode-box')
  //   for (let i = 0; i < qrcodes.length; i++) {
  //     let canvas = qrcodes[i].getElementsByTagName('canvas')[0]
  //     if (canvas) {
  //       let img = this.canvasToImage(canvas)
  //       canvas.remove()
  //       qrcodes[i].append(img)
  //     }
  //   }
  //   let pageSize = ['A4', 'A3', 'A5'].includes(config.setting.pageSize) ? config.setting.pageSize : 'A4'
  //   let pageLayout = config.setting.pageLayout !== 'horizontal' ? 'vertical' : 'horizontal'
  //   let hides = config.setting.hide || []
  //   let pageParam = {
  //     A4: {
  //       vertical: 980,
  //       horizontal: 1200,
  //     },
  //     A3: {
  //       vertical: 1200,
  //       horizontal: 1600,
  //     },
  //     A5: {
  //       vertical: 700,
  //       horizontal: 1000,
  //     }
  //   }
  //   let width = pageParam[pageSize][pageLayout]
  //   try {
  //     let jubuData =  document.getElementById(config.uuid).innerHTML
  //     let iframe = document.createElement('IFRAME')
  //     let linkList = document.getElementsByTagName('link')     // 获取父窗口link标签对象列表
  //     let styleList = document.getElementsByTagName('style')   // 获取父窗口style标签对象列表
  //     document.body.appendChild(iframe)
  //     let doc = iframe.contentWindow.document
  //     doc.open()
  //     doc.write(`<!DOCTYPE html><html lang="en"><head>`)
  //     for (let i = 0;i < linkList.length;i++) {
  //       if (linkList[i].type === 'text/css') {
  //         doc.write(`<LINK rel="stylesheet" type="text/css" href="${linkList[i].href}">`)
  //       }
  //     }
  //     doc.write(`<style>body{width: ${width}px!important;} *{border-style: solid;border-width: 0;} .print-button{display: none!important;} ${hides.includes('search') ? '.top-search{display: none!important;}' : ''} ${hides.includes('button') ? '.ant-btn{opacity: 0!important;}' : ''}</style>`)
  //     for (let i = 0;i < styleList.length;i++) {
  //       doc.write('<style>' + styleList[i].innerHTML + '</style>')
  //     }
  //     doc.write(`</head><body>`)
  //     doc.write(jubuData)
  //     doc.write(`</body></html>`)
  //     doc.close()
  //     setTimeout(() => {
  //       iframe.contentWindow.focus()
  //       iframe.contentWindow.print()
  //       document.body.removeChild(iframe)
  //       this.setState({printing: false})
  //     }, 500)
  //   } catch (e) {
  //     this.setState({printing: false})
  //     notification.warning({
  //       top: 92,
  //       message: '打印异常!',
  //       duration: 5
  //     })
  //   }
  // }
  render() {
    const { config } = this.props
    // const { printing } = this.state
    if (!config.components || config.components.length === 0) return (<div style={config.style}></div>)
    
@@ -399,7 +306,6 @@
        {config.setting && config.setting.title ? <div className="group-header" style={config.headerStyle}>
          <span className="title">{config.setting.title}</span>
        </div> : null}
        {/* {config.setting && config.setting.print === 'true' ? <Button className="print-button" icon="printer" loading={printing} onClick={this.print}></Button> : null} */}
        <Row className="component-wrap">{this.getComponents()}</Row>
      </div>
    )
src/tabviews/custom/components/module/voucher/index.jsx
@@ -220,11 +220,11 @@
      })
      res.logistics && res.logistics.forEach(item => {
        logistics.push({value: item.suppliercode, label: item.suppliername})
        logistics.push({value: item.logistics_code, label: item.logistics_name})
      })
      res.lessor && res.lessor.forEach(item => {
        lessor.push({value: item.suppliercode, label: item.suppliername})
        lessor.push({value: item.lessor_code, label: item.lessor_name})
      })
      res.customer && res.customer.forEach(item => {
@@ -422,11 +422,11 @@
              err = `第${_index}行,请选择辅助核算。`
            }
          } else if (item.sup_acc_type === 'logistics') {
            if (!item.suppliercode || !item.suppliername) {
            if (!item.logistics_code || !item.logistics_name) {
              err = `第${_index}行,请选择辅助核算。`
            }
          } else if (item.sup_acc_type === 'lessor') {
            if (!item.suppliercode || !item.suppliername) {
            if (!item.lessor_code || !item.lessor_name) {
              err = `第${_index}行,请选择辅助核算。`
            }
          } else if (item.sup_acc_type === 'customer') {
@@ -606,7 +606,7 @@
            supMap.delete(item.uuid + n.sup_acc_type)
          }
          sup_data.push(`'${n.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${n.voucher_sup_lp || ''}','${item.subject_code}','${item.subject_name}','${n.sup_voucher_text || ''}','${direct}',${item.debit || item.credit},'${n.customercode || ''}','${n.customername || ''}','${n.suppliercode || ''}','${n.suppliername || ''}','${n.co_pro_code || ''}','${n.co_pro_name || ''}','${n.workercode || ''}','${n.workername || ''}','${n.project_code || ''}','${n.project_name || ''}','${n.productcode || ''}','${n.productname || ''}','${n.cash_flow_code || ''}','${n.cash_flow_name || ''}','${n.sup_acc_code || ''}','${n.sup_acc_name || ''}','${n.sup_acc_type || ''}','${item.uuid}',0`)
          sup_data.push(`'${n.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${n.voucher_sup_lp || ''}','${item.subject_code}','${item.subject_name}','${n.sup_voucher_text || ''}','${direct}',${item.debit || item.credit},'${n.customercode || ''}','${n.customername || ''}','${n.suppliercode || ''}','${n.suppliername || ''}','${n.co_pro_code || ''}','${n.co_pro_name || ''}','${n.workercode || ''}','${n.workername || ''}','${n.project_code || ''}','${n.project_name || ''}','${n.productcode || ''}','${n.productname || ''}','${n.cash_flow_code || ''}','${n.cash_flow_name || ''}','${n.sup_acc_code || ''}','${n.sup_acc_name || ''}','${n.sup_acc_type || ''}','${item.uuid}',0,'${n.lessor_code || ''}','${n.lessor_name || ''}','${n.logistics_code || ''}','${n.logistics_name || ''}'`)
        })
      }
      return `'${item.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${item.subject_code}','${item.subject_name}','${item.subject_voucher_text || ''}',${count ? item.fcc_count || 0 : 0},${count ? item.net_unitprice || 0 : 0},'${item.unit}',${item.debit || item.credit},'${direct}','${curr ? item.exratecode : '01010001'}','${curr ? item.exratename : 'CNY'}',${curr ? item.unitratio || 0 : 0},'${item.sup_accounting}',${item.debit ? 1 : -1},${curr ? item.foreign_amount || 0 : 0},0,'${item.local_currency || ''}','${count ? 'Y' : ''}','${curr ? 'Y' : ''}'`
@@ -629,7 +629,7 @@
    })
    supMap.forEach(n => {
      sup_data.push(`'${n.uuid}','${n.sup_voucher_code}','${n.sup_voucher_lp}','${n.voucher_sup_lp || ''}','${n.sup_subject_code}','${n.sup_subject_name}','${n.sup_voucher_text || ''}','${n.sup_direct}',${n.sup_net_amount},'${n.customercode || ''}','${n.customername || ''}','${n.suppliercode || ''}','${n.suppliername || ''}','${n.co_pro_code || ''}','${n.co_pro_name || ''}','${n.workercode || ''}','${n.workername || ''}','${n.project_code || ''}','${n.project_name || ''}','${n.productcode || ''}','${n.productname || ''}','${n.cash_flow_code || ''}','${n.cash_flow_name || ''}','${n.sup_acc_code || ''}','${n.sup_acc_name || ''}','${n.sup_acc_type || ''}','${n.sup_bid}',1`)
      sup_data.push(`'${n.uuid}','${n.sup_voucher_code}','${n.sup_voucher_lp}','${n.voucher_sup_lp || ''}','${n.sup_subject_code}','${n.sup_subject_name}','${n.sup_voucher_text || ''}','${n.sup_direct}',${n.sup_net_amount},'${n.customercode || ''}','${n.customername || ''}','${n.suppliercode || ''}','${n.suppliername || ''}','${n.co_pro_code || ''}','${n.co_pro_name || ''}','${n.workercode || ''}','${n.workername || ''}','${n.project_code || ''}','${n.project_name || ''}','${n.productcode || ''}','${n.productname || ''}','${n.cash_flow_code || ''}','${n.cash_flow_name || ''}','${n.sup_acc_code || ''}','${n.sup_acc_name || ''}','${n.sup_acc_type || ''}','${n.sup_bid}',1,'${n.lessor_code || ''}','${n.lessor_name || ''}','${n.logistics_code || ''}','${n.logistics_name || ''}'`)
    })
    let attachments_data = []
@@ -724,11 +724,11 @@
              err = `第${_index}行,请选择辅助核算。`
            }
          } else if (item.sup_acc_type === 'logistics') {
            if (!item.suppliercode || !item.suppliername) {
            if (!item.logistics_code || !item.logistics_name) {
              err = `第${_index}行,请选择辅助核算。`
            }
          } else if (item.sup_acc_type === 'lessor') {
            if (!item.suppliercode || !item.suppliername) {
            if (!item.lessor_code || !item.lessor_name) {
              err = `第${_index}行,请选择辅助核算。`
            }
          } else if (item.sup_acc_type === 'customer') {
@@ -890,7 +890,7 @@
            supMap.delete(item.uuid + n.sup_acc_type)
          }
          sup_data.push(`'${n.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${n.voucher_sup_lp || ''}','${item.subject_code}','${item.subject_name}','${n.sup_voucher_text || ''}','${direct}',${item.debit || item.credit || 0},'${n.customercode || ''}','${n.customername || ''}','${n.suppliercode || ''}','${n.suppliername || ''}','${n.co_pro_code || ''}','${n.co_pro_name || ''}','${n.workercode || ''}','${n.workername || ''}','${n.project_code || ''}','${n.project_name || ''}','${n.productcode || ''}','${n.productname || ''}','${n.cash_flow_code || ''}','${n.cash_flow_name || ''}','${n.sup_acc_code || ''}','${n.sup_acc_name || ''}','${n.sup_acc_type || ''}','${item.uuid}',0`)
          sup_data.push(`'${n.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${n.voucher_sup_lp || ''}','${item.subject_code}','${item.subject_name}','${n.sup_voucher_text || ''}','${direct}',${item.debit || item.credit || 0},'${n.customercode || ''}','${n.customername || ''}','${n.suppliercode || ''}','${n.suppliername || ''}','${n.co_pro_code || ''}','${n.co_pro_name || ''}','${n.workercode || ''}','${n.workername || ''}','${n.project_code || ''}','${n.project_name || ''}','${n.productcode || ''}','${n.productname || ''}','${n.cash_flow_code || ''}','${n.cash_flow_name || ''}','${n.sup_acc_code || ''}','${n.sup_acc_name || ''}','${n.sup_acc_type || ''}','${item.uuid}',0,'${n.lessor_code || ''}','${n.lessor_name || ''}','${n.logistics_code || ''}','${n.logistics_name || ''}'`)
        })
      }
      return `'${item.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${item.subject_code}','${item.subject_name}','${item.subject_voucher_text || ''}',${count ? item.fcc_count || 0 : 0},${count ? item.net_unitprice || 0 : 0},'${item.unit}',${item.debit || item.credit || 0},'${direct}','${curr ? item.exratecode : '01010001'}','${curr ? item.exratename : 'CNY'}',${curr ? item.unitratio || 0 : 0},'${item.sup_accounting}',${item.direct ? 1 : -1},${curr ? item.foreign_amount || 0 : 0},0,'${item.local_currency || ''}','${count ? 'Y' : ''}','${curr ? 'Y' : ''}'`
@@ -905,7 +905,7 @@
    })
    supMap.forEach(n => {
      sup_data.push(`'${n.uuid}','${n.sup_voucher_code}','${n.sup_voucher_lp}','${n.voucher_sup_lp || ''}','${n.sup_subject_code}','${n.sup_subject_name}','${n.sup_voucher_text || ''}','${n.sup_direct}',${n.sup_net_amount},'${n.customercode || ''}','${n.customername || ''}','${n.suppliercode || ''}','${n.suppliername || ''}','${n.co_pro_code || ''}','${n.co_pro_name || ''}','${n.workercode || ''}','${n.workername || ''}','${n.project_code || ''}','${n.project_name || ''}','${n.productcode || ''}','${n.productname || ''}','${n.cash_flow_code || ''}','${n.cash_flow_name || ''}','${n.sup_acc_code || ''}','${n.sup_acc_name || ''}','${n.sup_acc_type || ''}','${n.sup_bid}',1`)
      sup_data.push(`'${n.uuid}','${n.sup_voucher_code}','${n.sup_voucher_lp}','${n.voucher_sup_lp || ''}','${n.sup_subject_code}','${n.sup_subject_name}','${n.sup_voucher_text || ''}','${n.sup_direct}',${n.sup_net_amount},'${n.customercode || ''}','${n.customername || ''}','${n.suppliercode || ''}','${n.suppliername || ''}','${n.co_pro_code || ''}','${n.co_pro_name || ''}','${n.workercode || ''}','${n.workername || ''}','${n.project_code || ''}','${n.project_name || ''}','${n.productcode || ''}','${n.productname || ''}','${n.cash_flow_code || ''}','${n.cash_flow_name || ''}','${n.sup_acc_code || ''}','${n.sup_acc_name || ''}','${n.sup_acc_type || ''}','${n.sup_bid}',1,'${n.lessor_code || ''}','${n.lessor_name || ''}','${n.logistics_code || ''}','${n.logistics_name || ''}'`)
    })
    param.subject_data = window.btoa(window.encodeURIComponent(subject_data.join(';un')))
src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
@@ -108,8 +108,12 @@
      let account = {}
      subAccounts.forEach(item => {
        if (item.field === 'supplier' || item.field === 'logistics' || item.field === 'lessor') {
        if (item.field === 'supplier') {
          account[item.field] = {suppliercode: item.value, suppliername: item.name}
        } else if (item.field === 'logistics') {
          account[item.field] = {logistics_code: item.value, logistics_name: item.name}
        } else if (item.field === 'lessor') {
          account[item.field] = {lessor_code: item.value, lessor_name: item.name}
        } else if (item.field === 'customer') {
          account[item.field] = {customercode: item.value, customername: item.name}
        } else if (item.field === 'department') {
@@ -762,8 +766,12 @@
            if (record.sup_accounting && record.supAccounts) {
              record.supAccounts.forEach(item => {
                if (item.sup_acc_type === 'supplier' || item.sup_acc_type === 'logistics' || item.sup_acc_type === 'lessor') {
                if (item.sup_acc_type === 'supplier') {
                  val += item.suppliercode ? '_' + item.suppliercode + ' ' + item.suppliername : ''
                } else if (item.sup_acc_type === 'logistics') {
                  val += item.logistics_code ? '_' + item.logistics_code + ' ' + item.logistics_name : ''
                } else if (item.sup_acc_type === 'lessor') {
                  val += item.lessor_code ? '_' + item.lessor_code + ' ' + item.lessor_name : ''
                } else if (item.sup_acc_type === 'customer') {
                  val += item.customercode ? '_' + item.customercode + ' ' + item.customername : ''
                } else if (item.sup_acc_type === 'department') {
src/tabviews/custom/components/share/normalTable/index.jsx
@@ -348,11 +348,8 @@
      if (content !== '') {
        content = `${col.prefix || ''}${content}${col.postfix || ''}`
        if (col.eval === 'false') {
          content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
          content = <span dangerouslySetInnerHTML={{__html: content}}></span>
        }
        content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
        content = <span dangerouslySetInnerHTML={{__html: content}}></span>
      }
      if (col.marks) {
@@ -990,6 +987,9 @@
    }
    let height = setting.height || false
    if (height && height <= 100) {
      height = height + 'vh'
    }
    let loading = this.props.loading
    if (setting.mask === 'hidden') {
      loading = false
@@ -1023,6 +1023,7 @@
            return {
              lineMarks: setting.tableMode !== 'fast' ? lineMarks : null,
              data: record,
              title: setting.tipField ? record[setting.tipField] : '',
              className: index === activeIndex ? ' mk-row-active ' : '',
              onClick: () => {this.changeRow(record, index)},
              onDoubleClick: () => {this.doubleClickLine(record)}
src/tabviews/custom/components/share/normalTable/index.scss
@@ -198,8 +198,11 @@
      display: block;
    }
  }
  .ant-table-small.ant-table-bordered {
    border-right: 1px solid #e8e8e8;
  }
  table, tr, th, td {
  table, tr, th, td, .ant-table-small {
    border-color: var(--mk-table-border-color)!important;
  }
  table tr {
@@ -219,11 +222,6 @@
  table tbody tr {
    color: var(--mk-table-color);
  }
  // table tbody {
  //   tr:nth-child(even) {
  //     background: #f5f5f5;
  //   }
  // }
}
.normal-custom-table:not(.ghost) {
  .ant-table-small > .ant-table-content .ant-table-thead > tr > th {
src/tabviews/custom/components/share/normalheader/index.scss
@@ -18,7 +18,7 @@
    position: relative;
    z-index: 1;
  }
  .top-search {
  .mk-search-wrap {
    background: transparent;
    text-decoration: unset;
    font-weight: normal;
src/tabviews/custom/components/share/tabtransfer/index.jsx
@@ -174,13 +174,10 @@
    })
  }
  getComponents = () => {
    const { config } = this.props
  getComponents = (components) => {
    const { mainSearch, data } = this.state
    if (!config || !config.components || config.components.length === 0) return (<Empty description={false} />)
    return config.components.map(item => {
    return components.map(item => {
      let style = null
      if (item.style && item.style.clear === 'left') {
@@ -355,8 +352,12 @@
  }
  render() {
    const { config } = this.props
    if (!config || !config.components || config.components.length === 0) return (<Empty description={false} />)
    return (
      <Row className="component-wrap" gutter={8}>{this.getComponents()}</Row>
      <Row className="component-wrap" id={'anchor' + config.uuid} gutter={8}>{this.getComponents(config.components)}</Row>
    )
  }
}
src/tabviews/custom/components/table/base-table/index.scss
@@ -5,16 +5,12 @@
  .normal-header {
    margin-bottom: 10px;
  }
  .top-search {
  .mk-search-wrap {
    border-bottom: 1px solid #efefef;
    padding-top: 10px;
  }
  .button-list.toolbar-button {
    min-height: 60px;
    padding-right: 60px;
    button {
      margin-bottom: 0px;
    }
  }
  .main-table-box {
    position: relative;
src/tabviews/custom/components/table/edit-table/index.jsx
@@ -38,8 +38,6 @@
    pageSize: 10,         // 每页数据条数
    orderBy: '',          // 排序
    search: '',           // 搜索条件数组,使用时需分场景处理
    statFValue: [],       // 合计值
    lock: false
  }
  /**
@@ -65,69 +63,100 @@
    _config.submit.style = _config.submit.style || {}
    _config.submit.wrapStyle = {}
    _config.submit.hasAction = _config.action.length > 0
    if (!_config.submit.hasAction) {
      if (_config.submit.style.marginTop) {
        _config.submit.wrapStyle.paddingTop = _config.submit.style.marginTop
    setting.hasAction = _config.action.length > 0
    _config.action.forEach(btn => {
      if (btn.funcType === 'addline') {
        setting.addable = true
      }
      if (_config.submit.style.marginBottom) {
        _config.submit.wrapStyle.paddingBottom = _config.submit.style.marginBottom
      btn.$tableId = setting.tableId
      if (!btn.controlField) {
        btn.controlField = '$lock'
        btn.controlVals = []
      }
    } else {
      _config.submit.wrapStyle.paddingTop = '15px'
    }
    if (setting.height) {
      setting.operType = 'btnMode'
    }
    let _columns = []
    let signAdd = false
    _config.cols.forEach(column => {
      if (column.Hide === 'true') return
      if (column.type === 'index') {
        column.field = '$Index'
        column.type = 'text'
      }
      if (setting.addable === 'true' && setting.operType === 'buoyMode' && column.type !== 'action' && !signAdd) {
        column.addable = true
        signAdd = true
      }
      if (column.marks && column.marks.length === 0) {
        column.marks = ''
      }
      column.tableId = setting.tableId
      if (column.type === 'text' && column.editable === 'true' && column.editType === 'select') {
        column.options = column.options || []
        column.options = column.options.filter(cell => {
          cell.value = cell.Value
          cell.label = cell.Text
          return !cell.Hide
        })
      }
      _columns.push(column)
    })
    if (setting.delable !== 'false' && setting.operType === 'buoyMode') {
      if (_columns[_columns.length - 1] && _columns[_columns.length - 1].type !== 'action') {
        _columns[_columns.length - 1].delable = true
      } else if (_columns[_columns.length - 2] && _columns[_columns.length - 2].type !== 'action') {
        _columns[_columns.length - 2].delable = true
      }
    let _columns = []
    setting.initId = ''
    let triMap = new Map()
    let getColumns = (cols) => {
      return cols.filter(item => {
        if (item.Hide === 'true') return false
        item.tableId = setting.tableId
        if (item.type === 'colspan') {
          item.subcols = getColumns(item.subcols)
          if (item.subcols.length === 0) {
            return false
          }
        } else if (item.type === 'action') {
          item.elements.forEach(btn => {
            if (btn.funcType === 'addline') {
              setting.addable = true
            }
            btn.$tableId = setting.tableId
            if (!btn.controlField) {
              btn.controlField = '$lock'
              btn.controlVals = []
            }
          })
        } else {
          if (item.type === 'index') {
            item.field = '$Index'
            item.type = 'text'
          }
          if (item.marks && item.marks.length === 0) {
            item.marks = ''
          }
          if (item.editable === 'true') {
            if (!setting.initId) {
              setting.initId = item.uuid
            }
            if (item.type === 'text' && (item.editType === 'switch' || item.editType === 'select')) {
              triMap.set(item.uuid, item.editType)
            }
            if (item.type === 'text' && item.editType === 'select') {
              item.options = item.options || []
              item.options = item.options.filter(cell => {
                cell.value = cell.Value
                cell.label = cell.Text
                return !cell.Hide
              })
            }
          }
        }
        return true
      })
    }
    // if (setting.color) {
    //   setting.style.color = setting.color
    // }
    // if (setting.fontSize) {
    //   setting.style.fontSize = setting.fontSize
    // }
    _columns = getColumns(_config.cols)
    if (triMap.size > 0) {
      let setColumns = (cols) => {
        return cols.map(item => {
          if (item.type === 'colspan') {
            item.subcols = setColumns(item.subcols)
          } else if (item.editable === 'true' && triMap.has(item.enter)) {
            item.triType = 'click'
          }
          return item
        })
      }
      _columns = setColumns(_columns)
      if (setting.initId && triMap.has(setting.initId)) {
        setting.triType = 'click'
      }
    }
    if (!_config.lineMarks || _config.lineMarks.length === 0) {
      _config.lineMarks = null
@@ -148,7 +177,6 @@
      if (_config.setting.onload === 'true') {
        setTimeout(() => {
          this.loadmaindata()
          this.getStatFieldsValue()
        }, _config.setting.delay || 0)
      }
    })
@@ -253,7 +281,7 @@
  /**
   * @description 获取单行数据
   */ 
  async loadmainLinedata (id, line) {
  async loadmainLinedata (id) {
    const { mainSearch } = this.props
    const { setting, config, arr_field, search, orderBy, BID, pageIndex, pageSize, BData } = this.state
@@ -276,10 +304,18 @@
    let result = await Api.genericInterface(param)
    if (result.status) {
      if (!result.data || !result.data[0]) {
        this.setState({
          loading: false
        })
        return
      }
      let data = fromJS(this.state.data).toJS()
      let selectedData = fromJS(this.state.selectedData).toJS()
      let _data = result.data[0] || {}
      let _data = result.data[0]
      _data.$$uuid = _data[setting.primaryKey] || ''
      _data.$$BID = BID || ''
      _data.$$BData = BData || ''
@@ -314,14 +350,8 @@
        console.warn('数据查询错误')
      }
      if (line) {
        if (line.$type === 'del' && !result.data[0]) {
          data = data.filter(m => m.$$uuid === line.$$uuid)
        }
        MKEmitter.emit('transferData', config.uuid, _data, 'line')
      } else {
        MKEmitter.emit('resetSelectLine', config.uuid, _data.$$uuid || '', _data)
      }
      MKEmitter.emit('transferData', config.uuid, _data, 'line')
      MKEmitter.emit('resetSelectLine', config.uuid, _data.$$uuid, _data)
      this.setState({
        data,
@@ -341,72 +371,6 @@
  }
  /**
   * @description 获取合计字段值
   */
  getStatFieldsValue = () => {
    const { mainSearch } = this.props
    const { setting, config, search, BID, orderBy } = this.state
    if (setting.supModule && !BID) { // BID 不存在时,不做查询
      this.setState({
        statFValue: []
      })
      return
    }
    if (config.statFields.length === 0 || setting.interType !== 'system' || !setting.dataresource) return
    let searches = fromJS(search).toJS()
    if (config.setting.useMSearch && mainSearch && mainSearch.length > 0) { // 主表搜索条件
      let keys = searches.map(item => item.key.toLowerCase())
      mainSearch.forEach(item => {
        if (!keys.includes(item.key.toLowerCase())) {
          searches.push(item)
        }
      })
    }
    let requireFields = searches.filter(item => item.required && item.value === '')
    if (requireFields.length > 0) {
      return
    }
    let _orderBy = orderBy || setting.order
    let param = UtilsDM.getStatQueryDataParams(setting, config.statFields, searches, _orderBy, BID)
    Api.genericInterface(param).then(res => {
      if (res.status) {
        let _data = res.data[0]
        let values = []
        if (_data) {
          config.statFields.forEach(item => {
            if (_data[item.field] || _data[item.field] === 0) {
              let val = +_data[item.field]
              if (isNaN(val)) {
                val = 0
              }
              val = val.toFixed(item.decimal)
              values.push({label: item.label, value: val})
            }
          })
        }
        this.setState({
          statFValue: values
        })
      } else {
        this.setState({
          statFValue: []
        })
        notification.error({
          top: 92,
          message: res.message,
          duration: 10
        })
      }
    })
  }
  /**
   * @description 搜索条件改变时,重置表格数据
   * 含有初始不加载的页面,修改设置
   */
@@ -420,7 +384,6 @@
        setting: {...setting, onload: 'true'}
      }, () => {
        this.loadmaindata()
        this.getStatFieldsValue()
      })
    } else {
      this.setState({
@@ -428,7 +391,6 @@
        search: searches
      }, () => {
        this.loadmaindata(true, 'true')
        this.getStatFieldsValue()
      })
    }
  }
@@ -463,11 +425,9 @@
        pageIndex: 1
      }, () => {
        this.loadmaindata(true, 'true')
        this.getStatFieldsValue()
      })
    } else {
      this.loadmaindata(true, 'false')
      this.getStatFieldsValue()
    }
  }
@@ -498,7 +458,7 @@
    })
  }
  reloadData = (menuId, id, item) => {
  reloadData = (menuId, id) => {
    const { config } = this.state
    if (config.uuid !== menuId) return
@@ -506,7 +466,7 @@
    if (!id) {
      this.reloadtable()
    } else {
      this.loadmainLinedata(id, item)
      this.loadmainLinedata(id)
    }
  }
@@ -521,7 +481,6 @@
        BData: data
      }, () => {
        this.loadmaindata(true, 'true')
        this.getStatFieldsValue()
      })
    }
  }
@@ -589,7 +548,7 @@
  }
  render() {
    const { BID, setting, actions, config, columns, BData, data, selectedData, lock } = this.state
    const { BID, setting, actions, config, columns, BData, data, selectedData } = this.state
    let style = {...config.style}
    if (config.wrap.empty === 'hidden' && data.length === 0) {
@@ -602,15 +561,14 @@
        {config.search && config.search.length ?
          <MainSearch BID={BID} config={config} refreshdata={this.refreshbysearch}/> : null
        }
        <MainAction
        {actions.length > 0 ? <MainAction
          BID={BID}
          setting={setting}
          actions={actions}
          BData={BData}
          lock={lock}
          columns={config.columns}
          selectedData={selectedData}
        />
        /> : null}
        <MainTable
          BID={BID}
          setting={setting}
@@ -623,8 +581,6 @@
          loading={this.state.loading}
          refreshdata={this.refreshbytable}
          chgSelectData={(selects) => this.setState({selectedData: selects})}
          changeLock={(lock) => this.setState({lock: lock})}
          statFValue={this.state.statFValue}
        />
      </div>
    )
src/tabviews/custom/components/table/edit-table/index.scss
@@ -5,19 +5,19 @@
  .normal-header {
    margin-bottom: 10px;
  }
  .top-search {
  .mk-search-wrap {
    border-bottom: 1px solid #efefef;
    padding-top: 10px;
  }
  .button-list.toolbar-button {
    padding: 0;
    line-height: 45px;
    float: left;
    float: right;
    margin-right: 80px;
    position: relative;
    z-index: 2;
    button {
      margin-right: 0px;
      margin-bottom: 0px;
    }
  }
  .toolbar-button + .edit-custom-table-btn-wrap {
    position: absolute;
    right: 0px;
    margin-top: 15px;
  }
}
src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -1,8 +1,8 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Table, Typography, Switch, Modal, Input, InputNumber, Tooltip, Button, notification, message, Select } from 'antd'
import { ExclamationCircleOutlined, EditOutlined, PlusOutlined, PlusCircleOutlined, DeleteOutlined } from '@ant-design/icons'
import { Table, Typography, Modal, Input, InputNumber, Button, notification, message, Select } from 'antd'
import { EditOutlined } from '@ant-design/icons'
import moment from 'moment'
import Api from '@/api'
@@ -17,7 +17,6 @@
import './index.scss'
const { Paragraph } = Typography
const { confirm } = Modal
const CardCellComponent = asyncComponent(() => import('@/tabviews/custom/components/card/cardcellList'))
class BodyRow extends React.Component {
@@ -99,17 +98,12 @@
class BodyCell extends React.Component {
  state = {
    editing: false,
    err: null
    err: null,
    value: ''
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props.record), fromJS(nextProps.record)) ||
      nextState.editing !== this.state.editing ||
      nextState.err !== this.state.err
  }
  componentDidMount () {
    MKEmitter.addListener('tdFocus', this.tdFocus)
    return !is(fromJS(this.props.record), fromJS(nextProps.record)) || !is(fromJS(this.state), fromJS(nextState))
  }
  /**
@@ -119,17 +113,6 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('tdFocus', this.tdFocus)
  }
  tdFocus = (id) => {
    const { col, record } = this.props
    if (id !== col.uuid + record.$$uuid) return
    if (col.ctrlField && col.ctrlValue.includes(record[col.ctrlField])) return
    this.focus()
  }
  enterPress = () => {
@@ -143,7 +126,8 @@
      } else if (col.enter === '$sub') {
        MKEmitter.emit('subLine', col, record)
      } else if (col.enter !== '$noAct') {
        MKEmitter.emit('tdFocus', col.enter + record.$$uuid)
        let node = document.getElementById(col.enter + record.$$uuid)
        node && node.click()
      }
    }, 50)
@@ -154,6 +138,8 @@
  focus = () => {
    const { col, record } = this.props
    if (col.ctrlField && col.ctrlValue.includes(record[col.ctrlField])) return
    if (col.editType === 'switch' || col.editType === 'select') {
      this.setState({editing: true}, () => {
@@ -214,6 +200,7 @@
    } else if (col.required === 'true' && !val) {
      err = '请填写' + col.label
    }
    this.setState({value: val, err})
  }
@@ -228,17 +215,18 @@
      } else if (col.enter === '$sub') {
        MKEmitter.emit('subLine', col, record)
      } else if (col.enter !== '$noAct') {
        MKEmitter.emit('tdFocus', col.enter + record.$$uuid)
        let node = document.getElementById(col.enter + record.$$uuid)
        node && node.click()
      }
    }, 50)
    let values = {}
    if (col.editField) {
      values[col.field] = label
      values[col.editField] = val
    } else {
    // if (col.editField) {
    //   values[col.field] = label
    //   values[col.editField] = val
    // } else {
      values[col.field] = val
    }
    // }
    MKEmitter.emit('changeRecord', col.tableId, {...record, ...values})
  }
@@ -256,12 +244,12 @@
        })
      }
      if (col.editField) {
        values[col.field] = _option.label
        values[col.editField] = val
      } else {
      // if (col.editField) {
      //   values[col.field] = _option.label
      //   values[col.editField] = val
      // } else {
        values[col.field] = val
      }
      // }
    }
    this.setState({editing: false})
@@ -272,7 +260,8 @@
      } else if (col.enter === '$sub') {
        MKEmitter.emit('subLine', col, record)
      } else if (col.enter !== '$noAct') {
        MKEmitter.emit('tdFocus', col.enter + record.$$uuid)
        let node = document.getElementById(col.enter + record.$$uuid)
        node && node.click()
      }
    }, 50)
@@ -301,6 +290,10 @@
      let content = ''
      if (record[col.field] !== undefined) {
        content = `${record[col.field]}`
      }
      if (col.editType === 'select' && col.options.length > 0) {
        content = col.map.get(content) || content
      }
      if (content !== '') {
@@ -337,26 +330,25 @@
        if (editing) {
          if (!col.editType || col.editType === 'text') {
            return (<td className="editing_table_cell">
              <Input id={col.uuid + record.$$uuid} defaultValue={value} onChange={(e) => this.onChange(e.target.value)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
              {err ? <Tooltip title={err}><ExclamationCircleOutlined /></Tooltip> : null}
              <Input className={err ? 'has-error' : ''} title={err} id={col.uuid + record.$$uuid} defaultValue={value} onChange={(e) => this.onChange(e.target.value)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
            </td>)
          } else if (col.editType === 'switch') {
            let _value = ''
            if (col.editField) {
              _value = record[col.editField] !== undefined ? record[col.editField] : ''
            } else {
            // if (col.editField) {
            //   _value = record[col.editField] !== undefined ? record[col.editField] : ''
            // } else {
              _value = record[col.field] !== undefined ? record[col.field] : ''
            }
            // }
            return (<td className="editing_table_cell">
              <CusSwitch config={col} defaultValue={_value} autoFocus={true} onChange={this.onSwitchChange} onBlur={this.switchBlur}/>
            </td>)
          } else {
            let _value = ''
            if (col.editField) {
              _value = record[col.editField] !== undefined ? record[col.editField] : ''
            } else {
            // if (col.editField) {
            //   _value = record[col.editField] !== undefined ? record[col.editField] : ''
            // } else {
              _value = record[col.field] !== undefined ? record[col.field] : ''
            }
            // }
            return (<td className="editing_table_cell">
              <Select
                showSearch
@@ -374,9 +366,7 @@
          }
        } else {
          return (<td className={className + ' pointer'} style={style}>
            {col.addable ? <PlusCircleOutlined onClick={() => MKEmitter.emit('addRecord', col.tableId, {...record})} className="mk-editable mk-plus"/> : null}
            <div className="mk-mask" onClick={this.focus}></div>{content}
            {col.delable ? <DeleteOutlined onClick={() => MKEmitter.emit('delRecord', col.tableId, {...record})} className="mk-editable mk-del"/> : null}
            <div className="mk-mask" id={col.uuid + record.$$uuid} onClick={this.focus}></div>{content}
          </td>)
        }
      } else {
@@ -387,6 +377,9 @@
      try {
        content = parseFloat(record[col.field])
        if (isNaN(content)) {
          content = ''
        }
        if (col.noValue === 'hide' && content === 0) {
          content = ''
        }
      } catch (e) {
@@ -431,15 +424,16 @@
      if (col.editable === 'true' && !disabled) {
        if (editing) {
          let val = value
          if (col.noValue === 'hide' && value === 0) {
            val = ''
          }
          return (<td className="editing_table_cell">
            <InputNumber id={col.uuid + record.$$uuid} defaultValue={value} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
            {err ? <Tooltip title={err}><ExclamationCircleOutlined /></Tooltip> : null}
            <InputNumber className={err ? 'has-error' : ''} title={err} id={col.uuid + record.$$uuid} defaultValue={val} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
          </td>)
        } else {
          return (<td className={className + ' pointer'} style={style}>
            {col.addable ? <PlusCircleOutlined onClick={() => MKEmitter.emit('addRecord', col.tableId, {...record})} className="mk-editable mk-plus"/> : null}
            <div className="mk-mask" onClick={this.focus}></div>{content}
            {col.delable ? <DeleteOutlined onClick={() => MKEmitter.emit('delRecord', col.tableId, {...record})} className="mk-editable mk-del"/> : null}
            <div className="mk-mask" id={col.uuid + record.$$uuid} onClick={this.focus}></div>{content}
          </td>)
        }
      } else {
@@ -478,13 +472,14 @@
      content = content === undefined ? '' : content
      if (col.noValue === 'hide' && content === 0) {
        content = ''
      }
      if (content !== '') {
        content = `${col.prefix || ''}${content}${col.postfix || ''}`
        if (col.eval === 'false') {
          content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
          content = <span dangerouslySetInnerHTML={{__html: content}}></span>
        }
        content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
        content = <span dangerouslySetInnerHTML={{__html: content}}></span>
      }
      if (col.marks) {
@@ -521,30 +516,37 @@
      children = (
        <CardCellComponent data={record} cards={config} elements={col.elements}/>
      )
    } else if (col.type === 'operation') {
      style.padding = '0px 5px'
      children = (
        <Button type="link" style={{color: 'rgb(255, 77, 79)', backgroundColor: 'transparent'}} onClick={() => MKEmitter.emit('delRecord', col.tableId, {...record})}>删除</Button>
      )
    }
    return (<td className={className} style={style}>{col.addable ? <PlusCircleOutlined onClick={() => MKEmitter.emit('addRecord', col.tableId, {...record})} className="mk-editable mk-plus"/> : null}{children}{col.delable ? <DeleteOutlined onClick={() => MKEmitter.emit('delRecord', col.tableId, {...record})} className="mk-editable mk-del"/> : null}</td>)
    // return (<td className={className} style={style}>{children}</td>)
    return (<td className={className} style={style}>{children}</td>)
  }
}
class BodyAllCell extends React.Component {
  state = {
    err: null
    err: null,
    value: ''
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props.record), fromJS(nextProps.record)) ||
      nextState.err !== this.state.err
    return !is(fromJS(this.props.record), fromJS(nextProps.record)) || !is(fromJS(this.state), fromJS(nextState))
  }
  componentDidMount () {
    MKEmitter.addListener('tdFocus', this.tdFocus)
  UNSAFE_componentWillMount() {
    const { col } = this.props
    if (col && col.editable === 'true') {
      this.setState({value: this.props.record[col.field]})
    }
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    const { col } = this.props
    const { value } = this.state
    if (col && col.editable === 'true' && nextProps.record[col.field] !== value) {
      this.setState({value: nextProps.record[col.field]})
    }
  }
  /**
@@ -554,18 +556,12 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('tdFocus', this.tdFocus)
  }
  tdFocus = (id) => {
    const { col, record } = this.props
    if (id !== col.uuid + record.$$uuid) return
    this.focus()
  }
  enterPress = () => {
    const { col, record } = this.props
    this.onBlur()
    setTimeout(() => {
      if (col.enter === '$next') {
@@ -573,46 +569,35 @@
      } else if (col.enter === '$sub') {
        MKEmitter.emit('subLine', col, record)
      } else if (col.enter !== '$noAct') {
        MKEmitter.emit('tdFocus', col.enter + record.$$uuid)
        let node = document.getElementById(col.enter + record.$$uuid)
        if (node) {
          if (col.triType === 'click') {
            node.click()
          } else {
            node.select && node.select()
          }
        }
      }
    }, 50)
  }
  focus = () => {
    const { col, record } = this.props
    if (col.editType === 'switch' || col.editType === 'select') {
      let node = document.getElementById(col.uuid + record.$$uuid)
      node && node.click()
    } else {
      let err = null
      let val = record[col.field] !== undefined ? record[col.field] : ''
      if (col.type === 'number') {
        val = +val
        if (isNaN(val)) {
          val = 0
        }
        if (typeof(col.max) === 'number' && val > col.max) {
          err = col.label + '最大为' + col.max
        } else if (typeof(col.min) === 'number' && val < col.min) {
          err = col.label + '最小为' + col.min
        }
      } else if (col.required === 'true' && !val) {
        err = '请填写' + col.label
      }
      this.setState({err}, () => {
        let node = document.getElementById(col.uuid + record.$$uuid)
        node && node.select()
      })
    }
  }
  
  onChange = (val) => {
    const { col } = this.props
    if (col.noValue === 'hide' && val === null) {
      this.setState({value: 0})
    } else {
      this.setState({value: val})
    }
  }
  onBlur = () => {
    const { col, record } = this.props
    const { value } = this.state
    
    let err = null
    let val = value
    if (col.type === 'number') {
      val = +val
@@ -627,8 +612,12 @@
    } else if (col.required === 'true' && !val) {
      err = '请填写' + col.label
    }
    this.setState({err})
    MKEmitter.emit('changeRecord', col.tableId, {...record, [col.field]: val})
    if (value !== record[col.field]) {
      MKEmitter.emit('changeRecord', col.tableId, {...record, [col.field]: val})
    }
  }
  onSwitchChange = (val, label) => {
@@ -640,17 +629,24 @@
      } else if (col.enter === '$sub') {
        MKEmitter.emit('subLine', col, record)
      } else if (col.enter !== '$noAct') {
        MKEmitter.emit('tdFocus', col.enter + record.$$uuid)
        let node = document.getElementById(col.enter + record.$$uuid)
        if (node) {
          if (col.triType === 'click') {
            node.click()
          } else {
            node.select && node.select()
          }
        }
      }
    }, 50)
    let values = {}
    if (col.editField) {
      values[col.field] = label
      values[col.editField] = val
    } else {
    // if (col.editField) {
    //   values[col.field] = label
    //   values[col.editField] = val
    // } else {
      values[col.field] = val
    }
    // }
    MKEmitter.emit('changeRecord', col.tableId, {...record, ...values})
  }
@@ -668,12 +664,12 @@
        })
      }
      if (col.editField) {
        values[col.field] = _option.label
        values[col.editField] = val
      } else {
      // if (col.editField) {
      //   values[col.field] = _option.label
      //   values[col.editField] = val
      // } else {
        values[col.field] = val
      }
      // }
    }
    setTimeout(() => {
@@ -682,7 +678,14 @@
      } else if (col.enter === '$sub') {
        MKEmitter.emit('subLine', col, record)
      } else if (col.enter !== '$noAct') {
        MKEmitter.emit('tdFocus', col.enter + record.$$uuid)
        let node = document.getElementById(col.enter + record.$$uuid)
        if (node) {
          if (col.triType === 'click') {
            node.click()
          } else {
            node.select && node.select()
          }
        }
      }
    }, 50)
@@ -690,8 +693,10 @@
  }
  render() {
    let { col, config, record, style, className } = this.props
    let { col, config, record, style, className, ...resProps } = this.props
    const { err } = this.state
    if (!col) return (<td {...resProps} className={className} style={style}/>)
    let disabled = false
    if (col.ctrlField) {
@@ -702,16 +707,15 @@
    if (col.type === 'text') {
      if (col.editable === 'true' && !disabled) {
        let _value = ''
        if (col.editField) {
          _value = record[col.editField] !== undefined ? record[col.editField] : ''
        } else {
        // if (col.editField) {
        //   _value = record[col.editField] !== undefined ? record[col.editField] : ''
        // } else {
          _value = record[col.field] !== undefined ? record[col.field] : ''
        }
        // }
        
        if (!col.editType || col.editType === 'text') {
          children = (<>
            <Input id={col.uuid + record.$$uuid} defaultValue={_value} onChange={(e) => this.onChange(e.target.value)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
            {err ? <Tooltip title={err}><ExclamationCircleOutlined /></Tooltip> : null}
            <Input className={err ? 'has-error' : ''} title={err} id={col.uuid + record.$$uuid} defaultValue={_value} onChange={(e) => this.onChange(e.target.value)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
          </>)
        } else if (col.editType === 'switch') {
          children = (
@@ -736,6 +740,10 @@
        let content = ''
        if (record[col.field] !== undefined) {
          content = `${record[col.field]}`
        }
        if (col.editType === 'select' && col.options.length > 0) {
          content = col.map.get(content) || content
        }
        if (content !== '') {
@@ -772,15 +780,22 @@
    } else if (col.type === 'number') {
      if (col.editable === 'true' && !disabled) {
        let _value = record[col.field] !== undefined ? record[col.field] : ''
        if (col.noValue === 'hide' && _value === 0) {
          _value = ''
        }
        children = (<>
          <InputNumber id={col.uuid + record.$$uuid} defaultValue={_value} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress}/>
          {err ? <Tooltip title={err}><ExclamationCircleOutlined /></Tooltip> : null}
          <InputNumber className={err ? 'has-error' : ''} title={err} id={col.uuid + record.$$uuid} defaultValue={_value} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
        </>)
      } else {
        let content = ''
        try {
          content = parseFloat(record[col.field])
          if (isNaN(content)) {
            content = ''
          }
          if (col.noValue === 'hide' && content === 0) {
            content = ''
          }
        } catch (e) {
@@ -857,13 +872,14 @@
      content = content === undefined ? '' : content
      if (col.noValue === 'hide' && content === 0) {
        content = ''
      }
      if (content !== '') {
        content = `${col.prefix || ''}${content}${col.postfix || ''}`
        if (col.eval === 'false') {
          content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
          content = <span dangerouslySetInnerHTML={{__html: content}}></span>
        }
        content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
        content = <span dangerouslySetInnerHTML={{__html: content}}></span>
      }
      if (col.marks) {
@@ -892,20 +908,22 @@
      children = (
        <CardCellComponent data={record} cards={config} elements={col.elements}/>
      )
    } else if (col.type === 'operation') {
      style.padding = '0px 5px'
    } else if (col.type === 'action') {
      style.padding = '0px'
      if (col.style) {
        style = {...style, ...col.style}
      }
      children = (
        <Button type="link" style={{color: 'rgb(255, 77, 79)', backgroundColor: 'transparent'}} onClick={() => MKEmitter.emit('delRecord', col.tableId, {...record})}>删除</Button>
        <CardCellComponent data={record} cards={config} elements={col.elements}/>
      )
    }
    return (<td className={'editing_all_table_cell ' + className} style={style}>{col.addable ? <PlusCircleOutlined onClick={() => MKEmitter.emit('addRecord', col.tableId, {...record})} className="mk-editable mk-plus"/> : null}{children}{col.delable ? <DeleteOutlined onClick={() => MKEmitter.emit('delRecord', col.tableId, {...record})} className="mk-editable mk-del"/> : null}</td>)
    return (<td className={'editing_all_table_cell ' + className} style={style}>{children}</td>)
  }
}
class NormalTable extends Component {
  static propTpyes = {
    statFValue: PropTypes.any,       // 合计字段数据
    MenuID: PropTypes.string,        // 菜单Id
    setting: PropTypes.object,       // 表格全局设置:tableType(表格是否可选、单选、多选)、actionfixed(按钮固定)
    columns: PropTypes.array,        // 表格列
@@ -915,37 +933,32 @@
    total: PropTypes.any,            // 总数
    loading: PropTypes.bool,         // 表格加载中
    refreshdata: PropTypes.func,     // 表格中排序列、页码的变化时刷新
    changeLock: PropTypes.func,
    chgSelectData: PropTypes.func,
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    data: [],
    edData: [],
    edColumns: [],
    selectedRowKeys: [],  // 表格中选中行
    tableId: '',          // 表格ID
    pageIndex: 1,         // 初始页面索引
    pageSize: 10,         // 每页数据条数
    columns: null,        // 显示列
    forms: [],
    pickup: false,        // 收起未选择项
    orderfields: {},      // 排序id与field转换
    loading: false,
    editable: false,
    pageOptions: []
    pageOptions: [],
    deForms: null
  }
  UNSAFE_componentWillMount () {
    const { setting, fields, columns } = this.props
    const { setting, fields, columns, BID } = this.props
    let orderfields = {}
    let initEditLine = null
    let edColumns = []
    let _columns = []
    let deForms = []
    let _forms = {}
    let hasBid = false
    let getColumns = (cols) => {
      return cols.map(item => {
@@ -957,26 +970,30 @@
        } else {
          if (item.editable === 'true') {
            _forms[item.field] = item
            if (!initEditLine) {
              initEditLine = item
            }
            if (item.ctrlField) {
              item.ctrlValue = item.ctrlValue.split(',')
            }
          }
          if (item.type === 'text' && item.editable === 'true' && item.editType === 'select' && item.resourceType === '1') {
            let _option = Utils.getSelectQueryOptions(item)
            if (window.GLOB.debugger === true || window.debugger === true) {
              console.info(_option.sql)
            if (item.type === 'text' && item.editType === 'select') {
              item.map = new Map()
              if (item.resourceType === '1') {
                let _option = Utils.getSelectQueryOptions(item)
                if (/@BID@/ig.test(_option.sql)) {
                  hasBid = true
                }
                item.base_sql = _option.sql
                item.arr_field = _option.field
                deForms.push(item)
              } else {
                item.options.forEach(cell => {
                  item.map.set(cell.value, cell.label)
                })
              }
            }
            item.base_sql = window.btoa(window.encodeURIComponent(_option.sql))
            item.arr_field = _option.field
            deForms.push(item)
          }
    
          if (item.field) {
@@ -986,7 +1003,7 @@
          cell = {
            align: item.Align,
            dataIndex: item.uuid,
            title: item.label,
            title: item.editable === 'true' ? <span>{item.label}<EditOutlined className="system-color mk-edit-sign"/></span> : item.label,
            sorter: !!(item.field && item.IsSort === 'true'),
            width: item.Width || 120,
            $type: item.type,
@@ -1001,6 +1018,7 @@
        return cell
      })
    }
    _columns = getColumns(columns)
    let forms = []
@@ -1013,32 +1031,6 @@
        forms.push(item)
      }
    })
    _columns.forEach(item => {
      if (item.$type === 'action') return
      let _copy = fromJS(item).toJS()
      _copy.sorter = false
      if (item.editable === 'true') {
        _copy.title = <span>{item.label}<EditOutlined className="system-color mk-edit-sign"/></span>
      }
      edColumns.push(_copy)
    })
    if (setting.delable !== 'false' && setting.operType !== 'buoyMode') {
      edColumns.push({
        align: 'center',
        dataIndex: 'mkoperation',
        title: '操作',
        sorter: false,
        width: 100,
        onCell: record => ({
          record,
          col: {type: 'operation', tableId: setting.tableId},
        })
      })
    }
    let size = (setting.pageSize || 10) + ''
    let pageOptions = ['10', '25', '50', '100', '500', '1000']
@@ -1053,14 +1045,15 @@
      pageSize: setting.pageSize || 10,
      pageOptions,
      columns: _columns,
      edColumns,
      tableId: setting.tableId,
      orderfields,
      initEditLine,
      editable: setting.editable === 'true'
      orderfields
    }, () => {
      if (deForms.length > 0) {
        this.improveActionForm(deForms)
        if (hasBid && setting.supModule && !BID) {
          this.setState({ deForms })
        } else {
          this.improveActionForm(deForms, BID)
        }
      }
      const element = document.getElementById(setting.tableId)
@@ -1075,10 +1068,19 @@
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    const { BID } = this.props
    const { deForms } = this.state
    if (deForms && nextProps.BID !== BID) {
      this.improveActionForm(deForms, nextProps.BID)
    }
  }
  componentDidMount () {
    MKEmitter.addListener('subLine', this.subLine)
    MKEmitter.addListener('nextLine', this.nextLine)
    MKEmitter.addListener('addRecord', this.addLine)
    MKEmitter.addListener('addRecord', this.addRecord)
    MKEmitter.addListener('delRecord', this.delRecord)
    MKEmitter.addListener('resetTable', this.resetTable)
    MKEmitter.addListener('transferData', this.transferData)
@@ -1094,7 +1096,7 @@
    }
    MKEmitter.removeListener('subLine', this.subLine)
    MKEmitter.removeListener('nextLine', this.nextLine)
    MKEmitter.removeListener('addRecord', this.addLine)
    MKEmitter.removeListener('addRecord', this.addRecord)
    MKEmitter.removeListener('delRecord', this.delRecord)
    MKEmitter.removeListener('resetTable', this.resetTable)
    MKEmitter.removeListener('transferData', this.transferData)
@@ -1102,24 +1104,19 @@
  }
  transferData = (menuid, data, type) => {
    if (menuid !== this.props.MenuID) return
    const { MenuID, setting } = this.props
    if (menuid !== MenuID) return
    if (type !== 'line') {
      this.setState({data: data || []})
      this.setState({edData: data})
      if (this.state.editable && !this.state.pickup) {
      if (setting.addable && data.length === 0) {
        setTimeout(() => {
          this.pickupChange()
        }, 200)
          this.plusLine(true)
        }, 10)
      }
    } else if (type === 'line' && data.$$uuid) {
      let _data = this.state.data.map(item => {
        if (item.$$uuid === data.$$uuid) {
          return data
        } else {
          return item
        }
      })
    } else if (type === 'line') {
      let _edData = this.state.edData.map(item => {
        if (item.$$uuid === data.$$uuid) {
          return data
@@ -1128,24 +1125,48 @@
        }
      })
      this.setState({edData: _edData, data: _data})
      this.setState({edData: _edData})
    }
    this.setState({editable: false})
  }
  improveActionForm = (deForms) => {
    const { BID, setting } = this.props
  improveActionForm = (deForms, BID) => {
    const { setting } = this.props
    let deffers = []
    let mainItems = []  // 云端或单点数据
    let localItems = [] // 本地数据
    let cache = setting.cache !== 'false'
    let debug = window.GLOB.debugger === true || window.debugger === true
    let _sql = `Declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)  select @mk_departmentcode='${sessionStorage.getItem('departmentcode') || ''}',@mk_organization='${sessionStorage.getItem('organization') || ''}',@mk_user_type='${sessionStorage.getItem('mk_user_type') || ''}'\n`
    let _sso = _sql
    deForms.forEach(item => {
      if (item.database === 'sso') {
        mainItems.push(`select '${item.uuid}' as obj_name,'${item.arr_field}' as arr_field,'${item.base_sql}' as LText`)
        let sql = _sso + item.base_sql
        _sso = ''
        sql = sql.replace(/@BID@/ig, `'${BID}'`)
        if (debug) {
          console.info(sql)
        }
        sql = sql.replace(/%/ig, ' mpercent ')
        mainItems.push(`select '${item.uuid}' as obj_name,'${item.arr_field}' as arr_field,'${window.btoa(window.encodeURIComponent(sql))}' as LText`)
      } else {
        localItems.push(`select '${item.uuid}' as obj_name,'${item.arr_field}' as arr_field,'${item.base_sql}' as LText`)
        let sql = _sql + item.base_sql
        _sql = ''
        sql = sql.replace(/@BID@/ig, `'${BID}'`)
        if (debug) {
          console.info(sql)
        }
        sql = sql.replace(/%/ig, ' mpercent ')
        localItems.push(`select '${item.uuid}' as obj_name,'${item.arr_field}' as arr_field,'${window.btoa(window.encodeURIComponent(sql))}' as LText`)
      }
    })
@@ -1228,16 +1249,14 @@
  }
  resetFormList = (result) => {
    const { columns } = this.props
    const { edColumns } = this.state
    const { columns, edData } = this.state
    let _edColumns = []
    let reCols = {}
    columns.forEach(item => {
    this.props.columns.forEach(item => {
      if (item.resourceType === '1' && result[item.uuid] && result[item.uuid].length > 0) {
        let options = []
        let _map = new Map()
        let all = false
        result[item.uuid].forEach(cell => {
          let _cell = {key: Utils.getuuid()}
@@ -1254,8 +1273,8 @@
            }
          }
          if (_map.has(_cell.value)) return
          _map.set(_cell.value, 0)
          if (item.map.has(_cell.value)) return
          item.map.set(_cell.value, _cell.label)
          if (item.linkSubField) {
            item.linkSubField.forEach(m => {
@@ -1272,11 +1291,11 @@
        item.options = options
        reCols[item.uuid] = item
        reCols[item.uuid] = fromJS(item).toJS()
      }
    })
    _edColumns = edColumns.map(item => {
    _edColumns = columns.map(item => {
      if (reCols[item.dataIndex]) {
        item.onCell = record => ({
          record,
@@ -1287,29 +1306,34 @@
      return item
    })
    if (this.state.pickup) {
      this.setState({
        pickup: false
      }, () => {
        this.setState({pickup: true, edColumns: _edColumns})
      })
    } else {
      this.setState({edColumns: _edColumns})
    }
    this.setState({columns: [], edData: []}, () => {
      this.setState({columns: _edColumns, edData: edData})
    })
  }
  
  nextLine = (col, uuid) => {
    const { setting } = this.props
    const { edData, initEditLine, tableId } = this.state
    const { edData, tableId } = this.state
    if (col.tableId !== tableId) return
    let index = edData.findIndex(item => item.$$uuid === uuid)
    let next = edData[index + 1] || null
    if (next && initEditLine) {
      MKEmitter.emit('tdFocus', initEditLine.uuid + next.$$uuid)
    } else if (setting.addable === 'true') {
    if (next) {
      let node = document.getElementById(setting.initId + next.$$uuid)
      if (node) {
        if (setting.editType === 'multi') {
          if (setting.triType === 'click') {
            node.click()
          } else {
            node.select && node.select()
          }
        } else {
          node.click()
        }
      }
    } else if (setting.addable) {
      setTimeout(() => {
        this.plusLine()
      }, 10)
@@ -1321,83 +1345,31 @@
  }
  subLine = (col, record) => {
    const { tableId, forms, edData } = this.state
    const { tableId, edData } = this.state
    if (col && col.tableId !== tableId) return
    if (edData.filter(item => !item.$origin).length > 1) {
      setTimeout(() => {
        this.submit(edData)
      }, 10)
      return
    }
    setTimeout(() => {
      let item = fromJS(record).toJS()
      let line = []
      forms.forEach(col => {
        if (col.editable !== 'true' || item.$deleted) {
          if (col.type === 'number') {
            item[col.field] = +item[col.field]
            if (isNaN(item[col.field])) {
              item[col.field] = 0
            }
          } else {
            item[col.field] = item[col.field] !== undefined ? (item[col.field] + '') : ''
          }
          return
        }
        if (col.type === 'text') {
          let val = item[col.field] !== undefined ? (item[col.field] + '') : ''
          if (col.required === 'true' && !val) {
            line.push(`${col.label}不可为空`)
          }
          item[col.field] = val
        } else if (col.type === 'number') {
          let val = item[col.field]
          if (!val && val !== 0) {
            line.push(`${col.label}不可为空`)
            return
          }
          val = +val
          if (isNaN(val)) {
            line.push(`${col.label}数据格式错误`)
            return
          }
          val = +val.toFixed(col.decimal || 0)
          if (typeof(col.max) === 'number' && val > col.max) {
            line.push(`${col.label}不可大于${col.max}`)
          } else if (typeof(col.min) === 'number' && val < col.min) {
            line.push(`${col.label}不可小于${col.min}`)
          }
          item[col.field] = val
        }
      })
      let err = line.join(',')
      if (err) {
        notification.warning({
          top: 92,
          message: err,
          duration: 5
        })
      } else {
        this.submit([item], 'simple')
    let _data = edData.map(item => {
      if (item.$$uuid === record.$$uuid) {
        item.$origin = false
      }
    }, 10)
      return item
    })
    this.setState({edData: _data}, () => {
      this.submit()
    })
  }
  plusLine = () => {
    const { edData, forms, initEditLine } = this.state
  plusLine = (auto) => {
    const { setting } = this.props
    const { edData, forms } = this.state
    let item = {...edData[edData.length - 1]}
    let item = edData.length > 0 ? {...edData[edData.length - 1]} : {}
    item.$$uuid = Utils.getguid()
    item.$type = 'add'
    item.$forbid = true
    item.$Index = ''
    forms.forEach(col => {
@@ -1416,7 +1388,18 @@
    })
    this.setState({edData: [...edData, item]}, () => {
      MKEmitter.emit('tdFocus', initEditLine.uuid + item.$$uuid)
      let node = document.getElementById(setting.initId + item.$$uuid)
      if (node && !auto) {
        if (setting.editType === 'multi') {
          if (setting.triType === 'click') {
            node.click()
          } else {
            node.select && node.select()
          }
        } else {
          node.click()
        }
      }
    })
  }
@@ -1425,118 +1408,112 @@
    const { tableId, edData } = this.state
    if (id !== tableId) return
    let _data = []
    if (record.$type === 'add') {
      _data = edData.filter(item => item.$$uuid !== record.$$uuid)
      let _data = edData.filter(item => item.$$uuid !== record.$$uuid)
      this.setState({edData: _data})
    } else {
      _data = edData.map(item => {
      let _data = fromJS(edData).toJS().map(item => {
        if (item.$$uuid === record.$$uuid) {
          record.$deleted = true
          record.$origin = false
          record.$type = 'del'
          return record
        } else {
          return item
          item.$deleted = true
          item.$origin = false
          item.$type = 'del'
        }
        return item
      })
      if (setting.commit === 'simple' && record.$deleted) {
        this.subLine(null, record)
      }
      this.setState({edData: _data}, () => {
        if (setting.commit === 'simple') {
          this.submit()
        }
      })
    }
    this.setState({edData: _data})
  }
  changeRecord = (id, record) => {
    const { setting } = this.props
    const { tableId } = this.state
    if (id !== tableId) return
    let lock = record.$lock
    let _data = this.state.edData.map(item => {
      if (item.$$uuid === record.$$uuid) {
        record.$origin = false
        record.$lock = true
        delete record.$forbid
        return record
      } else {
        return item
      }
    })
    this.setState({edData: _data})
    this.setState({edData: _data}, () => {
      if (setting.tableType && setting.hasAction && !lock && this.state.selectedRowKeys.includes(record.$$uuid)) {
        this.selectdata(this.state.selectedRowKeys)
      }
    })
  }
  addLine = (id, record) => {
  addRecord = (id, record) => {
    const { BID } = this.props
    const { edData, forms, tableId } = this.state
    if (id) {
      if (id !== tableId) return
      let _edData = fromJS(edData).toJS()
      let index = _edData.findIndex(item => record.$$uuid === item.$$uuid)
    if (id !== tableId) return
      let item = {}
    let _edData = fromJS(edData).toJS()
    let item = {}
    let index = null
    let copy = edData.length > 0 ? {...edData[edData.length - 1]} : null
      item.$$uuid = Utils.getguid()
      item.$type = 'add'
      item.$Index = ''
      item.$$BID = BID || ''
      forms.forEach(col => {
        if (col.initval !== '$copy') {
          item[col.field] = col.initval
        }
        if (col.type === 'number') {
          item[col.field] = +item[col.field]
          if (isNaN(item[col.field])) {
            item[col.field] = 0
          }
        }
        if (item[col.field] === undefined) {
          item[col.field] = ''
        }
      })
    if (record) {
      index = _edData.findIndex(item => record.$$uuid === item.$$uuid)
      index = index === -1 ? null : index
      _edData.splice(index, 0, item)
      this.setState({edData: _edData})
    } else {
      let item = {}
      if (edData.length > 0) {
        item = {...edData[edData.length - 1]}
        item.$$uuid = Utils.getguid()
        item.$type = 'add'
        item.$Index = ''
      } else {
        item.$$uuid = Utils.getguid()
        item.$type = 'add'
        item.$Index = ''
        item.$$BID = BID || ''
      }
      forms.forEach(col => {
        if (col.initval !== '$copy') {
          item[col.field] = col.initval
        }
        if (col.type === 'number') {
          item[col.field] = +item[col.field]
          if (isNaN(item[col.field])) {
            item[col.field] = 0
          }
        }
        if (item[col.field] === undefined) {
          item[col.field] = ''
        }
      })
      this.setState({edData: [...edData, item]})
      copy = {...record}
    }
    if (copy) {
      item = {...copy}
    }
    item.$$uuid = Utils.getguid()
    item.$type = 'add'
    item.$Index = ''
    item.$forbid = true
    item.$$BID = BID || ''
    forms.forEach(col => {
      if (col.initval !== '$copy') {
        item[col.field] = col.initval
      }
      if (col.type === 'number') {
        item[col.field] = +item[col.field]
        if (isNaN(item[col.field])) {
          item[col.field] = 0
        }
      }
      if (item[col.field] === undefined) {
        item[col.field] = ''
      }
    })
    if (index === null) {
      _edData.push(item)
    } else {
      _edData.splice(index, 0, item)
    }
    this.setState({edData: _edData})
  }
  checkData = () => {
    const { setting } = this.props
    const { edData, forms } = this.state
    if (edData.length === 0) {
@@ -1545,11 +1522,28 @@
        message: '提交数据不可为空!',
        duration: 5
      })
      return
      return null
    }
    let data = fromJS(edData).toJS()
    data = data.filter(item => !item.$forbid)
    if (setting.commit === 'change' || setting.commit === 'simple') {
      data = data.filter(item => !item.$origin)
    }
    if (data.length === 0) {
      notification.warning({
        top: 92,
        message: '数据未修改,不可提交!',
        duration: 5
      })
      return null
    }
    let err = ''
    let Index = 1
    let data = fromJS(edData).toJS().map(item => {
    data = data.map(item => {
      let line = []
      forms.forEach(col => {
        if (col.editable !== 'true' || item.$deleted) {
@@ -1571,7 +1565,9 @@
          item[col.field] = val
        } else if (col.type === 'number') {
          let val = item[col.field]
          if (!val && val !== 0) {
          if (col.noValue === 'hide' && !val) {
            val = 0
          } else if (!val && val !== 0) {
            line.push(`${col.label}不可为空`)
            return
          }
@@ -1609,27 +1605,30 @@
        message: err,
        duration: 5
      })
    } else {
      this.submit(data)
      return null
    }
    return data
  }
  submit = (data, type) => {
  submit = () => {
    const { submit, BID, setting } = this.props
    const { forms } = this.state
    if (type !== 'simple' && (setting.commit === 'change' || setting.commit === 'simple')) {
      data = data.filter(item => !item.$origin)
    }
    if (data.length === 0) {
    if (setting.supModule && !BID) {
      notification.warning({
        top: 92,
        message: '数据未修改,不可提交!',
        message: '需要上级主键值!',
        duration: 5
      })
      return
    }
    let data = this.checkData()
    if (!data) return
    let result = getEditTableSql(submit, data, forms)
@@ -1670,12 +1669,7 @@
      Api.genericInterface(param).then((res) => {
        if (res.status) {
          if (type === 'simple') {
            this.updataLine(data[0])
            this.execSuccess(res, type)
          } else {
            this.execSuccess(res)
          }
          this.execSuccess(res)
        } else {
          this.execError(res)
        }
@@ -1687,12 +1681,7 @@
      Api.genericInterface(param).then((res) => {
        if (res.status) {
          if (type === 'simple') {
            this.updataLine(data[0])
            this.execSuccess(res, type)
          } else {
            this.execSuccess(res)
          }
          this.execSuccess(res)
        } else {
          this.execError(res)
        }
@@ -1721,7 +1710,7 @@
    MKEmitter.emit('reloadData', this.props.MenuID, item.$$uuid, item)
  }
  execSuccess = (res, type) => {
  execSuccess = (res) => {
    const { submit } = this.props
    if (res && res.ErrCode === 'S') { // 执行成功
@@ -1742,13 +1731,11 @@
      loading: false
    })
    if (type === 'simple') return
    if (submit.closetab === 'true') {
      MKEmitter.emit('popclose')
    }
    if (submit.execSuccess !== 'never') {
      this.repick()
      MKEmitter.emit('refreshByButtonResult', submit.$menuId, submit.execSuccess, submit)
    }
  }
@@ -1782,33 +1769,12 @@
    })
    if (submit.execError !== 'never') {
      this.repick()
      MKEmitter.emit('refreshByButtonResult', submit.$menuId, submit.execError, submit)
    }
  }
  repick = () => {
    const { setting } = this.props
    const { data } = this.state
    if (setting.submittal === 'true') {
      this.setState({editable: true})
    }
    this.props.changeLock(false)
    this.setState({
      data: [],
      edData: [],
      pickup: false,
    }, () => {
      this.setState({
        data: data,
      })
    })
  }
  /**
   *
   * @description 选中行
   */
  onSelectChange = selectedRowKeys => {
    this.setState({ selectedRowKeys })
@@ -1824,28 +1790,28 @@
  /**
   * @description 点击整行,触发切换, 判断是否可选,单选或多选,进行对应操作
   */
  changeRow = (index) => {
  changeRow = (id) => {
    const { setting } = this.props
    if (!setting.tableType || this.state.pickup) return
    if (!setting.tableType) return
    
    let newkeys = fromJS(this.state.selectedRowKeys).toJS()
    let activeId = ''
    if (setting.tableType === 'radio') {
      activeId = index
      newkeys = [index]
      activeId = id
      newkeys = [id]
      this.setState({ selectedRowKeys: newkeys })
    } else {
      if (newkeys.includes(index)) {
        newkeys = newkeys.filter(item => item !== index)
      if (newkeys.includes(id)) {
        newkeys = newkeys.filter(item => item !== id)
        if (newkeys.length > 0) {
          activeId = newkeys.slice(-1)[0]
        }
      } else {
        activeId = index
        newkeys.push(index)
        activeId = id
        newkeys.push(id)
      }
      this.setState({ selectedRowKeys: newkeys })
@@ -1857,21 +1823,21 @@
  changedata = (id) => {
    const { MenuID } = this.props
    const { data } = this.state
    const { edData } = this.state
    let _data = ''
    if (id) {
      _data = data.filter(item => item.$$uuid === id)[0] || ''
      _data = edData.filter(item => item.$$uuid === id)[0] || ''
    }
    MKEmitter.emit('resetSelectLine', MenuID, id, _data)
  }
  selectdata = (keys) => {
    const { data } = this.state
    const { edData } = this.state
    let _data = data.filter(item => keys.includes(item.$$uuid))
    let _data = edData.filter(item => keys.includes(item.$$uuid))
    this.props.chgSelectData(_data)
  }
@@ -1907,96 +1873,23 @@
    }
  }
  pickupChange = () => {
    const { submit, MenuID, setting } = this.props
    const { data } = this.state
    let pickup = !this.state.pickup
    if (!submit.sheet) {
      notification.warning({
        top: 92,
        message: '提交按钮尚未设置,不可编辑!',
        duration: 5
      })
      return
    }
    if (!pickup && this.state.edData.filter(item => !item.$origin).length > 0) {
      const _this = this
      confirm({
        title: '数据已修改,确定放弃保存吗?',
        onOk() {
          _this.setState({
            data: [],
            edData: [],
            pickup
          }, () => {
            _this.setState({
              data: data,
              edData: pickup ? fromJS(data).toJS() : []
            })
          })
        },
        onCancel() {}
      })
    } else {
      pickup && MKEmitter.emit('resetSelectLine', MenuID, '', '')
      pickup && this.props.chgSelectData([])
      let keys = this.state.selectedRowKeys
      this.setState({
        data: [],
        edData: [],
        selectedRowKeys: [],
        pickup,
        loading: false,
        editable: false
      }, () => {
        if (pickup && setting.tableType === 'checkbox' && keys.length > 0) {
          this.setState({
            data: data,
            edData: fromJS(data).toJS().filter(item => {
              item.$origin = false
              return keys.includes(item.$$uuid)
            })
          })
        } else {
          this.setState({
            data: data,
            edData: pickup ? fromJS(data).toJS() : []
          })
        }
      })
    }
    this.props.changeLock(pickup)
  }
  render() {
    const { setting, statFValue, lineMarks, submit } = this.props
    const { pickup, tableId, data, edData, columns, edColumns, loading, pageOptions, selectedRowKeys } = this.state
    const { setting, lineMarks, submit } = this.props
    const { tableId, edData, columns, loading, pageOptions, selectedRowKeys } = this.state
    const components = {
      body: {
        row: BodyRow,
        cell: setting.editType !== 'multi' || !pickup ? BodyCell : BodyAllCell
        cell: setting.editType !== 'multi' ? BodyCell : BodyAllCell
      }
    }
    // 数据收起时,过滤已选数据
    let _data = data
    let _columns = columns
    if (pickup) {
      _data = edData
      _data = _data.filter(item => !item.$deleted)
      _columns = edColumns
    }
    let _data = edData.filter(item => !item.$deleted)
    // 设置表格选择属性:单选、多选、不可选
    let rowSelection = null
    if (setting.tableType && !pickup) {
    if (setting.tableType) {
      rowSelection = {
        selectedRowKeys,
        type: (setting.tableType === 'radio') ? 'radio' : 'checkbox',
@@ -2005,7 +1898,7 @@
    }
    let _pagination = false
    if (!pickup && setting.laypage !== 'false' && setting.laypage !== false) {
    if (setting.laypage) {
      _pagination = {
        current: this.state.pageIndex,
        pageSize: this.state.pageSize,
@@ -2018,36 +1911,31 @@
    let _footer = ''
    if (!pickup && statFValue && statFValue.length > 0) {
      _footer = statFValue.map(f => `${f.label}(合计):${f.value}`).join(';')
    }
    let height = setting.height || false
    if (height && height <= 100) {
      height = height + 'vh'
    }
    return (
      <>
        {submit.hasAction && pickup ? <div className="edit-custom-table-leftbtn-wrap">
          <Button style={submit.style} onClick={() => setTimeout(() => {this.checkData()}, 10)} loading={loading} className="submit-table" type="link">提交</Button>
        </div> : null}
        <div className="edit-custom-table-btn-wrap" style={submit.wrapStyle}>
          {!submit.hasAction && pickup ? <Button style={submit.style} onClick={() => setTimeout(() => {this.checkData()}, 10)} loading={loading} className="submit-table" type="link">提交</Button> : null}
          {setting.switchable !== 'false' ? <Switch title="编辑" className="main-pickup" checkedChildren="开" unCheckedChildren="关" disabled={loading || this.props.loading} checked={pickup} onChange={this.pickupChange} /> : null}
          <Button style={submit.style} onClick={() => setTimeout(() => {this.submit()}, 10)} loading={loading} className="submit-table" type="link">提交</Button>
        </div>
        <div className={`edit-custom-table ${pickup ? 'editable' : ''} ${setting.tableHeader || ''} ${setting.operType || ''} ${height ? 'fixed-height' : ''} ${setting.mode || ''} table-vertical-${setting.vertical || ''} mk-edit-${setting.editType || 'simple'}`} id={tableId}>
        <div className={`edit-custom-table ${setting.tableHeader || ''} ${height ? 'fixed-height' : ''} ${setting.mode || ''} table-vertical-${setting.vertical || ''} mk-edit-${setting.editType || 'simple'}`} id={tableId}>
          <Table
            rowKey="$$uuid"
            components={components}
            // style={setting.style}
            size={setting.size || 'middle'}
            bordered={setting.bordered !== 'false'}
            rowSelection={rowSelection}
            columns={_columns}
            columns={columns}
            dataSource={_data}
            loading={this.props.loading}
            scroll={{ x: '100%', y: height }}
            onRow={(record, index) => {
              return {
                lineMarks,
                title: setting.tipField ? record[setting.tipField] : '',
                data: record,
                onClick: () => {this.changeRow(record.$$uuid)},
              }
@@ -2056,8 +1944,7 @@
            pagination={_pagination}
          />
          {_footer ? <div className={'normal-table-footer ' + (_pagination ? 'pagination' : '')}>{_footer}</div> : null}
          {pickup && setting.addable === 'true' ? <Button className="mk-add-line" onClick={() => this.addLine()} disabled={this.props.loading} type="link"><PlusOutlined /></Button> : null}
          {pickup && _data.length > 10 ? <Button style={submit.style} onClick={() => setTimeout(() => {this.checkData()}, 10)} loading={loading} className="submit-footer-table" type="link">提交</Button> : null}
          {_data.length > 10 ? <Button style={submit.style} onClick={() => setTimeout(() => {this.submit()}, 10)} loading={loading} className="submit-footer-table" type="link">提交</Button> : null}
        </div>
      </>
    )
src/tabviews/custom/components/table/edit-table/normalTable/index.scss
@@ -26,9 +26,9 @@
  .mk-edit-sign {
    position: absolute;
    bottom: 2px;
    right: 5px;
    opacity: 0.7;
    font-size: 14px;
    right: 3px;
    opacity: 0.5;
    font-size: 10px;
  }
  table {
@@ -151,6 +151,7 @@
      height: auto;
      border-radius: 0;
      box-shadow: none!important;
      text-align: inherit;
    }
    .ant-select {
      padding: 0px;
@@ -174,15 +175,20 @@
      position: unset;
      border: none;
      box-shadow: none!important;
      text-align: inherit;
      
      .ant-input-number-handler-wrap {
        display: none;
      }
      .ant-input-number-input-wrap {
        text-align: inherit;
      }
      .ant-input-number-input {
        border-radius: 0;
        padding: 0;
        height: auto;
        position: absolute;
        text-align: inherit;
        top: 0px;
        left: 0px;
        right: 0px;
@@ -190,17 +196,15 @@
        border: 1px solid var(--mk-sys-color);
      }
    }
    .anticon-exclamation-circle {
      color: #ff4d4f;
      position: absolute;
      right: 3px;
      top: calc(50% - 8px);
    .has-error, .has-error .ant-input-number-input {
      border-color: #ff4d4f!important;
    }
  }
  .editing_all_table_cell {
    .ant-input {
      border-radius: 0;
      padding: 4px 5px;
      text-align: inherit;
    }
    .ant-select {
      width: 100%;
@@ -210,28 +214,27 @@
    }
    .ant-input-number {
      border-radius: 0;
      text-align: inherit;
      
      .ant-input-number-handler-wrap {
        display: none;
      }
      .ant-input-number-input-wrap {
        text-align: inherit;
      }
      .ant-input-number-input {
        border-radius: 0;
        padding: 4px 5px;
        text-align: inherit;
      }
    }
    .anticon-exclamation-circle {
      color: #ff4d4f;
      position: absolute;
      right: 13px;
      top: calc(50% - 8px);
    .has-error, .has-error .ant-input-number-input {
      border-color: #ff4d4f!important;
    }
  }
  td.pointer {
    position: relative;
  }
  td.pointer {
    .mk-mask {
      display: none;
      cursor: pointer;
      position: absolute;
      top: 0;
@@ -240,45 +243,11 @@
      right: 0;
    }
  }
  .mk-editable {
    position: absolute;
    display: none;
    top: calc(50% - 18px);
    cursor: pointer;
    padding: 10px 5px;
    opacity: 0;
  }
  tr:hover {
    .mk-editable {
      opacity: 1;
    }
    .mk-plus {
      left: -25px;
    }
    .mk-del {
      right: -25px;
    }
  }
  .mk-plus {
    left: 0px;
    color: rgb(38, 194, 129);
    padding-right: 10px;
  }
  .mk-del {
    right: 0px;
    color: rgb(255, 77, 79);
    padding-left: 10px;
  }
  .mk-add-line {
    width: 100px;
    color: #26C281;
    border-radius: 0;
    font-size: 25px;
    height: 45px;
  }
  .submit-footer-table {
    float: right;
    min-height: 24px;
    min-height: 28px;
    min-width: 65px;
    height: auto;
    color: #ffffff;
    background-color: #1890ff;
@@ -286,8 +255,10 @@
    margin-top: 10px!important;
    margin-right: 10px!important;
  }
  table, tr, th, td {
  .ant-table-small.ant-table-bordered {
    border-right: 1px solid #e8e8e8;
  }
  table, tr, th, td, .ant-table-small {
    border-color: var(--mk-table-border-color)!important;
  }
  table tr {
@@ -307,15 +278,22 @@
  table tbody tr {
    color: var(--mk-table-color);
  }
}
.edit-custom-table.buoyMode {
  .ant-table-scroll {
    overflow: unset;
    overflow-x: unset;
    .ant-table-body {
      overflow-x: unset!important;
  .ant-table-bordered {
    table {
      tbody {
        tr:last-child {
          td {
            border-bottom: none;
          }
        }
      }
    }
  }
}
.edit-custom-table.mk-edit-simple {
  table tbody tr td {
    min-height: 32px;
    height: 32px;
  }
}
.edit-custom-table.mk-edit-multi {
@@ -324,20 +302,13 @@
  }
}
.edit-custom-table.editable {
  td {
    background-color: #ffffff!important;
  }
  td.pointer .mk-mask {
    display: block;
  }
  .mk-operation {
    display: none;
  }
  .ant-table-placeholder {
    display: none;
  }
  .mk-editable {
    display: inline-block;
}
.edit-custom-table:not(.ghost) {
  .ant-table-small > .ant-table-content .ant-table-thead > tr > th {
    background-color: #fafafa!important;
  }
}
.edit-custom-table:not(.fixed-height) {
@@ -422,37 +393,16 @@
}
.edit-custom-table-btn-wrap {
  float: right;
  padding: 5px 0px;
  .main-pickup {
    position: relative;
    z-index: 2;
    margin-left: 10px;
  }
  .submit-table {
    position: relative;
    z-index: 2;
    min-width: 65px;
    margin-right: 15px;
    min-height: 24px;
    height: auto;
    color: #ffffff;
    background-color: #1890ff;
    border-width: 0;
    margin-top: 0px!important;
    margin-bottom: 0px!important;
  }
}
.edit-custom-table-leftbtn-wrap {
  float: left;
  line-height: 45px;
  .submit-table {
    position: relative;
    z-index: 2;
    min-height: 28px;
    height: auto;
    color: #ffffff;
    background-color: #1890ff;
    border-width: 0;
    margin-top: 0px;
    margin-bottom: 0px;
    margin-bottom: 10px!important;
  }
}
}
src/tabviews/custom/components/table/normal-table/index.jsx
@@ -340,46 +340,53 @@
    let result = await Api.genericInterface(param)
    if (result.status) {
      if (!result.data || !result.data[0]) {
        this.setState({
          loading: false
        })
        return
      }
      let data = fromJS(this.state.data).toJS()
      let selectedData = fromJS(this.state.selectedData).toJS()
      if (result.data && result.data[0]) {
        let _data = result.data[0] || {}
        _data.$$uuid = _data[setting.primaryKey] || ''
        _data.$$BID = BID || ''
        _data.$$BData = BData || ''
        if (config.absFields) {
          config.absFields.forEach(f => {
            if (!isNaN(_data[f])) {
              _data[f] = Math.abs(_data[f])
            }
          })
        }
      let _data = result.data[0]
      _data.$$uuid = _data[setting.primaryKey] || ''
      _data.$$BID = BID || ''
      _data.$$BData = BData || ''
        try {
          data = data.map(item => {
            if (item.$$uuid === _data.$$uuid) {
              _data.key = item.key
              _data.$$key = '' + item.key + item.$$uuid
              _data.$Index = item.$Index
              return _data
            } else {
              return item
            }
          })
          selectedData = selectedData.map(item => {
            if (_data.$$uuid === item.$$uuid) {
              return _data
            }
            return item
          })
        } catch (e) {
          console.warn('数据查询错误')
        }
        MKEmitter.emit('resetSelectLine', config.uuid, _data.$$uuid || '', _data)
      if (config.absFields) {
        config.absFields.forEach(f => {
          if (!isNaN(_data[f])) {
            _data[f] = Math.abs(_data[f])
          }
        })
      }
      try {
        data = data.map(item => {
          if (item.$$uuid === _data.$$uuid) {
            _data.key = item.key
            _data.$$key = '' + item.key + item.$$uuid
            _data.$Index = item.$Index
            return _data
          } else {
            return item
          }
        })
        selectedData = selectedData.map(item => {
          if (_data.$$uuid === item.$$uuid) {
            return _data
          }
          return item
        })
      } catch (e) {
        console.warn('数据查询错误')
      }
      MKEmitter.emit('resetSelectLine', config.uuid, _data.$$uuid || '', _data)
      this.setState({
        data,
        selectedData,
src/tabviews/custom/components/table/normal-table/index.scss
@@ -5,18 +5,12 @@
  .normal-header {
    margin-bottom: 10px;
  }
  .top-search {
  .mk-search-wrap {
    border-bottom: 1px solid #efefef;
    padding-top: 10px;
  }
  >.button-list.toolbar-button {
    min-height: 60px;
  .button-list.toolbar-button {
    padding-right: 60px;
    line-height: 40px;
    button {
      margin-right: 0px;
      margin-bottom: 0px;
    }
  }
  .main-table-box {
    position: relative;
@@ -47,15 +41,6 @@
      border-radius: 0;
      .ant-collapse-content-box {
        padding: 0;
        >.button-list.toolbar-button {
          padding: 0;
          line-height: 45px;
          padding-right: 60px;
          button {
            margin-right: 0px;
            margin-bottom: 0px;
          }
        }
      }
    }
  }
src/tabviews/custom/components/tabs/antv-tabs/index.jsx
@@ -144,7 +144,7 @@
    if (!tabs.subtabs.length) return null
    return (
      <div className={'menu-antv-tabs-wrap ' + (tabs.setting.tabLabel || '')} style={tabs.style}>
      <div className={'menu-antv-tabs-wrap ' + (tabs.setting.tabLabel || '')} id={'anchor' + tabs.uuid} style={tabs.style}>
        <Tabs defaultActiveKey="1" tabBarStyle={{background: tabs.setting.backgroundColor || 'transparent'}} tabPosition={tabs.setting.position} type={tabs.setting.tabStyle}>
          {tabs.subtabs.map(tab => (
            <TabPane tab={<span id={'tab' + tab.uuid}>{tab.icon ? <MkIcon type={tab.icon} /> : null}{tab.label}</span>} style={{backgroundColor: tab.backgroundColor || 'transparent'}} key={tab.uuid}>
src/tabviews/custom/components/tree/antd-tree/index.scss
@@ -120,18 +120,18 @@
  min-width: 85px;
  .button-list.toolbar-button {
    padding: 0px;
  }
  button {
    display: block;
    margin: 0!important;
    width: 100%;
    border-radius: 0px;
    padding-left: 15px!important;
    .anticon {
      display: none;
    }
    .anticon + span {
      margin-left: 0px;
    button {
      display: block;
      margin: 0!important;
      width: 100%;
      border-radius: 0px;
      padding-left: 15px!important;
      .anticon {
        display: none;
      }
      .anticon + span {
        margin-left: 0px;
      }
    }
  }
}
src/tabviews/custom/index.jsx
@@ -716,7 +716,11 @@
          return group
        })
      } else if (item.subtype === 'voucher') {
        item.wrap.supModule = item.wrap.supModule.pop()
        if (item.wrap.supModule && item.wrap.supModule.length > 0) {
          item.wrap.supModule = item.wrap.supModule.pop()
        } else {
          item.wrap.supModule = ''
        }
      }
      
      return true
src/tabviews/custom/popview/index.jsx
@@ -365,7 +365,7 @@
      // 权限过滤
      if (item.action && item.action.length > 0) {
        item.action = item.action.filter(cell => {
          if (cell.hidden === 'true' || ['popview', 'funcbutton'].includes(cell.OpenType)) return false
          if (cell.hidden === 'true' || cell.OpenType === 'popview') return false
          cell = this.resetButton(item, cell, Tab)
          cell.$toolbtn = true
@@ -392,7 +392,7 @@
          card.elements = card.elements.filter(cell => {
            if (cell.eleType === 'button') {
              if (cell.hidden === 'true' || ['popview', 'funcbutton'].includes(cell.OpenType)) return false
              if (cell.hidden === 'true' || cell.OpenType === 'popview') return false
              cell = this.resetButton(item, cell, Tab)
@@ -413,7 +413,7 @@
          card.backElements = card.backElements.filter(cell => {
            if (cell.eleType === 'button') {
              if (cell.hidden === 'true' || ['popview', 'funcbutton'].includes(cell.OpenType)) return false
              if (cell.hidden === 'true' || cell.OpenType === 'popview') return false
              cell = this.resetButton(item, cell, Tab)
@@ -440,7 +440,7 @@
        }
        item.elements = item.elements.filter(cell => {
          if (cell.eleType === 'button') {
            if (cell.hidden === 'true' || ['popview', 'funcbutton'].includes(cell.OpenType)) return false
            if (cell.hidden === 'true' || cell.OpenType === 'popview') return false
            cell = this.resetButton(item, cell, Tab)
@@ -460,7 +460,7 @@
        item.cols = item.cols.filter(col => {
          if (col.type !== 'action') return true
          col.elements = col.elements.filter(cell => {
            if (cell.hidden === 'true' || ['popview', 'funcbutton'].includes(cell.OpenType)) return false
            if (cell.hidden === 'true' || cell.OpenType === 'popview') return false
            
            cell = this.resetButton(item, cell, Tab)
src/tabviews/subtable/index.scss
@@ -2,7 +2,7 @@
  position: relative;
  min-height: 200px;
  >.top-search {
  >.mk-search-wrap {
    padding: 0px 0px 5px;
    border-bottom: 1px solid #efefef;
  }
src/tabviews/subtabtable/index.scss
@@ -2,7 +2,7 @@
  position: relative;
  min-height: 200px;
  padding-top: 16px;
  >.top-search {
  >.mk-search-wrap {
    padding: 0px 0px 5px;
    border-bottom: 1px solid #efefef;
  }
src/tabviews/zshare/actionList/editLine/index.jsx
New file
@@ -0,0 +1,149 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Button } from 'antd'
import MkIcon from '@/components/mk-icon'
import MKEmitter from '@/utils/events.js'
// import './index.scss'
class EditLine extends Component {
  static propTpyes = {
    btn: PropTypes.object,            // 按钮
    disabled: PropTypes.any,          // 行按钮禁用
  }
  state = {
    disabled: false,
    hidden: false
  }
  UNSAFE_componentWillMount () {
    const { btn, selectedData, BData, disabled } = this.props
    if (btn.controlField) {
      this.setStatus(btn, selectedData || [], BData, disabled)
    } else if (disabled) {
      this.setState({disabled: true})
    }
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    const { btn } = this.props
    if (btn.controlField) {
      this.setStatus(btn, nextProps.selectedData || [], nextProps.BData, nextProps.disabled)
    } else {
      this.setState({disabled: nextProps.disabled === true})
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  componentWillUnmount () {
    this.setState = () => {
      return
    }
  }
  setStatus = (btn, data, BData, disprop) => {
    let disabled = false
    let hidden = false
    if (btn.control !== 'parent') {
      if (data.length > 0) {
        data.forEach(item => {
          let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : ''
          if (btn.controlVals.includes(s)) {
            disabled = true
          }
        })
      } else if (btn.controlVals.includes('')) {
        disabled = true
      }
    } else {
      if (!BData || !BData.hasOwnProperty(btn.controlField)) {
        hidden = true
      } else {
        let s = BData[btn.controlField] + ''
        if (btn.controlVals.includes(s)) {
          hidden = true
        }
      }
    }
    if (disabled && btn.control === 'hidden') {
      hidden = true
    }
    if (disprop) {
      disabled = true
    }
    this.setState({hidden, disabled})
  }
  /**
   * @description 触发按钮操作
   */
  actionTrigger = () => {
    const { btn, selectedData } = this.props
    if (this.state.disabled) return
    let data = selectedData || []
    if (btn.funcType === 'addline') {
      MKEmitter.emit('addRecord', btn.$tableId, data[0] || null)
    } else {
      MKEmitter.emit('delRecord', btn.$tableId, data[0] || null)
    }
  }
  render() {
    const { btn } = this.props
    const { disabled, hidden } = this.state
    if (hidden) return null
    let label = ''
    let icon = ''
    let type = 'link'
    let className = ''
    if (btn.show === 'button') {
      label = btn.label
      icon = btn.icon || ''
    } else if (btn.show === 'link') {
      label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
      icon = ''
    } else if (btn.show === 'icon') {
      icon = btn.icon || ''
    } else if (!btn.$toolbtn) {
      icon = btn.icon || ''
      label = btn.label
      className = 'mk-btn mk-' + btn.class
    } else {
      type = ''
      icon = btn.icon || ''
      label = btn.label
      className = 'mk-btn mk-' + btn.class
    }
    return (
      <Button
        type={type}
        title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
        disabled={disabled}
        style={btn.style}
        icon={icon}
        className={className}
        onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
      >{label}</Button>
    )
  }
}
export default EditLine
src/tabviews/zshare/actionList/editLine/index.scss
src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -78,7 +78,7 @@
      if (data.length > 0) {
        data.forEach(item => {
          let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : ''
          if (btn.controlVals.includes(s)) {
          if (btn.controlVals.includes(s) || item.$lock) {
            disabled = true
          }
        })
src/tabviews/zshare/actionList/index.jsx
@@ -17,11 +17,11 @@
const PrintButton = asyncComponent(() => import('./printbutton'))
const FuncMegvii = asyncComponent(() => import('./funcMegvii'))
const FuncZip = asyncComponent(() => import('./funczip'))
const EditLine = asyncComponent(() => import('./editLine'))
class ActionList extends Component {
  static propTpyes = {
    BID: PropTypes.any,               // 主表ID
    lock: PropTypes.any,              // 可编辑表中按钮锁定
    BData: PropTypes.any,             // 主表数据
    selectedData: PropTypes.any,      // 子表中选择数据
    MenuID: PropTypes.string,         // 菜单ID
@@ -32,60 +32,21 @@
  state = {
    actions: [],
    mores: null,
    listId: ''
    mores: null
  }
  UNSAFE_componentWillMount() {
    const { setting, actions } = this.props
    let listId = (() => {
      let uuid = []
      let options = '0123456789abcdefghigklmnopqrstuv'
      for (let i = 0; i < 32; i++) {
        uuid.push(options.substr(Math.floor(Math.random() * 0x20), 1))
      }
      return uuid.join('')
    })()
    if (!setting.btnlimit || setting.btnlimit >= actions.length) {
      this.setState({actions: actions, listId})
      this.setState({actions: actions})
    } else {
      let mores = fromJS(actions).toJS()
      
      this.setState({
        actions: mores.splice(0, setting.btnlimit),
        mores,
        listId
        mores
      })
    }
  }
  componentDidMount() {
    const { actions, listId } = this.state
    if (actions.length > 9) {
      let node = document.getElementById(listId)
      // const resizeObserver = new ResizeObserver((entries) => {
      // })
      // resizeObserver.observe(node)
      let limit = 10
      let index = 1
      let check = () => {
        if (node.offsetHeight > 65) {
          node.classList.add('double-line')
        } else if (index < limit) {
          index++
          setTimeout(() => {
            check()
          }, 100)
        }
      }
      node && check()
    }
  }
@@ -94,14 +55,14 @@
  }
  getButtonList = (actions) => {
    const { BID, BData, MenuID, columns, setting, selectedData, lock } = this.props
    const { BID, BData, MenuID, columns, setting, selectedData } = this.props
    return actions.map(item => {
      if (['exec', 'prompt', 'pop'].includes(item.OpenType)) {
        return (
          <NormalButton
            key={item.uuid}
            show={item.show || 'actionList'}
            disabled={lock || false}
            disabled={false}
            BID={BID}
            btn={item}
            BData={BData}
@@ -115,7 +76,7 @@
          <ExcelInButton
            key={item.uuid}
            show={item.show || 'actionList'}
            disabled={lock || false}
            disabled={false}
            BID={BID}
            btn={item}
            BData={BData}
@@ -128,7 +89,7 @@
          <ExcelOutButton
            key={item.uuid}
            show={item.show || 'actionList'}
            disabled={lock || false}
            disabled={false}
            BID={BID}
            btn={item}
            BData={BData}
@@ -141,7 +102,7 @@
          <PopupButton
            key={item.uuid}
            show={item.show || 'actionList'}
            disabled={lock || false}
            disabled={false}
            BID={BID}
            btn={item}
            BData={BData}
@@ -154,7 +115,7 @@
          <TabButton
            key={item.uuid}
            show={item.show || 'actionList'}
            disabled={lock || false}
            disabled={false}
            btn={item}
            BID={BID}
            BData={BData}
@@ -167,7 +128,7 @@
          <NewPageButton
            key={item.uuid}
            show={item.show || 'actionList'}
            disabled={lock || false}
            disabled={false}
            btn={item}
            BData={BData}
            selectedData={selectedData}
@@ -179,7 +140,7 @@
            <ChangeUserButton
              key={item.uuid}
              show={item.show || 'actionList'}
              disabled={lock || false}
              disabled={false}
              BID={BID}
              btn={item}
              BData={BData}
@@ -193,7 +154,7 @@
            <PrintButton
              key={item.uuid}
              show={item.show || 'actionList'}
              disabled={lock || false}
              disabled={false}
              BID={BID}
              btn={item}
              BData={BData}
@@ -207,7 +168,7 @@
            <FuncMegvii
              key={item.uuid}
              show={item.show || 'actionList'}
              disabled={lock || false}
              disabled={false}
              BID={BID}
              btn={item}
              setting={setting}
@@ -219,10 +180,19 @@
            <FuncZip
              key={item.uuid}
              show={item.show || 'actionList'}
              disabled={lock || false}
              disabled={false}
              BID={BID}
              btn={item}
              setting={setting}
              selectedData={selectedData}
            />
          )
        } else if (item.funcType === 'addline' || item.funcType === 'delline') {
          return (
            <EditLine
              key={item.uuid}
              disabled={false}
              btn={item}
              selectedData={selectedData}
            />
          )
@@ -234,12 +204,12 @@
  render() {
    const { setting } = this.props
    const { actions, mores, listId } = this.state
    const { actions, mores } = this.state
    if (setting.actionfixed === 'true') {
      return (
        <Affix offsetTop={48}>
          <div className="button-list toolbar-button" id={listId}>
          <div className="button-list toolbar-button">
            {this.getButtonList(actions)}
            {mores ? <Dropdown overlay={<div className="mk-button-dropdown-wrap">{this.getButtonList(mores)}</div>} trigger={['hover']}>
              <div className="mk-button-more">更多<DownOutlined/></div>
@@ -249,7 +219,7 @@
      )
    } else {
      return (
        <div className="button-list toolbar-button" id={listId}>
        <div className="button-list toolbar-button">
          {this.getButtonList(actions)}
          {mores ? <Dropdown overlay={<div className="mk-button-dropdown-wrap">{this.getButtonList(mores)}</div>} trigger={['hover']}>
            <div className="mk-button-more">更多<DownOutlined/></div>
src/tabviews/zshare/actionList/index.scss
@@ -1,11 +1,13 @@
.button-list.toolbar-button {
  position: relative;
  padding: 15px 0px 5px;
  padding: 15px 0px 0px;
  background: #ffffff;
  min-height: 55px;
  button {
    min-width: 65px;
    margin-right: 15px;
    margin-bottom: 10px;
    margin-bottom: 10px!important;
    overflow: hidden;
    min-height: 28px;
    height: auto;
@@ -26,13 +28,7 @@
    display: none;
  }
}
.button-list.toolbar-button.double-line {
  padding-top: 10px;
  padding-bottom: 0px;
  button {
    margin-bottom: 10px!important;
  }
}
.mk-button-more {
  display: inline-block;
  height: 28px;
src/tabviews/zshare/actionList/newpagebutton/index.jsx
@@ -69,7 +69,7 @@
      if (data.length > 0) {
        data.forEach(item => {
          let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : ''
          if (btn.controlVals.includes(s)) {
          if (btn.controlVals.includes(s) || item.$lock) {
            disabled = true
          }
        })
src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -144,7 +144,7 @@
      if (data.length > 0) {
        data.forEach(item => {
          let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : ''
          if (btn.controlVals.includes(s)) {
          if (btn.controlVals.includes(s) || item.$lock) {
            disabled = true
          }
        })
@@ -601,7 +601,7 @@
            param.LText = sql
            param.$callbacksql = callbacksql
          } else {
            param.LText = getSysDefaultSql(btn, setting, '', param, cell, columns, false, this.moduleParams, Utils.getAllSearchOptions, Utils.getAllSearchOptions) // 数据源
            param.LText = getSysDefaultSql(btn, setting, '', param, cell, columns, false, this.moduleParams, Utils.getAllSearchOptions) // 数据源
            if (btn.output) {
              param.key_back_type = 'Y'
            }
@@ -838,7 +838,7 @@
  getSysDeclareSql = (btn, formdata, data, columns, primaryId, BID = '') => {
    let datavars = {}                 // 声明的变量,表单及显示列
    // 需要声明的变量集
    let _vars = ['tbid', 'errorcode', 'retmsg', 'billcode', 'bvoucher', 'fibvoucherdate', 'fiyear', 'username', 'fullname', 'modulardetailcode', 'roleid', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'bid']
    let _vars = ['tbid', 'errorcode', 'retmsg', 'billcode', 'bvoucher', 'fibvoucherdate', 'fiyear', 'username', 'fullname', 'modulardetailcode', 'roleid', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'mk_deleted', 'bid']
  
    // sql语句
    let _sql = ''
@@ -964,7 +964,7 @@
      _declarefields = ',' + _declarefields
    }
    _sql = `/* 系统生成 */
        Declare @tbid nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@BillCode nvarchar(50),@BVoucher nvarchar(50),@FIBVoucherDate nvarchar(50), @FiYear nvarchar(50),@ModularDetailCode nvarchar(50), @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@bid nvarchar(50)${_declarefields}
        Declare @tbid nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@BillCode nvarchar(50),@BVoucher nvarchar(50),@FIBVoucherDate nvarchar(50), @FiYear nvarchar(50),@ModularDetailCode nvarchar(50), @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@mk_deleted int,@bid nvarchar(50)${_declarefields}
      `
  
    let userName = sessionStorage.getItem('User_Name') || ''
@@ -987,7 +987,7 @@
    // 初始化凭证及用户信息字段
    _sql += `
        /* 凭证及用户信息初始化赋值 */
        select @BVoucher='',@FIBVoucherDate='',@FiYear='',@ErrorCode='',@retmsg='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}', @bid='${BID}', @BillCode='', @ModularDetailCode=''
        select @BVoucher='',@FIBVoucherDate='',@FiYear='',@ErrorCode='',@retmsg='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}', @mk_deleted=1, @bid='${BID}', @BillCode='', @ModularDetailCode=''
        `
  
    // 表单变量赋值
@@ -1061,37 +1061,48 @@
      if (params[0].$unCheckParam) {
        this.checkLoopRequest(params, _resolve)
      } else if (btn.preFunc && params.length === 1) {
        let param = params[0]
        let _param = fromJS(param).toJS()
        _param.func = btn.preFunc
        Api.genericInterface(_param).then(res => {
          if (res.status) {
            if (res.ErrCode !== '-1') {
              param = {...param, ...res}
              delete param.status
              delete param.ErrCode
              delete param.ErrMesg
              delete param.message
              setTimeout(() => {
                Api.genericInterface(param).then(result => {
                  if (!result.status) {
                    notification.warning({
                      top: 92,
                      message: result.message,
                      duration: 5
                    })
                  }
                })
              }, 600)
            }
            this.triggerNote(res) // 消息
            this.execSuccess(res)
          } else {
            this.execError(res)
          }
        }, () => {
          this.updateStatus()
          _resolve()
        })
      } else if (params.length <= 20 && btn.execType !== 'single') {
        let deffers = params.map((param, i) => {
          return new Promise(resolve => {
            setTimeout(() => {
              let _param = null
              if (btn.preFunc) {
                _param = fromJS(param).toJS()
                param.func = btn.preFunc
              }
              Api.genericInterface(param).then(res => {
                if (btn.preFunc && res.status && res.ErrCode !== '-1') {
                  _param = {..._param, ...res}
                  delete _param.status
                  delete _param.ErrCode
                  delete _param.ErrMesg
                  delete _param.message
                  setTimeout(() => {
                    Api.genericInterface(_param).then(result => {
                      if (!result.status) {
                        notification.warning({
                          top: 92,
                          message: result.message,
                          duration: 5
                        })
                      }
                    })
                  }, 600)
                }
                if (res.status) {
                  this.triggerNote(res) // 消息
                }
@@ -1566,36 +1577,8 @@
      loadingNumber: params.length
    })
    let _param = null
    if (btn.preFunc) {
      _param = fromJS(param).toJS()
      param.func = btn.preFunc
    }
    Api.genericInterface(param).then(res => {
      if (res.status) {
        if (btn.preFunc && res.ErrCode !== '-1') {
          _param = {..._param, ...res}
          delete _param.status
          delete _param.ErrCode
          delete _param.ErrMesg
          delete _param.message
          setTimeout(() => {
            Api.genericInterface(_param).then(result => {
              if (!result.status) {
                notification.warning({
                  top: 92,
                  message: result.message,
                  duration: 5
                })
              }
            })
          }, 600)
        }
        this.triggerNote(res) // 消息
        if (params.length === 0) {
@@ -2683,6 +2666,16 @@
        _item.type = 'text'
      } else  if (_item.type === 'date') {
        _item.type = item.declareType === 'nvarchar(50)' ? 'text' : 'date'
      } else if (_item.type === 'switch' || _item.type === 'check') {
        if (_readin) {
          _item.value = _item.value === item.openVal ? item.openVal : item.closeVal
        } else {
          if (item.initval === true) {
            _item.value = item.openVal
          } else {
            _item.value = item.closeVal
          }
        }
      } else if (_item.type === 'rate') {
        let count = item.rateCount || 5
        _item.value = parseInt(_item.value)
src/tabviews/zshare/actionList/popupbutton/index.jsx
@@ -84,7 +84,7 @@
      if (data.length > 0) {
        data.forEach(item => {
          let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : ''
          if (btn.controlVals.includes(s)) {
          if (btn.controlVals.includes(s) || item.$lock) {
            disabled = true
          }
        })
src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -94,7 +94,7 @@
      if (data.length > 0) {
        data.forEach(item => {
          let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : ''
          if (btn.controlVals.includes(s)) {
          if (btn.controlVals.includes(s) || item.$lock) {
            disabled = true
          }
        })
@@ -2189,6 +2189,16 @@
        _item.type = 'text'
      } else  if (_item.type === 'date') {
        _item.type = item.declareType === 'nvarchar(50)' ? 'text' : 'date'
      } else if (_item.type === 'switch' || _item.type === 'check') {
        if (_readin) {
          _item.value = _item.value === item.openVal ? item.openVal : item.closeVal
        } else {
          if (item.initval === true) {
            _item.value = item.openVal
          } else {
            _item.value = item.closeVal
          }
        }
      } else if (_item.type === 'rate') {
        let count = item.rateCount || 5
        _item.value = parseInt(_item.value)
src/tabviews/zshare/actionList/tabbutton/index.jsx
@@ -69,7 +69,7 @@
      if (data.length > 0) {
        data.forEach(item => {
          let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : ''
          if (btn.controlVals.includes(s)) {
          if (btn.controlVals.includes(s) || item.$lock) {
            disabled = true
          }
        })
src/tabviews/zshare/mutilform/index.jsx
@@ -19,6 +19,7 @@
const MKCheckCard = asyncComponent(() => import('./mkCheckCard'))
const MKSwitch = asyncComponent(() => import('./mkSwitch'))
const MKCheck = asyncComponent(() => import('./mkCheck'))
const MKCheckbox = asyncComponent(() => import('./mkCheckbox'))
const MKRadio = asyncComponent(() => import('./mkRadio'))
const MKDatePicker = asyncComponent(() => import('./mkDatePicker'))
@@ -124,11 +125,13 @@
        item.precision = 'second'
      }
      if (!item.field || !['text', 'number', 'switch', 'rate', 'select', 'link', 'cascader', 'linkMain', 'funcvar', 'date', 'datemonth', 'radio', 'checkbox', 'checkcard', 'fileupload', 'textarea', 'multiselect', 'brafteditor', 'color', 'vercode'].includes(item.type)) return false
      if (!item.field || !['text', 'number', 'switch', 'check', 'rate', 'select', 'link', 'cascader', 'linkMain', 'funcvar', 'date', 'datemonth', 'radio', 'checkbox', 'checkcard', 'fileupload', 'textarea', 'multiselect', 'brafteditor', 'color', 'vercode'].includes(item.type)) return false
      if (/^\s+$/.test(item.label)) {
        item.style = item.style || {}
        item.style.color = 'transparent'
        item.style.opacity = 0
        item.style.width = 1
        item.style.display = 'inline-block'
      }
      // 数据自动填充
@@ -218,7 +221,7 @@
        if (newval === '$empty' && item.initval) {
          newval = moment().subtract(item.initval, 'month').format('YYYY-MM')
        }
      } else if (item.type === 'switch') { // 开关只接收固定值
      } else if (item.type === 'switch' || item.type === 'check') { // 开关勾选框只接收固定值
        if (newval !== '$empty' && (newval === item.closeVal || newval === item.openVal)) {
        } else if (item.initval === true) {
@@ -584,6 +587,9 @@
        if (debug) {
          console.info(sql)
        }
        sql = sql.replace(/%/ig, ' mpercent ')
        mainItems.push(`select '${item.field}' as obj_name,'${item.arr_field}' as arr_field,'${window.btoa(window.encodeURIComponent(sql))}' as LText`)
      } else {
        let sql = _sql + item.base_sql
@@ -595,6 +601,9 @@
        if (debug) {
          console.info(sql)
        }
        sql = sql.replace(/%/ig, ' mpercent ')
        localItems.push(`select '${item.field}' as obj_name,'${item.arr_field}' as arr_field,'${window.btoa(window.encodeURIComponent(sql))}' as LText`)
      }
    })
@@ -995,6 +1004,8 @@
          content = (<MKCheckCard config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)}/>)
        } else if (item.type === 'switch') {
          content = (<MKSwitch config={item} onChange={(val) => this.recordChange({[item.field]: val}, item)}/>)
        } else if (item.type === 'check') {
          content = (<MKCheck config={item} onChange={(val) => this.recordChange({[item.field]: val}, item)}/>)
        } else if (item.type === 'checkbox') {
          content = (<MKCheckbox config={item} onChange={(val) => this.recordChange({[item.field]: val})}/>)
        } else if (item.type === 'radio') {
src/tabviews/zshare/mutilform/mkCheck/index.jsx
New file
@@ -0,0 +1,41 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Checkbox } from 'antd'
class MKCheck extends Component {
  static propTpyes = {
    config: PropTypes.object,
    onChange: PropTypes.func
  }
  state = {
    defaultChecked: this.props.config.initval === this.props.config.openVal
  }
  onChange = (e) => {
    const { config } = this.props
    if (e.target.checked) {
      this.props.onChange(config.openVal)
    } else {
      this.props.onChange(config.closeVal)
    }
  }
  componentWillUnmount () {
    this.setState = () => {
      return
    }
  }
  render() {
    const { config } = this.props
    const { defaultChecked } = this.state
    return (
      <Checkbox disabled={config.readonly} defaultChecked={defaultChecked} onChange={this.onChange}>{config.checkTip}</Checkbox>
    )
  }
}
export default MKCheck
src/tabviews/zshare/mutilform/mkCheck/index.scss
src/tabviews/zshare/normalTable/index.scss
@@ -232,11 +232,6 @@
      display: block;
    }
  }
  // table tbody {
  //   tr:nth-child(even) {
  //     background: #f9f9f9;
  //   }
  // }
}
.image-scale-modal {
  width: 70vw;
src/tabviews/zshare/topSearch/index.jsx
@@ -16,6 +16,8 @@
const MutilForm = asyncSpinComponent(() => import('./advanceform'))
const MKCheckCard = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkCheckCard'))
const MKCheck = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkCheck'))
const MKSwitch = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkSwitch'))
const MKSelect = asyncComponent(() => import('./mkSelect'))
const DateGroup = asyncComponent(() => import('./dategroup'))
const MKDatePicker = asyncComponent(() => import('./mkDatePicker'))
@@ -189,9 +191,9 @@
            })
          } else { // 合并请求,区分本地及系统
            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`)
              mainItems.push(`select '${item.field}' as obj_name,'${_option.field}' as arr_field,'${window.btoa(window.encodeURIComponent(_option.sql.replace(/%/ig, ' mpercent ')))}' as LText`)
            } else {
              localItems.push(`select '${item.field}' as obj_name,'${_option.field}' as arr_field,'${window.btoa(window.encodeURIComponent(_option.sql))}' as LText`)
              localItems.push(`select '${item.field}' as obj_name,'${_option.field}' as arr_field,'${window.btoa(window.encodeURIComponent(_option.sql.replace(/%/ig, ' mpercent ')))}' as LText`)
            }
          }
        }
@@ -532,6 +534,10 @@
        content = <DateGroup position={index} config={item} onChange={(val, type) => this.dateGroupChange(val, type, item)} />
      } else if (item.type === 'checkcard') {
        content = <MKCheckCard config={item} onChange={(val) => this.cardChange(val, item)} />
      } else if (item.type === 'check') {
        content = <MKCheck config={item} onChange={(val) => this.recordChange(val, false, item)} />
      } else if (item.type === 'switch') {
        content = <MKSwitch config={item} onChange={(val) => this.recordChange(val, false, item)} />
      }
      if (content) {
@@ -836,7 +842,7 @@
    return (
      <>
        <Form {...formItemLayout} className={`top-search mk-float-${setting.float}`} style={setting.style}>
        <Form {...formItemLayout} className={`mk-search-wrap mk-float-${setting.float}`} style={setting.style}>
          <Row gutter={24}>{this.getFields()}</Row>
          {advanceValues.length && (setting.advanceType !== 'pulldown' || (setting.advanceType === 'pulldown' && !visible)) ? <Row gutter={24}>
            <div className="advanced-list">
src/tabviews/zshare/topSearch/index.scss
@@ -1,4 +1,4 @@
.top-search {
.mk-search-wrap {
  background: #ffffff;
  .mk-search-col {
@@ -114,7 +114,7 @@
    margin-top: 3px;
  }
}
.top-search.mk-float-right {
.mk-search-wrap.mk-float-right {
  >.ant-row {
    text-align: right;
  }
src/templates/calendarconfig/index.jsx
@@ -8,7 +8,6 @@
import moment from 'moment'
import Api from '@/api'
import MKEmitter from '@/utils/events.js'
import Utils from '@/utils/utils.js'
import asyncComponent from '@/utils/asyncComponent'
@@ -399,8 +398,6 @@
      // }
      resolve()
    }).then(() => {
      let reload = _config.isAdd
      // 保存时删除配置类型,system 、user
      delete _config.type
      delete _config.isAdd
@@ -481,8 +478,6 @@
            originMenu: fromJS(_config).toJS(),
            menuloading: false,
            menucloseloading: false
          }, () => {
            reload && MKEmitter.emit('revert')
          })
          this.props.reloadmenu()
src/templates/calendarconfig/source.jsx
@@ -31,42 +31,7 @@
      remarkfield: '',
      refresh: 'false'
    },
    search: [
      {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'label',
        field: '',
        initval: '',
        type: 'text',
        resourceType: '0',
        options: [],
        orderType: 'asc',
        match: 'like',
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'label',
        field: '',
        initval: '',
        type: 'select',
        resourceType: '0',
        options: [],
        orderType: 'asc',
        match: '=',
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'label',
        field: '',
        initval: '',
        type: 'date',
        resourceType: '0',
        options: [],
        orderType: 'asc',
        match: 'greater',
      }
    ]
    search: []
  }
  searchItems = [
src/templates/comtableconfig/index.jsx
@@ -9,7 +9,6 @@
import Api from '@/api'
import Utils from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import { updateCommonTable } from '@/utils/utils-update.js'
import asyncComponent from '@/utils/asyncComponent'
@@ -27,7 +26,7 @@
const Versions = asyncComponent(() => import('@/menu/versions'))
const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
// const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const UpdateTable = asyncComponent(() => import('./updatetable'))
const Unattended = asyncComponent(() => import('@/templates/zshare/unattended'))
const EditComponent = asyncComponent(() => import('@/templates/zshare/editcomponent'))
@@ -357,7 +356,6 @@
    }
    let _LongParam = ''
    let reload = _config.isAdd
    // 保存时删除配置类型,system 、user
    delete _config.type
@@ -561,8 +559,6 @@
              config: _config,
              openEdition: response.open_edition || '',
              originMenu: fromJS(_config).toJS()
            }, () => {
              reload && MKEmitter.emit('revert')
            })
            localParam.func = 'sPC_TrdMenu_AddUpt_For_Local'
@@ -1202,7 +1198,7 @@
              <div>
                <Unattended config={config} updateConfig={this.updateconfig}/>
                <Versions MenuId={menu.MenuID} open_edition={openEdition} updateConfig={this.refreshConfig}/>
                <ReplaceField type="table" config={config} updateConfig={this.updateconfig}/>
                {/* <ReplaceField type="table" config={config} updateConfig={this.updateconfig}/> */}
                <EditComponent type="table" options={['search', 'form', 'action', 'columns']} config={this.state.config} refresh={this.editConfig}/>
                <UpdateTable config={config}/>
                <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={this.state.config.enabled} onChange={this.onEnabledChange} />
src/templates/comtableconfig/source.jsx
@@ -24,125 +24,125 @@
    },
    tables: [],
    search: [
      {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'label',
        field: '',
        initval: '',
        type: 'text',
        resourceType: '0',
        options: [],
        orderType: 'asc',
        match: 'like',
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'label',
        field: '',
        initval: '',
        type: 'select',
        resourceType: '0',
        options: [],
        orderType: 'asc',
        match: '=',
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'label',
        field: '',
        initval: '',
        type: 'date',
        resourceType: '0',
        options: [],
        orderType: 'asc',
        match: 'greater',
      }
      // {
      //   origin: true,
      //   uuid: Utils.getuuid(),
      //   label: 'label',
      //   field: '',
      //   initval: '',
      //   type: 'text',
      //   resourceType: '0',
      //   options: [],
      //   orderType: 'asc',
      //   match: 'like',
      // }, {
      //   origin: true,
      //   uuid: Utils.getuuid(),
      //   label: 'label',
      //   field: '',
      //   initval: '',
      //   type: 'select',
      //   resourceType: '0',
      //   options: [],
      //   orderType: 'asc',
      //   match: '=',
      // }, {
      //   origin: true,
      //   uuid: Utils.getuuid(),
      //   label: 'label',
      //   field: '',
      //   initval: '',
      //   type: 'date',
      //   resourceType: '0',
      //   options: [],
      //   orderType: 'asc',
      //   match: 'greater',
      // }
    ],
    action: [
      {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'add',
        intertype: 'system',
        Ot: 'notRequired',
        position: 'toolbar',
        execSuccess: 'grid',
        execError: 'never',
        OpenType: 'pop',
        icon: 'plus',
        class: 'green',
        verify: null
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'update',
        intertype: 'system',
        Ot: 'requiredSgl',
        position: 'toolbar',
        execSuccess: 'grid',
        execError: 'never',
        OpenType: 'pop',
        icon: 'form',
        class: 'purple',
        verify: null
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'delete',
        intertype: 'system',
        Ot: 'required',
        position: 'toolbar',
        execSuccess: 'grid',
        execError: 'never',
        OpenType: 'prompt',
        icon: 'delete',
        class: 'red',
        verify: null
      }
      // {
      //   origin: true,
      //   uuid: Utils.getuuid(),
      //   label: 'add',
      //   intertype: 'system',
      //   Ot: 'notRequired',
      //   position: 'toolbar',
      //   execSuccess: 'grid',
      //   execError: 'never',
      //   OpenType: 'pop',
      //   icon: 'plus',
      //   class: 'green',
      //   verify: null
      // }, {
      //   origin: true,
      //   uuid: Utils.getuuid(),
      //   label: 'update',
      //   intertype: 'system',
      //   Ot: 'requiredSgl',
      //   position: 'toolbar',
      //   execSuccess: 'grid',
      //   execError: 'never',
      //   OpenType: 'pop',
      //   icon: 'form',
      //   class: 'purple',
      //   verify: null
      // }, {
      //   origin: true,
      //   uuid: Utils.getuuid(),
      //   label: 'delete',
      //   intertype: 'system',
      //   Ot: 'required',
      //   position: 'toolbar',
      //   execSuccess: 'grid',
      //   execError: 'never',
      //   OpenType: 'prompt',
      //   icon: 'delete',
      //   class: 'red',
      //   verify: null
      // }
    ],
    columns: [
      {
        origin: true,
        uuid: Utils.getuuid(),
        Align: 'left',
        label: 'label',
        field: '',
        Hide: 'false',
        IsSort: 'true',
        type: 'text',
        Width: 120
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        Align: 'left',
        label: 'label',
        field: '',
        Hide: 'false',
        IsSort: 'true',
        type: 'text',
        Width: 120
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        Align: 'left',
        label: 'label',
        field: '',
        Hide: 'false',
        IsSort: 'true',
        type: 'text',
        Width: 120
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        Align: 'left',
        label: 'label',
        field: '',
        Hide: 'false',
        IsSort: 'true',
        type: 'text',
        Width: 120
      }
      // {
      //   origin: true,
      //   uuid: Utils.getuuid(),
      //   Align: 'left',
      //   label: 'label',
      //   field: '',
      //   Hide: 'false',
      //   IsSort: 'true',
      //   type: 'text',
      //   Width: 120
      // }, {
      //   origin: true,
      //   uuid: Utils.getuuid(),
      //   Align: 'left',
      //   label: 'label',
      //   field: '',
      //   Hide: 'false',
      //   IsSort: 'true',
      //   type: 'text',
      //   Width: 120
      // }, {
      //   origin: true,
      //   uuid: Utils.getuuid(),
      //   Align: 'left',
      //   label: 'label',
      //   field: '',
      //   Hide: 'false',
      //   IsSort: 'true',
      //   type: 'text',
      //   Width: 120
      // }, {
      //   origin: true,
      //   uuid: Utils.getuuid(),
      //   Align: 'left',
      //   label: 'label',
      //   field: '',
      //   Hide: 'false',
      //   IsSort: 'true',
      //   type: 'text',
      //   Width: 120
      // }
    ],
    gridBtn: {
      display: false,
src/templates/modalconfig/dragelement/card.jsx
@@ -129,6 +129,8 @@
      <Checkbox value="C">C</Checkbox>
      <Checkbox value="D">D</Checkbox>
    </Checkbox.Group>)
  } else if (card.type === 'check') {
    formItem = <Checkbox checked={card.initval}>{card.checkTip || ''}</Checkbox>
  } else if (card.type === 'hint') {
    formItem = <div style={{marginTop: '8px', color: 'rgba(0, 0, 0, 0.85)', lineHeight: '1.5', ...card.style}}>{card.message}</div>
  } else if (card.type === 'formula') {
@@ -146,7 +148,7 @@
    formItem = <CheckCard config={card} />
  }
  let _label = <span className="mk-form-label" style={card.style}>{card.label}</span>
  let _label = <span className={'mk-form-label ' + (/^\s+$/.test(card.label) ? 'no-colon' : '')} style={card.style}>{card.label}</span>
  if (card.tooltip) {
    _label = <><QuestionCircleOutlined className="mk-form-tip" /><span className="mk-form-label" style={card.style}>{card.label}</span></>
@@ -185,7 +187,7 @@
            {formItem}
            <div></div>
            {showField ? <div className="field-name" style={card.writein === 'false' ? {color: 'orange'} : {}}>
              {card.field}{card.hidden === 'true' || card.type === 'funcvar' ? '(隐藏)' : ''}{card.readonly === 'true' ? '(只读)' : ''}{card.linkField ? <span style={{color: '#1890ff'}}>{`(关联${card.linkField})`}</span> : ''}{card.supField ? <span style={{color: '#8E44AD'}}>{`(上级${card.supField})`}</span> : ''}
              {card.field}{card.hidden === 'true' || card.type === 'funcvar' ? '(隐藏)' : ''}{card.readonly === 'true' ? '(只读)' : ''}{card.readin === 'false' ? '(未填充)' : ''}{card.linkField ? <span style={{color: '#1890ff'}}>{`(关联${card.linkField})`}</span> : ''}{card.supField ? <span style={{color: '#8E44AD'}}>{`(上级${card.supField})`}</span> : ''}
            </div> : ''}
          </Form.Item>}
        </div>
src/templates/modalconfig/dragelement/index.scss
@@ -38,12 +38,17 @@
      color: #1890ff;
    }
  }
  .mk-form-label::after {
  .mk-form-label:after {
    content: ':';
    position: relative;
    top: -0.5px;
    margin: 0 8px 0 2px;
    text-decoration: none;
  }
  .mk-form-label.no-colon {
    opacity: 0;
    width: 1px;
    display: inline-block;
  }
  .ant-form-item-no-colon::after {
    content: none!important;
@@ -135,12 +140,12 @@
}
.modal-fields-row.up_down {
  .ant-form-item {
    display: block;
    display: block!important;
    .ant-form-item-label {
      width: 100%!important;
      text-align: left;
      height: 24px;
      line-height: 28px;
      height: 24px!important;
      line-height: 28px!important;
    }
    .ant-form-item-control-wrapper {
      width: 100%!important;
src/templates/modalconfig/index.jsx
@@ -268,7 +268,7 @@
        })
      }
      if (item.type === 'switch') {
      if (item.type === 'switch' || item.type === 'check') {
        _linksupFields.push({
          field: item.field,
          label: item.label
src/templates/sharecomponent/actioncomponent/actionform/index.jsx
@@ -186,14 +186,8 @@
          reReadonly.interface = true
          reRequired.interface = false
        }
      } else if (intertype === 'inner') { // preFunc 前置函数
      } else if (intertype === 'inner') {
        shows.push('innerFunc', 'output')
        // positecgroup
        if (window.GLOB.appkey === '20201102081641237BDDE0D5F2E98420BA7EC') {
          shows.push('preFunc')
        }
        reRequired.innerFunc = true
      } else {
        shows.push('sql', 'sqlType', 'output')
src/templates/sharecomponent/actioncomponent/index.jsx
@@ -56,15 +56,15 @@
  componentDidMount () {
    this.getBillPrintTemp()
    MKEmitter.addListener('revert', this.revert)
    // MKEmitter.addListener('revert', this.revert)
    MKEmitter.addListener('pasteButton', this.pasteButton)
  }
  revert = () => {
    this.setState({
      actionlist: fromJS(this.props.config.action).toJS()
    })
  }
  // revert = () => {
  //   this.setState({
  //     actionlist: fromJS(this.props.config.action).toJS()
  //   })
  // }
  pasteButton = (MenuId, btn) => {
    const { config } = this.props
@@ -847,7 +847,7 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('revert', this.revert)
    // MKEmitter.removeListener('revert', this.revert)
    MKEmitter.removeListener('pasteButton', this.pasteButton)
  }
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -122,7 +122,7 @@
      {
        title: '报错编码',
        dataIndex: 'errorCode',
        width: '12%',
        width: '10%',
        editable: true,
        inputType: 'select',
        options: [
@@ -135,13 +135,24 @@
      {
        title: '验证类型',
        dataIndex: 'verifyType',
        width: '12%',
        render: (text, record) => record.verifyType === 'logic' ? '逻辑验证' : '物理验证',
        width: '14%',
        render: (text, record) => {
          let names = {
            physical: '物理验证(全量验证)',
            logic: '逻辑验证(全量验证)',
            physical_temp: '物理验证(仅临时表)',
            logic_temp: '逻辑验证(仅临时表)',
          }
          return names[text] || '物理验证(全量验证)'
        },
        inputType: 'select',
        editable: true,
        options: [
          { value: 'physical', text: '物理验证' },
          { value: 'logic', text: '逻辑验证' }
          { value: 'physical', text: '物理验证(全量验证)' },
          { value: 'logic', text: '逻辑验证(全量验证)' },
          { value: 'physical_temp', text: '物理验证(仅临时表)' },
          { value: 'logic_temp', text: '逻辑验证(仅临时表)' }
        ]
      },
      {
src/templates/sharecomponent/actioncomponent/verifyexcelin/uniqueform/index.jsx
@@ -108,8 +108,10 @@
                ]
              })(
                <Select>
                  <Select.Option value="physical"> 物理验证 </Select.Option>
                  <Select.Option value="logic"> 逻辑验证 </Select.Option>
                  <Select.Option value="physical"> 物理验证(全量验证) </Select.Option>
                  <Select.Option value="logic"> 逻辑验证(全量验证) </Select.Option>
                  <Select.Option value="physical_temp"> 物理验证(仅临时表) </Select.Option>
                  <Select.Option value="logic_temp"> 逻辑验证(仅临时表)  </Select.Option>
                </Select>
              )}
            </Form.Item>
src/templates/sharecomponent/columncomponent/index.jsx
@@ -470,18 +470,18 @@
    })
  }
  revert = () => {
    this.setState({
      columnlist: fromJS(this.props.config.columns).toJS()
    })
  }
  // revert = () => {
  //   this.setState({
  //     columnlist: fromJS(this.props.config.columns).toJS()
  //   })
  // }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  componentDidMount () {
    MKEmitter.addListener('revert', this.revert)
    // MKEmitter.addListener('revert', this.revert)
    MKEmitter.addListener('plusColumns', this.plusColumns)
  }
@@ -492,7 +492,7 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('revert', this.revert)
    // MKEmitter.removeListener('revert', this.revert)
    MKEmitter.removeListener('plusColumns', this.plusColumns)
  }
src/templates/sharecomponent/fieldscomponent/index.jsx
@@ -197,7 +197,13 @@
          required: 'true'
        }
        if (item.type === 'text' && item.length >= 256) {
        if (/^icon|images?$/ig.test(item.field)) {
          newcard.type = 'fileupload'
          newcard.fileType = 'picture-card'
          newcard.fieldlength = item.length || 512
          newcard.maxSize = 1
          newcard.maxfile = 1
        } else if (item.type === 'text' && item.length >= 256) {
          newcard.type = 'textarea'
          newcard.required = 'false'
          newcard.fieldlength = item.length
src/templates/sharecomponent/searchcomponent/index.jsx
@@ -44,12 +44,12 @@
  componentDidMount () {
    MKEmitter.addListener('plusSearch', this.plusSearch)
    MKEmitter.addListener('revert', this.revert)
    // MKEmitter.addListener('revert', this.revert)
  }
  revert = () => {
    this.setState({searchlist: fromJS(this.props.config.search).toJS()})
  }
  // revert = () => {
  //   this.setState({searchlist: fromJS(this.props.config.search).toJS()})
  // }
  plusSearch = (MenuId, item, type) => {
    const { config } = this.props
@@ -321,7 +321,7 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('revert', this.revert)
    // MKEmitter.removeListener('revert', this.revert)
    MKEmitter.removeListener('plusSearch', this.plusSearch)
  }
src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -87,6 +87,8 @@
      {value: '[7, -7]', label: '前后七天'},
      {value: '[30, -30]', label: '前后30天'},
      {value: '[90, -90]', label: '前后90天'},
      {value: '[180, -180]', label: '前后180天'},
      {value: '[365, -365]', label: '前后365天'},
      {value: '[-1, -1]', label: '明天'},
      {value: '[-2, -2]', label: '后天'}
    ]
@@ -104,6 +106,8 @@
  datemonth: ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'advanced', 'query', 'labelwidth'],
  daterange: ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'advanced', 'query', 'precision', 'labelwidth'],
  group: ['label', 'type', 'field', 'datefield', 'initval', 'blacklist', 'ratio', 'items', 'required', 'labelShow', 'query', 'labelwidth'],
  switch: ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'openVal', 'closeVal', 'openText', 'closeText', 'Hide', 'labelShow', 'advanced', 'query', 'labelwidth'],
  check: ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'openVal', 'closeVal', 'checkTip', 'Hide', 'labelShow', 'advanced', 'query', 'labelwidth'],
  range: ['label', 'type', 'field', 'initval', 'match', 'blacklist', 'Hide', 'required', 'maxValue', 'minValue', 'step', 'labelShow', 'query', 'labelwidth']
}
@@ -226,22 +230,24 @@
    }
    if (type === 'text') {
      reOptions.match = matchReg.text
      reOptions.match = matchReg.class1
    } else if (type === 'multiselect') {
      reOptions.match = matchReg.multiselect
      reOptions.match = matchReg.class3
    } else if (type === 'select' || type === 'link') {
      reOptions.match = matchReg.select
      reOptions.match = matchReg.class1
    } else if (type === 'switch' || type === 'check') {
      reOptions.match = matchReg.class2
    } else if (type === 'date') {
      reOptions.match = matchReg.date
      reOptions.match = matchReg.class4
    } else if (type === 'datemonth') {
      reOptions.match = matchReg.datemonth
      reOptions.match = matchReg.class5
    } else if (type === 'dateweek' || type === 'daterange' || type === 'range') {
      reOptions.match = matchReg.daterange
      reOptions.match = matchReg.class5
    } else if (type === 'checkcard') {
      if (this.record.multiple === 'false') {
        reOptions.match = matchReg.select
        reOptions.match = matchReg.class1
      } else if (this.record.multiple === 'true') {
        reOptions.match = matchReg.multiselect
        reOptions.match = matchReg.class3
      }
    }
@@ -738,6 +744,8 @@
              })
              return
            }
          } else if (values.type === 'switch' || values.type === 'check') {
            values.initval = values.initval === values.openVal ? values.openVal : values.closeVal
          }
          ['linkField', 'valueField', 'valueText', 'orderBy'].forEach(item => {
src/templates/subtableconfig/index.jsx
@@ -9,7 +9,6 @@
import Api from '@/api'
import Utils from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import { updateSubTable } from '@/utils/utils-update.js'
import asyncComponent from '@/utils/asyncComponent'
@@ -26,7 +25,7 @@
const { confirm } = Modal
const Versions = asyncComponent(() => import('@/menu/versions'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
// const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const EditComponent = asyncComponent(() => import('@/templates/zshare/editcomponent'))
const SettingComponent = asyncComponent(() => import('@/templates/sharecomponent/settingcomponent'))
const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
@@ -342,7 +341,6 @@
    }
    let _LongParam = ''
    let reload = _config.isAdd
    // 保存时删除配置类型,system 、user
    delete _config.type
@@ -502,7 +500,6 @@
            config: _config,
            originConfig: fromJS(_config).toJS()
          }, () => {
            reload && MKEmitter.emit('revert')
            this.setState({
              menuloading: false,
              menucloseloading: false
@@ -998,7 +995,7 @@
            } bordered={false} extra={
              <div>
                <Versions MenuId={config.uuid} open_edition={openEdition} updateConfig={this.refreshConfig}/>
                <ReplaceField type="table" config={config} updateConfig={this.updateconfig}/>
                {/* <ReplaceField type="table" config={config} updateConfig={this.updateconfig}/> */}
                <EditComponent type="table" options={['search', 'form', 'action', 'columns']} config={config} refresh={this.updateConfig}/>
                <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config.enabled} onChange={this.onEnabledChange} />
                <Button type="primary" id="save-config" onClick={this.submitConfig} loading={this.state.menuloading}>保存</Button>
src/templates/subtableconfig/source.jsx
@@ -22,127 +22,9 @@
      outerFunc: ''
    },
    tables: [],
    search: [
      {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'label',
        field: '',
        initval: '',
        type: 'text',
        resourceType: '0',
        options: [],
        orderType: 'asc',
        match: 'like',
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'label',
        field: '',
        initval: '',
        type: 'select',
        resourceType: '0',
        options: [],
        orderType: 'asc',
        match: '=',
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'label',
        field: '',
        initval: '',
        type: 'date',
        resourceType: '0',
        options: [],
        orderType: 'asc',
        match: 'greater',
      }
    ],
    action: [
      {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'add',
        intertype: 'system',
        Ot: 'notRequired',
        position: 'toolbar',
        execSuccess: 'grid',
        execError: 'never',
        OpenType: 'pop',
        icon: 'plus',
        class: 'green',
        verify: null
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'update',
        intertype: 'system',
        Ot: 'requiredSgl',
        position: 'grid',
        execSuccess: 'grid',
        execError: 'never',
        OpenType: 'pop',
        icon: 'form',
        class: 'purple',
        verify: null
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        label: 'delete',
        intertype: 'system',
        Ot: 'required',
        position: 'toolbar',
        execSuccess: 'grid',
        execError: 'never',
        OpenType: 'prompt',
        icon: 'delete',
        class: 'red',
        verify: null
      }
    ],
    columns: [
      {
        origin: true,
        uuid: Utils.getuuid(),
        Align: 'left',
        label: 'label',
        field: '',
        Hide: 'false',
        IsSort: 'true',
        type: 'text',
        Width: 120
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        Align: 'left',
        label: 'label',
        field: '',
        Hide: 'false',
        IsSort: 'true',
        type: 'text',
        Width: 120
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        Align: 'left',
        label: 'label',
        field: '',
        Hide: 'false',
        IsSort: 'true',
        type: 'text',
        Width: 120
      }, {
        origin: true,
        uuid: Utils.getuuid(),
        Align: 'left',
        label: 'label',
        field: '',
        Hide: 'false',
        IsSort: 'true',
        type: 'text',
        Width: 120
      }
    ],
    search: [],
    action: [],
    columns: [],
    gridBtn: {
      display: false,
      Align: 'center',
src/templates/zshare/formconfig.jsx
@@ -355,6 +355,12 @@
    }, {
      value: 'group',
      text: '日期(组合)'
    }, {
      value: 'switch',
      text: '开关'
    }, {
      value: 'check',
      text: '勾选框'
    }]
  }
@@ -834,6 +840,42 @@
        value: 'custom',
        text: '自定义'
      }]
    },
    {
      type: 'text',
      key: 'openVal',
      label: '开启值',
      initVal: card.openVal || '',
      required: false
    },
    {
      type: 'text',
      key: 'closeVal',
      label: '关闭值',
      initVal: card.closeVal || '',
      required: false
    },
    {
      type: 'text',
      key: 'openText',
      label: '开启提示',
      initVal: card.openText || '',
      required: false
    },
    {
      type: 'text',
      key: 'closeText',
      label: '关闭提示',
      initVal: card.closeText || '',
      required: false
    },
    {
      type: 'text',
      key: 'checkTip',
      label: '提示',
      initVal: card.checkTip || '',
      tooltip: '勾选框后的提示文字',
      required: false
    },
    {
      type: 'color',
@@ -1477,16 +1519,6 @@
        value: 'close',
        text: '关闭'
      }]
    },
    {
      type: 'text',
      key: 'preFunc',
      label: '前置函数',
      initVal: card.preFunc || '',
      tooltip: usefulFields.length ? `函数名称需以${usefulFields.join(', ')}等字符开始;前置函数执行完成后,结果会传入内部函数中,此时内部函数会异步执行;当前置函数返回中ErrCode等于-1时,将不再执行内部函数。` : '',
      fields: usefulFields,
      required: false,
      readonly: false
    },
    {
      type: 'radio',
@@ -2468,6 +2500,9 @@
    value: 'switch',
    text: '开关'
  }, {
    value: 'check',
    text: '勾选框'
  }, {
    value: 'checkbox',
    text: '多选框'
  }, {
@@ -2542,6 +2577,9 @@
      value: 'switch',
      text: '开关'
    }, {
      value: 'check',
      text: '勾选框'
    }, {
      value: 'checkbox',
      text: '多选框'
    }, {
@@ -2610,7 +2648,7 @@
  }
  let initval = card.initval || ''
  if (card.type === 'switch') {
  if (card.type === 'switch' || card.type === 'check') {
    initval = card.initval === true
  } else if (card.type === 'number') {
    initval = card.initval || 0
@@ -2687,6 +2725,14 @@
      key: 'closeText',
      label: '关闭提示',
      initVal: card.closeText || '',
      required: false
    },
    {
      type: 'text',
      key: 'checkTip',
      label: '提示',
      initVal: card.checkTip || '',
      tooltip: '勾选框后的提示文字',
      required: false
    },
    {
@@ -3942,6 +3988,8 @@
      options: [
        {value: 'default', text: '默认'},
        {value: 'board', text: '面板'},
        {value: 'board-block', text: '面板2'},
        {value: 'dropdown', text: '下拉框'},
      ],
      forbid: appType !== 'mob'
    },
src/templates/zshare/modalform/index.jsx
@@ -29,6 +29,7 @@
  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'setAll', 'linkField', 'linkSubField', 'span', 'place', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom', 'pickerMode'],
  fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'span', 'labelwidth', 'tooltip', 'extra', 'compress', 'miniSet', 'splitline', 'marginTop', 'marginBottom', 'maxSize'],
  switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom'],
  check: ['initval', 'openVal', 'closeVal', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom', 'checkTip'],
  date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'mode', 'splitline', 'place', 'marginTop', 'marginBottom', 'minDate', 'maxDate', 'precision'],
  datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'place', 'marginTop', 'marginBottom'],
  datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'mode', 'splitline', 'marginTop', 'marginBottom', 'minDate', 'maxDate'],
@@ -236,7 +237,7 @@
    } else if (['date', 'datemonth', 'datetime'].includes(type)) {
      reOptions.initval = dateOptions[type]
      reTypes.initval = 'select'
    } else if (type === 'switch') {
    } else if (type === 'switch' || type === 'check') {
      reOptions.initval = [
        {value: true, text: '开'},
        {value: false, text: '关'}
@@ -370,7 +371,7 @@
      if (value === 'number' || value === 'rate') {
        this.record.initval = 0
        _fieldval.initval = 0
      } else if (value === 'switch') {
      } else if (value === 'switch' || value === 'check') {
        this.record.initval = false
        _fieldval.initval = false
      }
@@ -808,6 +809,52 @@
    return fields
  }
  transfer = (options) => {
    if (options.length === 0) return options
    let isNumber = true
    options.forEach(item => {
      if (!/^([0-9]|[1-9]\d{0,2})$/.test(item.Value)) {
        isNumber = false
      }
    })
    if (isNumber) {
      return options.map(item => {
        item.Value = +item.Value
        return item
      })
    } else {
      return options.map(item => {
        item.Value = item.Value + ''
        return item
      })
    }
  }
  transferCard = (options) => {
    if (options.length === 0) return options
    let isNumber = true
    options.forEach(item => {
      if (!/^([0-9]|[1-9]\d{0,2})$/.test(item.$value)) {
        isNumber = false
      }
    })
    if (isNumber) {
      return options.map(item => {
        item.$value = +item.$value
        return item
      })
    } else {
      return options.map(item => {
        item.$value = item.$value + ''
        return item
      })
    }
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
@@ -823,6 +870,8 @@
              if (values.type === 'radio' && values.linkField) {
                type = 'link'
              }
              values.options = this.transfer(values.options)
              if (values.options.filter(op => op.Text === '').length > 0) {
                notification.warning({
@@ -877,6 +926,8 @@
                return m
              })
              values.options = this.transferCard(values.options)
              let type = values.type
              if (values.linkField) {
                type = 'link'
src/templates/zshare/modalform/modaleditable/index.jsx
@@ -140,51 +140,51 @@
    })
  }
  changeDatatype = (column) => {
    const { columns, dataSource } = this.state
    let value = column.datatype !== 'number' ? 'number' : 'string'
    let _data = dataSource.map(item => {
      let val = item[column.dataIndex]
      if (value === 'number') {
        val = parseFloat(val)
        if (isNaN(val)) {
          val = 0
        }
      } else {
        val = '' + val
      }
  // changeDatatype = (column) => {
  //   const { columns, dataSource } = this.state
  //   let value = column.datatype !== 'number' ? 'number' : 'string'
  //   let _data = dataSource.map(item => {
  //     let val = item[column.dataIndex]
  //     if (value === 'number') {
  //       val = parseFloat(val)
  //       if (isNaN(val)) {
  //         val = 0
  //       }
  //     } else {
  //       val = '' + val
  //     }
      item[column.dataIndex] = val
  //     item[column.dataIndex] = val
      return item
    })
  //     return item
  //   })
    this.setState({
      dataSource: _data,
      columns: columns.map(col => {
        if (col.dataIndex === column.dataIndex) {
          col.datatype = value
        }
  //   this.setState({
  //     dataSource: _data,
  //     columns: columns.map(col => {
  //       if (col.dataIndex === column.dataIndex) {
  //         col.datatype = value
  //       }
        if (col.dataIndex !== 'operation') {
          col.title = <div>
            {col.$title}
            <Popconfirm
              title={`确定切换为${col.datatype === 'number' ? '文本' : '数值'}吗?`}
              overlayClassName="popover-confirm"
              onConfirm={() => this.changeDatatype(col)
            }>
              <SwapOutlined style={{ color: col.datatype === 'number' ? '#1890ff' : ''}} />
            </Popconfirm>
          </div>
        }
  //       if (col.dataIndex !== 'operation') {
  //         col.title = <div>
  //           {col.$title}
  //           {/* <Popconfirm
  //             title={`确定切换为${col.datatype === 'number' ? '文本' : '数值'}吗?`}
  //             overlayClassName="popover-confirm"
  //             onConfirm={() => this.changeDatatype(col)
  //           }>
  //             <SwapOutlined style={{ color: col.datatype === 'number' ? '#1890ff' : ''}} />
  //           </Popconfirm> */}
  //         </div>
  //       }
        return col
      })
    }, () => {
      this.props.onChange(_data)
    })
  }
  //       return col
  //     })
  //   }, () => {
  //     this.props.onChange(_data)
  //   })
  // }
  handleUpDown = (record, direction) => {
    const { dataSource } = this.state
@@ -373,13 +373,13 @@
        if (col.dataIndex !== 'operation') {
          col.title = <div>
            {col.$title}
            <Popconfirm
            {/* <Popconfirm
              title={`确定切换为${col.datatype === 'number' ? '文本' : '数值'}吗?`}
              overlayClassName="popover-confirm"
              onConfirm={() => this.changeDatatype(col)
            }>
              <SwapOutlined style={{ color: col.datatype === 'number' ? '#1890ff' : ''}} />
            </Popconfirm>
            </Popconfirm> */}
          </div>
        }
        return col
src/templates/zshare/pasteform/index.jsx
@@ -66,7 +66,7 @@
              let list = values.config.match(/[a-zA-Z0-9_]+\s+(nvarchar\(\d+\)|Decimal\(18,\d+\)|Int)/ig)
              list.forEach(item => {
                _config.data.push({
                _config.data.unshift({
                  datatype: item.split(/\s+/)[1],
                  field: item.split(/\s+/)[0],
                  label: item.split(/\s+/)[0],
src/templates/zshare/verifycard/callbackcustomscript/index.jsx
@@ -247,7 +247,7 @@
          <Col span={24} className="sqlfield">
            <Form.Item label={'可用字段'}>
              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'公共值,请按照@xxx@格式使用。'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id, typename</span></Tooltip>,&nbsp;
              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'系统变量,系统会定义变量并赋值。'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address</span></Tooltip>,&nbsp;
              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'系统变量,系统会定义变量并赋值。'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address, mk_deleted</span></Tooltip>,&nbsp;
              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'系统变量,系统会定义变量并在单号生成或创建凭证时使用。'}><span style={{color: '#13c2c2'}}>BillCode, BVoucher, FIBVoucherDate, FiYear, ModularDetailCode</span></Tooltip>
              {usefulfields ? <span>, {usefulfields}</span> : ''}
            </Form.Item>
src/templates/zshare/verifycard/customform/index.jsx
@@ -197,7 +197,7 @@
          <Col span={21} className="sqlfield">
            <Form.Item label={'可用字段'}>
              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'公共值,请按照@xxx@格式使用。'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'系统变量,系统会定义变量并赋值。'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address</span></Tooltip>,&nbsp;
              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'系统变量,系统会定义变量并赋值。'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address, mk_deleted</span></Tooltip>,&nbsp;
              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'系统变量,系统会定义变量并在单号生成或创建凭证时使用。'}><span style={{color: '#13c2c2'}}>BillCode, BVoucher, FIBVoucherDate, FiYear, ModularDetailCode</span></Tooltip>
              {usefulfields ? <span>, {usefulfields}</span> : ''}
            </Form.Item>
src/templates/zshare/verifycard/customscript/index.jsx
@@ -293,7 +293,7 @@
          {!_type ? <Col span={24} className="sqlfield">
            <Form.Item label={'可用字段'}>
              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'公共值,请按照@xxx@格式使用。'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id, typename</span></Tooltip>,&nbsp;
              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'系统变量,系统会定义变量并赋值。'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address</span></Tooltip>,&nbsp;
              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'系统变量,系统会定义变量并赋值。'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address, mk_deleted</span></Tooltip>,&nbsp;
              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'系统变量,系统会定义变量并在单号生成或创建凭证时使用。'}><span style={{color: '#13c2c2'}}>BillCode, BVoucher, FIBVoucherDate, FiYear, ModularDetailCode</span></Tooltip>
              {usefulfields ? <span>, {usefulfields}</span> : ''}
            </Form.Item>
src/templates/zshare/verifycard/index.jsx
@@ -668,9 +668,9 @@
        resolve(_fields)
      }
    }).then(_fields => {
      let _usefulfields = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'BillCode', 'BVoucher', 'FIBVoucherDate', 'FiYear', 'ModularDetailCode', 'tbid']
      let _declare = ['@UserName nvarchar(50)', '@FullName nvarchar(50)', '@RoleID nvarchar(512)', '@mk_departmentcode nvarchar(512)', '@mk_organization nvarchar(512)', '@mk_user_type nvarchar(20)', '@mk_nation nvarchar(50)', '@mk_province nvarchar(50)', '@mk_city nvarchar(50)', '@mk_district nvarchar(50)', '@mk_address nvarchar(100)', '@ErrorCode nvarchar(50)', '@retmsg nvarchar(4000)', '@BillCode nvarchar(50)', '@BVoucher nvarchar(50)', '@FIBVoucherDate nvarchar(50)', '@FiYear nvarchar(50)', '@ModularDetailCode nvarchar(50)', '@bid nvarchar(50)', '@tbid nvarchar(50)']
      let _select = ['@UserName=\'\'', '@FullName=\'\'', '@RoleID=\'\'', '@mk_departmentcode=\'\'', '@mk_organization=\'\'', '@mk_user_type=\'\'', '@mk_nation=\'\'', '@mk_province=\'\'', '@mk_city=\'\'', '@mk_district=\'\'', '@mk_address=\'\'', '@ErrorCode=\'\'', '@retmsg=\'\'', '@BillCode=\'\'', '@BVoucher=\'\'', '@FIBVoucherDate=\'\'', '@FiYear=\'\'', '@ModularDetailCode=\'\'', '@bid=\'\'']
      let _usefulfields = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'BillCode', 'BVoucher', 'FIBVoucherDate', 'FiYear', 'ModularDetailCode', 'tbid', 'mk_deleted']
      let _declare = ['@UserName nvarchar(50)', '@FullName nvarchar(50)', '@RoleID nvarchar(512)', '@mk_departmentcode nvarchar(512)', '@mk_organization nvarchar(512)', '@mk_user_type nvarchar(20)', '@mk_nation nvarchar(50)', '@mk_province nvarchar(50)', '@mk_city nvarchar(50)', '@mk_district nvarchar(50)', '@mk_address nvarchar(100)', '@ErrorCode nvarchar(50)', '@retmsg nvarchar(4000)', '@BillCode nvarchar(50)', '@BVoucher nvarchar(50)', '@FIBVoucherDate nvarchar(50)', '@FiYear nvarchar(50)', '@ModularDetailCode nvarchar(50)', '@bid nvarchar(50)', '@tbid nvarchar(50)', '@mk_deleted int']
      let _select = ['@UserName=\'\'', '@FullName=\'\'', '@RoleID=\'\'', '@mk_departmentcode=\'\'', '@mk_organization=\'\'', '@mk_user_type=\'\'', '@mk_nation=\'\'', '@mk_province=\'\'', '@mk_city=\'\'', '@mk_district=\'\'', '@mk_address=\'\'', '@ErrorCode=\'\'', '@retmsg=\'\'', '@BillCode=\'\'', '@BVoucher=\'\'', '@FIBVoucherDate=\'\'', '@FiYear=\'\'', '@ModularDetailCode=\'\'', '@bid=\'\'', '@mk_deleted=1']
      let fieldArr = _usefulfields.map(_f => _f.toLowerCase())
      let hasBid = false
@@ -950,7 +950,7 @@
        if (_verify.voucher && _verify.voucher.enabled) {
          _voucher = ',BVoucher=@BVoucher,FIBVoucherDate=@FIBVoucherDate,FiYear=@FiYear'
        }
        _defaultsql = `update ${card.sql} set deleted=1,modifydate=getdate(),modifyuser=@username,modifystaff=@fullname,modifyuserid=@userid@${_voucher} where ${_primaryKey}${card.Ot !== 'requiredOnce' ? '=@ID@' : ' in (select ID  from dbo.SplitComma(@ID@))'};`
        _defaultsql = `update ${card.sql} set deleted=@mk_deleted,modifydate=getdate(),modifyuser=@username,modifystaff=@fullname,modifyuserid=@userid@${_voucher} where ${_primaryKey}${card.Ot !== 'requiredOnce' ? '=@ID@' : ' in (select ID  from dbo.SplitComma(@ID@))'};`
      } else if (card.sqlType === 'delete') {
        let _msg = ''
        if (columns && columns.length > 0 && card.Ot !== 'notRequired') {
src/utils/option.js
@@ -157,6 +157,8 @@
    {value: '[7, -7]', text: '前后七天'},
    {value: '[30, -30]', text: '前后30天'},
    {value: '[90, -90]', text: '前后90天'},
    {value: '[180, -180]', label: '前后180天'},
    {value: '[365, -365]', label: '前后365天'},
    {value: '[-1, -1]', text: '明天'},
    {value: '[-2, -2]', text: '后天'},
    {value: 'week', text: '本周'},
@@ -188,7 +190,7 @@
// 匹配规则
export const matchReg = {
  text: [{
  class1: [{
    value: 'like',
    text: 'like'
  }, {
@@ -210,20 +212,7 @@
    value: '<=',
    text: '<='
  }],
  multiselect: [{
    value: 'like',
    text: 'like'
  }, {
    value: 'not like',
    text: 'not like'
  }],
  select: [{
    value: 'like',
    text: 'like'
  }, {
    value: 'not like',
    text: 'not like'
  }, {
  class2: [{
    value: '=',
    text: '='
  }, {
@@ -239,7 +228,14 @@
    value: '<=',
    text: '<='
  }],
  date: [{
  class3: [{
    value: 'like',
    text: 'like'
  }, {
    value: 'not like',
    text: 'not like'
  }],
  class4: [{
    value: '>=',
    text: '>='
  }, {
@@ -249,11 +245,7 @@
    value: '=',
    text: '='
  }],
  datemonth: [{
    value: 'between',
    text: 'between'
  }],
  daterange: [{
  class5: [{
    value: 'between',
    text: 'between'
  }]
src/utils/utils-custom.js
@@ -1399,12 +1399,12 @@
          if (cell.hidden === 'true') return
          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
            if (!cell.modal || cell.modal.fields.length === 0) {
              card.errors.push({ level: 0, detail: `按钮“${cell.label}”中表单尚未添加`})
              errors.push({ level: 0, detail: `按钮“${cell.label}”中表单尚未添加`})
            }
          } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
            card.errors.push({ level: 0, detail: `按钮“${cell.label}”中导入列未设置!`})
            errors.push({ level: 0, detail: `按钮“${cell.label}”中导入列未设置!`})
          } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
            card.errors.push({ level: 0, detail: `按钮“${cell.label}”中导出列未设置!`})
            errors.push({ level: 0, detail: `按钮“${cell.label}”中导出列未设置!`})
          }
          if (doubleClick === cell.uuid) {
@@ -1414,16 +1414,16 @@
      } else if (col.type === 'custom') {
        col.elements.forEach(cell => {
          if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
            card.errors.push({ level: 1, detail: `显示列“${col.label}”中动态字段“${cell.field}”无效`})
            errors.push({ level: 1, detail: `显示列“${col.label}”中动态字段“${cell.field}”无效`})
          }
        })
      } else if (col.field && !columns.includes(col.field)) {
        card.errors.push({ level: 1, detail: `显示列“${col.label}”中字段“${col.field}”无效`})
        errors.push({ level: 1, detail: `显示列“${col.label}”中字段“${col.field}”无效`})
      }
    })
    if (doubleClick) {
      card.errors.push({ level: 1, detail: `绑定的双击按钮已删除`})
      errors.push({ level: 1, detail: `绑定的双击按钮已删除`})
    }
  }
src/utils/utils.js
@@ -142,19 +142,19 @@
  static verifySql (sql, type) {
    if (!sql) return ''
    let chars = [
      {key: 'create', reg: /(^|\s)create\s/ig},
      {key: 'insert', reg: /(^|\s)insert\s/ig},
      {key: 'delete', reg: /(^|\s)delete\s/ig},
      {key: 'update', reg: /(^|\s)update\s/ig},
      {key: 'set', reg: /(^|\s)set\s/ig},
      {key: 'drop', reg: /(^|\s)drop\s/ig},
      {key: 'alter', reg: /(^|\s)alter\s/ig},
      {key: 'truncate', reg: /(^|\s)truncate\s/ig},
      {key: 'if', reg: /(^|\s)if\s/ig},
      {key: 'exec', reg: /(^|\s)exec(\s|\()/ig},
      {key: 'OBJECT', reg: /(^|\s)object(\s|\()/ig},
      {key: 'sys.', reg: /(^|\s)sys\./ig},
      {key: 'kill', reg: /(^|\s)kill\s/ig}
      {key: 'create', reg: /(^|\s|\(|\))create\s/ig},
      {key: 'insert', reg: /(^|\s|\(|\))insert\s/ig},
      {key: 'delete', reg: /(^|\s|\(|\))delete\s/ig},
      {key: 'update', reg: /(^|\s|\(|\))update\s/ig},
      {key: 'set', reg: /(^|\s|\(|\))set\s/ig},
      {key: 'drop', reg: /(^|\s|\(|\))drop\s/ig},
      {key: 'alter', reg: /(^|\s|\(|\))alter\s/ig},
      {key: 'truncate', reg: /(^|\s|\(|\))truncate\s/ig},
      {key: 'if', reg: /(^|\s|\(|\))if\s/ig},
      {key: 'exec', reg: /(^|\s|\(|\))exec(\s|\()/ig},
      {key: 'OBJECT', reg: /(^|\s|\(|\))object(\s|\()/ig},
      {key: 'sys.', reg: /(^|\s|\(|\))sys\./ig},
      {key: 'kill', reg: /(^|\s|\(|\))kill\s/ig}
    ]
    
    if (type === 'customscript') {
@@ -808,6 +808,8 @@
    }
    if (['select', 'radio', 'link', 'checkcard'].includes(item.type) && item.linkSubField && item.linkSubField.length > 0) {
      arrfield.push(...item.linkSubField)
    } else if (item.type === 'text' && item.editType === 'select' && item.linkSubField && item.linkSubField.length > 0) { // 可编辑表
      arrfield.push(...item.linkSubField)
    }
    if (item.disableField) {
      arrfield.push(item.disableField)
@@ -1070,14 +1072,14 @@
    let _uniquesql = ''
    if (btn.uniques && btn.uniques.length > 0) {
      btn.uniques.forEach(unique => {
        if (unique.status === 'false') return
        if (unique.status === 'false' || !unique.verifyType) return
        let _fields = unique.field.split(',')
        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
        let _afields = _fields.map(_field => `a.${_field}`)
        _fields_ = _fields_.join(' and ')
        if (unique.verifyType !== 'physical') {
        if (unique.verifyType === 'logic' || unique.verifyType === 'logic_temp') {
          _fields_ += ' and b.deleted=0'
        }
@@ -1092,14 +1094,14 @@
        goto aaa
      end
      
      Set @tbid=''
      ${unique.verifyType.indexOf('temp') === -1 ? `Set @tbid=''
      Select top 1 @tbid=${_afields.join('+\' \'+')} from  @${sheet} a Inner join ${sheet} b on ${_fields_}
      
      If @tbid!=''
      Begin
        select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 与已有数据重复'
        goto aaa
      end
      end` : ''}
      `
      })
    }
@@ -1291,14 +1293,14 @@
    let _uniquesql = ''
    if (btn.uniques && btn.uniques.length > 0) {
      btn.uniques.forEach(unique => {
        if (unique.status === 'false') return
        if (unique.status === 'false' || !unique.verifyType) return
        let _fields = unique.field.split(',')
        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
        let _afields = _fields.map(_field => `a.${_field}`)
        _fields_ = _fields_.join(' and ')
        if (unique.verifyType !== 'physical') {
        if (unique.verifyType === 'logic' || unique.verifyType === 'logic_temp') {
          _fields_ += ' and b.deleted=0'
        }
@@ -1313,14 +1315,14 @@
        goto aaa
      end
      
      Set @tbid=''
      ${unique.verifyType.indexOf('temp') === -1 ? `Set @tbid=''
      Select top 1 @tbid=${_afields.join('+\' \'+')} from  @${sheet} a Inner join ${sheet} b on ${_fields_}
      
      If @tbid!=''
      Begin
        select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 与已有数据重复'
        goto aaa
      end
      end` : ''}
      `
      })
    }
@@ -1453,7 +1455,7 @@
  })
  // 需要声明的变量集
  let _vars = ['tbid', 'errorcode', 'retmsg', 'billcode', 'bvoucher', 'fibvoucherdate', 'fiyear', 'username', 'fullname', 'modulardetailcode', 'roleid', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'bid']
  let _vars = ['tbid', 'errorcode', 'retmsg', 'billcode', 'bvoucher', 'fibvoucherdate', 'fiyear', 'username', 'fullname', 'modulardetailcode', 'roleid', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'mk_deleted', 'bid']
  // 主键字段
  let primaryKey = setting.primaryKey || 'id'
@@ -1582,7 +1584,7 @@
    _declarefields = ',' + _declarefields
  }
  _sql = `/* 系统生成 */
      Declare @tbid nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@BillCode nvarchar(50),@BVoucher nvarchar(50),@FIBVoucherDate nvarchar(50), @FiYear nvarchar(50),@ModularDetailCode nvarchar(50), @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@bid nvarchar(50)${_declarefields}
      Declare @tbid nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@BillCode nvarchar(50),@BVoucher nvarchar(50),@FIBVoucherDate nvarchar(50), @FiYear nvarchar(50),@ModularDetailCode nvarchar(50), @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@mk_deleted int,@bid nvarchar(50)${_declarefields}
    `
  let userName = sessionStorage.getItem('User_Name') || ''
@@ -1605,7 +1607,7 @@
  // 初始化凭证及用户信息字段
  _sql += `
      /* 凭证及用户信息初始化赋值 */
      select @BVoucher='',@FIBVoucherDate='',@FiYear='',@ErrorCode='',@retmsg='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}', @bid='${BID}', @BillCode='', @ModularDetailCode=''
      select @BVoucher='',@FIBVoucherDate='',@FiYear='',@ErrorCode='',@retmsg='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}', @mk_deleted=1, @bid='${BID}', @BillCode='', @ModularDetailCode=''
      `
  // 表单变量赋值
@@ -2078,7 +2080,7 @@
    _sql += `
      /* 默认sql */
      update ${btn.sql} set deleted=1,modifydate=getdate(),modifyuser=@username,modifystaff=@fullname,modifyuserid=@userid@ where ${primaryKey}${_ID};`
      update ${btn.sql} set deleted=@mk_deleted,modifydate=getdate(),modifyuser=@username,modifystaff=@fullname,modifyuserid=@userid@ where ${primaryKey}${_ID};`
  
  } else if (_actionType === 'delete') {      // 物理删除
    let _msg = ''