king
2022-08-15 704f82b06befe96e5f739b2dce419f76f5683a6f
Merge branch 'develop'
4 文件已重命名
108个文件已修改
4个文件已删除
2个文件已添加
5181 ■■■■■ 已修改文件
package-lock.json 497 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/options.json 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/viewstyle.scss 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/index.jsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/mob.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/model.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/mob.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/model.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/bgcontroller/index.jsx 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/bgcontroller/index.scss 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/balcony/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.jsx 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/options.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/prop-card/index.jsx 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/prop-card/index.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/table-card/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/data-card/index.jsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/prop-card/index.jsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-dashboard/index.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/index.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-scatter/index.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/chart-custom/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/code/sandbox/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/editor/braft-editor/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/actionform/index.jsx 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/actionform/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/formconfig.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/index.jsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/step-form/index.jsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/tab-form/index.jsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/actionform/index.jsx 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/formconfig.jsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/index.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/index.jsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/index.jsx 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/options.jsx 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/timeline/normal-timeline/index.jsx 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tree/antd-tree/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/columnform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/menushell/index.scss 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/padcontroller/index.jsx 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/padcontroller/index.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecombcontrolbutton/index.scss 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/sysinterface/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/sysinterface/settingform/simplescript/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/menubar/normal-menubar/menucomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/menubar/normal-menubar/menucomponent/options.jsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx 134 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/antv-tabs/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/antv-tabs/options.jsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/bgcontroller/index.jsx 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx 74 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/menushell/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/calendar/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/prop-card/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/data-card/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/prop-card/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/assistTable/index.jsx 738 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/assistTable/index.scss 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/normal-table/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/tabs/antv-tabs/index.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/timeline/normal-timeline/index.jsx 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 80 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/formtab/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtable/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtabtable/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/subtabtable/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/exceloutbutton/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/normalbutton/index.jsx 682 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/fileupload/index.jsx 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkInput/index.jsx 73 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkTextArea/index.jsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/actionform/index.jsx 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/actionform/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/customscript/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 141 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.jsx 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/customscript/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-datamanage.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/index.jsx 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/index.scss 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/imdesign/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/index.jsx 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.jsx 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/popdesign/index.jsx 320 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/popdesign/index.scss 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/popdesign/menuform/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/popdesign/menuform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -623,6 +623,257 @@
        }
      }
    },
    "@antv/x6": {
      "version": "1.33.0",
      "resolved": "https://registry.npmjs.org/@antv/x6/-/x6-1.33.0.tgz",
      "integrity": "sha512-B9KkOZJrhgjwDfwUBl58YAGcnD3lpebVaGPGxFMtLcBWmM7K6aDu+TK0CbcdoTS99OyqUQkzNI4O4RFwrw+SRA==",
      "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"
      },
      "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-react-components": {
      "version": "1.1.15",
      "resolved": "https://registry.npmjs.org/@antv/x6-react-components/-/x6-react-components-1.1.15.tgz",
      "integrity": "sha512-tXUak5CPuZLIA0fVBSM2vZ+TxxoEGBcokr0J69e7H0G3WIutDf6J6RkNeRGuKvcW8O1Lef1jiBGSLLjlrRXf0g==",
      "requires": {
        "clamp": "^1.0.1",
        "classnames": "^2.2.6",
        "rc-dropdown": "^3.0.0-alpha.0",
        "rc-util": "^4.15.7",
        "react-color": "^2.17.3",
        "react-resize-detector": "^6.6.4",
        "ua-parser-js": "^0.7.20"
      },
      "dependencies": {
        "@babel/runtime": {
          "version": "7.18.9",
          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz",
          "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==",
          "requires": {
            "regenerator-runtime": "^0.13.4"
          }
        },
        "lodash": {
          "version": "4.17.21",
          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
          "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
        },
        "rc-align": {
          "version": "4.0.12",
          "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.12.tgz",
          "integrity": "sha512-3DuwSJp8iC/dgHzwreOQl52soj40LchlfUHtgACOUtwGuoFIOVh6n/sCpfqCU8kO5+iz6qR0YKvjgB8iPdE3aQ==",
          "requires": {
            "@babel/runtime": "^7.10.1",
            "classnames": "2.x",
            "dom-align": "^1.7.0",
            "lodash": "^4.17.21",
            "rc-util": "^5.3.0",
            "resize-observer-polyfill": "^1.5.1"
          },
          "dependencies": {
            "rc-util": {
              "version": "5.23.0",
              "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.23.0.tgz",
              "integrity": "sha512-lgm6diJ/pLgyfoZY59Vz7sW4mSoQCgozqbBye9IJ7/mb5w5h4T7h+i2JpXAx/UBQxscBZe68q0sP7EW+qfkKUg==",
              "requires": {
                "@babel/runtime": "^7.18.3",
                "react-is": "^16.12.0",
                "shallowequal": "^1.1.0"
              }
            }
          }
        },
        "rc-dropdown": {
          "version": "3.6.2",
          "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-3.6.2.tgz",
          "integrity": "sha512-Wsw7GkVbUXADEs8FPL0v8gd+3mWQiydPFXBlr2imMScQaf8hh79pG9KrBc1DwK+nqHmYOpQfK2gn6jG2AQw9Pw==",
          "requires": {
            "@babel/runtime": "^7.10.1",
            "classnames": "^2.2.6",
            "rc-trigger": "^5.0.4",
            "rc-util": "^5.17.0"
          },
          "dependencies": {
            "rc-util": {
              "version": "5.23.0",
              "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.23.0.tgz",
              "integrity": "sha512-lgm6diJ/pLgyfoZY59Vz7sW4mSoQCgozqbBye9IJ7/mb5w5h4T7h+i2JpXAx/UBQxscBZe68q0sP7EW+qfkKUg==",
              "requires": {
                "@babel/runtime": "^7.18.3",
                "react-is": "^16.12.0",
                "shallowequal": "^1.1.0"
              }
            }
          }
        },
        "rc-trigger": {
          "version": "5.3.1",
          "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.3.1.tgz",
          "integrity": "sha512-5gaFbDkYSefZ14j2AdzucXzlWgU2ri5uEjkHvsf1ynRhdJbKxNOnw4PBZ9+FVULNGFiDzzlVF8RJnR9P/xrnKQ==",
          "requires": {
            "@babel/runtime": "^7.18.3",
            "classnames": "^2.2.6",
            "rc-align": "^4.0.0",
            "rc-motion": "^2.0.0",
            "rc-util": "^5.19.2"
          },
          "dependencies": {
            "rc-util": {
              "version": "5.23.0",
              "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.23.0.tgz",
              "integrity": "sha512-lgm6diJ/pLgyfoZY59Vz7sW4mSoQCgozqbBye9IJ7/mb5w5h4T7h+i2JpXAx/UBQxscBZe68q0sP7EW+qfkKUg==",
              "requires": {
                "@babel/runtime": "^7.18.3",
                "react-is": "^16.12.0",
                "shallowequal": "^1.1.0"
              }
            }
          }
        },
        "rc-util": {
          "version": "4.21.1",
          "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-4.21.1.tgz",
          "integrity": "sha512-Z+vlkSQVc1l8O2UjR3WQ+XdWlhj5q9BMQNLk2iOBch75CqPfrJyGtcWMcnhRlNuDu0Ndtt4kLVO8JI8BrABobg==",
          "requires": {
            "add-dom-event-listener": "^1.1.0",
            "prop-types": "^15.5.10",
            "react-is": "^16.12.0",
            "react-lifecycles-compat": "^3.0.4",
            "shallowequal": "^1.1.0"
          }
        },
        "react-is": {
          "version": "16.13.1",
          "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
          "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
        },
        "regenerator-runtime": {
          "version": "0.13.9",
          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
          "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
        }
      }
    },
    "@antv/x6-react-shape": {
      "version": "1.6.1",
      "resolved": "https://registry.npmjs.org/@antv/x6-react-shape/-/x6-react-shape-1.6.1.tgz",
      "integrity": "sha512-EkcDoIlfbQC69DGgwznFRsi78fW+apTO0OW5J6tnKpMW3r6zB5zr5QM06hzq5UEUgGheMUxNh3wrTd0jnCwR3A=="
    },
    "@antv/xflow": {
      "version": "1.0.50",
      "resolved": "https://registry.npmjs.org/@antv/xflow/-/xflow-1.0.50.tgz",
      "integrity": "sha512-LZ6vSgL13TZSykuIu5zInU7bUSKcgP35tXdsmLAxh7yVDPprBsEm0pGFQSE0QqSWT3TJy/hUZ8HIF8Lo2QJ2Wg==",
      "requires": {
        "@antv/layout": "^0.1.22",
        "@antv/x6": "^1.31.0",
        "@antv/x6-react-components": "^1.1.15",
        "@antv/x6-react-shape": "^1.5.2",
        "@antv/xflow-core": "1.0.50",
        "@antv/xflow-extension": "1.0.50",
        "@antv/xflow-hook": "1.0.50"
      },
      "dependencies": {
        "@antv/layout": {
          "version": "0.1.31",
          "resolved": "https://registry.npmjs.org/@antv/layout/-/layout-0.1.31.tgz",
          "integrity": "sha512-iz9i19dOJGiZr5xBWI5sfG+2K3QVMNAGOBrbjWKH2RGLvGpf2TSFySidhz0siDrcQA46cDsjLmGstezQdgeGzA==",
          "requires": {
            "@antv/g-webgpu": "0.5.5",
            "@dagrejs/graphlib": "2.1.4",
            "d3-force": "^2.0.1",
            "ml-matrix": "^6.5.0"
          }
        }
      }
    },
    "@antv/xflow-core": {
      "version": "1.0.50",
      "resolved": "https://registry.npmjs.org/@antv/xflow-core/-/xflow-core-1.0.50.tgz",
      "integrity": "sha512-KREkPxkWkfy4FjK3N23XTHjSlPGwgrmpwlp5EGkyl0gOwlQVLuSUofNoK4rRg0CW+KLJI5AIDdqFkBMHl3udmA==",
      "requires": {
        "@antv/xflow-hook": "1.0.50",
        "classnames": "^2.3.1",
        "immer": "^9.0.7",
        "mana-common": "^0.3.1",
        "mana-syringe": "^0.2.2",
        "reflect-metadata": "^0.1.13",
        "rxjs": "^6.6.7"
      },
      "dependencies": {
        "classnames": {
          "version": "2.3.1",
          "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
          "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
        },
        "immer": {
          "version": "9.0.15",
          "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz",
          "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ=="
        },
        "rxjs": {
          "version": "6.6.7",
          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
          "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
          "requires": {
            "tslib": "^1.9.0"
          }
        }
      }
    },
    "@antv/xflow-extension": {
      "version": "1.0.50",
      "resolved": "https://registry.npmjs.org/@antv/xflow-extension/-/xflow-extension-1.0.50.tgz",
      "integrity": "sha512-kJ61xa38112ObRPuui7LEpz0+ZB9qoKR4Kf/A48GoG/iC4VtwmYuSeZ4ivztqnLVZHa5lh4l482FJIM7qyzGjA==",
      "requires": {
        "@antv/xflow-core": "1.0.50",
        "@antv/xflow-hook": "1.0.50",
        "mana-syringe": "^0.2.2",
        "moment": "^2.29.1",
        "rc-field-form": "^1.22.0",
        "react-color": "2.17.1",
        "reflect-metadata": "^0.1.13"
      },
      "dependencies": {
        "moment": {
          "version": "2.29.4",
          "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
          "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
        },
        "react-color": {
          "version": "2.17.1",
          "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.17.1.tgz",
          "integrity": "sha512-S+I6TkUKJaqfALLkAIfiCZ/MANQyy7dKkf7g9ZU5GTUy2rf8c2Rx62otyvADAviWR+6HRkzdf2vL1Qvz9goCLQ==",
          "requires": {
            "@icons/material": "^0.2.4",
            "lodash": "^4.17.11",
            "material-colors": "^1.2.1",
            "prop-types": "^15.5.10",
            "reactcss": "^1.2.0",
            "tinycolor2": "^1.4.1"
          }
        }
      }
    },
    "@antv/xflow-hook": {
      "version": "1.0.50",
      "resolved": "https://registry.npmjs.org/@antv/xflow-hook/-/xflow-hook-1.0.50.tgz",
      "integrity": "sha512-d/Mia7LaWs1wba35PhdqQaWdM84qti7Yh73rb0gziUNQTPra04AtIaAkDgZ17gphQ85c4IgiDLJK2fXn8+F1sQ==",
      "requires": {
        "toposort": "^2.0.2"
      }
    },
    "@babel/code-frame": {
      "version": "7.5.5",
      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
@@ -1802,6 +2053,14 @@
      "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz",
      "integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ=="
    },
    "@dagrejs/graphlib": {
      "version": "2.1.4",
      "resolved": "https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-2.1.4.tgz",
      "integrity": "sha512-QCg9sL4uhjn468FDEsb/S9hS2xUZSrv/+dApb1Ze5VKO96pTXKNJZ6MGhIpgWkc1TVhbVGH9/7rq/Mf8/jWicw==",
      "requires": {
        "lodash": "^4.11.1"
      }
    },
    "@fast-csv/format": {
      "version": "4.3.5",
      "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz",
@@ -2932,6 +3191,11 @@
        "reselect": "*"
      }
    },
    "@types/resize-observer-browser": {
      "version": "0.1.7",
      "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz",
      "integrity": "sha512-G9eN0Sn0ii9PWQ3Vl72jDPgeJwRWhv2Qk/nQkJuWmRmOB4HX3/BhD5SE1dZs/hzPZL/WKnvF0RHdTSG54QJFyg=="
    },
    "@types/shallowequal": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/@types/shallowequal/-/shallowequal-1.1.1.tgz",
@@ -3389,7 +3653,7 @@
    "amdefine": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
      "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg=="
    },
    "anser": {
      "version": "1.4.10",
@@ -3724,9 +3988,9 @@
      }
    },
    "are-we-there-yet": {
      "version": "1.1.5",
      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
      "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
      "version": "1.1.7",
      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz",
      "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==",
      "requires": {
        "delegates": "^1.0.0",
        "readable-stream": "^2.0.6"
@@ -3782,7 +4046,7 @@
    "array-find-index": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E="
      "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw=="
    },
    "array-flatten": {
      "version": "2.1.2",
@@ -3905,7 +4169,7 @@
    "async-foreach": {
      "version": "0.1.3",
      "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
      "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI="
      "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA=="
    },
    "async-limiter": {
      "version": "1.0.1",
@@ -4652,7 +4916,7 @@
    "block-stream": {
      "version": "0.0.9",
      "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
      "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
      "integrity": "sha512-OorbnJVPII4DuUKbjARAe8u8EfqOmkEEaSFIyoQ7OjTHn6kafxWl0wLgoZ2rXaYd7MyLcDaU4TmhfxtwgcccMQ==",
      "requires": {
        "inherits": "~2.0.0"
      }
@@ -5115,7 +5379,7 @@
    "camelcase-keys": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
      "integrity": "sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==",
      "requires": {
        "camelcase": "^2.0.0",
        "map-obj": "^1.0.0"
@@ -5124,7 +5388,7 @@
        "camelcase": {
          "version": "2.1.1",
          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
          "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
          "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw=="
        }
      }
    },
@@ -5280,6 +5544,11 @@
        "safe-buffer": "^5.0.1"
      }
    },
    "clamp": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/clamp/-/clamp-1.0.1.tgz",
      "integrity": "sha512-kgMuFyE78OC6Dyu3Dy7vcx4uy97EIbVxJB/B0eJ3bUNAkwdNcxYzgKltnyADiYwsR7SEqkkUPsEUT//OVS6XMA=="
    },
    "class-utils": {
      "version": "0.3.6",
      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
@@ -5342,7 +5611,7 @@
    "cliui": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
      "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
      "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==",
      "requires": {
        "string-width": "^1.0.1",
        "strip-ansi": "^3.0.1",
@@ -5639,7 +5908,7 @@
    "console-control-strings": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
      "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
    },
    "constants-browserify": {
      "version": "1.0.0",
@@ -5822,7 +6091,7 @@
    "cross-spawn": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
      "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
      "integrity": "sha512-eZ+m1WNhSZutOa/uRblAc9Ut5MQfukFrFMtPSm3bZCA888NmMd5AWXWdgRZ80zd+pTk1P2JrGjg9pUPTvl2PWQ==",
      "requires": {
        "lru-cache": "^4.0.1",
        "which": "^1.2.9"
@@ -6133,7 +6402,7 @@
    "currently-unhandled": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
      "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==",
      "requires": {
        "array-find-index": "^1.0.1"
      }
@@ -6515,7 +6784,7 @@
    "delegates": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
      "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
    },
    "denodeify": {
      "version": "1.2.1",
@@ -10034,7 +10303,7 @@
    "gauge": {
      "version": "2.7.4",
      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
      "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==",
      "requires": {
        "aproba": "^1.0.3",
        "console-control-strings": "^1.0.0",
@@ -10067,7 +10336,7 @@
    "get-stdin": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4="
      "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw=="
    },
    "get-stream": {
      "version": "4.1.0",
@@ -10220,13 +10489,20 @@
      }
    },
    "globule": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
      "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
      "version": "1.3.4",
      "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz",
      "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==",
      "requires": {
        "glob": "~7.1.1",
        "lodash": "~4.17.10",
        "lodash": "^4.17.21",
        "minimatch": "~3.0.2"
      },
      "dependencies": {
        "lodash": {
          "version": "4.17.21",
          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
          "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
        }
      }
    },
    "graceful-fs": {
@@ -10344,7 +10620,7 @@
    "has-unicode": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
      "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
    },
    "has-value": {
      "version": "1.0.0",
@@ -10811,14 +11087,14 @@
      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
    },
    "in-publish": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
      "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E="
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz",
      "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ=="
    },
    "indent-string": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
      "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
      "integrity": "sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==",
      "requires": {
        "repeating": "^2.0.0"
      }
@@ -12248,10 +12524,20 @@
      "resolved": "https://registry.npmjs.org/jetifier/-/jetifier-1.6.6.tgz",
      "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=="
    },
    "jquery-mousewheel": {
      "version": "3.1.13",
      "resolved": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz",
      "integrity": "sha512-GXhSjfOPyDemM005YCEHvzrEALhKDIswtxSHSR2e4K/suHVJKJxxRCGz3skPjNxjJjQa9AVSGGlYjv1M3VLIPg=="
    },
    "js-base64": {
      "version": "2.5.1",
      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz",
      "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw=="
      "version": "2.6.4",
      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
      "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ=="
    },
    "js-cookie": {
      "version": "2.2.1",
@@ -12637,6 +12923,11 @@
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
    },
    "lodash-es": {
      "version": "4.17.21",
      "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
    },
    "lodash._getnative": {
      "version": "3.9.1",
      "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
@@ -12962,7 +13253,7 @@
    "loud-rejection": {
      "version": "1.6.0",
      "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
      "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
      "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==",
      "requires": {
        "currently-unhandled": "^0.4.1",
        "signal-exit": "^3.0.0"
@@ -13016,6 +13307,19 @@
      "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz",
      "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA=="
    },
    "mana-common": {
      "version": "0.3.1",
      "resolved": "https://registry.npmjs.org/mana-common/-/mana-common-0.3.1.tgz",
      "integrity": "sha512-nU4h4ES0nPP0/QHCJzd7zTfr0nvJWaQR1H7N3zQc+clEAwRcMNti9i+1NIvLBUarhQZ74+bU95xfqkQpr8jPog=="
    },
    "mana-syringe": {
      "version": "0.2.2",
      "resolved": "https://registry.npmjs.org/mana-syringe/-/mana-syringe-0.2.2.tgz",
      "integrity": "sha512-Sv5r0/PrQRq4pW+9lDicGsEPzPLkd1PwjTs5zHUV1I293S3alkBNyuSjktVeBploofH8MAMLd4DS2crwct48wg==",
      "requires": {
        "inversify": "^5.0.1"
      }
    },
    "map-age-cleaner": {
      "version": "0.1.3",
      "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
@@ -13032,7 +13336,7 @@
    "map-obj": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0="
      "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg=="
    },
    "map-visit": {
      "version": "1.0.0",
@@ -13123,7 +13427,7 @@
    "meow": {
      "version": "3.7.0",
      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
      "integrity": "sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==",
      "requires": {
        "camelcase-keys": "^2.0.0",
        "decamelize": "^1.1.2",
@@ -14189,6 +14493,11 @@
      "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
      "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
    },
    "mousetrap": {
      "version": "1.6.5",
      "resolved": "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.5.tgz",
      "integrity": "sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA=="
    },
    "move-concurrently": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -14330,7 +14639,7 @@
        "semver": {
          "version": "5.3.0",
          "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
          "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
          "integrity": "sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw=="
        }
      }
    },
@@ -14455,12 +14764,12 @@
        "ansi-styles": {
          "version": "2.2.1",
          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
          "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA=="
        },
        "chalk": {
          "version": "1.1.3",
          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
          "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
          "requires": {
            "ansi-styles": "^2.2.1",
            "escape-string-regexp": "^1.0.2",
@@ -14472,7 +14781,7 @@
        "supports-color": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
          "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g=="
        }
      }
    },
@@ -14484,7 +14793,7 @@
    "nopt": {
      "version": "3.0.6",
      "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
      "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
      "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==",
      "requires": {
        "abbrev": "1"
      }
@@ -14873,7 +15182,7 @@
    "os-locale": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
      "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
      "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==",
      "requires": {
        "lcid": "^1.0.0"
      }
@@ -16936,6 +17245,46 @@
        }
      }
    },
    "rc-motion": {
      "version": "2.6.2",
      "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.6.2.tgz",
      "integrity": "sha512-4w1FaX3dtV749P8GwfS4fYnFG4Rb9pxvCYPc/b2fw1cmlHJWNNgOFIz7ysiD+eOrzJSvnLJWlNQQncpNMXwwpg==",
      "requires": {
        "@babel/runtime": "^7.11.1",
        "classnames": "^2.2.1",
        "rc-util": "^5.21.0"
      },
      "dependencies": {
        "@babel/runtime": {
          "version": "7.18.9",
          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz",
          "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==",
          "requires": {
            "regenerator-runtime": "^0.13.4"
          }
        },
        "rc-util": {
          "version": "5.23.0",
          "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.23.0.tgz",
          "integrity": "sha512-lgm6diJ/pLgyfoZY59Vz7sW4mSoQCgozqbBye9IJ7/mb5w5h4T7h+i2JpXAx/UBQxscBZe68q0sP7EW+qfkKUg==",
          "requires": {
            "@babel/runtime": "^7.18.3",
            "react-is": "^16.12.0",
            "shallowequal": "^1.1.0"
          }
        },
        "react-is": {
          "version": "16.13.1",
          "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
          "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
        },
        "regenerator-runtime": {
          "version": "0.13.9",
          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
          "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
        }
      }
    },
    "rc-notification": {
      "version": "3.3.1",
      "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-3.3.1.tgz",
@@ -17969,6 +18318,23 @@
      "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
      "integrity": "sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA=="
    },
    "react-resize-detector": {
      "version": "6.7.8",
      "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.8.tgz",
      "integrity": "sha512-0FaEcUBAbn+pq3PT5a9hHRebUfuS1SRLGLpIw8LydU7zX429I6XJgKerKAMPsJH0qWAl6o5bVKNqFJqr6tGPYw==",
      "requires": {
        "@types/resize-observer-browser": "^0.1.6",
        "lodash": "^4.17.21",
        "resize-observer-polyfill": "^1.5.1"
      },
      "dependencies": {
        "lodash": {
          "version": "4.17.21",
          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
          "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
        }
      }
    },
    "react-router": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.0.1.tgz",
@@ -18097,7 +18463,7 @@
    "redent": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
      "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
      "integrity": "sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==",
      "requires": {
        "indent-string": "^2.1.0",
        "strip-indent": "^1.0.1"
@@ -18594,9 +18960,9 @@
      }
    },
    "sass-graph": {
      "version": "2.2.4",
      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
      "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
      "version": "2.2.6",
      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.6.tgz",
      "integrity": "sha512-MKuEYXFSGuRSi8FZ3A7imN1CeVn9Gpw0/SFJKdL1ejXJneI9a5rwlEZrKejhEFAA3O6yr3eIyl/WuvASvlT36g==",
      "requires": {
        "glob": "^7.0.0",
        "lodash": "^4.0.0",
@@ -18691,7 +19057,7 @@
    "scss-tokenizer": {
      "version": "0.2.3",
      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
      "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
      "integrity": "sha512-dYE8LhncfBUar6POCxMTm0Ln+erjeczqEvCJib5/7XNkdw1FkUGgwMPY360FY0FgPWQxHWCx29Jl3oejyGLM9Q==",
      "requires": {
        "js-base64": "^2.1.8",
        "source-map": "^0.4.2"
@@ -18700,7 +19066,7 @@
        "source-map": {
          "version": "0.4.4",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
          "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
          "integrity": "sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A==",
          "requires": {
            "amdefine": ">=0.0.4"
          }
@@ -19727,7 +20093,7 @@
    "strip-indent": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
      "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
      "integrity": "sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==",
      "requires": {
        "get-stdin": "^4.0.1"
      }
@@ -20168,6 +20534,11 @@
        "commander": "2"
      }
    },
    "toposort": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
      "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg=="
    },
    "tough-cookie": {
      "version": "2.4.3",
      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
@@ -20200,7 +20571,7 @@
    "trim-newlines": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
      "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM="
      "integrity": "sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw=="
    },
    "trim-right": {
      "version": "1.0.1",
@@ -20806,6 +21177,11 @@
      "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
      "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw="
    },
    "utility-types": {
      "version": "3.10.0",
      "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz",
      "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg=="
    },
    "utils-merge": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -21283,14 +21659,14 @@
    "which-module": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
      "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
      "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ=="
    },
    "wide-align": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
      "version": "1.1.5",
      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
      "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
      "requires": {
        "string-width": "^1.0.2 || 2"
        "string-width": "^1.0.2 || 2 || 3 || 4"
      }
    },
    "wolfy87-eventemitter": {
@@ -21612,9 +21988,9 @@
      "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
    },
    "yargs": {
      "version": "7.1.0",
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
      "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
      "version": "7.1.2",
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz",
      "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==",
      "requires": {
        "camelcase": "^3.0.0",
        "cliui": "^3.2.0",
@@ -21628,28 +22004,29 @@
        "string-width": "^1.0.2",
        "which-module": "^1.0.0",
        "y18n": "^3.2.1",
        "yargs-parser": "^5.0.0"
        "yargs-parser": "^5.0.1"
      },
      "dependencies": {
        "camelcase": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
          "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg=="
        }
      }
    },
    "yargs-parser": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
      "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz",
      "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==",
      "requires": {
        "camelcase": "^3.0.0"
        "camelcase": "^3.0.0",
        "object.assign": "^4.1.0"
      },
      "dependencies": {
        "camelcase": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
          "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg=="
        }
      }
    },
package.json
@@ -8,6 +8,7 @@
    "@antv/g2": "^4.1.34",
    "@antv/g6": "^4.6.4",
    "@antv/util": "^2.0.17",
    "@antv/xflow": "^1.0.50",
    "@babel/core": "7.5.5",
    "@svgr/webpack": "4.3.2",
    "@typescript-eslint/eslint-plugin": "1.13.0",
public/options.json
@@ -1,20 +1,20 @@
{
  "appId": "202108312122504607B107A83F55B40C98CCF",
  "appkey": "20210831212235413F287EC3BF489424496C8",
  "mainSystemApi": "https://sso.mk9h.cn/cloud/webapi/dostars",
  "appId": "201912040924165801464FF1788654BC5AC73",
  "appkey": "20191106103859640976D6E924E464D029CF0",
  "mainSystemApi": "http://sso.mk9h.cn/cloud/webapi/dostars",
  "systemType": "",
  "externalDatabase": "false",
  "lineColor": "",
  "filter": "false",
  "defaultApp": "mkindustry",
  "defaultApp": "mk",
  "defaultLang": "zh-CN",
  "WXAppID": "wx4d8a34c8d4494872",
  "WXAppID": "",
  "WXminiAppID": "",
  "debugger": false,
  "licenseKey": "",
  "probation": "",
  "keepPassword": "true",
  "platforms": ["H5", "wechat", "android", "ios", "wxMiniProgram"],
  "host": "http://demo.mk9h.cn",
  "service": "erp_new/"
  "host": "http://qingqiumarket.cn",
  "service": "MKWMS/"
}
src/api/index.js
@@ -29,7 +29,7 @@
axios.interceptors.request.use((config) => {
  if (config.url.includes('LoginAndRedirect') || config.url.includes('getjsonresult') || config.url.includes('wxNativePay')) {
    config.data = qs.stringify(config.data)
  } else if (config.url.includes('doupload') || config.url.includes('dopreload')) {
  } else if (/\/doupload|\/dopreload|\/upload/.test(config.url)) {
    config.headers = { 'Content-Type': 'multipart/form-data' }
  } else if (config.method === 'post' && config.data) {
    config.data = JSON.stringify(config.data)
@@ -810,17 +810,16 @@
      param.LoginUID = sessionStorage.getItem('CloudLoginUID') || param.LoginUID || ''
    }
    // 待优化,增加是否支持跨域请求
    // let url = '/webapi/dostars'
    // if (param.rduri) {
    //   url = param.rduri
    //   delete param.rduri
    // }
    let url = '/webapi/dostars'
    if (param.rduri && /\/dostars/.test(param.rduri)) {
      url = param.rduri
      delete param.rduri
    }
    param = this.encryptParam(param)
    return axios({
      url: `/webapi/dostars${param.func ? '/' + param.func : ''}`,
      url: `${url}${param.func ? '/' + param.func : ''}`,
      method: 'post',
      data: param
    })
@@ -929,6 +928,33 @@
  }
  /**
   * @description oss文件上传
   */
  fileOssUpload (param) {
    let _url = window.GLOB.location + '/file/oss/upload'
    if (process.env.NODE_ENV === 'production') {
      _url = document.location.origin + '/file/oss/upload'
    }
    if (/^http:\/\/(qingqiumarket.cn|cloud.mk9h.cn|sso.mk9h.cn)/.test(_url)) {
      _url = window.GLOB.location + ':8080/file/oss/upload'
      if (process.env.NODE_ENV === 'production') {
        _url = document.location.origin + ':8080/file/oss/upload'
      }
    } else if (/^https:\/\/(qingqiumarket.cn|cloud.mk9h.cn|sso.mk9h.cn)/.test(_url)) {
      _url = window.GLOB.location + ':8443/file/oss/upload'
      if (process.env.NODE_ENV === 'production') {
        _url = document.location.origin + ':8443/file/oss/upload'
      }
    }
    return axios({
      url: _url,
      method: 'post',
      data: param
    })
  }
  /**
   * @description 获取微信支付二维码
   */
  getWxNativePay (param) {
src/assets/css/viewstyle.scss
@@ -227,6 +227,34 @@
        }
      }
    }
    .data-zoom.radio.tabs, .data-zoom.checkbox.tabs {
      .mk-card {
        > .card-item-box {
          border-top: none!important;
          border-left: none!important;
          border-right: none!important;
          border-radius: 0px!important;
          border-bottom: 2px solid transparent!important;
          transition: all 0.3s;
          cursor: pointer;
        }
      }
      .mk-card:hover {
        > .card-item-box {
          .ant-mk-text, .ant-mk-date {
            color: $color6;
          }
        }
      }
      .mk-card.active, .mk-card.selected {
        > .card-item-box {
          border-bottom-color: $color6!important;
          .ant-mk-text, .ant-mk-date {
            color: $color6;
          }
        }
      }
    }
  }
  .normal-group-wrap {
    .print-button:hover, .print-button:focus, .print-button:active {
src/components/header/index.jsx
@@ -14,7 +14,7 @@
  initMenuPermission,
  logout
} from '@/store/action'
import asyncComponent from '@/utils/asyncComponent'
import asyncComponent from '@/utils/asyncSpinComponent'
import Api from '@/api'
import MKEmitter from '@/utils/events.js'
import options from '@/store/options.js'
@@ -67,6 +67,8 @@
  }
  resetPwdSubmit = () => {
    if (!this.formRef) return
    this.formRef.handleConfirm().then(res => {
      this.setState({
        confirmLoading: true
@@ -399,9 +401,12 @@
  }
  loginSubmit = () => {
    if (!this.loginRef) return
    this.setState({
      loginLoading: true
    })
    this.loginRef.handleConfirm().then(param => {
      Api.getusermsg(param.username, param.password, true).then(res => {
        if (res.status) {
src/components/normalform/modalform/index.jsx
@@ -275,16 +275,29 @@
      if (!content) return
      fields.push(
        <Col span={item.span || 12} key={index}>
          <Form.Item label={label}>
            {getFieldDecorator(item.field, {
              initialValue: item.initval,
              rules: item.rules
            })(content)}
          </Form.Item>
        </Col>
      )
      if (item.help) {
        fields.push(
          <Col span={item.span || 12} key={index}>
            <Form.Item label={label} help={<span style={{fontSize: '12px'}}>{item.help}</span>}>
              {getFieldDecorator(item.field, {
                initialValue: item.initval,
                rules: item.rules
              })(content)}
            </Form.Item>
          </Col>
        )
      } else {
        fields.push(
          <Col span={item.span || 12} key={index}>
            <Form.Item label={label}>
              {getFieldDecorator(item.field, {
                initialValue: item.initval,
                rules: item.rules
              })(content)}
            </Form.Item>
          </Col>
        )
      }
    })
    
    return fields
src/locales/en-US/mob.js
@@ -20,7 +20,6 @@
  'mob.component': '组件',
  'mob.status.open': '启用',
  'mob.status.change': '切换',
  'mob.basemsg': '基本信息',
  'mob.query.delete': '确定删除吗?',
  'mob.logout.hint': '您确定要退出吗?',
  'mob.required.input': '请输入',
src/locales/en-US/model.js
@@ -148,7 +148,6 @@
  'model.form.color': 'Color',
  'model.query.delete': '确定删除吗?',
  'header.form.status.change': '状态切换',
  'model.status.open': '启用',
  'model.form.funcbutton': 'Function button',
  'model.form.execMode': 'Mode',
  'header.form.paste': '粘贴',
src/locales/zh-CN/mob.js
@@ -20,7 +20,6 @@
  'mob.component': '组件',
  'mob.status.open': '启用',
  'mob.status.change': '切换',
  'mob.basemsg': '基本信息',
  'mob.query.delete': '确定删除吗?',
  'mob.logout.hint': '您确定要退出吗?',
  'mob.required.input': '请输入',
src/locales/zh-CN/model.js
@@ -148,7 +148,6 @@
  'model.form.color': '颜色',
  'model.query.delete': '确定删除吗?',
  'header.form.status.change': '状态切换',
  'model.status.open': '启用',
  'model.form.funcbutton': '功能按钮',
  'model.form.execMode': '执行方式',
  'header.form.paste': '粘贴',
src/menu/bgcontroller/index.jsx
File was deleted
src/menu/bgcontroller/index.scss
File was deleted
src/menu/components/card/balcony/index.jsx
@@ -139,18 +139,20 @@
        }
      })
    } else {
      let supModule = card.wrap.linkType === 'static' ? '' : 'has'
      let columns = card.columns.map(c => c.field)
      let lowcols = card.columns.map(c => c.field.toLowerCase())
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!columns.includes(card.setting.primaryKey)) {
        card.errors.push({ level: 0, detail: '主键已失效!'})
      }
      let supModule = card.wrap.linkType === 'static' ? '' : 'has'
      let columns = card.columns.map(c => c.field)
      let lowcols = card.columns.map(c => c.field.toLowerCase())
      card.elements.forEach(cell => {
        if (cell.eleType === 'button') {
src/menu/components/card/cardcellcomponent/index.jsx
@@ -731,7 +731,7 @@
          <Modal
            title="按钮·编辑"
            visible={actvisible}
            width={850}
            width={920}
            maskClosable={false}
            onCancel={this.editModalCancel}
            footer={[
src/menu/components/card/data-card/index.jsx
@@ -197,6 +197,8 @@
    }
    card.errors = []
    let columns = card.columns.map(c => c.field)
    let lowcols = card.columns.map(c => c.field.toLowerCase())
    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
      card.errors.push({ level: 0, detail: '未设置数据源!'})
@@ -204,6 +206,8 @@
      card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
    } else if (!card.setting.primaryKey) {
      card.errors.push({ level: 0, detail: '未设置主键!'})
    } else if (!columns.includes(card.setting.primaryKey)) {
      card.errors.push({ level: 0, detail: '主键已失效!'})
    } else if (card.wrap.supType !== 'multi' && !card.setting.supModule) {
      card.errors.push({ level: 0, detail: '未设置上级组件!'})
    }
@@ -220,9 +224,6 @@
      }
    }
    let columns = card.columns.map(c => c.field)
    let lowcols = card.columns.map(c => c.field.toLowerCase())
    card.action.forEach(cell => {
      if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
        if (!cell.modal || cell.modal.fields.length === 0) {
@@ -237,6 +238,16 @@
          })
        }
      }
      // $check@有效性检测
      // if (['prompt', 'exec', 'pop'].includes(cell.OpenType) && cell.Ot === 'required' && cell.verify && cell.verify.scripts && cell.verify.scripts.length > 0) {
      //   cell.verify.scripts.some(s => {
      //     if (s.status !== 'false' && /\$check@|@check\$/ig.test(s.sql)) {
      //       card.errors.push({ level: 1, detail: `可选择多行的按钮“${cell.label}”中 $check@ 或 @check$ 将不会生效!`})
      //       return true
      //     }
      //     return false
      //   })
      // }
    })
    card.subcards.forEach((item, i) => {
@@ -573,7 +584,9 @@
  }
  updateWrap = (res) => {
    let _card = {...this.state.card, wrap: res}
    const { card } = this.state
    let _card = {...card, wrap: res}
    if (res.supNodes) {
      _card.supNodes = res.supNodes
@@ -587,11 +600,31 @@
      delete _card.supNodes
    }
    if (res.layout === 'flex') {
      _card.wrap.pagestyle = 'page'
    }
    if (res.selStyle === 'tabs' && card.wrap.selStyle !== 'tabs') {
      Object.keys(_card.style).forEach(key => {
        if (/^border/.test(key)) {
          delete _card.style[key]
        }
      })
      _card.style.borderBottomColor = '#eeeeee'
      _card.style.borderBottomWidth = '1px'
      _card.style.paddingBottom = '0px'
    this.updateComponent(_card)
      _card.subcards.forEach(item => {
        delete item.style.marginBottom
      })
      this.setState({card: {..._card, subcards: []}}, () => {
        this.updateComponent(_card)
      })
    } else {
      this.updateComponent(_card)
    }
  }
  pasteComponent = (res, resolve) => {
@@ -760,7 +793,7 @@
          <ToolOutlined />
        </Popover>
        <ActionComponent config={card} type="datacard" setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/>
        <div className={'float-' + (card.wrap.cardFloat || 'left')}>
        <div className={'float-' + (card.wrap.cardFloat || 'left') + ' select-' + card.wrap.selStyle}>
          {card.subcards.map((subcard, index) => (<CardComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        </div>
        <div style={{clear: 'both'}}></div>
src/menu/components/card/data-card/index.scss
@@ -109,6 +109,15 @@
      vertical-align: top;
    }
  }
  .select-tabs {
    .card-item {
      border-top: none!important;
      border-left: none!important;
      border-right: none!important;
      border-radius: 0px!important;
      border-bottom: 2px solid transparent!important;
    }
  }
}
.menu-data-card-edit-box::-webkit-scrollbar {
src/menu/components/card/data-card/options.jsx
@@ -188,6 +188,7 @@
        {value: 'active', label: '外阴影'},
        {value: 'backFont', label: '背景+文字'},
        {value: 'font', label: '文字'},
        {value: 'tabs', label: '标签页'},
        ...(subtype === 'datacard' && appType === 'mob' ? [{value: 'check', label: '勾选'}] : [])
      ],
      forbid: subtype === 'tablecard'
src/menu/components/card/prop-card/index.jsx
@@ -238,22 +238,24 @@
        }
      })
    } else {
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
      if (supModule === 'empty') {
        supModule = ''
      }
      let columns = card.columns.map(c => c.field)
      let lowcols = card.columns.map(c => c.field.toLowerCase())
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!columns.includes(card.setting.primaryKey)) {
        card.errors.push({ level: 0, detail: '主键已失效!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      card.subcards.forEach((item, i) => {
        let linkbtn = item.setting.linkbtn || ''
@@ -574,7 +576,9 @@
  }
  updateWrap = (res) => {
    let _card = {...this.state.card, wrap: res}
    const { card } = this.state
    let _card = {...card, wrap: res}
    if (res.datatype === 'static') {
      if (res.supModule && res.supModule.length > 0) {
@@ -587,7 +591,26 @@
      _card.wrap.pagestyle = 'page'
    }
    this.updateComponent(_card)
    if (res.selStyle === 'tabs' && card.wrap.selStyle !== 'tabs') {
      Object.keys(_card.style).forEach(key => {
        if (/^border/.test(key)) {
          delete _card.style[key]
        }
      })
      _card.style.borderBottomColor = '#eeeeee'
      _card.style.borderBottomWidth = '1px'
      _card.style.paddingBottom = '0px'
      _card.subcards.forEach(item => {
        delete item.style.marginBottom
      })
      this.setState({card: {..._card, subcards: []}}, () => {
        this.updateComponent(_card)
      })
    } else {
      this.updateComponent(_card)
    }
  }
  clickComponent = (e) => {
@@ -624,7 +647,7 @@
        } trigger="hover">
          <ToolOutlined />
        </Popover>
        <div className={(card.wrap.layout || 'grid') + '-layout float-' + (card.wrap.cardFloat || 'left')}>
        <div className={(card.wrap.layout || 'grid') + '-layout float-' + (card.wrap.cardFloat || 'left') + ' select-' + card.wrap.selStyle}>
          {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        </div>
        <div className="component-name">
src/menu/components/card/prop-card/index.scss
@@ -97,6 +97,15 @@
      vertical-align: top;
    }
  }
  .select-tabs {
    .card-item {
      border-top: none!important;
      border-left: none!important;
      border-right: none!important;
      border-radius: 0px!important;
      border-bottom: 2px solid #1890ff!important;
    }
  }
}
.menu-prop-card-edit-box::after {
  display: block;
src/menu/components/card/table-card/index.jsx
@@ -186,6 +186,13 @@
    card.errors = []
    let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
    if (supModule === 'empty') {
      supModule = ''
    }
    let columns = card.columns.map(c => c.field)
    let lowcols = card.columns.map(c => c.field.toLowerCase())
    if (card.subcards.length === 0) {
      card.errors.push({ level: 0, detail: '卡片不可为空!'})
    }
@@ -196,16 +203,11 @@
      card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
    } else if (!card.setting.primaryKey) {
      card.errors.push({ level: 0, detail: '未设置主键!'})
    } else if (!columns.includes(card.setting.primaryKey)) {
      card.errors.push({ level: 0, detail: '主键已失效!'})
    } else if (!card.setting.supModule) {
      card.errors.push({ level: 0, detail: '未设置上级组件!'})
    }
    let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
    if (supModule === 'empty') {
      supModule = ''
    }
    let columns = card.columns.map(c => c.field)
    let lowcols = card.columns.map(c => c.field.toLowerCase())
    card.subcards.forEach((item, i) => {
      let linkbtn = item.setting.linkbtn || ''
src/menu/components/carousel/data-card/index.jsx
@@ -145,16 +145,6 @@
    card.errors = []
    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
      card.errors.push({ level: 0, detail: '未设置数据源!'})
    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
      card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
    } else if (!card.setting.primaryKey) {
      card.errors.push({ level: 0, detail: '未设置主键!'})
    } else if (!card.setting.supModule) {
      card.errors.push({ level: 0, detail: '未设置上级组件!'})
    }
    let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
    if (supModule === 'empty') {
      supModule = ''
@@ -163,6 +153,18 @@
    let columns = card.columns.map(c => c.field)
    let lowcols = card.columns.map(c => c.field.toLowerCase())
    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
      card.errors.push({ level: 0, detail: '未设置数据源!'})
    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
      card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
    } else if (!card.setting.primaryKey) {
      card.errors.push({ level: 0, detail: '未设置主键!'})
    } else if (!columns.includes(card.setting.primaryKey)) {
      card.errors.push({ level: 0, detail: '主键已失效!'})
    } else if (!card.setting.supModule) {
      card.errors.push({ level: 0, detail: '未设置上级组件!'})
    }
    card.subcards.forEach((item, i) => {
      item.elements.forEach(cell => {
        if (cell.eleType === 'button') {
src/menu/components/carousel/prop-card/index.jsx
@@ -188,16 +188,6 @@
        })
      })
    } else {
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
      if (supModule === 'empty') {
        supModule = ''
@@ -205,6 +195,18 @@
      let columns = card.columns.map(c => c.field)
      let lowcols = card.columns.map(c => c.field.toLowerCase())
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!columns.includes(card.setting.primaryKey)) {
        card.errors.push({ level: 0, detail: '主键已失效!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      card.subcards.forEach((item, i) => {
        item.elements.forEach(cell => {
          if (cell.eleType === 'button') {
src/menu/components/chart/antv-bar/index.jsx
@@ -1233,17 +1233,20 @@
    card.btnlog = []
    card.errors = []
    let columns = card.columns.map(c => c.field)
    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
      card.errors.push({ level: 0, detail: '未设置数据源!'})
    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
      card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
    } else if (!card.setting.primaryKey) {
      card.errors.push({ level: 0, detail: '未设置主键!'})
    } else if (!columns.includes(card.setting.primaryKey)) {
      card.errors.push({ level: 0, detail: '主键已失效!'})
    } else if (!card.setting.supModule) {
      card.errors.push({ level: 0, detail: '未设置上级组件!'})
    }
    
    let columns = card.columns.map(c => c.field)
    if (!card.plot.Xaxis) {
      card.errors.push({ level: 0, detail: '坐标轴尚未设置!'})
    } else if (card.plot.datatype === 'query') {
src/menu/components/chart/antv-dashboard/index.jsx
@@ -483,17 +483,20 @@
    card.errors = []
    let columns = card.columns.map(c => c.field)
    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
      card.errors.push({ level: 0, detail: '未设置数据源!'})
    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
      card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
    } else if (!card.setting.primaryKey) {
      card.errors.push({ level: 0, detail: '未设置主键!'})
    } else if (!columns.includes(card.setting.primaryKey)) {
      card.errors.push({ level: 0, detail: '主键已失效!'})
    } else if (!card.setting.supModule) {
      card.errors.push({ level: 0, detail: '未设置上级组件!'})
    }
    
    let columns = card.columns.map(c => c.field)
    if (!card.plot.valueField) {
      card.errors.push({ level: 0, detail: '显示值尚未设置!'})
    } else if (!columns.includes(card.plot.valueField)) {
src/menu/components/chart/antv-pie/index.jsx
@@ -617,17 +617,20 @@
    card.name = card.plot.name
    card.errors = []
    let columns = card.columns.map(c => c.field)
    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
      card.errors.push({ level: 0, detail: '未设置数据源!'})
    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
      card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
    } else if (!card.setting.primaryKey) {
      card.errors.push({ level: 0, detail: '未设置主键!'})
    } else if (!columns.includes(card.setting.primaryKey)) {
      card.errors.push({ level: 0, detail: '主键已失效!'})
    } else if (!card.setting.supModule) {
      card.errors.push({ level: 0, detail: '未设置上级组件!'})
    }
    
    let columns = card.columns.map(c => c.field)
    if (!card.plot.Xaxis) {
      card.errors.push({ level: 0, detail: '名称字段尚未设置!'})
    } else {
src/menu/components/chart/antv-scatter/index.jsx
@@ -265,17 +265,20 @@
    card.name = card.plot.name
    card.errors = []
    let columns = card.columns.map(c => c.field)
    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
      card.errors.push({ level: 0, detail: '未设置数据源!'})
    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
      card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
    } else if (!card.setting.primaryKey) {
      card.errors.push({ level: 0, detail: '未设置主键!'})
    } else if (!columns.includes(card.setting.primaryKey)) {
      card.errors.push({ level: 0, detail: '主键已失效!'})
    } else if (!card.setting.supModule) {
      card.errors.push({ level: 0, detail: '未设置上级组件!'})
    }
    
    let columns = card.columns.map(c => c.field)
    if (!card.plot.Xaxis) {
      card.errors.push({ level: 0, detail: '坐标轴尚未设置!'})
    } else {
src/menu/components/chart/chart-custom/index.jsx
@@ -194,12 +194,16 @@
    card.name = card.plot.name
    card.errors = []
    let columns = card.columns.map(c => c.field)
    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
      card.errors.push({ level: 0, detail: '未设置数据源!'})
    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
      card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
    } else if (!card.setting.primaryKey) {
      card.errors.push({ level: 0, detail: '未设置主键!'})
    } else if (!columns.includes(card.setting.primaryKey)) {
      card.errors.push({ level: 0, detail: '主键已失效!'})
    } else if (!card.setting.supModule) {
      card.errors.push({ level: 0, detail: '未设置上级组件!'})
    }
src/menu/components/code/sandbox/index.jsx
@@ -110,6 +110,8 @@
    card.errors = []
    let columns = card.columns.map(c => c.field)
    if (card.wrap.datatype !== 'static') {
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
@@ -117,6 +119,8 @@
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!columns.includes(card.setting.primaryKey)) {
        card.errors.push({ level: 0, detail: '主键已失效!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
src/menu/components/editor/braft-editor/index.jsx
@@ -105,6 +105,8 @@
    card.errors = []
    let columns = card.columns.map(c => c.field)
    if (card.wrap.datatype !== 'static') {
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
@@ -112,6 +114,8 @@
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!columns.includes(card.setting.primaryKey)) {
        card.errors.push({ level: 0, detail: '主键已失效!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
src/menu/components/form/formaction/actionform/index.jsx
@@ -21,7 +21,8 @@
    formlist: null,  // 表单信息
    interType: null, // 接口类型:内部、外部
    procMode: null,  // 参数方式
    linkmenu: null
    linkmenu: null,
    callbackType: null
  }
  
@@ -30,12 +31,14 @@
    let _intertype = card.intertype || 'system'  // 接口类型
    let _procMode = card.procMode || 'system'    // 参数请求方式
    let _callbackType = card.callbackType || 'script'
    let _options = this.getOptions(_intertype, _procMode, card.linkmenu)
    let _options = this.getOptions(_intertype, _procMode, card.linkmenu, _callbackType)
    this.setState({
      interType: _intertype,
      procMode: _procMode,
      callbackType: _callbackType,
      linkmenu: card.linkmenu,
      formlist: this.props.formlist.map(item => {
        if (item.key === 'innerFunc' && _procMode === 'inner') {
@@ -48,7 +51,7 @@
    })
  }
  getOptions = (_intertype, _procMode, linkmenu) => {
  getOptions = (_intertype, _procMode, linkmenu, _callbackType) => {
    const { card } = this.props
    if (card.type === 'prev') {
@@ -60,14 +63,30 @@
    
    if (_intertype === 'custom') {
      _options.pop()
      _options.push('procMode', 'interface', 'callbackType', 'cbTable', 'proInterface', 'method', 'cross')
      _options.push('procMode', 'interface', 'callbackType', 'proInterface', 'method', 'cross')
      if (_procMode === 'system') {
        _options.push('sql', 'sqlType')
      } else {
        _options.push('innerFunc')
      }
      if (_callbackType === 'func') {
        _options.push('callbackFunc')
      } else if (_callbackType !== 'none') {
        _options.push('cbTable')
      }
    } else if (_intertype === 'outer') {
      _options.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
      _options.push('procMode', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackType')
      if (_procMode === 'system') {
        _options.push('sql', 'sqlType')
      } else if (_procMode === 'inner') {
        _options.push('innerFunc')
      }
      if (_callbackType === 'func') {
        _options.push('callbackFunc')
      } else if (_callbackType !== 'none') {
        _options.push('cbTable')
      }
    } else if (_intertype === 'inner') {
      _options.push('innerFunc')
    } else {
@@ -88,10 +107,10 @@
   * 3、切换标签类型,重置可选标签
   */
  optionChange = (key, value) => {
    const { procMode, linkmenu } = this.state
    const { procMode, linkmenu, callbackType } = this.state
    if (key === 'intertype') {
      let _options = this.getOptions(value, procMode, linkmenu)
      let _options = this.getOptions(value, procMode, linkmenu, callbackType)
      this.setState({
        interType: value,
@@ -107,25 +126,38 @@
        })
      })
    } else if (key === 'procMode') {
      let _options = this.getOptions(this.state.interType, value, linkmenu)
      let _options = this.getOptions(this.state.interType, value, linkmenu, callbackType)
      this.setState({
        procMode: value,
        formlist: this.state.formlist.map(item => {
          item.hidden = !_options.includes(item.key)
          if (item.key === 'innerFunc') {
            item.required = true
          if (item.key === 'procMode') {
            item.initVal = value
          }
          return item
        })
      })
    } else if (key === 'linkmenu') {
      let _options = this.getOptions(this.state.interType, procMode, value)
      let _options = this.getOptions(this.state.interType, procMode, value, callbackType)
      this.setState({
        linkmenu: value,
        formlist: this.state.formlist.map(item => {
          item.hidden = !_options.includes(item.key)
          return item
        })
      })
    } else if (key === 'callbackType') {
      let _options = this.getOptions(this.state.interType, procMode, linkmenu, value)
      this.setState({
        callbackType: value,
        formlist: this.state.formlist.map(item => {
          if (item.key === 'callbackType') {
            item.initVal = value
          }
          item.hidden = !_options.includes(item.key)
          return item
        })
@@ -160,7 +192,7 @@
  getFields() {
    const { getFieldDecorator } = this.props.form
    const { interType } = this.state
    const { interType, callbackType } = this.state
    const fields = []
    this.state.formlist.forEach((item, index) => {
@@ -187,7 +219,7 @@
            message: formRule.func.maxMessage
          }]
        } else if (item.key === 'output') {
          if (interType === 'system') {
          if (interType === 'system' || ((interType === 'outer' || interType === 'custom') && callbackType === 'script')) {
            _rules = [{
              pattern: /^@[0-9a-zA-Z_]+@?$/,
              message: '变量以@符开头,可使用字母、数字以及_'
src/menu/components/form/formaction/actionform/index.scss
@@ -4,6 +4,11 @@
    color: #1890ff;
    cursor: pointer;
  }
  >.ant-row >.ant-col {
    float: none;
    display: inline-block;
    vertical-align: top;
  }
  .textarea {
    .ant-col-sm-7 {
      width: 14%;
src/menu/components/form/formaction/formconfig.jsx
@@ -92,6 +92,9 @@
      }, {
        value: 'inner',
        text: '内部函数'
      }, {
        value: 'none',
        text: '无'
      }]
    },
    {
@@ -126,7 +129,7 @@
      tooltip: functip,
      fields: usefulFields,
      tooltipClass: 'middle',
      required: card.intertype === 'inner',
      required: true,
      readonly: false
    },
    {
@@ -224,6 +227,12 @@
      }, {
        value: 'default',
        text: '后台脚本'
      }, {
        value: 'func',
        text: '回调函数'
      }, {
        value: 'none',
        text: '无'
      }]
    },
    {
@@ -238,7 +247,7 @@
      key: 'callbackFunc',
      label: Formdict['header.form.callbackFunc'],
      initVal: card.callbackFunc || '',
      required: false,
      required: true,
      readonly: false
    },
    {
src/menu/components/form/formaction/index.jsx
@@ -237,7 +237,7 @@
        <Modal
          title={dict['model.edit']}
          visible={visible}
          width={800}
          width={920}
          maskClosable={false}
          onCancel={this.editModalCancel}
          footer={[
src/menu/components/form/simple-form/index.jsx
@@ -157,16 +157,6 @@
    card.errors = []
    if (card.wrap.datatype !== 'static') {
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
      if (supModule === 'empty') {
        supModule = ''
@@ -174,6 +164,18 @@
      let columns = card.columns.map(c => c.field)
      let lowcols = card.columns.map(c => c.field.toLowerCase())
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!columns.includes(card.setting.primaryKey)) {
        card.errors.push({ level: 0, detail: '主键已失效!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      card.subcards.forEach(item => {
        item.fields.forEach(m => {
          if (m.type === 'linkMain' && !supModule) {
src/menu/components/form/step-form/index.jsx
@@ -164,16 +164,6 @@
    card.errors = []
    if (card.wrap.datatype !== 'static') {
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
      if (supModule === 'empty') {
        supModule = ''
@@ -181,6 +171,18 @@
      let columns = card.columns.map(c => c.field)
      let lowcols = card.columns.map(c => c.field.toLowerCase())
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!columns.includes(card.setting.primaryKey)) {
        card.errors.push({ level: 0, detail: '主键已失效!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      card.subcards.forEach(item => {
        item.fields.forEach(m => {
          if (m.type === 'linkMain' && !supModule) {
src/menu/components/form/tab-form/index.jsx
@@ -176,16 +176,6 @@
    card.errors = []
    if (card.wrap.datatype !== 'static') {
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
      if (supModule === 'empty') {
        supModule = ''
@@ -193,6 +183,18 @@
      let columns = card.columns.map(c => c.field)
      let lowcols = card.columns.map(c => c.field.toLowerCase())
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!columns.includes(card.setting.primaryKey)) {
        card.errors.push({ level: 0, detail: '主键已失效!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      card.subcards.forEach(item => {
        item.fields.forEach(m => {
          if (m.type === 'linkMain' && !supModule) {
src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -61,13 +61,13 @@
    }],
    interTypeOptions: [{
      value: 'system',
      text: this.props.dict['model.interface.system']
      text: '系统'
    }, {
      value: 'inner',
      text: this.props.dict['model.interface.inner']
      text: '内部'
    }, {
      value: 'outer',
      text: this.props.dict['model.interface.outer']
      text: '外部'
    }, {
      value: 'custom',
      text: '自定义'
@@ -163,18 +163,33 @@
      reOptions.intertype = this.state.interTypeOptions
      if (intertype === 'custom') {
        shows.push('procMode', 'interface', 'callbackType', 'cbTable', 'proInterface', 'method', 'cross')
        shows.push('procMode', 'interface', 'callbackType', 'proInterface', 'method', 'cross')
        if (this.record.procMode === 'system') {
          shows.push('sql', 'sqlType')
        } else {
        } else if (this.record.procMode === 'inner') {
          reRequired.innerFunc = true
          shows.push('innerFunc')
        }
        if (this.record.callbackType === 'func') {
          shows.push('callbackFunc')
        } else if (this.record.callbackType !== 'none') {
          shows.push('cbTable')
        }
        reReadonly.interface = false
        reRequired.interface = true
      } else if (intertype === 'outer') {
        shows.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc', 'output')
        reRequired.innerFunc = false
        shows.push('procMode', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackType', 'output')
        if (this.record.procMode === 'system') {
          shows.push('sql', 'sqlType')
        } else if (this.record.procMode === 'inner') {
          reRequired.innerFunc = true
          shows.push('innerFunc')
        }
        if (this.record.callbackType === 'func') {
          shows.push('callbackFunc')
        } else if (this.record.callbackType !== 'none') {
          shows.push('cbTable')
        }
        if (this.record.sysInterface === 'false') {
          reReadonly.interface = false
@@ -226,8 +241,18 @@
      reOptions.intertype = this.state.interTypeOptions.filter(item => item.value !== 'custom')
      if (intertype === 'outer') {
        shows.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
        reRequired.innerFunc = false
        shows.push('procMode', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackType')
        if (this.record.procMode === 'system') {
          shows.push('sql', 'sqlType')
        } else if (this.record.procMode === 'inner') {
          reRequired.innerFunc = true
          shows.push('innerFunc')
        }
        if (this.record.callbackType === 'func') {
          shows.push('callbackFunc')
        } else if (this.record.callbackType !== 'none') {
          shows.push('cbTable')
        }
        if (this.record.sysInterface === 'false') {
          reReadonly.interface = false
@@ -265,6 +290,7 @@
      if (this.record.intertype === 'outer') {
        shows.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
        reRequired.innerFunc = false
        reRequired.callbackFunc = false
        if (this.record.sysInterface === 'false') {
          reReadonly.interface = false
@@ -346,6 +372,7 @@
        if (this.record.intertype === 'outer') {
          shows.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
          reRequired.innerFunc = false
          reRequired.callbackFunc = false
          if (this.record.sysInterface === 'false') {
            reReadonly.interface = false
@@ -695,7 +722,7 @@
            { max: formRule.func.max, message: formRule.func.maxMessage }
          )
        } else if (item.key === 'output') {
          if (this.record.intertype === 'system') {
          if (this.record.intertype === 'system' || ((this.record.intertype === 'outer' || this.record.intertype === 'custom') && this.record.callbackType === 'script')) {
            rules = [{
              pattern: /^@[0-9a-zA-Z_]+@?$/,
              message: '变量以@符开头,可使用字母、数字以及_'
src/menu/components/share/actioncomponent/formconfig.jsx
@@ -52,15 +52,28 @@
  ]
  let getTabs = (list) => {
    return list.filter(item => {
      if (item.type !== 'tabs') return false
    let _list = []
    list.forEach(item => {
      if (item.type !== 'tabs') return
      item.children = item.children.map(cell => {
        cell.children = getTabs(cell.children)
        return cell
      _list.push({
        value: item.uuid,
        label: item.name,
        children: item.subtabs.map(cell => {
          let children = getTabs(cell.components)
          if (children.length === 0) {
            children = null
          }
          return {
            value: cell.uuid,
            label: cell.label,
            children: children
          }
        })
      })
      return item
    })
    return _list
  }
  // if (type === 'editable') {
@@ -74,8 +87,7 @@
  //     }
  //   ]
  // }
  let tabs = getTabs(JSON.parse(JSON.stringify(modules)))
  let tabs = getTabs(JSON.parse(JSON.stringify(window.GLOB.customMenu.components)))
  let pageTemps = [
    { value: 'billprint', text: '单据打印' },
@@ -189,6 +201,13 @@
      options: opentypes
    },
    {
      type: 'text',
      key: 'label',
      label: '按钮名称',
      initVal: card.label,
      required: true,
    },
    {
      type: 'select',
      key: 'funcType',
      label: '功能类型',
@@ -246,13 +265,6 @@
      options: []
    },
    {
      type: 'text',
      key: 'label',
      label: '按钮名称',
      initVal: card.label,
      required: true,
    },
    {
      type: 'checkbox',
      key: 'payType',
      label: '支付方式',
@@ -278,6 +290,9 @@
      }, {
        value: 'inner',
        text: '内部函数'
      }, {
        value: 'none',
        text: '无'
      }]
    },
    {
@@ -424,6 +439,12 @@
      }, {
        value: 'default',
        text: '后台脚本'
      }, {
        value: 'func',
        text: '回调函数'
      }, {
        value: 'none',
        text: '无'
      }]
    },
    {
@@ -438,7 +459,7 @@
      key: 'callbackFunc',
      label: Formdict['header.form.callbackFunc'],
      initVal: card.callbackFunc || '',
      required: false,
      required: true
    },
    {
      type: 'select',
src/menu/components/share/actioncomponent/index.jsx
@@ -533,7 +533,7 @@
        <Modal
          title="按钮·编辑"
          visible={visible}
          width={850}
          width={920}
          maskClosable={false}
          onCancel={this.editModalCancel}
          footer={[
src/menu/components/table/edit-table/columns/index.jsx
@@ -18,6 +18,7 @@
const TableVerify = asyncComponent(() => import('./tableIn'))
const MarkColumn = asyncIconComponent(() => import('@/menu/components/share/markcomponent'))
const CardCellComponent = asyncComponent(() => import('@/menu/components/card/cardcellcomponent'))
const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
class HeaderCol extends Component {
  deleteCol = () => {
@@ -51,7 +52,7 @@
  }
  render() {
    const { connectDragSource, connectDropTarget, moveCol, addElement, updateCol, editColumn, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props
    const { connectDragSource, connectDropTarget, moveCol, addElement, updateCol, editColumn, pasteCell, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props
    if (!column) return (
      <th {...restProps} index={index}>
@@ -67,6 +68,7 @@
              <PlusOutlined className="plus" title="添加" onClick={() => this.props.addElement(column)} /> : null
            }
            <EditOutlined className="edit" title="编辑" onClick={() => this.props.editColumn(column)} />
            {column.type === 'custom' ? <PasteComponent options={['customCardElement']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
            {column.type === 'custom' ? <FontColorsOutlined className="style" title="调整样式" onClick={() => this.props.changeStyle(column)}/> : null}
            <DeleteOutlined className="close" title="删除" onClick={this.deleteCol} />
            {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
@@ -280,6 +282,16 @@
    this.setState({
      card: fromJS(col).toJS()
    })
  }
  pasteCell = (col, cell, resolve) => {
    resolve({status: true})
    delete cell.copyType
    cell.uuid = Utils.getuuid()
    cell.focus = true
    MKEmitter.emit('cardAddElement', [this.props.config.uuid, col.uuid], cell)
  }
  addElement = (col) => {
@@ -554,6 +566,7 @@
          updateCol: this.updateCol,
          addElement: this.addElement,
          editColumn: this.editColumn,
          pasteCell: this.pasteCell,
          changeStyle: this.changeStyle,
          deleteCol: this.deleteCol,
        }),
src/menu/components/table/edit-table/columns/tableIn/index.jsx
@@ -86,7 +86,7 @@
          ) :
          (
            <div>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleTwoTone style={{marginLeft: '5px'}} twoToneColor="#52c41a" />
            </div>
          )
@@ -139,7 +139,7 @@
          ) :
          (
            <div>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleTwoTone style={{marginLeft: '5px'}} twoToneColor="#52c41a" />
            </div>
          )
src/menu/components/table/edit-table/index.jsx
@@ -170,16 +170,6 @@
    if (!window.GLOB.styling || !card.errors) { // 样式修改时不做筛查
      card.errors = []
  
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
      if (supModule === 'empty') {
        supModule = ''
@@ -187,6 +177,18 @@
  
      let columns = card.columns.map(c => c.field)
      let lowcols = card.columns.map(c => c.field.toLowerCase())
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!columns.includes(card.setting.primaryKey)) {
        card.errors.push({ level: 0, detail: '主键已失效!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
  
      card.action.forEach(cell => {
        if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
src/menu/components/table/normal-table/columns/index.jsx
@@ -18,6 +18,7 @@
const MarkColumn = asyncIconComponent(() => import('@/menu/components/share/markcomponent'))
const CardCellComponent = asyncComponent(() => import('@/menu/components/card/cardcellcomponent'))
const MobPagination = asyncIconComponent(() => import('@/menu/components/share/mobPagination'))
const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
class HeaderCol extends Component {
  deleteCol = () => {
@@ -51,7 +52,7 @@
  }
  render() {
    const { connectDragSource, connectDropTarget, moveCol, addElement, updateCol, editColumn, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props
    const { connectDragSource, connectDropTarget, moveCol, addElement, updateCol, editColumn, pasteCell, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props
    if (index !== undefined) {
      return connectDragSource(
@@ -62,6 +63,7 @@
                <PlusOutlined className="plus" title="添加" onClick={() => this.props.addElement(column)} /> : null
              }
              <EditOutlined className="edit" title="编辑" onClick={() => this.props.editColumn(column)} />
              {column && column.type === 'custom' ? <PasteComponent options={['customCardElement']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
              {column && column.type === 'custom' ? <FontColorsOutlined className="style" title="调整样式" onClick={() => this.props.changeStyle(column)}/> : null}
              <DeleteOutlined className="close" title="删除" onClick={this.deleteCol} />
              {column && ['text', 'number', 'formula'].includes(column.type) ? <MarkColumn columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
@@ -80,6 +82,7 @@
                <PlusOutlined className="plus" title="添加" onClick={() => this.props.addElement(column)} /> : null
              }
              <EditOutlined className="edit" title="编辑" onClick={() => this.props.editColumn(column)} />
              {column.type === 'custom' ? <PasteComponent options={['customCardElement']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
              <DeleteOutlined className="close" title="删除" onClick={this.deleteCol} />
              {column && ['text', 'number', 'formula'].includes(column.type) ? <MarkColumn columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
            </div>
@@ -303,6 +306,16 @@
    })
  }
  pasteCell = (col, cell, resolve) => {
    resolve({status: true})
    delete cell.copyType
    cell.uuid = Utils.getuuid()
    cell.focus = true
    MKEmitter.emit('cardAddElement', [this.props.config.uuid, col.uuid], cell)
  }
  addElement = (col) => {
    const { config } = this.props
    let column = fromJS(col).toJS()
@@ -482,6 +495,7 @@
          updateCol: this.updateCol,
          addElement: this.addElement,
          editColumn: this.editColumn,
          pasteCell: this.pasteCell,
          changeStyle: this.changeStyle,
          deleteCol: this.deleteCol,
        }),
src/menu/components/table/normal-table/index.jsx
@@ -207,17 +207,7 @@
    if (!window.GLOB.styling || !card.errors) { // 样式修改时不做筛查
      card.errors = []
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
      if (supModule === 'empty') {
        supModule = ''
@@ -227,6 +217,18 @@
      let columns = card.columns.map(c => c.field)
      let lowcols = card.columns.map(c => c.field.toLowerCase())
  
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!columns.includes(card.setting.primaryKey)) {
        card.errors.push({ level: 0, detail: '主键已失效!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      card.action.forEach(cell => {
        if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
          if (!cell.modal || cell.modal.fields.length === 0) {
src/menu/components/tabs/antv-tabs/index.jsx
@@ -318,6 +318,7 @@
    editab.hide = res.hide || 'false'
    editab.backgroundColor = res.backgroundColor
    editab.controlVal = res.controlVal || ''
    editab.selectVal = res.selectVal || ''
    editab.blacklist = res.blacklist
    if (editab.uuid) {
src/menu/components/tabs/antv-tabs/options.jsx
@@ -52,9 +52,16 @@
      field: 'controlVal',
      label: '隐藏标记',
      initval: tab.controlVal || '',
      tooltip: '当禁用字段值与隐藏标记相等时,标签页会隐藏。',
      tooltip: '当禁用字段值与隐藏标记相等时,标签页会隐藏。注:多个值请用逗号分隔。',
      required: false,
      // forbid: appType === 'mob',
    },
    {
      type: 'text',
      field: 'selectVal',
      label: '选中标记',
      initval: tab.selectVal || '',
      tooltip: '当选中字段值与选中标记相等时,标签页默认选中。',
      required: false
    },
    {
      type: 'color',
@@ -96,6 +103,10 @@
  let roleList = sessionStorage.getItem('sysRoles')
  let modules = MenuUtils.getSupModules(window.GLOB.customMenu.components, uuid) || []
  modules.push({
    value: 'preview',
    label: '上一页(url参数)'
  })
  if (roleList) {
    try {
@@ -198,13 +209,13 @@
      label: '上级组件',
      initval: setting.supModule || [],
      tooltip: '标签组可以选择上级组件,填入禁用字段,用于控制标签隐藏。',
      help: '用于控制标签页隐藏。',
      required: false,
      allowClear: true,
      options: modules,
      controlFields: [
        {field: 'controlField', notNull: true},
      ],
      // forbid: appType === 'mob',
    },
    {
      type: 'text',
@@ -213,7 +224,14 @@
      initval: setting.controlField || '',
      tooltip: '用于控制标签隐藏的字段,在标签中填入隐藏标记。',
      required: true,
      // forbid: appType === 'mob',
    },
    {
      type: 'text',
      field: 'selectField',
      label: '选中字段',
      initval: setting.selectField || '',
      tooltip: '用于控制标签页初始化选中,在标签中填入选中标记,注:数据源于url参数。',
      required: false
    },
    {
      type: 'color',
src/menu/components/timeline/normal-timeline/index.jsx
@@ -117,17 +117,7 @@
    card.name = card.wrap.name
    if (!window.GLOB.styling || !card.errors) { // 样式修改时不做筛查
      card.errors = []
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
      if (supModule === 'empty') {
        supModule = ''
@@ -135,6 +125,18 @@
      let columns = card.columns.map(c => c.field)
      let lowcols = card.columns.map(c => c.field.toLowerCase())
  
      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
        card.errors.push({ level: 0, detail: '未设置数据源!'})
      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
        card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
      } else if (!card.setting.primaryKey) {
        card.errors.push({ level: 0, detail: '未设置主键!'})
      } else if (!columns.includes(card.setting.primaryKey)) {
        card.errors.push({ level: 0, detail: '主键已失效!'})
      } else if (!card.setting.supModule) {
        card.errors.push({ level: 0, detail: '未设置上级组件!'})
      }
      card.subcards.forEach(col => {
        col.elements.forEach(cell => {
          if (cell.eleType === 'button') {
src/menu/components/tree/antd-tree/index.jsx
@@ -105,12 +105,16 @@
    card.errors = []
    let columns = card.columns.map(c => c.field)
    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
      card.errors.push({ level: 0, detail: '未设置数据源!'})
    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
      card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
    } else if (!card.setting.primaryKey) {
      card.errors.push({ level: 0, detail: '未设置主键!'})
    } else if (!columns.includes(card.setting.primaryKey)) {
      card.errors.push({ level: 0, detail: '主键已失效!'})
    } else if (!card.setting.supModule) {
      card.errors.push({ level: 0, detail: '未设置上级组件!'})
    }
src/menu/datasource/verifycard/columnform/index.jsx
@@ -53,7 +53,7 @@
                    message: dict['form.required.input'] + '名称!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" />)}
              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleConfirm}/>)}
            </Form.Item>
          </Col>
          <Col span={6}>
@@ -70,7 +70,7 @@
                    message: '字段名只允许包含数字、字母、汉字以及_'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" />)}
              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleConfirm} />)}
            </Form.Item>
          </Col>
          <Col span={6}>
src/menu/datasource/verifycard/index.jsx
@@ -133,7 +133,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
src/menu/menushell/index.scss
@@ -1,6 +1,7 @@
.menu-shell-inner {
  min-height: calc(100vh - 100px);
  width: 100%;
  width: auto!important;
  overflow-x: hidden;
  background-size: 100%;
  .anticon {
src/menu/padcontroller/index.jsx
File was deleted
src/menu/padcontroller/index.scss
File was deleted
src/menu/stylecombcontrolbutton/index.scss
@@ -17,6 +17,16 @@
    z-index: 12;
    background:rgba(0, 0, 0, 0.2);
  }
  .pc-poper-view::before {
    content: ' ';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    right: 0;
    z-index: 12;
    background:rgba(0, 0, 0, 0.2);
  }
  .menu-body .menu-view >.ant-card >.ant-card-body {
    position: relative;
    z-index: 13;
src/menu/sysinterface/index.jsx
@@ -199,6 +199,7 @@
          destroyOnClose
        > 
          <Button key="add-interface" className="mk-border-green" onClick={this.addInterface}> 添加 </Button>
          {/* <div style={{fontSize: '12px', position: 'relative', top: '20px'}}>注:接口执行完成后,会触发默认不加载的组件刷新数据。</div> */}
          <EditTable key="manage-interface" actions={['move', 'copy']} type="interface" data={interfaces} columns={columns} onChange={this.changeScripts}/>
        </Modal>
        <Modal
src/menu/sysinterface/settingform/simplescript/index.jsx
@@ -72,7 +72,7 @@
          ) :
          (
            <div>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleTwoTone style={{marginLeft: '5px'}} twoToneColor="#52c41a" />
            </div>
          )
src/mob/components/menubar/normal-menubar/menucomponent/index.jsx
@@ -110,7 +110,7 @@
        MenuID: card.setting.type === 'linkmenu' ? card.setting.linkMenuId : card.uuid,
        copyMenuId: card.setting.type === 'menu' ? card.setting.copyMenuId : '',
        clearMenu: card.setting.clearMenu || 'true',
        MenuNo: card.setting.MenuNo || '',
        // MenuNo: card.setting.MenuNo || '',
        MenuName: card.setting.name,
      })
    }
src/mob/components/menubar/normal-menubar/menucomponent/options.jsx
@@ -22,24 +22,13 @@
      initval: setting.name || '',
      required: true
    },
    {
      type: 'text',
      field: 'MenuNo',
      label: '菜单参数',
      initval: setting.MenuNo || '',
      required: true
    },
    {
      type: 'number',
      field: 'width',
      label: '宽度',
      initval: setting.width || 24,
      tooltip: '栅格布局,每行等分为24列。',
      min: 1,
      max: 24,
      precision: 0,
      required: true
    },
    // {
    //   type: 'text',
    //   field: 'MenuNo',
    //   label: '菜单参数',
    //   initval: setting.MenuNo || '',
    //   required: true
    // },
    {
      type: 'radio',
      field: 'type',
@@ -55,6 +44,7 @@
        {field: 'copyMenuId', values: ['menu']},
        {field: 'linkMenuId', values: ['linkmenu']},
        {field: 'linkurl', values: ['link']},
        {field: 'primaryId', values: ['menu', 'linkmenu']},
      ]
    },
    {
@@ -132,6 +122,17 @@
    },
    {
      type: 'number',
      field: 'width',
      label: '宽度',
      initval: setting.width || 24,
      tooltip: '栅格布局,每行等分为24列。',
      min: 1,
      max: 24,
      precision: 0,
      required: true
    },
    {
      type: 'number',
      field: 'iconFont',
      label: '字体大小',
      initval: setting.iconFont || 20,
@@ -198,6 +199,14 @@
      required: false,
      options: columns
    },
    {
      type: 'text',
      field: 'primaryId',
      label: '静态主键值',
      initval: setting.primaryId || '',
      tooltip: '可作为BID传到下一页面。',
      required: false
    }
  ]
  return menuWrapForm
src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx
@@ -106,44 +106,6 @@
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="菜单参数">
              {getFieldDecorator('MenuNo', {
                initialValue: menu.MenuNo || '',
                rules: [
                  {
                    required: true,
                    message: '请输入菜单参数!'
                  }
                ]
              })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="图标">
              {getFieldDecorator('icon', {
                initialValue: menu.icon || ''
              })(
                <MkEditIcon options={['normal', 'data', 'direction', 'edit', 'hint']} allowClear />
              )}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="绑定提示字段后,会在菜单右上角显示提示信息。注:在添加图标时有效。">
                <QuestionCircleOutlined className="mk-form-tip" />
                提示
              </Tooltip>
            }>
              {getFieldDecorator('tip', {
                initialValue: menu.tip || ''
              })(
                <Select allowClear>
                  {cols.map(item => <Select.Option key={item.uuid} value={item.field}>{item.label}</Select.Option>)}
                </Select>
              )}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="菜单属性">
              {getFieldDecorator('property', {
                initialValue: menu.property || 'menu'
@@ -156,35 +118,6 @@
              )}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="隐藏">
              {getFieldDecorator('hidden', {
                initialValue: menu.hidden || 'false'
              })(
                <Radio.Group>
                  <Radio value="false">否</Radio>
                  <Radio value="true">是</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
          {property === 'menu' || property === 'linkmenu' ? <Col span={12}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="替换当前页面或打开新页面,在H5或小程序中有效。">
                <QuestionCircleOutlined className="mk-form-tip" />
                打开方式
              </Tooltip>
            }>
              {getFieldDecorator('open', {
                initialValue: menu.open || 'self'
              })(
                <Radio.Group>
                  <Radio value="self">标签页</Radio>
                  <Radio value="blank">新页面</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col> : null}
          {property === 'link' ? <Col span={24}>
            <Form.Item label="链接地址" className="textarea">
              {getFieldDecorator('link', {
@@ -261,6 +194,73 @@
              )}
            </Form.Item>
          </Col> : null}
          {/* <Col span={12}>
            <Form.Item label="菜单参数">
              {getFieldDecorator('MenuNo', {
                initialValue: menu.MenuNo || '',
                rules: [
                  {
                    required: true,
                    message: '请输入菜单参数!'
                  }
                ]
              })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
            </Form.Item>
          </Col> */}
          <Col span={12}>
            <Form.Item label="图标">
              {getFieldDecorator('icon', {
                initialValue: menu.icon || ''
              })(
                <MkEditIcon options={['normal', 'data', 'direction', 'edit', 'hint']} allowClear />
              )}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="绑定提示字段后,会在菜单右上角显示提示信息。注:在添加图标时有效。">
                <QuestionCircleOutlined className="mk-form-tip" />
                提示
              </Tooltip>
            }>
              {getFieldDecorator('tip', {
                initialValue: menu.tip || ''
              })(
                <Select allowClear>
                  {cols.map(item => <Select.Option key={item.uuid} value={item.field}>{item.label}</Select.Option>)}
                </Select>
              )}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="隐藏">
              {getFieldDecorator('hidden', {
                initialValue: menu.hidden || 'false'
              })(
                <Radio.Group>
                  <Radio value="false">否</Radio>
                  <Radio value="true">是</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
          {property === 'menu' || property === 'linkmenu' ? <Col span={12}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="替换当前页面或打开新页面,在H5或小程序中有效。">
                <QuestionCircleOutlined className="mk-form-tip" />
                打开方式
              </Tooltip>
            }>
              {getFieldDecorator('open', {
                initialValue: menu.open || 'self'
              })(
                <Radio.Group>
                  <Radio value="self">标签页</Radio>
                  <Radio value="blank">新页面</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col> : null}
          <Col span={12}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="在H5或小程序中有效。">
src/mob/components/tabs/antv-tabs/index.jsx
@@ -341,6 +341,7 @@
    editab.hide = res.hide || 'false'
    editab.backgroundColor = res.backgroundColor
    editab.controlVal = res.controlVal || ''
    editab.selectVal = res.selectVal || ''
    editab.blacklist = res.blacklist
    if (editab.uuid) {
src/mob/components/tabs/antv-tabs/options.jsx
@@ -52,7 +52,15 @@
      field: 'controlVal',
      label: '隐藏标记',
      initval: tab.controlVal || '',
      tooltip: '当禁用字段值与隐藏标记相等时,标签页会隐藏。',
      tooltip: '当禁用字段值与隐藏标记相等时,标签页会隐藏。注:多个值请用逗号分隔。',
      required: false
    },
    {
      type: 'text',
      field: 'selectVal',
      label: '选中标记',
      initval: tab.selectVal || '',
      tooltip: '当选中字段值与选中标记相等时,标签页默认选中。',
      required: false
    },
    {
@@ -92,6 +100,10 @@
 */
export function getTabsSetForm(setting, uuid) {
  let modules = MenuUtils.getSupModules(window.GLOB.customMenu.components, uuid) || []
  modules.push({
    value: 'preview',
    label: '上一页(url参数)'
  })
  const tabForm = [
    {
@@ -146,6 +158,7 @@
      label: '上级组件',
      initval: setting.supModule || [],
      tooltip: '标签组可以选择上级组件,填入禁用字段,用于控制标签隐藏。',
      help: '用于控制标签页隐藏。',
      required: false,
      allowClear: true,
      options: modules,
@@ -162,6 +175,14 @@
      required: true
    },
    {
      type: 'text',
      field: 'selectField',
      label: '选中字段',
      initval: setting.selectField || '',
      tooltip: '用于控制标签页初始化选中,在标签中填入选中标记,注:数据源于url参数。',
      required: false
    },
    {
      type: 'color',
      field: 'backgroundColor',
      label: '背景(标题栏)',
src/pc/bgcontroller/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Form, Select } from 'antd'
import { Form, Select, Input } from 'antd'
import { ArrowUpOutlined, ArrowDownOutlined, ArrowLeftOutlined, ArrowRightOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
@@ -19,6 +19,7 @@
  }
  state = {
    background: '',
    backgroundColor: '',
    backgroundImage: '',
    backgroundSize: '',
@@ -38,6 +39,7 @@
    }
    this.setState({
      background: config.style.background || '',
      backgroundColor: config.style.backgroundColor,
      backgroundImage: bgImg,
      backgroundSize: config.style.backgroundSize || '100%',
@@ -123,9 +125,34 @@
    this.props.updateConfig(config)
  }
  changeBackground = (val) => {
    this.setState({
      background: val,
    })
    if (!val || /(^linear-gradient|^radial-gradient)\(.*\)$/.test(val)) {
      let config = fromJS(this.props.config).toJS()
      config.style.background = val
      delete config.style.backgroundColor
      delete config.style.backgroundImage
      if (!val) {
        delete config.style.background
      }
      this.setState({
        backgroundImage: '',
        backgroundColor: ''
      })
      this.props.updateConfig(config)
    }
  }
  render () {
    const { config } = this.props
    const { backgroundColor, backgroundImage, backgroundSize, backgroundRepeat, backgroundPosition } = this.state
    const { backgroundColor, backgroundImage, backgroundSize, backgroundRepeat, backgroundPosition, background } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -140,16 +167,19 @@
    return (
      <div className="pc-style-controller">
        <Form {...formItemLayout}>
          <Form.Item
          {/* <Form.Item
            colon={false}
            label="宽度"
            className="normal-view"
          >
            <StyleInput defaultValue={config.style.width || '100%'} options={['px', '%', 'vw']} onChange={(val) => this.changePadding(val, 'width')}/>
          </Form.Item>
          </Form.Item> */}
          <Form.Item className="color-control" colon={false} label="背景色">
            <ColorSketch value={backgroundColor} onChange={this.changeBackgroundColor} />
          </Form.Item>
          {window.develop === true ? <Form.Item colon={false} label="颜色">
            <Input value={background} onChange={(e) => this.changeBackground(e.target.value)} />
          </Form.Item> : null}
          <Form.Item colon={false} label="背景图">
            <SourceComponent value={backgroundImage} type="" placement="right" onChange={this.imgChange}/>
          </Form.Item>
src/pc/components/navbar/normal-navbar/index.jsx
@@ -141,7 +141,7 @@
      MenuID: menu.property === 'linkmenu' ? menu.linkMenuId : menu.MenuID,
      copyMenuId: menu.property === 'menu' ? menu.copyMenuId : '',
      clearMenu: menu.clearMenu || 'true',
      MenuNo: menu.MenuNo,
      // MenuNo: menu.MenuNo,
      MenuName: menu.name,
    })
  }
@@ -153,7 +153,7 @@
      MKEmitter.emit('changeEditMenu', {
        MenuID: card.wrap.linkmenu,
        copyMenuId: '',
        MenuNo: '',
        // MenuNo: '',
        MenuName: ''
      })
    }
src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx
@@ -102,7 +102,7 @@
              })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
            </Form.Item>
          </Col>
          <Col span={22}>
          {/* <Col span={22}>
            <Form.Item label="菜单参数">
              {getFieldDecorator('MenuNo', {
                initialValue: menu.MenuNo || '',
@@ -114,7 +114,7 @@
                ]
              })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
            </Form.Item>
          </Col>
          </Col> */}
          <Col span={22}>
            <Form.Item label="菜单属性">
              {getFieldDecorator('property', {
@@ -129,41 +129,6 @@
              )}
            </Form.Item>
          </Col>
          <Col span={22}>
            <Form.Item label="隐藏">
              {getFieldDecorator('hidden', {
                initialValue: menu.hidden || 'false'
              })(
                <Radio.Group>
                  <Radio value="false">否</Radio>
                  <Radio value="true">是</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
          {property !== 'classify' ? <Col span={22}>
            <Form.Item label="打开方式">
              {getFieldDecorator('open', {
                initialValue: menu.open || 'blank'
              })(
                <Radio.Group>
                  <Radio value="blank">新窗口</Radio>
                  <Radio value="self">当前窗口</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col> : null}
          {property === 'link' ? <Col span={22}>
            <Form.Item label="链接地址">
              {getFieldDecorator('link', {
                initialValue: menu.link || '',
                rules: [{
                  required: true,
                  message: '请输入链接地址!'
                }]
              })(<TextArea rows={2} />)}
            </Form.Item>
          </Col> : null}
          {property === 'linkmenu' ? <Col span={22}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="关联当前app中已有的菜单。">
@@ -217,6 +182,41 @@
              )}
            </Form.Item>
          </Col> : null}
          <Col span={22}>
            <Form.Item label="隐藏">
              {getFieldDecorator('hidden', {
                initialValue: menu.hidden || 'false'
              })(
                <Radio.Group>
                  <Radio value="false">否</Radio>
                  <Radio value="true">是</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
          {property !== 'classify' ? <Col span={22}>
            <Form.Item label="打开方式">
              {getFieldDecorator('open', {
                initialValue: menu.open || 'blank'
              })(
                <Radio.Group>
                  <Radio value="blank">新窗口</Radio>
                  <Radio value="self">当前窗口</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col> : null}
          {property === 'link' ? <Col span={22}>
            <Form.Item label="链接地址">
              {getFieldDecorator('link', {
                initialValue: menu.link || '',
                rules: [{
                  required: true,
                  message: '请输入链接地址!'
                }]
              })(<TextArea rows={2} />)}
            </Form.Item>
          </Col> : null}
        </Row>
      </Form>
    )
src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx
@@ -21,7 +21,7 @@
    editMenu: null,
    columns: [
      { title: '菜单名称', dataIndex: 'name', key: 'name' },
      { title: '菜单参数', dataIndex: 'MenuNo', key: 'MenuNo' },
      // { title: '菜单参数', dataIndex: 'MenuNo', key: 'MenuNo' },
      { title: '菜单属性', dataIndex: 'property', key: 'property',  render: text => {
        const trans = {menu: '菜单', link: '链接', linkmenu: '关联菜单', classify: '分类'}
@@ -203,7 +203,7 @@
    editMenu: null,
    columns: [
      { title: '菜单名称', dataIndex: 'name', key: 'name' },
      { title: '菜单参数', dataIndex: 'MenuNo', key: 'MenuNo' },
      // { title: '菜单参数', dataIndex: 'MenuNo', key: 'MenuNo' },
      { title: '菜单属性', dataIndex: 'property', key: 'property',  render: text => {
        const trans = {menu: '菜单', link: '链接', linkmenu: '关联菜单', classify: '分类'}
@@ -402,7 +402,7 @@
    editMenu: null,
    columns: [
      { title: '菜单名称', dataIndex: 'name', key: 'name' },
      { title: '菜单参数', dataIndex: 'MenuNo', key: 'MenuNo' },
      // { title: '菜单参数', dataIndex: 'MenuNo', key: 'MenuNo' },
      { title: '菜单属性', dataIndex: 'property', key: 'property',  render: text => {
        const trans = {menu: '菜单', link: '链接', linkmenu: '关联菜单', classify: '分类'}
src/pc/menushell/index.scss
@@ -1,6 +1,6 @@
.menu-shell-inner {
  min-height: calc(100vh - 100px);
  width: 100%;
  width: auto!important;
  background-size: 100%;
  .anticon {
src/router/index.js
@@ -16,6 +16,7 @@
const AppCheck = asyncLoadComponent(() => import('@/views/appcheck'))
const PCDesign = asyncLoadComponent(() => import('@/views/pcdesign'))
const MobDesign = asyncLoadComponent(() => import('@/views/mobdesign'))
const PopDesign = asyncLoadComponent(() => import('@/views/popdesign'))
const ImDesign = asyncLoadComponent(() => import('@/views/imdesign'))
const MenuDesign = asyncLoadComponent(() => import('@/views/menudesign'))
const BaseDesign = asyncLoadComponent(() => import('@/views/basedesign'))
@@ -39,6 +40,7 @@
  {path: '/imdesign/:param', name: 'imdesign', component: ImDesign, auth: true},
  {path: '/menudesign/:param', name: 'menudesign', component: MenuDesign, auth: true},
  {path: '/basedesign/:param', name: 'basedesign', component: BaseDesign, auth: true},
  {path: '/popdesign/:param', name: 'popdesign', component: PopDesign, auth: true},
  {path: '/billprint/:param', name: 'billprint', component: BillPrint, auth: true},
  {path: '/docprint/:menuId', name: 'docprint', component: BillPrint, auth: false},
  {path: '/docprint/:menuId/:id', name: 'docprint', component: BillPrint, auth: false},
src/tabviews/calendar/index.jsx
@@ -40,7 +40,7 @@
    config: {},           // 页面配置信息,包括按钮、搜索、显示列、标签等
    userConfig: null,     // 用户自定义设置
    searchlist: null,     // 搜索条件
    arr_field: '',        // 使用 sPC_Get_TableData 时的查询字段集
    arr_field: '',        // 查询字段集
    setting: null,        // 页面全局设置:数据源、按钮及显示列固定、主键等
    data: null,           // 列表数据集
    loading: false,       // 列表数据加载中
@@ -321,7 +321,7 @@
  }
  /**
   * @description 获取系统存储过程 sPC_Get_TableData 的参数
   * @description 获取系统存储过程的参数
   */
  getDefaultParam = () => {
    const { arr_field, search, setting, config, calendarYear } = this.state
src/tabviews/commontable/index.jsx
@@ -51,7 +51,7 @@
    searchlist: null,     // 搜索条件
    actions: null,        // 按钮集
    columns: null,        // 显示列
    arr_field: '',        // 使用 sPC_Get_TableData 时的查询字段集
    arr_field: '',        // 查询字段集
    setting: null,        // 页面全局设置:数据源、按钮及显示列固定、主键等
    data: [],             // 列表数据集
    selectedData: [],     // 已选表格数据
@@ -653,14 +653,6 @@
      sql = sql.join('')
      
      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql, BID)
      if (BID) {
        param.BID = BID
      }
      if (window.GLOB.mkHS) { // 函数 sPC_TableData_InUpDe 云端验证
        param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
      }
    } else {
      param.func = 's_ex_result_back'
      param.s_ex_result = lines.map((item, index) => ({
src/tabviews/custom/components/card/prop-card/index.jsx
@@ -117,7 +117,7 @@
        setTimeout(() => {
          this.loadData()
        }, _config.setting.delay || 0)
      } else if ((!_sync || _config.wrap.priKeyType === 'static') && selected !== 'false') {
      } else if (!_sync && selected !== 'false') {
        setTimeout(() => {
          this.checkTopLine()
        }, 200)
@@ -168,7 +168,7 @@
      _data.$$uuid = _data[config.setting.primaryKey] || ''
      this.setState({sync: false, data: _data}, () => {
        if (config.wrap.priKeyType !== 'static' && selected !== 'false') {
        if (selected !== 'false') {
          setTimeout(() => {
            this.checkTopLine()
          }, 200)
@@ -368,7 +368,7 @@
        data: _data,
        loading: false
      }, () => {
        if (config.wrap.priKeyType !== 'static' && selected !== 'false') {
        if (selected !== 'false') {
          this.checkTopLine()
        }
      })
src/tabviews/custom/components/carousel/data-card/index.scss
@@ -10,6 +10,7 @@
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    overflow: hidden;
  }
  .ant-empty {
src/tabviews/custom/components/carousel/prop-card/index.scss
@@ -12,6 +12,7 @@
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    overflow: hidden;
  }
  .loading-mask {
src/tabviews/custom/components/module/voucher/assistTable/index.jsx
New file
@@ -0,0 +1,738 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Table, Modal, Input, InputNumber, notification, message } from 'antd'
// import { EditOutlined } from '@ant-design/icons'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import zhCN from '@/locales/zh-CN/main.js'
import enUS from '@/locales/en-US/main.js'
import '@/assets/css/table.scss'
import './index.scss'
class BodyRow extends React.Component {
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props.data), fromJS(nextProps.data))
  }
  render() {
    let { data, ...resProps } = this.props
    let style = {}
    let className = ''
    return <tr {...resProps} className={className} style={style}/>
  }
}
class BodyCell extends React.Component {
  state = {
    editing: false,
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props.record), fromJS(nextProps.record)) ||
      nextState.editing !== this.state.editing
  }
  componentDidMount () {
    MKEmitter.addListener('tdFocus', this.tdFocus)
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    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
    const { value } = this.state
    this.setState({editing: false})
    if (value !== record[col.field]) {
      let line = {...record, [col.field]: value}
      if (col.field === 'debtor') {
        line.creditor = ''
      } else {
        line.debtor = ''
      }
      MKEmitter.emit('changeRecord', col.tableId, line)
    }
    setTimeout(() => {
      if (col.field === 'creditor') {
        MKEmitter.emit('nextLine', col, record)
      } else {
        let cl = {remark: 'subject', subject: 'debtor', debtor: 'creditor'}
        MKEmitter.emit('tdFocus', cl[col.uuid] + record.uuid)
      }
    }, 50)
  }
  focus = () => {
    const { col, record } = this.props
    if (record.type === 'total') return
    this.setState({editing: true, value: record[col.field]}, () => {
      let node = document.getElementById(col.uuid + record.uuid)
      node && node.select()
    })
  }
  onBlur = () => {
    const { col, record } = this.props
    const { value } = this.state
    this.setState({editing: false})
    if (value !== record[col.field]) {
      let line = {...record, [col.field]: value}
      if (col.field === 'debtor') {
        line.creditor = ''
      } else {
        line.debtor = ''
      }
      MKEmitter.emit('changeRecord', col.tableId, line)
    }
  }
  onChange = (val) => {
    this.setState({value: val})
  }
  render() {
    let { col, record, className } = this.props
    const { editing } = this.state
    let children = null
    let colSpan = 1
    if (col.field === 'remark') {
      let val = record.remark || ''
      if (record.type === 'total') {
        children = <div className="content-wrap" style={{lineHeight: '60px'}}>合计: {val}</div>
        colSpan = 2
      } else {
        if (editing) {
          children = <Input.TextArea id={col.uuid + record.uuid} autoSize={false} defaultValue={val} onChange={(e) => this.onChange(e.target.value)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
        } else {
          children = <div className="content-wrap" onClick={this.focus}>{val}</div>
        }
      }
    } else if (col.field === 'subject') {
      if (record.type === 'total') {
        colSpan = 0
      } else {
        let val = record.subject || ''
        if (editing) {
          children = <Input.TextArea id={col.uuid + record.uuid} autoSize={false} defaultValue={val} onChange={(e) => this.onChange(e.target.value)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
        } else {
          children = <div className="content-wrap" onClick={this.focus}>{val}</div>
        }
      }
    } else if (col.field === 'debtor') {
      let val = record.debtor
      let down = false
      let vals = []
      if (typeof(val) === 'number') {
        if (val < 0) {
          down = true
          val = Math.abs(val)
        }
        vals = (val * 100).toFixed(0).split('').reverse()
      }
      if (editing) {
        children = <InputNumber id={col.uuid + record.uuid} defaultValue={val} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
      } else {
        children = <div className={'money-uint' + (down ? ' down' : '')} onClick={this.focus}>
          <span>{vals[10] || ''}</span> <span>{vals[9] || ''}</span> <span>{vals[8] || ''}</span> <span>{vals[7] || ''}</span> <span>{vals[6] || ''}</span> <span>{vals[5] || ''}</span>
          <span>{vals[4] || ''}</span> <span>{vals[3] || ''}</span> <span>{vals[2] || ''}</span> <span>{vals[1] || ''}</span> <span className="last">{vals[0] || ''}</span>
        </div>
      }
    } else if (col.field === 'creditor') {
      let val = record.creditor
      let down = false
      let vals = []
      if (typeof(val) === 'number') {
        if (val < 0) {
          down = true
          val = Math.abs(val)
        }
        vals = (val * 100).toFixed(0).split('').reverse()
      }
      if (editing) {
        children = <InputNumber id={col.uuid + record.uuid} defaultValue={val} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
      } else {
        children = <div className={'money-uint' + (down ? ' down' : '')} onClick={this.focus}>
        <span>{vals[10] || ''}</span> <span>{vals[9] || ''}</span> <span>{vals[8] || ''}</span> <span>{vals[7] || ''}</span> <span>{vals[6] || ''}</span> <span>{vals[5] || ''}</span>
        <span>{vals[4] || ''}</span> <span>{vals[3] || ''}</span> <span>{vals[2] || ''}</span> <span>{vals[1] || ''}</span> <span className="last">{vals[0] || ''}</span>
      </div>
      }
    }
    if (!colSpan) return null
    return (<td colSpan={colSpan} className={className}>{children}</td>)
  }
}
class AssistTable extends Component {
  static propTpyes = {
    config: PropTypes.object,        // 菜单Id
    BID: PropTypes.any,              // 主表ID
    data: PropTypes.any,             // 表格数据
    total: PropTypes.any,            // 总数
    loading: PropTypes.bool,         // 表格加载中
    refreshdata: PropTypes.func,     // 表格中排序列、页码的变化时刷新
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    data: [],
    edData: [],
    edColumns: [],
    tableId: '',          // 表格ID
    pageSize: 10,         // 每页数据条数
    columns: null,        // 显示列
    loading: false,
  }
  UNSAFE_componentWillMount () {
    const { config } = this.props
    let data = [
      {remark: '提现', subject: '1001 库存现金', debtor: 124, creditor: ''},
      {remark: '购入固定资产', subject: '1001 库存现金', debtor: '', creditor: 124},
      {remark: '转结销售成本', subject: '1001 库存现金', debtor: -524, creditor: ''},
      {remark: '提现', subject: '1001 库存现金', debtor: 34, creditor: ''},
    ]
    data = this.initData(data)
    data.push(this.getTotalLine(data))
    let columns = [
      {
        title: '摘要',
        dataIndex: 'remark',
        key: 'remark',
        width: '22%',
        onCell: record => ({
          record,
          col: {uuid: 'remark', field: 'remark', tableId: config.uuid},
        })
      },
      {
        title: '会计科目',
        dataIndex: 'subject',
        key: 'subject',
        width: '34%',
        onCell: record => ({
          record,
          col: {uuid: 'subject', field: 'subject', tableId: config.uuid},
        })
      },
      {
        title: () => (<>
          <div className="money-title">借方金额</div>
          <div className="money-uint">
            <span>亿</span> <span>千</span> <span>百</span> <span>十</span> <span>万</span> <span>千</span>
            <span>百</span> <span>十</span> <span>元</span> <span>角</span> <span className="last">分</span>
          </div>
        </>),
        dataIndex: 'debtor',
        key: 'debtor',
        width: '22%',
        onCell: record => ({
          record,
          col: {uuid: 'debtor', field: 'debtor', tableId: config.uuid},
        })
      },
      {
        title: () => (<>
          <div className="money-title">贷方金额</div>
          <div className="money-uint">
            <span>亿</span> <span>千</span> <span>百</span> <span>十</span> <span>万</span> <span>千</span>
            <span>百</span> <span>十</span> <span>元</span> <span>角</span> <span className="last">分</span>
          </div>
        </>),
        dataIndex: 'creditor',
        key: 'creditor',
        width: '22%',
        onCell: record => ({
          record,
          col: {uuid: 'creditor', field: 'creditor', tableId: config.uuid},
        })
      }
    ]
    this.setState({
      data: data,
      edData: fromJS(data).toJS(),
      columns,
      tableId: config.uuid
    })
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  componentDidMount () {
    MKEmitter.addListener('nextLine', this.nextLine)
    MKEmitter.addListener('delRecord', this.delRecord)
    MKEmitter.addListener('changeRecord', this.changeRecord)
  }
  /**
   * @description 组件销毁,清除state更新
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('nextLine', this.nextLine)
    MKEmitter.removeListener('delRecord', this.delRecord)
    MKEmitter.removeListener('changeRecord', this.changeRecord)
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (!is(fromJS(this.props.data), fromJS(nextProps.data))) {
      this.setState({data: nextProps.data || []})
    }
  }
  initData = (data) => {
    let _data = data.map((item, i) => {
      item.uuid = Utils.getuuid()
      item.index = i
      return item
    })
    if (_data.length < 4) {
      for (let i = _data.length - 1; i < 4; i++) {
        _data.push({uuid: Utils.getuuid(), index: i + 1, remark: '', subject: '', debtor: '', creditor: ''})
      }
    }
    return _data
  }
  getTotalLine = (data) => {
    let totalLine = {uuid: Utils.getuuid(), type: 'total'}
    let debtor = ''
    let creditor = ''
    data.forEach(item => {
      if (typeof(item.debtor) === 'number') {
        if (debtor === '') {
          debtor = 0
        }
        debtor += item.debtor
      } else if (typeof(item.creditor) === 'number') {
        if (debtor === '') {
          debtor = 0
        }
        if (creditor === '') {
          creditor = 0
        }
        creditor += item.creditor
      }
    })
    totalLine.debtor = debtor
    totalLine.creditor = creditor
    totalLine.remark = this.changeMoneyToChinese(debtor)
    return totalLine
  }
  changeMoneyToChinese = (money) => {
    let cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
    let cnIntRadice = ['', '拾', '佰', '仟']
    let cnIntUnits = ['', '万', '亿', '兆']
    let cnDecUnits = ['角', '分', '毫', '厘']
    let cnInteger = '整'
    let cnIntLast = '元'
    let maxNum = 999999999999999.9999 // 最大处理的数字
    let IntegerNum = null
    let DecimalNum = null
    let ChineseStr = ''
    let parts = null // 分离金额后用的数组,预定义
    let Symbol = ''  // 正负值标记
    if (money === '') return ''
    if (money >= maxNum) return '超出最大处理数字'
    if (money === 0) {
      ChineseStr = cnNums[0] + cnIntLast + cnInteger;
      return ChineseStr
    }
    if(money < 0) {
      money = -money
      Symbol = '负'
    }
    money = money.toString() // 转换为字符串
    if (money.indexOf('.') === -1) {
      IntegerNum = money
      DecimalNum = ''
    } else {
      parts = money.split('.')
      IntegerNum = parts[0]
      DecimalNum = parts[1].substr(0, 4)
    }
    if (parseInt(IntegerNum, 10) > 0) { // 获取整型部分转换
      let zeroCount = 0
      let IntLen = IntegerNum.length
      for (let i = 0; i < IntLen; i++) {
        let n = IntegerNum.substr(i, 1)
        let p = IntLen - i - 1
        let q = p / 4
        let m = p % 4
        if (n === '0') {
          zeroCount++
        } else {
          if (zeroCount > 0) {
            ChineseStr += cnNums[0]
          }
          zeroCount = 0 // 归零
          ChineseStr += cnNums[parseInt(n)] + cnIntRadice[m]
        }
        if (m === 0 && zeroCount < 4) {
          ChineseStr += cnIntUnits[q]
        }
      }
      ChineseStr += cnIntLast
    }
    if (DecimalNum !== '') { // 小数部分
      let decLen = DecimalNum.length
      for (let i = 0; i < decLen; i++) {
        let n = DecimalNum.substr(i, 1)
        if (n !== '0') {
          ChineseStr += cnNums[Number(n)] + cnDecUnits[i]
        }
      }
    }
    if (ChineseStr === '') {
      ChineseStr += cnNums[0] + cnIntLast + cnInteger
    } else if (DecimalNum === '') {
      ChineseStr += cnInteger
    }
    ChineseStr = Symbol + ChineseStr
    return ChineseStr
  }
  nextLine = (col, record) => {
    const { edData, tableId } = this.state
    if (col.tableId !== tableId) return
    if (record.index < edData.length - 2) {
      MKEmitter.emit('tdFocus', 'remark' + edData[record.index + 1].uuid)
    } else {
      let _data = fromJS(edData).toJS()
      let line = {uuid: Utils.getuuid(), index: _data.length - 1, remark: record.remark || '', subject: '', debtor: '', creditor: ''}
      _data.splice(_data.length - 1, 0, line)
      this.setState({edData: _data}, () => {
        MKEmitter.emit('tdFocus', 'remark' + line.uuid)
      })
    }
  }
  plusLine = (initEditLine) => {
    const { edData } = this.state
    let item = {...edData[edData.length - 1]}
    item.key = item.key + 1
    item.$$uuid = '$new'
    this.setState({edData: [...edData, item]}, () => {
      MKEmitter.emit('tdFocus', initEditLine.uuid + item.uuid)
    })
  }
  delRecord = (id, record) => {
    const { tableId, edData } = this.state
    if (id !== tableId) return
    let _data = edData.filter(item => item.uuid !== record.uuid)
    _data.pop()
    if (_data.length < 4) {
      for (let i = _data.length - 1; i < 4; i++) {
        _data.push({uuid: Utils.getuuid(), index: i + 1, remark: '', subject: '', debtor: '', creditor: ''})
      }
    }
    _data.push(this.getTotalLine(_data))
    this.setState({edData: _data})
  }
  changeRecord = (tableId, record) => {
    if (tableId !== this.state.tableId) return
    let _data = this.state.edData.map(item => {
      if (item.uuid === record.uuid) {
        return record
      } else {
        return item
      }
    })
    _data.pop()
    if (record.index === _data.length - 1) {
      _data.push({uuid: Utils.getuuid(), index: record.index + 1, remark: '', subject: '', debtor: '', creditor: ''})
    }
    _data.push(this.getTotalLine(_data))
    this.setState({edData: _data})
  }
  addLine = () => {
    const { BID } = this.props
    const { edData } = this.state
    let item = {}
    if (edData.length > 0) {
      item = {...edData[edData.length - 1]}
      item.key = item.key + 1
      item.$$uuid = '$new'
    } else {
      item.key = 0
      item.$$uuid = '$new'
      item.$$BID = BID || ''
    }
    this.setState({edData: [...edData, item]})
  }
  checkData = () => {
    const { edData } = this.state
    if (edData.length === 0) {
      notification.warning({
        top: 92,
        message: '提交数据不可为空!',
        duration: 5
      })
      return
    }
    let err = ''
    let data = fromJS(edData).toJS().map(item => {
      // let line = []
      // fields.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
      //   }
      // })
      return item
    })
    if (err) {
      notification.warning({
        top: 92,
        message: err,
        duration: 5
      })
    } else {
      this.submit(data)
    }
  }
  submit = (data) => {
    const { BID } = this.props
    let param = {
      // excel_in: result.lines,
      BID: BID || ''
    }
    this.setState({
      loading: true
    })
    param.func = 'submit.innerFunc'
    Api.genericInterface(param).then((res) => {
      if (res.status) {
        this.execSuccess(res)
      } else {
        this.execError(res)
      }
    }, () => {
      this.execError({})
    })
  }
  execSuccess = (res) => {
    const { submit } = this.props
    if (res && res.ErrCode === 'S') { // 执行成功
      notification.success({
        top: 92,
        message: res.ErrMesg || this.state.dict['main.action.confirm.success'],
        duration: submit.stime ? submit.stime : 2
      })
    } else if (res && res.ErrCode === 'Y') { // 执行成功
      Modal.success({
        title: res.ErrMesg || this.state.dict['main.action.confirm.success']
      })
    } else if (res && res.ErrCode === '-1') { // 完成后不提示
    }
    this.setState({
      loading: false
    })
    if (submit.closetab === 'true') {
      MKEmitter.emit('popclose')
    }
    if (submit.execSuccess !== 'never') {
      MKEmitter.emit('refreshByButtonResult', submit.$menuId, submit.execSuccess, submit)
    }
  }
  execError = (res) => {
    const { submit } = this.props
    if (res.ErrCode === 'E') {
      Modal.error({
        title: res.message || res.ErrMesg,
      })
    } else if (res.ErrCode === 'N') {
      notification.error({
        top: 92,
        message: res.message || res.ErrMesg,
        duration: submit.ntime ? submit.ntime : 10
      })
    } else if (res.ErrCode === 'F') {
      notification.error({
        className: 'notification-custom-error',
        top: 92,
        message: res.message || res.ErrMesg,
        duration: submit.ftime ? submit.ftime : 10
      })
    } else if (res.ErrCode === 'NM') {
      message.error(res.message || res.ErrMesg)
    }
    this.setState({
      loading: false
    })
    if (submit.execError !== 'never') {
      MKEmitter.emit('refreshByButtonResult', submit.$menuId, submit.execError, submit)
    }
  }
  render() {
    const { edData, columns} = this.state
    const components = {
      body: {
        row: BodyRow,
        cell: BodyCell
      }
    }
    return (
      <div className="voucher-table-wrap">
        <Table
          rowKey="uuid"
          components={components}
          columns={columns}
          dataSource={edData}
          bordered={true}
          // loading={this.props.loading}
          onRow={(record, index) => {
            return {
              data: record
            }
          }}
          pagination={false}
        />
      </div>
    )
  }
}
export default AssistTable
src/tabviews/custom/components/module/voucher/assistTable/index.scss
New file
@@ -0,0 +1,259 @@
.voucher-table-wrap {
  position: relative;
  padding: 0px;
  .normal-table-footer {
    padding: 10px 0px;
    color: rgba(0, 0, 0, 0.65);
  }
  .normal-table-footer.pagination {
    position: absolute;
    bottom: 10px;
  }
  >.ant-table-wrapper {
    position: relative;
    z-index: 1;
  }
  .ant-table {
    color: inherit;
    font-size: inherit;
  }
  .money-uint {
    display: flex;
    span {
      display: inline-block;
      flex: 1;
      text-align: center;
      font-size: 12px;
    }
    span:not(.last) {
      border-right: 1px solid #e9e9e9;
    }
    span:nth-child(3), span:nth-child(6) {
      border-color: #91d5ff;
    }
    span:nth-child(9) {
      border-color: #ffa39e;
    }
  }
  table {
    max-width: 100%;
    width: 100%;
    .ant-table-thead {
      tr {
        th {
          position: relative;
          background-color: transparent;
          padding: 0;
          height: 60px;
          line-height: 60px;
          text-align: center;
          .ant-table-header-column {
            display: block;
            width: 100%;
            height: 100%;
            .ant-table-column-title {
              display: block;
              width: 100%;
              height: 100%;
              font-weight: bold;
              font-size: 13px;
            }
          }
          .money-title {
            line-height: 30px;
            font-weight: bold;
            font-size: 13px;
          }
          .money-uint {
            line-height: 30px;
            border-top: 1px solid #dadada;
          }
        }
      }
    }
    .ant-table-selection-column {
      width: 60px;
      min-width: 60px;
      max-width: 60px;
    }
    .ant-table-tbody {
      tr td {
        position: relative;
        background-color: transparent;
        padding: 0;
        height: 60px;
        vertical-align: top;
        .content-wrap {
          padding: 5px;
          height: 100%;
          font-size: 13px;
          font-weight: bold;
        }
        .money-uint {
          height: 100%;
          line-height: 60px;
          span {
            font-size: 14px;
            font-weight: bold;
          }
        }
        .money-uint.down {
          span {
            color: #ff4d4f;
          }
        }
      }
    }
  }
  .ant-input {
    height: 60px;
    border-radius: 0;
    resize: none;
  }
  .ant-input-number {
    height: 60px;
    border-radius: 0;
    .ant-input-number-handler-wrap {
      display: none;
    }
    .ant-input-number-input {
      border-radius: 0;
      height: 60px;
    }
  }
  .editing_table_cell {
    .ant-input {
      padding: 0px;
      position: absolute;
      top: 0px;
      left: 0px;
      right: 0px;
      bottom: 0px;
      border: 1px solid #1890ff;
    }
    .ant-input-number-input {
      position: absolute;
      top: 0px;
      left: 0px;
      right: 0px;
      bottom: 0px;
      border: 1px solid #1890ff;
    }
    .anticon {
      color: #ff4d4f;
      position: absolute;
      right: 3px;
      top: calc(50% - 8px);
    }
  }
  td.pointer {
    position: relative;
  }
  td.pointer {
    .mk-mask {
      display: none;
      cursor: pointer;
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
    }
  }
}
.edit-custom-table.editable {
  td {
    background-color: #ffffff!important;
  }
  td.pointer .mk-mask {
    display: block;
  }
  .mk-operation {
    display: none;
  }
  .ant-table-placeholder {
    display: none;
  }
}
.edit-custom-table:not(.fixed-height) {
  .ant-table-body::-webkit-scrollbar {
    width: 8px;
    height: 10px;
  }
  ::-webkit-scrollbar-thumb {
    border-radius: 5px;
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
    background: rgba(0, 0, 0, 0.13);
  }
  ::-webkit-scrollbar-track {/*滚动条里面轨道*/
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
    border-radius: 3px;
    border: 1px solid rgba(0, 0, 0, 0.07);
    background: rgba(0, 0, 0, 0);
  }
}
.edit-custom-table.fixed-height {
  .ant-table-body {
    border-bottom: 1px solid rgba(0, 0, 0, .05);
    .ant-table-fixed {
      border-bottom: 0;
    }
  }
}
.edit-custom-table.hidden {
  thead {
    display: none;
  }
}
.edit-custom-table.ghost {
  .ant-table-thead > tr {
    > th {
      color: inherit;
      background: transparent;
      .ant-table-column-sorter .ant-table-column-sorter-inner {
        color: inherit;
      }
    }
    > th:hover {
      background: transparent;
    }
  }
  .ant-table-body {
    overflow-x: auto;
    tr {
      td {
        background: transparent!important;
      }
    }
    tr:hover td {
      background: transparent!important;
    }
  }
}
.image-scale-modal {
  width: 70vw;
  min-height: 80vh;
  top: 10vh;
  .ant-modal-body {
    min-height: calc(80vh - 110px);
    line-height: calc(80vh - 160px);
    text-align: center;
  }
  .ant-modal-footer {
    text-align: center;
    span {
      display: inline-block;
      color: #1890ff;
      padding: 5px 15px;
      cursor: pointer;
    }
  }
}
src/tabviews/custom/components/table/edit-table/index.jsx
@@ -29,7 +29,7 @@
    config: {},           // 页面配置信息,包括按钮、搜索、显示列、标签等
    actions: null,        // 按钮集
    columns: null,        // 显示列
    arr_field: '',        // 使用 sPC_Get_TableData 时的查询字段集
    arr_field: '',        // 查询字段集
    setting: null,        // 页面全局设置:数据源、按钮及显示列固定、主键等
    data: [],             // 列表数据集
    selectedData: [],     // 已选表格数据
src/tabviews/custom/components/table/normal-table/index.jsx
@@ -32,7 +32,7 @@
    config: {},           // 页面配置信息,包括按钮、搜索、显示列、标签等
    actions: null,        // 按钮集
    columns: null,        // 显示列
    arr_field: '',        // 使用 sPC_Get_TableData 时的查询字段集
    arr_field: '',        // 查询字段集
    setting: null,        // 页面全局设置:数据源、按钮及显示列固定、主键等
    data: [],             // 列表数据集
    selectedData: [],     // 已选表格数据
src/tabviews/custom/components/tabs/antv-tabs/index.jsx
@@ -52,8 +52,13 @@
    if (config.setting.autoSwitch === 'true' && config.subtabs.length > 1 && config.setting.interval) {
      this.autoSwitch(config.setting.interval)
    }
    MKEmitter.addListener('resetSelectLine', this.resetParentParam)
    if (config.activeKey) {
      let node = document.getElementById('tab' + config.activeKey)
      node && node.click()
    }
    MKEmitter.addListener('resetSelectLine', this.resetParentParam)
  }
  /**
@@ -81,13 +86,18 @@
          tabs: {...tabs, subtabs: []}
        })
      } else {
        let val = data[tabs.setting.controlField] === undefined ? '' : data[tabs.setting.controlField] + ''
        let val = ''
        Object.keys(data).forEach(key => {
          if (key.toLowerCase() === tabs.setting.controlField) {
            val = data[key]
          }
        })
        this.setState({
          tabs: {...tabs, subtabs: this.props.config.subtabs.filter(tab => {
            if (tab.controlVal === val) {
              return false
            } else if (/,/ig.test(tab.controlVal)) {
              return tab.controlVal.split(',').includes(val)
              return !tab.controlVal.split(',').includes(val)
            }
            return true
          })}
src/tabviews/custom/components/timeline/normal-timeline/index.jsx
@@ -240,6 +240,11 @@
      return
    }
    // if (config.setting.interType === 'inner' && config.setting.innerFunc === 'z_mk_express') {
    //   this.getExpress()
    //   return
    // }
    this.setState({
      loading: true
    })
@@ -272,6 +277,36 @@
    }
  }
  getExpress = () => {
    this.setState({
      loading: true
    })
    Api.wxNginxRequest(`express/yuantong/YT6590674317601`, 'get').then(res => {
      if (!res || typeof(res) !== 'string') {
        notification.error({
          top: 92,
          message: '未获取到快递信息',
          duration: 10
        })
      } else {
        let data = res.split(/\n/).filter(Boolean)
        data = data.map((item, i) => {
          return {
            $Index: i,
            date: item.substr(0, 19),
            content: item.substr(20)
          }
        })
        this.setState({
          data: data,
          loading: false
        })
      }
    })
  }
  getnodes = (data) => {
    const { config, card } = this.state
src/tabviews/custom/index.jsx
@@ -73,7 +73,7 @@
   * @description 获取页面配置信息
   */
  async loadconfig () {
    const { permAction, param } = this.props
    const { permAction } = this.props
    let _param = {
      func: 'sPC_Get_LongParam',
@@ -138,7 +138,9 @@
      let roleId = sessionStorage.getItem('role_id') || '' // 角色ID
      let balMap = new Map()
      let skip = config.permission === 'false' || window.GLOB.mkHS
      config.components = this.filterComponent(config.components, roleId, permAction, balMap, skip)
      let param = this.props.param || {} // url参数
      config.components = this.filterComponent(config.components, roleId, permAction, balMap, skip, param)
      
      // 获取主搜索条件
      let mainSearch = []
@@ -147,7 +149,7 @@
        component.search = component.search.map(item => {
          item.oriInitval = item.initval
          if (['text', 'select', 'link'].includes(item.type) && param && param.$searchkey === item.field) {
          if (['text', 'select', 'link'].includes(item.type) && param.$searchkey === item.field) {
            item.initval = param.$searchval
          }
@@ -158,7 +160,7 @@
      })
      let params = []
      let BID = param && param.$BID ? param.$BID : ''
      let BID = param.$BID || ''
      let inherit = {}
      if (config.cacheUseful === 'true') { // 缓存继承
@@ -188,7 +190,7 @@
      }
      if (config.urlFields) {
        config.urlFields.forEach(field => {
          let val = `'${param ? (param[field] || '') : ''}'`
          let val = `'${param[field] || ''}'`
          regs.push({
            reg: new RegExp('@' + field + '@', 'ig'),
            value: val
@@ -405,14 +407,6 @@
      sql = sql.join('')
      
      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql, this.state.BID)
      if (this.state.BID) {
        param.BID = this.state.BID
      }
      if (window.GLOB.mkHS) { // 函数 sPC_TableData_InUpDe 云端验证
        param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
      }
    } else {
      param.func = 's_ex_result_back'
      param.s_ex_result = lines.map((item, index) => ({
@@ -449,7 +443,7 @@
    })
  }
  filterComponent = (components, roleId, permAction, balMap, skip) => {
  filterComponent = (components, roleId, permAction, balMap, skip, urlparam) => {
    return components.filter(item => {
      
      if (item.style && item.style.boxShadow) {
@@ -481,8 +475,58 @@
          return true
        })
        if (item.setting.supModule) {
          let pid = item.setting.supModule.pop()
          item.setting.supModule = pid || ''
          if (item.setting.supModule) {
            item.setting.controlField = item.setting.controlField.toLowerCase()
            if (item.setting.supModule === 'preview') {
              item.setting.supModule = ''
              let val = ''
              Object.keys(urlparam).forEach(key => {
                if (key.toLowerCase() === item.setting.controlField) {
                  val = urlparam[key]
                }
              })
              item.subtabs = item.subtabs.filter(tab => {
                if (tab.controlVal === val) {
                  return false
                } else if (/,/ig.test(tab.controlVal)) {
                  return !tab.controlVal.split(',').includes(val)
                }
                return true
              })
            }
          }
        }
        if (item.setting.selectField) {
          item.setting.selectField = item.setting.selectField.toLowerCase()
          let val = ''
          Object.keys(urlparam).forEach(key => {
            if (key.toLowerCase() === item.setting.selectField) {
              val = urlparam[key]
            }
          })
          let activeKey = ''
          item.subtabs.forEach(tab => {
            if (!activeKey && tab.selectVal === val) {
              activeKey = tab.uuid
            }
          })
          item.activeKey = activeKey
        }
        item.subtabs = item.subtabs.map(tab => {
          tab.components = this.filterComponent(tab.components, roleId, permAction, balMap, skip)
          tab.components = this.filterComponent(tab.components, roleId, permAction, balMap, skip, urlparam)
          return tab
        })
@@ -497,6 +541,8 @@
          })
        })
        item.parentIds = supIds
        return true
      } else if (item.type === 'group') {
        if (
          item.setting.blacklist && item.setting.blacklist.length > 0 &&
@@ -505,7 +551,9 @@
          return false
        }
        item.components = this.filterComponent(item.components, roleId, permAction, balMap, skip)
        item.components = this.filterComponent(item.components, roleId, permAction, balMap, skip, urlparam)
        return true
      } else if (['pie', 'bar', 'line', 'dashboard', 'scatter', 'chart'].includes(item.type)) {
        if (
          item.plot.blacklist && item.plot.blacklist.length > 0 &&
src/tabviews/formtab/index.jsx
@@ -37,7 +37,7 @@
    config: {},           // 页面配置信息,包括按钮、表单、标签等
    groups: null,         // 表单组
    actions: null,        // 按钮集
    arr_field: '',        // 使用 sPC_Get_TableData 时的查询字段集
    arr_field: '',        // 查询字段集
    setting: null,        // 页面全局设置:数据源、按钮及显示列固定、主键等
    data: null,           // 列表数据集
    BIDs: {},             // 上级表id
@@ -390,7 +390,7 @@
  }
  /**
   * @description 获取系统存储过程 sPC_Get_TableData 的参数
   * @description 获取系统存储过程的参数
   */
  getDefaultParam = () => {
    const { arr_field, setting, primaryId } = this.state
src/tabviews/scriptmanage/index.jsx
@@ -34,7 +34,7 @@
    searchlist: [],       // 搜索条件
    actions: [],          // 按钮集
    columns: [],          // 显示列
    arr_field: '',        // 使用 sPC_Get_TableData 时的查询字段集
    arr_field: '',        // 查询字段集
    setting: {},          // 页面全局设置:数据源、按钮及显示列固定、主键等
    data: [],             // 列表数据集
    selectedData: [],     // 已选表格数据
@@ -155,7 +155,7 @@
  }
  /**
   * @description 获取系统存储过程 sPC_Get_TableData 的参数
   * @description 获取系统存储过程的参数
   */
  getDefaultParam = () => {
    const { arr_field, pageIndex, pageSize, orderBy, search, setting } = this.state
src/tabviews/subtable/index.jsx
@@ -46,7 +46,7 @@
    searchlist: null,     // 搜索条件
    actions: null,        // 按钮集
    columns: null,        // 显示列
    arr_field: '',        // 使用 sPC_Get_TableData 时的查询字段集
    arr_field: '',        // 查询字段集
    setting: null,        // 页面全局设置:数据源、按钮及显示列固定、主键等
    data: [],             // 列表数据集
    selectedData: [],     // 已选表格数据
@@ -545,14 +545,6 @@
      sql = sql.join('')
      
      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql, BID)
      if (BID) {
        param.BID = BID
      }
      if (window.GLOB.mkHS) { // 函数 sPC_TableData_InUpDe 云端验证
        param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
      }
    } else {
      param.func = 's_ex_result_back'
      param.s_ex_result = lines.map((item, index) => ({
src/tabviews/subtabtable/index.jsx
@@ -40,7 +40,7 @@
    searchlist: null,     // 搜索条件
    actions: null,        // 按钮集
    columns: null,        // 显示列
    arr_field: '',        // 使用 sPC_Get_TableData 时的查询字段集
    arr_field: '',        // 查询字段集
    setting: null,        // 页面全局设置:数据源、按钮及显示列固定、主键等
    data: [],             // 列表数据集
    selectedData: [],     // 已选表格数据
@@ -484,14 +484,6 @@
      sql = sql.join('')
      
      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql, this.props.BID)
      if (this.props.BID) {
        param.BID = this.props.BID
      }
      if (window.GLOB.mkHS) { // 函数 sPC_TableData_InUpDe 云端验证
        param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
      }
    } else {
      let name = this.props.Tab ? (this.props.Tab.label || '') : ''
      param.func = 's_ex_result_back'
src/tabviews/verupmanage/index.jsx
@@ -37,7 +37,7 @@
    searchlist: [],       // 搜索条件
    actions: [],          // 按钮集
    columns: [],          // 显示列
    arr_field: '',        // 使用 sPC_Get_TableData 时的查询字段集
    arr_field: '',        // 查询字段集
    setting: {},          // 页面全局设置:数据源、按钮及显示列固定、主键等
    data: [],             // 列表数据集
    selectedData: [],     // 已选表格数据
@@ -206,7 +206,7 @@
  }
  /**
   * @description 获取系统存储过程 sPC_Get_TableData 的参数
   * @description 获取系统存储过程的参数
   */
  getDefaultParam = () => {
    const { arr_field, pageIndex, pageSize, orderBy, search, setting } = this.state
src/tabviews/verupmanage/subtabtable/index.jsx
@@ -39,7 +39,7 @@
    searchlist: null,     // 搜索条件
    actions: null,        // 按钮集
    columns: null,        // 显示列
    arr_field: '',        // 使用 sPC_Get_TableData 时的查询字段集
    arr_field: '',        // 查询字段集
    setting: null,        // 页面全局设置:数据源、按钮及显示列固定、主键等
    data: null,           // 列表数据集
    selectedData: [],     // 已选表格数据
@@ -228,7 +228,7 @@
  }
  /**
   * @description 获取系统存储过程 sPC_Get_TableData 的参数
   * @description 获取系统存储过程的参数
   */
  getDefaultParam = (BID) => {
    const { arr_field, pageIndex, pageSize, orderBy, search, setting } = this.state
src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -670,7 +670,7 @@
    param.secretkey = Utils.encrypt('', param.timestamp)
    param.LText = Utils.formatOptions(script)
    if (window.GLOB.mkHS) { // 函数 sPC_TableData_InUpDe 云端验证
    if (window.GLOB.mkHS) { // 系统函数云端验证
      param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
    }
src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -267,12 +267,20 @@
      return
    } else if (!['requiredSgl', 'notRequired', 'requiredOnce', 'required'].includes(btn.Ot)) {
      // 数据选择类型校验
      this.actionSettingError()
      notification.warning({
        top: 92,
        message: '按钮行设置错误!',
        duration: 5
      })
      return
    } else if (btn.intertype === 'system') {
      // 使用内部接口时,操作类型和数据源不可为空
      if (!btn.sql || !btn.sqlType) {
        this.actionSettingError()
        notification.warning({
          top: 92,
          message: '按钮操作类型错误!',
          duration: 5
        })
        return
      } else if (data.length === 0 && btn.verify && btn.verify.voucher && btn.verify.voucher.enabled) {
        notification.warning({
@@ -285,12 +293,20 @@
    } else if (btn.intertype === 'inner') {
      // 使用内部接口时,内部函数不可为空
      if (!btn.innerFunc) {
        this.actionSettingError()
        notification.warning({
          top: 92,
          message: '按钮内部函数不可为空!',
          duration: 5
        })
        return
      }
    } else if (btn.intertype === 'custom') {
    } else if (btn.intertype === 'custom' || btn.intertype === 'outer') {
      if (btn.callbackType === 'script' && (!btn.verify || !btn.verify.cbScripts || !btn.verify.cbScripts.filter(item => item.status !== 'false').length === 0)) {
        this.actionSettingError()
        notification.warning({
          top: 92,
          message: '使用自定义脚本回调时,回调脚本不可为空!',
          duration: 5
        })
        return
      } else if (btn.procMode === 'system' && data.length === 0 && btn.verify && btn.verify.voucher && btn.verify.voucher.enabled) {
        notification.warning({
@@ -299,7 +315,7 @@
          duration: 5
        })
        return
      } else if (window.GLOB.systemType === 'production' && !btn.proInterface) {
      } else if (btn.intertype === 'custom' && window.GLOB.systemType === 'production' && !btn.proInterface) {
        notification.warning({
          top: 92,
          message: '尚未设置正式系统接口地址!',
@@ -307,15 +323,13 @@
        })
        return
      }
    } else if (btn.intertype === 'outer') {
      // 接口地址不存在时报错
      if (!btn.interface && btn.sysInterface !== 'true') {
        this.actionSettingError()
        return
      }
    } else if (!['inner', 'outer', 'system', 'custom'].includes(btn.intertype)) {
      // 接口类型错误
      this.actionSettingError()
      notification.warning({
        top: 92,
        message: '按钮接口类型错误!',
        duration: 5
      })
      return
    }
@@ -659,11 +673,9 @@
          param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
        }
        if (param.func === 'sPC_TableData_InUpDe') {
          param.menuname = btn.logLabel
          if (window.GLOB.probation) {
            param.s_debug_type = 'Y'
          }
        param.menuname = btn.logLabel
        if (window.GLOB.probation) {
          param.s_debug_type = 'Y'
        }
        return param
@@ -673,13 +685,13 @@
    return _params
  }
  getInnerParam = (data, formdata) => {
    const { setting, btn } = this.props
  getInnerParam = (data, formdata, retmsg) => {
    const { setting, btn, columns } = this.props
    let _params = []
    if ( btn.Ot === 'notRequired' || btn.Ot === 'requiredSgl' || btn.Ot === 'requiredOnce' ) {
      let param = {
        func: btn.innerFunc
        func: btn.innerFunc || ''
      }
      if (this.props.BID) {
@@ -708,6 +720,10 @@
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.secretkey = Utils.encrypt(param.LTextOut, param.timestamp)
        param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
      }
      if (retmsg) {
        param.$callbacksql = this.getSysDeclareSql(btn, formdata, data[0], columns)
      }
      _params.push(param)
@@ -747,11 +763,188 @@
          param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
        }
        if (retmsg) {
          param.$callbacksql = this.getSysDeclareSql(btn, formdata, cell, columns)
        }
        return param
      })
    }
    return _params
  }
  /**
   * @description 获取回调脚本的字段定义
   */
  getSysDeclareSql = (btn, formdata, data, columns) => {
    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']
    // sql语句
    let _sql = ''
    let _initvars = [] // 已赋值字段集
    let _initFormfields = []
    let _initColfields = []
    let _declarefields = []
    // 获取字段键值对
    formdata && formdata.forEach(form => {
      let _key = form.key.toLowerCase()
      datavars[_key] = form.value
      if (!_initvars.includes(_key)) {
        _initvars.push(_key)
        if (form.type === 'number' || form.type === 'rate') {
          let val = form.value
          if (typeof(val) !== 'number') {
            val = parseFloat(val)
            if (isNaN(val)) {
              val = 0
            }
          }
          _initFormfields.push(`@${_key}=${val}`)
        } else if (['date', 'datemonth', 'datetime'].includes(form.type)) {
          _initFormfields.push(`@${_key}='${form.value || '1949-10-01'}'`)
        } else {
          _initFormfields.push(`@${_key}='${form.value}'`)
        }
      }
      if (!_vars.includes(_key)) {
        _vars.push(_key)
        if (form.fieldlen && form.fieldlen > 2048) {
          form.fieldlen = 'max'
        }
        let _type = `nvarchar(${form.fieldlen})`
        if (form.type.match(/date/ig)) {
          _type = 'datetime'
        } else if (form.type === 'number') {
          _type = `decimal(18,${form.fieldlen})`
        } else if (form.type === 'rate') {
          _type = `decimal(18,2)`
        }
        _declarefields.push(`@${_key} ${_type}`)
      }
    })
    if (data) {
      Object.keys(data).forEach(key => {
        data[key.toLowerCase()] = data[key]
      })
    }
    // 添加数据中字段,表单值优先(按钮不选行或多行拼接时跳过)
    if (data && btn.Ot !== 'notRequired' && btn.Ot !== 'requiredOnce') {
      datavars = {...data, ...datavars}
      const setField = (col) => {
        if (!col.field) return
        let _key = col.field.toLowerCase()
        if (!_initvars.includes(_key)) {
          let _val = datavars.hasOwnProperty(_key) ? datavars[_key] : ''
          if (col.datatype && /^date/ig.test(col.datatype) && !_val) {
            _val = '1949-10-01'
          }
          _initvars.push(_key)
          _initColfields.push(`@${_key}='${_val}'`)
        }
        if (!_vars.includes(_key)) {
          _vars.push(_key)
          if (col.datatype) {
            _declarefields.push(`@${_key} ${col.datatype}`)
          } else {
            if (col.fieldlength && col.fieldlength > 2048) {
              col.fieldlength = 'max'
            }
            let _type = `nvarchar(${col.fieldlength || 50})`
            if (col.type === 'number') {
              let _length = col.decimal ? col.decimal : 0
              _type = `decimal(18,${_length})`
            } else if (col.type === 'picture' || col.type === 'textarea') {
              _type = `nvarchar(${col.fieldlength || 512})`
            }
            _declarefields.push(`@${_key} ${_type}`)
          }
        }
      }
      if (columns && columns.length > 0) {
        columns.forEach(col => {
          if (col.type === 'colspan' || col.type === 'old_colspan') {
            col.subcols.forEach(cell => {
              setField(cell)
            })
          } else {
            setField(col)
          }
        })
      }
    }
    // 变量声明
    _declarefields = _declarefields.join(',')
    if (_declarefields) {
      _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(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@bid nvarchar(50)${_declarefields}
      `
    let userName = sessionStorage.getItem('User_Name') || ''
    let fullName = sessionStorage.getItem('Full_Name') || ''
    let RoleID = sessionStorage.getItem('role_id') || ''
    let departmentcode = sessionStorage.getItem('departmentcode') || ''
    let organization = sessionStorage.getItem('organization') || ''
    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
    let nation = sessionStorage.getItem('nation') || ''
    let province = sessionStorage.getItem('province') || ''
    let city = sessionStorage.getItem('city') || ''
    let district = sessionStorage.getItem('district') || ''
    let address = sessionStorage.getItem('address') || ''
    if (sessionStorage.getItem('isEditState') === 'true') {
      userName = sessionStorage.getItem('CloudUserName') || ''
      fullName = sessionStorage.getItem('CloudFullName') || ''
    }
    // 初始化凭证及用户信息字段
    _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}', @BillCode='', @ModularDetailCode=''
        `
    // 表单变量赋值
    if (_initFormfields.length > 0) {
      _sql += `
        /* 表单变量赋值 */
        select ${_initFormfields.join(',')}
        `
    }
    // 显示列变量赋值
    if (_initColfields.length > 0) {
      _sql += `
        /* 显示列变量赋值 */
        select ${_initColfields.join(',')}
        `
    }
    return _sql
  }
  /**
@@ -875,58 +1068,14 @@
      /** *********************调用外部接口************************* */
      let _params = [] // 请求参数数组
      if (btn.Ot === 'notRequired' || btn.Ot === 'requiredSgl' || btn.Ot === 'requiredOnce') {
        let param = {}
        if (this.props.BID) {
          param.BID = this.props.BID
        }
        if ((btn.OpenType === 'pop' || btn.OpenType === 'formSubmit' || btn.OpenType === 'form') && formdata) { // 表单
          formdata.forEach(_data => {
            param[_data.key] = _data.value
          })
        }
        // 获取id
        if (btn.Ot === 'notRequired') {
        } else if (btn.Ot === 'requiredSgl' && setting.primaryKey) {
          param[setting.primaryKey] = data[0][setting.primaryKey]
        } else if (btn.Ot === 'requiredOnce' && setting.primaryKey) {
          let ids = data.map(d => { return d[setting.primaryKey]})
          param[setting.primaryKey] = ids.join(',')
        }
        _params.push(param)
      } else if (btn.Ot === 'required') {
        // 选择多行,循环调用
        _params = data.map((cell, index) => {
          let _cell = {}
          if (this.props.BID) {
            _cell.BID = this.props.BID
          }
          let _formparam = {}
          if (btn.OpenType === 'pop' && formdata) { // 表单
            formdata.forEach(_data => {
              if (index !== 0 && _data.readin && cell.hasOwnProperty(_data.key)) {
                _formparam[_data.key] = cell[_data.key]
              } else {
                _formparam[_data.key] = _data.value
              }
            })
          }
          if (setting.primaryKey) {
            _cell[setting.primaryKey] = cell[setting.primaryKey]
          }
          _cell = {..._formparam, ..._cell}
          return _cell
      if (btn.procMode === 'system') {
        _params = this.getSystemParam(data, formdata, true)
        _params = _params.map(item => {
          item.script_type = 'Y'
          return item
        })
      } else {
        _params = this.getInnerParam(data, formdata, btn.callbackType === 'script')
      }
      if (_params.length > 1 && btn.progress === 'progressbar' && btn.$toolbtn) {
@@ -936,7 +1085,7 @@
      }
      // 循环调用外部接口(包括内部及回调函数)
      this.outerLoopRequest(_params, btn, _resolve)
      this.outerLoopRequest(_params, _resolve)
    } else if (btn.intertype === 'custom') { // 系统接口
      let params = []
@@ -947,7 +1096,7 @@
          return item
        })
      } else {
        params = this.getInnerParam(data, formdata)
        params = this.getInnerParam(data, formdata, btn.callbackType === 'script')
      }
      if (params.length > 1 && btn.progress === 'progressbar' && btn.$toolbtn) {
@@ -978,6 +1127,11 @@
    delete param.$callbacksql
    if (!param.func) {
      this.customOuterRequest(params, param, record, _resolve)
      return
    }
    Api.genericInterface(param).then(res => {
      if (res.status) {
        if ((res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) && params.length === 0) {
@@ -988,41 +1142,6 @@
        } else {
          this.customOuterRequest(params, res, record, _resolve)
        }
      } else if (res.ErrCode === 'C' && this.state.checkParam) {
        const _this = this
        confirm({
          title: res.message || res.ErrMesg,
          content: '继续执行?',
          onOk() {
            return new Promise(resolve => {
              Api.genericInterface(_this.state.checkParam).then((result) => {
                if (result.status) {
                  if ((result.mk_ex_invoke === 'false' || result.mk_ex_invoke === false) && params.length === 0) {
                    _this.execSuccess(result)
                    _resolve()
                  } else if ((result.mk_ex_invoke === 'false' || result.mk_ex_invoke === false) && params.length > 0) {
                    _this.customLoopRequest(params, _resolve)
                  } else {
                    _this.customOuterRequest(params, result, record, _resolve)
                  }
                } else {
                  _this.execError(result)
                  _resolve()
                }
                resolve()
              }, () => {
                _this.updateStatus()
                resolve()
                _resolve()
              })
            })
          },
          onCancel() {
            _this.execError({...res, ErrCode: 'P'})
            _resolve()
          }
        })
        this.setState({checkParam: null})
      } else {
        this.execError(res)
        _resolve()
@@ -1105,6 +1224,68 @@
   * @description 回调请求循环执行
   */
  customCallbackRequest = (params, result, record, _resolve) => {
    const { btn } = this.props
    let param = null
    if (btn.callbackType === 'script' || btn.callbackType === 'default') {
      param = this.getCallBackSql(result, record)
    } else if (btn.callbackType === 'func') {
      param = {
        ...result,
        func: btn.callbackFunc
      }
      if (result.$ErrCode === 'E') {
        delete param.$ErrCode
        delete param.$ErrMesg
        param.ErrCode = 'E'
      }
    } else {
      if (result.$ErrCode === 'E') {
        result.status = false
        result.message = result.$ErrMesg
        result.ErrCode = 'E'
        result.ErrMesg = result.$ErrMesg
      } else {
        result.status = result.status !== false
        result.ErrCode = result.ErrCode || '-1'
      }
      if (result.status) {
        if (params.length === 0) {
          this.execSuccess(result)
          _resolve()
        } else {
          this.customLoopRequest(params, _resolve)
        }
      } else {
        this.execError(result)
        _resolve()
      }
      return
    }
    Api.genericInterface(param).then(res => {
      if (res.status) {
        if (params.length === 0) {
          this.execSuccess(res)
          _resolve()
        } else {
          this.customLoopRequest(params, _resolve)
        }
      } else {
        this.execError(res)
        _resolve()
      }
    }, () => {
      this.updateStatus()
      _resolve()
    })
  }
  getCallBackSql = (result, record) => {
    const { btn } = this.props
    let lines = []
    let pre = btn.callbackType === 'script' ? '@' : ''
@@ -1213,8 +1394,13 @@
        }
      })
      _backCustomScript += `
        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
      if (btn.output) {
        _backCustomScript += `
          aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg,${btn.output} as mk_b_id`
      } else {
        _backCustomScript += `
          aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
      }
      let sql = [...lineMap.values()].map(item => (`
        ${item.insert}
@@ -1273,22 +1459,7 @@
      }
    }
    Api.genericInterface(param).then(res => {
      if (res.status) {
        if (params.length === 0) {
          this.execSuccess(res)
          _resolve()
        } else {
          this.customLoopRequest(params, _resolve)
        }
      } else {
        this.execError(res)
        _resolve()
      }
    }, () => {
      this.updateStatus()
      _resolve()
    })
    return param
  }
  /**
@@ -1352,137 +1523,153 @@
  /**
   * @description 外部请求循环执行
   */
  outerLoopRequest = (params, btn, _resolve) => {
  outerLoopRequest = (params, _resolve) => {
    if (!params && params.length === 0) return
    let param = params.shift()
    let _outParam = null
    this.setState({
      loadingNumber: params.length
    })
    new Promise(resolve => {
      // 内部请求
      if (btn.innerFunc) {
        param.func = btn.innerFunc
    let record = {
      BID: param.BID || '',
      ID: param.ID || '',
      callbacksql: param.$callbacksql || ''
    }
        // 函数 s_sDataDictb_TBBack 云端验证
        if (window.GLOB.mkHS && param.func === 's_sDataDictb_TBBack' && param.LTextOut) {
          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
          param.secretkey = Utils.encrypt(param.LTextOut, param.timestamp)
          param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
        }
    delete param.$callbacksql
        // 存在内部函数时,数据预处理
        Api.genericInterface(param).then(res => {
          if (res.status) {
            delete res.ErrCode
            delete res.ErrMesg
            delete res.message
            delete res.status
    if (!param.func) {
      this.outerOuterRequest(params, param, record, _resolve)
      return
    }
            // 使用处理后的数据调用外部接口
            let keys = Object.keys(res) // 提交外部接口前,添加BID
            if (this.props.BID && keys.filter(key => key.toLowerCase() === 'bid').length === 0) {
              res.BID = this.props.BID
            }
            resolve(res)
          } else {
            this.execError(res, btn)
            resolve(false)
            _resolve()
          }
        }, () => {
          this.updateStatus()
          _resolve()
        })
      } else {
        resolve(param)
      }
    }).then(res => {
      if (!res) return
      // 外部请求
      _outParam = JSON.parse(JSON.stringify(res))
      if (btn.outerFunc) {
        res.func = btn.outerFunc
      }
      if (window.GLOB.mkHS) {
        if (btn.sysInterface === 'true' && options.cloudServiceApi) {
          res.rduri = options.cloudServiceApi
        } else if (btn.sysInterface !== 'true') {
          if (window.GLOB.systemType === 'production' && btn.proInterface) {
            res.rduri = btn.proInterface
          } else {
            res.rduri = btn.interface
          }
        }
        // 函数 s_sDataDictb_TBBack 云端验证
        if (res.func === 's_sDataDictb_TBBack' && res.LTextOut) {
          res.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
          res.secretkey = Utils.encrypt(res.LTextOut, res.timestamp)
          res.open_key = Utils.encryptOpenKey(res.secretkey, res.timestamp)
        }
      } else {
        if (btn.sysInterface === 'true' && window.GLOB.mainSystemApi) {
          res.rduri = window.GLOB.mainSystemApi
        } else if (btn.sysInterface !== 'true') {
          if (window.GLOB.systemType === 'production' && btn.proInterface) {
            res.rduri = btn.proInterface
          } else {
            res.rduri = btn.interface
          }
        }
      }
      return Api.genericInterface(res)
    }).then(response => {
      if (!response) return
      // 回调请求
      if (btn.callbackFunc) {
        // 存在回调函数时,调用
        delete response.message
        delete response.status
        response.func = btn.callbackFunc
        let _callbackparam = {..._outParam, ...response}
        // 函数 s_sDataDictb_TBBack 云端验证
        if (window.GLOB.mkHS && _callbackparam.func === 's_sDataDictb_TBBack' && _callbackparam.LTextOut) {
          _callbackparam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
          _callbackparam.secretkey = Utils.encrypt(_callbackparam.LTextOut, _callbackparam.timestamp)
          _callbackparam.open_key = Utils.encryptOpenKey(_callbackparam.secretkey, _callbackparam.timestamp)
        }
        return Api.genericInterface(_callbackparam)
      } else {
        if (response.status) {
          // 一次请求成功,进行下一项请求
          if (params.length === 0) {
            this.execSuccess(response)
            _resolve()
          } else {
            this.outerLoopRequest(params, btn, _resolve)
          }
        } else {
          this.execError(response)
          _resolve()
        }
      }
    }).then(res => {
      if (!res) return
    Api.genericInterface(param).then(res => {
      if (res.status) {
        if ((res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) && params.length === 0) {
          this.execSuccess(res)
          _resolve()
        } else if ((res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) && params.length > 0) {
          this.outerLoopRequest(params, _resolve)
        } else {
          delete res.mk_ex_invoke
          delete res.ErrCode
          delete res.ErrMesg
          delete res.message
          delete res.status
          // 使用处理后的数据调用外部接口
          let keys = Object.keys(res) // 提交外部接口前,添加BID
          if (this.props.BID && keys.filter(key => key.toLowerCase() === 'bid').length === 0) {
            res.BID = this.props.BID
          }
          this.outerOuterRequest(params, res, record, _resolve)
        }
      } else {
        this.execError(res)
        _resolve()
      }
    }, () => {
      this.updateStatus()
      _resolve()
    })
  }
  outerOuterRequest = (params, result, record, _resolve) => {
    const { btn } = this.props
    let outParam = JSON.parse(JSON.stringify(result))
    if (btn.outerFunc) {
      result.func = btn.outerFunc
    }
    if (window.GLOB.mkHS) {
      if (btn.sysInterface === 'true' && options.cloudServiceApi) {
        result.rduri = options.cloudServiceApi
      } else if (btn.sysInterface !== 'true') {
        if (window.GLOB.systemType === 'production' && btn.proInterface) {
          result.rduri = btn.proInterface
        } else {
          result.rduri = btn.interface
        }
      }
      // 函数 s_sDataDictb_TBBack 云端验证
      if (result.func === 's_sDataDictb_TBBack' && result.LTextOut) {
        result.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        result.secretkey = Utils.encrypt(result.LTextOut, result.timestamp)
        result.open_key = Utils.encryptOpenKey(result.secretkey, result.timestamp)
      }
    } else {
      if (btn.sysInterface === 'true' && window.GLOB.mainSystemApi) {
        result.rduri = window.GLOB.mainSystemApi
      } else if (btn.sysInterface !== 'true') {
        if (window.GLOB.systemType === 'production' && btn.proInterface) {
          result.rduri = btn.proInterface
        } else {
          result.rduri = btn.interface
        }
      }
    }
    Api.genericInterface(result).then(res => {
      this.outerCallbackRequest(params, res, record, outParam, _resolve)
    }, () => {
      this.outerCallbackRequest(params, {status: false, message: 500, ErrCode: 'E', ErrMesg: 500}, record, outParam, _resolve)
    })
  }
  /**
   * @description 回调请求循环执行
   */
  outerCallbackRequest = (params, result, record, outParam, _resolve) => {
    const { btn } = this.props
    let param = null
    if (btn.callbackType === 'script' || btn.callbackType === 'default') {
      param = this.getCallBackSql(result, record)
    } else if (btn.callbackType === 'func' || btn.callbackFunc) {
      delete result.message
      delete result.status
      param = {
        ...outParam,
        ...result,
        func: btn.callbackFunc
      }
      // 函数 s_sDataDictb_TBBack 云端验证
      if (window.GLOB.mkHS && param.func === 's_sDataDictb_TBBack' && param.LTextOut) {
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.secretkey = Utils.encrypt(param.LTextOut, param.timestamp)
        param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
      }
    } else {
      if (result.status) {
        if (params.length === 0) {
          this.execSuccess(result)
          _resolve()
        } else {
          this.outerLoopRequest(params, _resolve)
        }
      } else {
        this.execError(result)
        _resolve()
      }
      return
    }
    Api.genericInterface(param).then(res => {
      if (res.status) {
        // 一次请求成功,进行下一项请求
        if (params.length === 0) {
          this.execSuccess(res)
          _resolve()
        } else {
          this.outerLoopRequest(params, btn, _resolve)
          this.outerLoopRequest(params, _resolve)
        }
      } else {
        this.execError(res)
@@ -1935,17 +2122,6 @@
      let data = this.props.selectedData && this.props.selectedData[0] ? this.props.selectedData[0] : null
      this.setState({check: data && data[btn.field] === btn.openVal})
    }
  }
  /**
   * @description 按钮配置信息错误提示
   */
  actionSettingError = () => {
    notification.warning({
      top: 92,
      message: this.state.dict['main.action.settingerror'],
      duration: 5
    })
  }
  handleModelConfig = (config) => {
src/tabviews/zshare/fileupload/index.jsx
@@ -28,7 +28,7 @@
    maxFile: null,
    rduri: '',
    limit: 2,
    compress: false,
    compress: 'false',
    fileType: 'text',
    showprogress: false,
    filelist: []
@@ -66,13 +66,12 @@
    let accept = ''
    let accepts = null
    let compress = false
    let compress = config.compress || 'false'
    let maxFile = config.maxfile && config.maxfile > 0 ? config.maxfile : null
    if (config.compress === 'true' || config.compress === 'base64') {
      compress = true
    if (compress === 'true' || compress === 'base64') {
      accepts = ['.jpg', '.png', '.gif', '.jpeg']
      accept = accepts.join(',')
      if (config.compress === 'base64') {
      if (compress === 'base64') {
        maxFile = 1
      }
    } else if (config.suffix) {
@@ -249,7 +248,7 @@
      percent: 0
    })
    if (compress) {
    if (compress === 'true' || compress === 'base64') {
      let reader = new FileReader()
      let fileSize = file.size / 1024 / 1024
      let compressRate = 0.9
@@ -345,6 +344,35 @@
      reader.readAsDataURL(file)
      return false
    } else if (compress === 'oss') {
      let _param = new FormData()
      _param.append('multipartFile', file)
      _param.append('userId', sessionStorage.getItem('UserID') || '')
      Api.fileOssUpload(_param).then(res => {
        if (res.status) {
          if (res.urlPath) {
            let path = (/^\/\//.test(res.urlPath) ? 'https:' : '') + res.urlPath
            this.onUpdate(path)
            this.setState({
              percent: 100
            }, () => {
              setTimeout(() => {
                this.setState({
                  showprogress: false,
                  percent: 0
                })
              }, 200)
            })
          } else {
            this.onFail('文件上传失败!')
          }
        } else {
          this.onFail(res.message || '文件上传失败!')
        }
      })
      return false
    }
    // 兼容性的处理
src/tabviews/zshare/mutilform/index.jsx
@@ -306,10 +306,8 @@
          {
            max: item.fieldlength,
            message: formRule.input.formMessage.replace('@max', item.fieldlength)
          }
        ]
        if (item.encryption !== 'true') {
          _rules.push({
          },
          {
            pattern: /^[^']*$/ig,
            message: '不可使用英文状态的单引号!'
          }, {
@@ -320,8 +318,8 @@
                callback()
              }
            }
          })
        }
          }
        ]
        item.rules = _rules
      } else if (item.type === 'brafteditor') {
        item.rules = [
src/tabviews/zshare/mutilform/mkInput/index.jsx
@@ -1,6 +1,7 @@
import React, { Component } from 'react'
import { is, fromJS } from 'immutable'
import { Input } from 'antd'
import md5 from 'md5'
import MKEmitter from '@/utils/events.js'
@@ -14,9 +15,25 @@
    super(props)
    
    const config = props.config
    let _value = config.initval
    let encryption = 'false'
    if (config.encryption === 'true') {
      encryption = 'true'
      if (_value) {
        try {
          _value = window.decodeURIComponent(window.atob(_value))
        } catch (e) {
          _value = config.initval
        }
      }
    } else if (config.encryption === 'md5') {
      encryption = 'md5'
    }
    
    this.state = {
      value: config.initval
      value: _value,
      encryption
    }
  }
  
@@ -43,27 +60,55 @@
      this.inputRef.current.select()
    } else if (type === 'input') {
      this.setState({value})
      this.props.onChange(value, true)
      let _val = value
      if (this.state.encryption === 'true') {
        try {
          _val = window.btoa(window.encodeURIComponent(_val))
        } catch (e) {
          _val = value
        }
        this.props.onChange(_val)
      } else if (this.state.encryption === 'md5') {
        _val = _val + ''
        _val = md5(_val.toLowerCase())
        _val = _val.toUpperCase()
        this.props.onChange(_val)
      } else {
        this.props.onChange(_val, true)
      }
    }
  }
  handleChange = (e) => {
    let val = e.target.value
    let submit = /\n/ig.test(val)
    if (!/\n/ig.test(val)) {
      this.props.onChange(val)
      this.setState({value: val})
      if (!val) {
    val = val.replace(/\n/ig, '')
    let _val = val
    if (this.state.encryption === 'true') {
      try {
        _val = window.btoa(window.encodeURIComponent(_val))
      } catch (e) {
        _val = val
      }
    } else if (this.state.encryption === 'md5') {
      _val = md5(_val.toLowerCase())
      _val = _val.toUpperCase()
    }
    this.props.onChange(_val)
    this.setState({value: val}, () => {
      if (submit) {
        this.handleInputSubmit()
      } else if (!val) {
        this.inputRef.current.focus()
      }
    } else {
      val = val.replace(/\n/ig, '')
      this.props.onChange(val)
      this.setState({value: val}, () => {
        this.handleInputSubmit()
      })
    }
    })
  }
  handleInputSubmit = () => {
src/tabviews/zshare/mutilform/mkTextArea/index.jsx
@@ -1,6 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Input } from 'antd'
import md5 from 'md5'
import MKEmitter from '@/utils/events.js'
@@ -33,6 +34,8 @@
          _value = config.initval
        }
      }
    } else if (config.encryption === 'md5') {
      encryption = 'md5'
    }
    
    this.setState({
@@ -58,7 +61,23 @@
      this.inputRef.current.focus()
    } else if (type === 'input') {
      this.setState({value})
      this.props.onChange(value, true)
      let _val = value
      if (this.state.encryption === 'true') {
        try {
          _val = window.btoa(window.encodeURIComponent(_val))
        } catch (e) {
          _val = value
        }
        this.props.onChange(_val)
      } else if (this.state.encryption === 'md5') {
        _val = _val + ''
        _val = md5(_val.toLowerCase())
        _val = _val.toUpperCase()
        this.props.onChange(_val)
      } else {
        this.props.onChange(_val, true)
      }
    }
  }
@@ -75,7 +94,11 @@
      } catch (e) {
        _val = val
      }
    } else if (encryption === 'md5') {
      _val = md5(_val.toLowerCase())
      _val = _val.toUpperCase()
    }
    this.props.onChange(_val)
  }
src/templates/formtabconfig/index.jsx
@@ -1955,7 +1955,7 @@
        <Modal
          title={this.state.dict['model.action'] + '-' + this.state.dict['model.edit']}
          visible={modaltype === 'actionEdit'}
          width={900}
          width={920}
          maskClosable={false}
          onCancel={this.editModalCancel}
          footer={[
src/templates/sharecomponent/actioncomponent/actionform/index.jsx
@@ -149,18 +149,34 @@
      reOptions.intertype = this.state.interTypeOptions
      if (intertype === 'custom') {
        shows.push('procMode', 'interface', 'callbackType', 'cbTable', 'proInterface', 'method', 'cross')
        shows.push('procMode', 'interface', 'callbackType', 'proInterface', 'method', 'cross')
        if (this.record.procMode === 'system') {
          shows.push('sql', 'sqlType')
        } else {
        } else if (this.record.procMode === 'inner') {
          reRequired.innerFunc = true
          shows.push('innerFunc')
        }
        if (this.record.callbackType === 'func') {
          shows.push('callbackFunc')
        } else if (this.record.callbackType !== 'none') {
          shows.push('cbTable')
        }
        reReadonly.interface = false
        reRequired.interface = true
      } else if (intertype === 'outer') {
        shows.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc', 'output')
        reRequired.innerFunc = false
        shows.push('procMode', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackType', 'output')
        // reRequired.innerFunc = false
        if (this.record.procMode === 'system') {
          shows.push('sql', 'sqlType')
        } else if (this.record.procMode === 'inner') {
          reRequired.innerFunc = true
          shows.push('innerFunc')
        }
        if (this.record.callbackType === 'func') {
          shows.push('callbackFunc')
        } else if (this.record.callbackType !== 'none') {
          shows.push('cbTable')
        }
        if (this.record.sysInterface === 'false') {
          reReadonly.interface = false
@@ -198,6 +214,7 @@
      if (this.record.intertype === 'outer') {
        shows.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
        reRequired.innerFunc = false
        reRequired.callbackFunc = false
        if (this.record.sysInterface === 'false') {
          reReadonly.interface = false
@@ -260,6 +277,7 @@
        if (this.record.intertype === 'outer') {
          shows.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
          reRequired.innerFunc = false
          reRequired.callbackFunc = false
          if (this.record.sysInterface === 'false') {
            reReadonly.interface = false
@@ -531,7 +549,7 @@
            { max: formRule.func.max, message: formRule.func.maxMessage }
          )
        } else if (item.key === 'output') {
          if (this.record.intertype === 'system') {
          if (this.record.intertype === 'system' || ((this.record.intertype === 'outer' || this.record.intertype === 'custom') && this.record.callbackType === 'script')) {
            rules = [{
              pattern: /^@[0-9a-zA-Z_]+@?$/,
              message: '变量以@符开头,可使用字母、数字以及_'
src/templates/sharecomponent/actioncomponent/actionform/index.scss
@@ -4,6 +4,11 @@
    color: #1890ff;
    cursor: pointer;
  }
  >.ant-row >.ant-col {
    float: none;
    display: inline-block;
    vertical-align: top;
  }
  .textarea {
    .ant-col-sm-7 {
      width: 14%;
src/templates/sharecomponent/actioncomponent/index.jsx
@@ -932,7 +932,7 @@
          title={dict['model.action'] + '-' + (card && card.copyType === 'action' ? dict['model.copy'] : dict['model.edit'])}
          wrapClassName="model-table-action-edit-modal"
          visible={visible}
          width={850}
          width={920}
          maskClosable={false}
          onCancel={this.editModalCancel}
          footer={[
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -161,7 +161,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
@@ -212,7 +212,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -161,7 +161,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx
@@ -76,7 +76,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
src/templates/zshare/customscript/index.jsx
@@ -64,7 +64,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
src/templates/zshare/formconfig.jsx
@@ -938,6 +938,8 @@
      value: 'equaltab',
      text: '刷新同级标签'
    })
  } else if (card.execSuccess === 'maingrid') {
    card.execSuccess = 'grid'
  }
  if (card.OpenType === 'blank') {
@@ -945,6 +947,10 @@
  }
  if (!card.control && card.controlField) {
    card.control = 'disabled'
  }
  if (card.intertype === 'outer' && !card.procMode && !card.innerFunc) { // 兼容外部函数直传类型
    card.procMode = 'none'
  }
  return [
@@ -955,6 +961,14 @@
      initVal: card.OpenType,
      required: true,
      options: opentypes
    },
    {
      type: 'text',
      key: 'label',
      label: '按钮名称',
      initVal: card.label,
      required: true,
      readonly: false
    },
    {
      type: 'select',
@@ -1018,7 +1032,8 @@
      type: 'radio',
      key: 'procMode',
      label: '参数处理',
      initVal: card.procMode || 'system',
      initVal: card.procMode || (card.innerFunc ? 'inner' : 'system'),
      tooltip: '当返回值存在 mk_ex_invoke 且值为 false 时,不会调用外部接口。',
      required: true,
      options: [{
        value: 'system',
@@ -1026,6 +1041,9 @@
      }, {
        value: 'inner',
        text: '内部函数'
      }, {
        value: 'none',
        text: '无'
      }]
    },
    {
@@ -1035,14 +1053,6 @@
      initVal: card.sqlType || '',
      required: true,
      options: []
    },
    {
      type: 'text',
      key: 'label',
      label: '按钮名称',
      initVal: card.label,
      required: true,
      readonly: false
    },
    {
      type: 'text',
@@ -1193,7 +1203,7 @@
      type: 'radio',
      key: 'callbackType',
      label: '回调方式',
      initVal: card.callbackType || 'script',
      initVal: card.callbackType || (card.callbackFunc ? 'func' : 'script'),
      tooltip: '使用后台脚本执行时,需要配合计划任务。',
      required: true,
      options: [{
@@ -1202,6 +1212,12 @@
      }, {
        value: 'default',
        text: '后台脚本'
      }, {
        value: 'func',
        text: '回调函数'
      }, {
        value: 'none',
        text: '无'
      }]
    },
    {
@@ -1216,7 +1232,7 @@
      key: 'callbackFunc',
      label: Formdict['header.form.callbackFunc'],
      initVal: card.callbackFunc || '',
      required: false,
      required: true,
      readonly: false
    },
    {
@@ -2931,7 +2947,7 @@
      type: 'text',
      key: 'separator',
      label: '连接符',
      initVal: card.separator || card.separator === undefined ? '/' : '',
      initVal: card.separator === undefined ? '/' : card.separator,
      tooltip: '表单提交时信息之间的连接符。注:连接符为空时,初始化时填充其他表单无效。',
      required: false,
      readonly: false
@@ -3267,12 +3283,16 @@
      key: 'encryption',
      label: '加密传输',
      initVal: card.type === 'brafteditor' ? (card.encryption || 'true') : (card.encryption || 'false'),
      tooltip: '使用md5加密时,加密前内容会转为小写,加密后的md5值为32位大写。',
      options: [{
        value: 'true',
        text: Formdict['model.true']
      }, {
        value: 'false',
        text: Formdict['model.false']
        text: '无'
      }, {
        value: 'true',
        text: 'base64加密'
      }, {
        value: 'md5',
        text: 'md5加密'
      }]
    },
    {
@@ -3372,13 +3392,16 @@
      tooltip: '文件压缩或base64必须为图片,图片格式为jpg、png、gif 或 jpeg。注:base64只可上传一张图片。',
      options: [{
        value: 'false',
        text: '无'
        text: '默认'
      }, {
        value: 'true',
        text: '压缩'
      }, {
        value: 'base64',
        text: 'base64'
      }, {
        value: 'oss',
        text: 'oss上传'
      }]
    },
    {
@@ -3393,6 +3416,90 @@
      required: true
    },
    {
      type: 'radio',
      key: 'miniSet',
      label: '小程序设置',
      initVal: card.miniSet || 'default',
      options: [{
        value: 'default',
        text: '默认'
      }, {
        value: 'custom',
        text: '自定义'
      }],
      forbid: appType !== 'mob'
    },
    {
      type: 'checkbox',
      key: 'mediaType',
      label: '文件类型',
      initVal: card.mediaType || ['image', 'video'],
      options: [{
        value: 'image',
        text: '图片'
      }, {
        value: 'video',
        text: '视频'
      }],
      required: true,
      forbid: appType !== 'mob'
    },
    {
      type: 'checkbox',
      key: 'sourceType',
      label: '文件来源',
      initVal: card.sourceType || ['album', 'camera'],
      options: [{
        value: 'album',
        text: '相册选择'
      }, {
        value: 'camera',
        text: '相机拍摄'
      }],
      required: true,
      forbid: appType !== 'mob'
    },
    {
      type: 'radio',
      key: 'sizeType',
      label: '图片压缩',
      initVal: card.sizeType || 'compressed',
      options: [{
        value: 'compressed',
        text: '是'
      }, {
        value: 'original',
        text: '否'
      }],
      forbid: appType !== 'mob'
    },
    {
      type: 'number',
      key: 'maxDuration',
      label: '拍摄时长',
      initVal: card.maxDuration || 10,
      tooltip: '拍摄视频最长拍摄时间,单位秒。时间范围为 3s 至 60s 之间。不限制相册。',
      min: 3,
      max: 60,
      precision: 0,
      required: true,
      forbid: appType !== 'mob'
    },
    {
      type: 'radio',
      key: 'camera',
      label: '摄像头',
      initVal: card.camera || 'back',
      options: [{
        value: 'back',
        text: '后置'
      }, {
        value: 'front',
        text: '前置'
      }],
      forbid: appType !== 'mob'
    },
    {
      type: 'number',
      key: 'span',
      min: 1,
src/templates/zshare/modalform/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Form, Row, Col, Input, Select, Radio, notification, InputNumber, Tooltip } from 'antd'
import { Form, Row, Col, Input, Select, Radio, notification, InputNumber, Tooltip, Checkbox } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons'
import { formRule } from '@/utils/option.js'
@@ -19,7 +19,7 @@
const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
const modalTypeOptions = {
  text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'scan', 'splitline', 'placeholder', 'place', 'marginTop', 'marginBottom', 'lenControl'],
  text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'encryption', 'tooltip', 'extra', 'enter', 'cursor', 'scan', 'splitline', 'placeholder', 'place', 'marginTop', 'marginBottom', 'lenControl'],
  number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'splitline', 'place', 'marginTop', 'marginBottom'],
  select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'setAll', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom'],
  checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
@@ -27,12 +27,12 @@
  checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'span', 'labelwidth', 'display', 'tooltip', 'extra', 'width', 'multiple', 'splitline', 'marginTop', 'marginBottom'],
  multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'marginTop', 'marginBottom'],
  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'setAll', 'linkField', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom'],
  fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'span', 'labelwidth', 'tooltip', 'extra', 'compress', 'splitline', 'marginTop', 'marginBottom'],
  fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'span', 'labelwidth', 'tooltip', 'extra', 'compress', 'miniSet', 'splitline', 'marginTop', 'marginBottom'],
  switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom'],
  date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'mode', 'splitline', 'marginTop', 'marginBottom', 'minDate', 'maxDate', 'precision'],
  datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'splitline', 'marginTop', 'marginBottom'],
  datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'mode', 'splitline', 'marginTop', 'marginBottom', 'minDate', 'maxDate'],
  textarea: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'span', 'labelwidth', 'maxRows', 'encryption', 'interception', 'tooltip', 'extra', 'count', 'placeholder', 'marginTop', 'marginBottom', 'enterReplace'],
  textarea: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'span', 'labelwidth', 'maxRows', 'encryption', 'interception', 'tooltip', 'extra', 'count', 'placeholder', 'marginTop', 'marginBottom'],
  cascader: ['readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom', 'separator'],
  color: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'marginTop', 'marginBottom'],
  rate: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'splitline', 'tooltip', 'extra', 'marginTop', 'marginBottom', 'allowHalf', 'rateCount', 'character', 'place'],
@@ -230,8 +230,25 @@
    } else if (type === 'fileupload') {
      if (this.record.compress === 'true') {
        shows.push('limit', 'rduri', 'proRduri')
      } else {
      } else if (this.record.compress !== 'base64') {
        shows.push('suffix')
      }
      if (this.record.miniSet === 'custom') {
        shows.push('mediaType', 'sourceType')
        if (this.record.sourceType.includes('camera') && this.record.mediaType.includes('video')) {
          shows.push('maxDuration')
        }
        if (this.record.mediaType.includes('image')) {
          shows.push('sizeType')
        }
        if (this.record.sourceType.includes('camera')) {
          shows.push('camera')
        }
      }
    } else if (type === 'textarea') {
      if (this.record.encryption === 'false') {
        shows.push('enterReplace')
      }
    }
@@ -262,6 +279,27 @@
      }, {
        value: '1',
        text: '数据源'
      }]
    }
    if (type === 'brafteditor') {
      reOptions.encryption = [{
        value: 'false',
        text: '无'
      }, {
        value: 'true',
        text: 'base64加密'
      }]
    } else {
      reOptions.encryption = [{
        value: 'false',
        text: '无'
      }, {
        value: 'true',
        text: 'base64加密'
      }, {
        value: 'md5',
        text: 'md5加密'
      }]
    }
@@ -613,6 +651,15 @@
            )
          })}
        </Radio.Group>
      } else if (item.type === 'checkbox') {
        rules = [
          { required: item.required, message: dict['form.required.select'] + item.label + '!' }
        ]
        initVal = item.initVal
        content = <Checkbox.Group onChange={(values) => {this.optionChange(item.key, values)}}>
          {item.options.map(option => <Checkbox key={option.value} value={option.value}>{option.text}</Checkbox>)}
        </Checkbox.Group>
      } else if (item.type === 'codemirror') {
        rules = [
          { required: item.required, message: dict['form.required.input'] + item.label + '!' }
src/templates/zshare/verifycard/customscript/index.jsx
@@ -325,7 +325,7 @@
          </Col>
          <Col span={24} className="sql">
            <Form.Item label={
              <Tooltip placement="topLeft" title={'数据检查替换符 $check@ -> \'\'、 @check$ -> \'\',ErrorCode等于C时 $check@ -> /*、 @check$ -> */'}>
              <Tooltip placement="topLeft" title={'数据检查替换符 $check@ -> \'\'、 @check$ -> \'\',ErrorCode等于C时 $check@ -> /*、 @check$ -> */。注:1、需使用系统接口 2、行设置为“选择多行”时无效。'}>
                <QuestionCircleOutlined className="mk-form-tip" />
                sql
              </Tooltip>
src/templates/zshare/verifycard/index.jsx
@@ -114,7 +114,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
@@ -150,7 +150,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
@@ -224,7 +224,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
@@ -276,7 +276,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
@@ -345,7 +345,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
@@ -412,7 +412,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
@@ -513,7 +513,7 @@
          ) :
          (
            <div style={{color: '#26C281'}}>
              {this.props.dict['model.status.open']}
              启用
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
@@ -594,17 +594,22 @@
      item.$index = i + 1
    })
    let verifyInter = card.intertype === 'system' || (card.intertype === 'custom' && card.procMode === 'system') ? 'system' : 'inner'
    let verifyInter = card.intertype === 'system' || card.procMode === 'system' ? 'system' : 'inner'
    let activeKey = verifyInter === 'system' || card.intertype === 'inner' ? 'base' : 'tip'
    if (card.callbackType === 'script') {
      activeKey = 'cbScripts'
    }
    this.setState({
      activeKey: verifyInter === 'system' || card.intertype === 'inner' ? 'base' : 'tip',
      activeKey: activeKey,
      verifyInter: verifyInter,
      setting: config.setting || {},
      verify: _verify,
      oriVerify: fromJS(_verify).toJS()
    })
    if (config.Template !== 'FormTab' && (card.intertype === 'inner' || card.intertype === 'outer')) { // 内部或外部接口
    if (config.Template !== 'FormTab' && card.intertype === 'inner') {
      return
    }
@@ -1613,7 +1618,7 @@
            />
            <EditTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/>
          </TabPane> : null}
          {card.callbackType === 'script' && card.intertype === 'custom' ? <TabPane tab={
          {card.callbackType === 'script' ? <TabPane tab={
            <span>
              回调脚本
              {verify.cbScripts.length ? <span className="count-tip">{verify.cbScripts.length}</span> : null}
src/utils/utils-datamanage.js
@@ -78,7 +78,7 @@
  }
  /**
   * @description 获取系统存储过程 sPC_Get_TableData 的参数
   * @description 获取系统存储过程的参数
   */
  static getDefaultQueryParam (setting, arrFields, search, orderBy, pageIndex, pageSize, id, BID) {
    let param = {
@@ -127,7 +127,6 @@
    _customScript = _customScript.replace(/\$sum@/ig, '/*')
    _customScript = _customScript.replace(/@sum\$/ig, '*/')
    let time_id = Utils.getguid().substring(0, 32) || ''
    _dataresource = _dataresource.replace(/@ID@/ig, `''`)
    _customScript = _customScript.replace(/@ID@/ig, `''`)
    _dataresource = _dataresource.replace(/@BID@/ig, `'${BID || ''}'`)
@@ -140,8 +139,6 @@
    _customScript = _customScript.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
    _dataresource = _dataresource.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
    _customScript = _customScript.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
    _dataresource = _dataresource.replace(/@time_id@/ig, `'${time_id}'`)
    _customScript = _customScript.replace(/@time_id@/ig, `'${time_id}'`)
    let regoptions = null
    if (setting.queryType === 'statistics' || _customScript) {
@@ -270,7 +267,7 @@
  }
  /**
   * @description 获取系统存储过程 sPC_Get_TableData 合计值的参数
   * @description 获取系统存储过程合计值的参数
   */
  static getStatQueryDataParams (setting, statFields, search, orderBy, BID) {
    let param = {
@@ -318,7 +315,6 @@
    _customScript = _customScript.replace(/\$select@/ig, '/*')
    _customScript = _customScript.replace(/@select\$/ig, '*/')
    let time_id = Utils.getguid().substring(0, 32) || ''
    _dataresource = _dataresource.replace(/@ID@/ig, `''`)
    _customScript = _customScript.replace(/@ID@/ig, `''`)
    _dataresource = _dataresource.replace(/@BID@/ig, `'${BID || ''}'`)
@@ -331,8 +327,6 @@
    _customScript = _customScript.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
    _dataresource = _dataresource.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
    _customScript = _customScript.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
    _dataresource = _dataresource.replace(/@time_id@/ig, `'${time_id}'`)
    _customScript = _customScript.replace(/@time_id@/ig, `'${time_id}'`)
    let regoptions = null
    if (setting.queryType === 'statistics' || _customScript) {
@@ -515,7 +509,6 @@
      sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
      sql = sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
      sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
      sql = sql.replace(/@time_id@/ig, `'${Utils.getguid().substring(0, 32) || ''}'`)
      // 测试系统打印查询语句
      if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
@@ -604,7 +597,6 @@
    sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
    sql = sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
    sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
    sql = sql.replace(/@time_id@/ig, `'${Utils.getguid().substring(0, 32) || ''}'`)
    if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
      console.info(sql.replace(/\n\s{8}/ig, '\n'))
@@ -616,6 +608,14 @@
    param.secretkey = Utils.encrypt('', param.timestamp)
    param.LText = Utils.formatOptions(param.LText)
    param.menuname = setting.MenuName || ''
    if (BID) {
      param.BID = BID
    }
    if (window.GLOB.mkHS) { // 系统函数云端验证
      param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
    }
    return param
  }
@@ -783,7 +783,6 @@
  let LText_field = []
  let diffUser = false
  let transaction = false
  let time_id = Utils.getguid().substring(0, 32) || ''
  let loginId = `'${sessionStorage.getItem('LoginUID') || ''}'`
  let sessionId = `'${localStorage.getItem('SessionUid') || ''}'`
  let userId = `'${sessionStorage.getItem('UserID') || ''}'`
@@ -811,8 +810,6 @@
    _script = _script.replace(/@UserID@/ig, userId)
    _sql = _sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
    _script = _script.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
    _sql = _sql.replace(/@time_id@/ig, `'${time_id}'`)
    _script = _script.replace(/@time_id@/ig, `'${time_id}'`)
    // 测试系统打印查询语句
    if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
src/utils/utils.js
@@ -2082,21 +2082,12 @@
      aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
  }
  let time_id = []
  let options = '0123456789abcdefghigklmnopqrstuv'
  for (let i = 0; i < 15; i++) {
    time_id.push(options.substr(Math.floor(Math.random() * 0x20), 1))
  }
  time_id = moment().format('YYYYMMDDHHmmssSSS') + time_id.join('')
  time_id = time_id.toUpperCase()
  _sql = _sql.replace(/@ID@/ig, `'${primaryId || ''}'`)
  _sql = _sql.replace(/@BID@/ig, `'${BID || ''}'`)
  _sql = _sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
  _sql = _sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
  _sql = _sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
  _sql = _sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
  _sql = _sql.replace(/@time_id@/ig, `'${time_id}'`)
  if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
    // _sql = _sql.replace(/\n\s{8}/ig, '\n')
src/views/design/header/index.jsx
@@ -2,7 +2,7 @@
import { withRouter } from 'react-router-dom'
import {connect} from 'react-redux'
import { Dropdown, Menu, Modal, notification, Switch, Button, Popover } from 'antd'
import { MenuFoldOutlined, SettingOutlined, AppstoreOutlined, DownOutlined, HomeOutlined, ApiOutlined, PlusOutlined, SwapOutlined, MenuOutlined } from '@ant-design/icons'
import { MenuFoldOutlined, SettingOutlined, AppstoreOutlined, DownOutlined, HomeOutlined, ApiOutlined, PlusOutlined, EditOutlined, MenuOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import {
@@ -340,7 +340,7 @@
        {!editLevel && window.GLOB.systemType !== 'production' && menulist ? <Popover overlayClassName="mk-popover-control-wrap mk-menu-control" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <PlusOutlined onClick={() => this.setState({visible: true, loading: false})}/>
            <SwapOutlined onClick={this.enterEdit}/>
            <EditOutlined onClick={this.enterEdit}/>
            <div style={{display: 'inline-block', minWidth: '32px'}}><ThawMenu ParentId="0" Type="10"/></div>
          </div>
        } trigger="hover">
src/views/design/index.jsx
@@ -22,8 +22,7 @@
    if (window.GLOB.systemType !== 'production' && window.GLOB.WXAppID && !sessionStorage.getItem('wxTemplates')) {
      Api.wxAccessToken().then(res => {
        let wxtoken = res.oa_access_token || ''
        wxtoken = '59_DH0hrAp0B8jtdJvU-7BV_-nG01qh2rUU1L8ihj-2pMWlUFLE2eEtVv4zZYAUIKcxCit4SgOTwxvUGdYHltaha3RmgnZqkQSgkxXRm9hz18kGbGhMc5r11W5Iv9Xr50Pz-Sz7FUVHCM-6GZLXJPIjAIAVBU'
        let minitoken = res.mini_access_token || ''
        // let minitoken = res.mini_access_token || ''
  
        if (wxtoken) {
          Api.wxNginxRequest(`cgi-bin/template/get_all_private_template?access_token=${wxtoken}`, 'get').then(res => {
@@ -37,17 +36,17 @@
        } else {
          sessionStorage.setItem('wxTemplates', JSON.stringify([]))
        }
        if (minitoken) {
          Api.wxNginxRequest(`wxaapi/newtmpl/gettemplate?access_token=${minitoken}`, 'get').then(res => {
            if (res.errmsg === 'ok' && res.data) {
              sessionStorage.setItem('wxMiniTemplates', JSON.stringify(res.data))
            } else {
              sessionStorage.setItem('wxMiniTemplates', JSON.stringify([]))
            }
          })
        } else {
          sessionStorage.setItem('wxMiniTemplates', JSON.stringify([]))
        }
        // if (minitoken) {
        //   Api.wxNginxRequest(`wxaapi/newtmpl/gettemplate?access_token=${minitoken}`, 'get').then(res => {
        //     if (res.errmsg === 'ok' && res.data) {
        //       sessionStorage.setItem('wxMiniTemplates', JSON.stringify(res.data))
        //     } else {
        //       sessionStorage.setItem('wxMiniTemplates', JSON.stringify([]))
        //     }
        //   })
        // } else {
        //   sessionStorage.setItem('wxMiniTemplates', JSON.stringify([]))
        // }
      })
    }
  }
src/views/design/index.scss
@@ -25,13 +25,10 @@
  .anticon-plus {
    color: #26C281;
  }
  .anticon-swap {
  .anticon-edit {
    position: relative;
    z-index: 2;
    color: #1890ff;
  }
  .mk-swap {
    transform: rotate(90deg);
  }
  .mk-swap.disabled {
    cursor: not-allowed!important;
src/views/design/sidemenu/index.jsx
@@ -2,7 +2,7 @@
import { connect } from 'react-redux'
import { is, fromJS } from 'immutable'
import { Menu, Popover, Modal, notification } from 'antd'
import { SwapOutlined, PlusOutlined, SettingOutlined } from '@ant-design/icons'
import { EditOutlined, PlusOutlined, SettingOutlined } from '@ant-design/icons'
import moment from 'moment'
import asyncComponent from '@/utils/asyncComponent'
@@ -282,7 +282,7 @@
            <Popover overlayClassName="mk-popover-control-wrap mk-menu-control" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
              <div className="mk-popover-control">
                <PlusOutlined onClick={this.addSecMenu}/>
                <SwapOutlined onClick={this.enterSubEdit} className={'mk-swap' + (mainMenu.children.length === 0 ? ' disabled' : '')}/>
                <EditOutlined onClick={this.enterSubEdit} className={'mk-swap' + (mainMenu.children.length === 0 ? ' disabled' : '')}/>
                <div style={{display: 'inline-block', minWidth: '32px'}}><ThawMenu ParentId={mainMenu.MenuID} Type="20"/></div>
              </div>
            } trigger="hover" placement="top">
@@ -304,7 +304,7 @@
                  <Popover overlayClassName="mk-popover-control-wrap mk-menu-control" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
                    <div className="mk-popover-control">
                      <div style={{display: 'inline-block', minWidth: '32px'}}><AddThdMenu mainMenu={mainMenu} supMenu={item} menuTree={this.props.menuTree}/></div>
                      <SwapOutlined onClick={(e) => {this.enterThrEdit(e, item)}} className="mk-swap"/>
                      <EditOutlined onClick={(e) => {this.enterThrEdit(e, item)}} className="mk-swap"/>
                      <div style={{display: 'inline-block', minWidth: '32px'}}><ThawMenu ParentId={item.MenuID} Type="30"/></div>
                    </div>
                  } trigger="hover" placement="top">
src/views/imdesign/index.jsx
@@ -485,7 +485,7 @@
            <div className="pc-setting-tools">
              <Collapse accordion defaultActiveKey="basedata" bordered={false}>
                {/* 基本信息 */}
                <Panel header={dict['mob.basemsg']} forceRender key="basedata">
                <Panel header="基本信息" forceRender key="basedata">
                  {/* 菜单信息 */}
                  {config ? <MenuForm
                    dict={dict}
src/views/menudesign/index.jsx
@@ -1,5 +1,6 @@
import React, { Component } from 'react'
import { DndProvider } from 'react-dnd'
import { withRouter } from 'react-router'
import { is, fromJS } from 'immutable'
import moment from 'moment'
import HTML5Backend from 'react-dnd-html5-backend'
@@ -12,7 +13,7 @@
import Utils, { setGLOBFuncs } from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/mob.js'
import enUS from '@/locales/en-US/mob.js'
import antdEnUS from 'antd/es/locale/en_US'
// import antdEnUS from 'antd/es/locale/en_US'
import antdZhCN from 'antd/es/locale/zh_CN'
import MKEmitter from '@/utils/events.js'
import MenuUtils from '@/utils/utils-custom.js'
@@ -23,7 +24,7 @@
const { Panel } = Collapse
const { confirm } = Modal
const { Paragraph } = Typography
const _locale = sessionStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS
const _locale = antdZhCN
const MenuForm = asyncComponent(() => import('./menuform'))
const HomeForm = asyncComponent(() => import('./homeform'))
@@ -31,10 +32,8 @@
const MenuShell = asyncComponent(() => import('@/menu/menushell'))
const PrintMenuForm = asyncComponent(() => import('./printmenuform'))
const SourceWrap = asyncComponent(() => import('@/menu/modulesource'))
const PopviewController = asyncComponent(() => import('@/menu/popview'))
const BgController = asyncComponent(() => import('@/menu/bgcontroller'))
const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
const PaddingController = asyncComponent(() => import('@/menu/padcontroller'))
const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const Versions = asyncComponent(() => import('@/menu/versions'))
@@ -47,13 +46,8 @@
const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
sessionStorage.setItem('isEditState', 'true')
sessionStorage.setItem('editMenuType', 'menu') // 编辑菜单类型
sessionStorage.setItem('appType', '')          // 应用类型
document.body.className = ''
window.GLOB.UserComponentMap = new Map() // 缓存用户自定义组件
window.GLOB.TabsMap = new Map()          // 缓存用户操作的标签页
window.GLOB.urlFields = []               // url变量
window.GLOB.customMenu = null            // 保存菜单信息
class MenuDesign extends Component {
  state = {
@@ -65,13 +59,10 @@
    MenuNo: '',
    delButtons: [],
    copyButtons: [],
    thawButtons: [],
    activeKey: 'basedata',
    menuloading: false,
    oriConfig: null,
    config: null,
    popBtn: null,             // 弹窗标签页
    visible: false,
    customComponents: [],
    comloading: false,
    settingshow: true,
@@ -80,6 +71,13 @@
  }
  UNSAFE_componentWillMount() {
    sessionStorage.setItem('editMenuType', 'menu') // 编辑菜单类型
    window.GLOB.UserComponentMap = new Map() // 缓存用户自定义组件
    window.GLOB.TabsMap = new Map()          // 缓存用户操作的标签页
    window.GLOB.urlFields = []               // url变量
    window.GLOB.customMenu = null            // 保存菜单信息
    try {
      let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
@@ -108,16 +106,24 @@
  componentDidMount () {
    MKEmitter.addListener('delButtons', this.delButtons)
    MKEmitter.addListener('modalStatus', this.modalStatus)
    MKEmitter.addListener('thawButtons', this.thawButtons)
    // MKEmitter.addListener('thawButtons', this.thawButtons)
    MKEmitter.addListener('copyButtons', this.copyButtons)
    MKEmitter.addListener('changePopview', this.initPopview)
    MKEmitter.addListener('triggerMenuSave', this.triggerMenuSave)
    MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
    MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent)
    setTimeout(() => {
      this.updateCustomComponent()
      if (sessionStorage.getItem('app_custom_components')) {
        let list = sessionStorage.getItem('app_custom_components')
        list = JSON.parse(list)
        this.setCustomComponent(list)
      } else {
        this.updateCustomComponent()
      }
      this.getAppPictures()
      this.getPrintTemp()
      this.getRoleFields()
      setGLOBFuncs()
    }, 1000)
@@ -151,9 +157,6 @@
        let node = document.getElementById('save-modal-config')
        if (!node) {
          node = document.getElementById('save-pop-config')
        }
        if (!node) {
          node = document.getElementById('save-config')
        }
@@ -174,7 +177,7 @@
    }
    MKEmitter.removeListener('delButtons', this.delButtons)
    MKEmitter.removeListener('modalStatus', this.modalStatus)
    MKEmitter.removeListener('thawButtons', this.thawButtons)
    // MKEmitter.removeListener('thawButtons', this.thawButtons)
    MKEmitter.removeListener('copyButtons', this.copyButtons)
    MKEmitter.removeListener('changePopview', this.initPopview)
    MKEmitter.removeListener('triggerMenuSave', this.triggerMenuSave)
@@ -187,8 +190,6 @@
  }
  triggerMenuSave = () => {
    if (this.state.visible) return
    this.submitConfig()
  }
@@ -281,36 +282,46 @@
      typename: '',
      typecharone: ''
    }).then(res => {
      let coms = []
      if (res.cus_list && res.cus_list.length > 0) {
        res.cus_list.forEach(item => {
          let config = ''
          try {
            config = JSON.parse(window.decodeURIComponent(window.atob(item.long_param)))
          } catch (e) {
            console.warn('Parse Failure')
            config = ''
          }
          if (!config || !item.c_name) return
          window.GLOB.UserComponentMap.set(item.c_id, item.c_name)
          coms.push({
            uuid: item.c_id,
            type: 'menu',
            title: item.c_name,
            url: item.images,
            component: config.type,
            subtype: config.subtype,
            width: config.width || 24,
            config
          })
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      } else if (res.cus_list) {
        sessionStorage.setItem('app_custom_components', JSON.stringify(res.cus_list))
        this.setCustomComponent(res.cus_list)
      }
      this.setState({customComponents: coms})
      this.getRoleFields()
    })
  }
  setCustomComponent = (cus_list) => {
    let coms = []
    cus_list.forEach(item => {
      let config = ''
      try {
        config = JSON.parse(window.decodeURIComponent(window.atob(item.long_param)))
      } catch (e) {
        console.warn('Parse Failure')
        config = ''
      }
      if (!config || !item.c_name) return
      window.GLOB.UserComponentMap.set(item.c_id, item.c_name)
      coms.push({
        uuid: item.c_id,
        type: 'menu',
        title: item.c_name,
        url: item.images,
        component: config.type,
        subtype: config.subtype,
        config
      })
    })
    this.setState({customComponents: coms})
  }
  updateComponentStyle = (parentId, keys, style) => {
@@ -343,9 +354,9 @@
    this.setState({copyButtons: [...this.state.copyButtons, ...items]})
  }
  
  thawButtons = (item) => {
    this.setState({thawButtons: [...this.state.thawButtons, item]})
  }
  // thawButtons = (item) => {
  //   this.setState({thawButtons: [...this.state.thawButtons, item]})
  // }
  initPopview = (card, btn) => {
    const { oriConfig, config } = this.state
@@ -359,20 +370,11 @@
      return
    }
    btn.config = fromJS(config).toJS()
    btn.component = card
    let _btn = fromJS(btn).toJS()
    _btn.MenuName = config.MenuName + '-' + card.name + '-' + btn.label
    _btn.ParentMenuID = config.uuid
    sessionStorage.setItem('editMenuType', 'popview') // 编辑弹窗标签
    this.setState({popBtn: btn, visible: true})
  }
  handleBack = () => {
    this.setState({popBtn: null, delButtons: [], copyButtons: []}, () => {
      sessionStorage.setItem('editMenuType', 'menu')
      window.GLOB.customMenu = this.state.config
      this.setState({visible: false})
    })
    this.props.history.push('/popdesign/' + window.btoa(window.encodeURIComponent((JSON.stringify(_btn)))))
  }
  closeView = () => {
@@ -498,7 +500,6 @@
              delButtons.push(btn.uuid)
              return
            }
            this.checkBtn(btn)
            buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
            _sort++
          })
@@ -509,7 +510,6 @@
                delButtons.push(cell.uuid)
                return
              }
              this.checkBtn(cell)
              buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
              _sort++
            })
@@ -519,7 +519,6 @@
                delButtons.push(cell.uuid)
                return
              }
              this.checkBtn(cell)
              buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
              _sort++
            })
@@ -532,7 +531,6 @@
                delButtons.push(cell.uuid)
                return
              }
              this.checkBtn(cell)
              buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
              _sort++
            })
@@ -544,7 +542,6 @@
              delButtons.push(cell.uuid)
              return
            }
            this.checkBtn(cell)
            buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
            _sort++
          })
@@ -554,7 +551,6 @@
              delButtons.push(btn.uuid)
              return
            }
            this.checkBtn(btn)
            buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
            _sort++
          })
@@ -564,7 +560,6 @@
              delButtons.push(btn.uuid)
              return
            }
            this.checkBtn(btn)
            buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
            _sort++
          })
@@ -575,7 +570,6 @@
                delButtons.push(btn.uuid)
                return
              }
              this.checkBtn(btn)
              buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
              _sort++
            })
@@ -589,28 +583,8 @@
    return buttons
  }
  checkBtn = (btn) => {
    if (['prompt', 'exec', 'pop'].includes(btn.OpenType) && btn.Ot === 'required' && btn.verify && btn.verify.scripts && btn.verify.scripts.length > 0) {
      let hascheck = false
      btn.verify.scripts.forEach(item => {
        if (item.status === 'false') return
        if (/\$check@|@check\$/ig.test(item.sql)) {
          hascheck = true
        }
      })
      if (hascheck) {
        notification.warning({
          top: 92,
          message: `可选择多行的按钮《${btn.label}》中 $check@ 或 @check$ 将不会生效!`,
          duration: 5
        })
      }
    }
  }
  submitConfig = () => {
    const { MenuType, copyButtons, thawButtons } = this.state
    const { MenuType, copyButtons } = this.state
    let config = fromJS(this.state.config).toJS()
    if (MenuType === 'billPrint' && config.printPage === 'page' && !config.everyPCount) {
@@ -752,28 +726,28 @@
          }
          return Api.getSystemConfig(_param)
        }
      }).then(res => { // 按钮解除冻结
        if (!res) return
        if (!res.status) {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
          return false
        }
      // }).then(res => { // 按钮解除冻结
      //   if (!res) return
      //   if (!res.status) {
      //     notification.warning({
      //       top: 92,
      //       message: res.message,
      //       duration: 5
      //     })
      //     return false
      //   }
        let ids = thawButtons.filter(item => btnIds.indexOf(item) !== -1)
        if (ids.length === 0) {
          return {
            status: true
          }
        } else {
          return Api.getSystemConfig({
            func: 'sPC_MainMenu_ReDel',
            MenuID: ids.join(',')
          })
        }
      //   let ids = thawButtons.filter(item => btnIds.indexOf(item) !== -1)
      //   if (ids.length === 0) {
      //     return {
      //       status: true
      //     }
      //   } else {
      //     return Api.getSystemConfig({
      //       func: 'sPC_MainMenu_ReDel',
      //       MenuID: ids.join(',')
      //     })
      //   }
      }).then(res => { // 页面保存
        if (!res) return
@@ -917,7 +891,6 @@
          this.setState({
            delButtons: [],
            copyButtons: [],
            thawButtons: [],
            menuloading: false
          })
          notification.success({
@@ -936,6 +909,7 @@
  }
  getRoleFields = () => {
    if (sessionStorage.getItem('sysRoles') || sessionStorage.getItem('permFuncField')) return
    Api.getSystemConfig({func: 'sPC_Get_Roles_sModular'}).then(res => {
      if (res.status) {
        let _permFuncField = []
@@ -1095,13 +1069,13 @@
  }
  render () {
    const { activeKey, comloading, MenuType, popBtn, visible, dict, MenuId, config, settingshow, ParentId, menuloading, customComponents, eyeopen } = this.state
    const { activeKey, comloading, MenuType, dict, MenuId, config, settingshow, ParentId, menuloading, customComponents, eyeopen } = this.state
    return (
      <ConfigProvider locale={_locale}>
        <div className={'pc-menu-view ' + (MenuType || '')} id="mk-menu-design-view">
          <Header />
          {!popBtn && !visible ? <DndProvider backend={HTML5Backend}>
          <DndProvider backend={HTML5Backend}>
            <div className="menu-body">
              <div className={'menu-setting ' + (!settingshow ? 'hidden' : '')}>
                <div className="draw">
@@ -1109,7 +1083,7 @@
                </div>
                <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
                  {/* 基本信息 */}
                  <Panel header={dict['mob.basemsg']} key="basedata">
                  <Panel header="基本信息" key="basedata">
                    {/* 菜单信息 */}
                    {config && MenuType === 'custom' ? <MenuForm
                      dict={dict}
@@ -1139,17 +1113,14 @@
                    {config ? <Paragraph style={{padding: '15px 0px 0px 18px'}} copyable={{ text: MenuId }}>菜单ID</Paragraph> : null}
                  </Panel>
                  {/* 组件添加 */}
                  <Panel header={dict['mob.component']} key="component">
                  <Panel header="组件" key="component">
                    <SourceWrap MenuType={MenuType} />
                  </Panel>
                  {customComponents && customComponents.length ? <Panel header="自定义组件" key="cuscomponent">
                    <SourceWrap components={customComponents} MenuType={MenuType} />
                  </Panel> : null}
                  <Panel header={'页面背景'} key="background">
                  <Panel header="页面样式" key="background">
                    {config ? <BgController config={config} updateConfig={this.updateConfig} /> : null}
                  </Panel>
                  <Panel header={'页面内边距'} key="padding">
                    {config ? <PaddingController config={config} updateConfig={this.updateConfig} /> : null}
                  </Panel>
                </Collapse>
              </div>
@@ -1174,8 +1145,7 @@
                </Card>
              </div>
            </div>
          </DndProvider> : null}
          {popBtn && visible ? <PopviewController btn={popBtn} handleBack={this.handleBack}/> : null}
          </DndProvider>
          <StyleController />
          <StyleCombController />
          <ModalController />
@@ -1185,4 +1155,4 @@
  }
}
export default MenuDesign
export default withRouter(MenuDesign)
src/views/mobdesign/index.jsx
@@ -161,9 +161,17 @@
    MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
    MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent)
    setTimeout(() => {
      this.updateCustomComponent()
      if (sessionStorage.getItem('app_custom_components')) {
        let list = sessionStorage.getItem('app_custom_components')
        list = JSON.parse(list)
        this.setCustomComponent(list)
      } else {
        this.updateCustomComponent()
      }
      this.getAppPictures()
      this.getSmStemp()
      this.getRoleFields()
      setGLOBFuncs()
    }, 1000)
@@ -413,36 +421,46 @@
      typename: sessionStorage.getItem('typename'),
      typecharone: ''
    }).then(res => {
      let coms = []
      if (res.cus_list && res.cus_list.length > 0) {
        res.cus_list.forEach(item => {
          let config = ''
          try {
            config = JSON.parse(window.decodeURIComponent(window.atob(item.long_param)))
          } catch (e) {
            console.warn('Parse Failure')
            config = ''
          }
          if (!config || !item.c_name) return
          window.GLOB.UserComponentMap.set(item.c_id, item.c_name)
          coms.push({
            uuid: item.c_id,
            type: 'menu',
            title: item.c_name,
            url: item.images,
            component: config.type,
            subtype: config.subtype,
            width: config.width || 24,
            config
          })
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      } else if (res.cus_list) {
        sessionStorage.setItem('app_custom_components', JSON.stringify(res.cus_list))
        this.setCustomComponent(res.cus_list)
      }
      this.setState({customComponents: coms})
      this.getRoleFields()
    })
  }
  setCustomComponent = (cus_list) => {
    let coms = []
    cus_list.forEach(item => {
      let config = ''
      try {
        config = JSON.parse(window.decodeURIComponent(window.atob(item.long_param)))
      } catch (e) {
        console.warn('Parse Failure')
        config = ''
      }
      if (!config || !item.c_name) return
      window.GLOB.UserComponentMap.set(item.c_id, item.c_name)
      coms.push({
        uuid: item.c_id,
        type: 'menu',
        title: item.c_name,
        url: item.images,
        component: config.type,
        subtype: config.subtype,
        config
      })
    })
    this.setState({customComponents: coms})
  }
  updateComponentStyle = (parentId, keys, style) => {
@@ -551,7 +569,8 @@
            Template: 'webPage',
            enabled: false,
            MenuName: urlParam.MenuName || '',
            MenuNo: urlParam.MenuNo || '',
            // MenuNo: urlParam.MenuNo || '',
            MenuNo: '',
            tables: [],
            components: [],
            viewType: 'menu',
@@ -801,7 +820,8 @@
      config.MenuID = MenuId
      config.open_edition = ''
      config.MenuName = urlParam.MenuName || ''
      config.MenuNo = urlParam.MenuNo || ''
      // config.MenuNo = urlParam.MenuNo || ''
      config.MenuNo = ''
      let indeComs = []
      config.components.forEach(item => {
@@ -957,7 +977,6 @@
          item.action && item.action.forEach(btn => {
            if (btn.hidden === 'true') return
            this.checkBtn(btn)
            m.children.push({
              key: btn.uuid,
              title: btn.label,
@@ -968,7 +987,6 @@
              if (cell.eleType !== 'button') return
              if (cell.hidden === 'true') return
              this.checkBtn(cell)
              m.children.push({
                key: cell.uuid,
                title: cell.label,
@@ -981,7 +999,6 @@
              if (cell.eleType !== 'button') return
              if (cell.hidden === 'true') return
              this.checkBtn(cell)
              m.children.push({
                key: cell.uuid,
                title: cell.label,
@@ -993,7 +1010,6 @@
            if (cell.eleType !== 'button') return
            if (cell.hidden === 'true') return
            this.checkBtn(cell)
            m.children.push({
              key: cell.uuid,
              title: cell.label,
@@ -1023,7 +1039,6 @@
          item.action && item.action.forEach(btn => {
            if (btn.hidden === 'true') return
            this.checkBtn(btn)
            m.children.push({
              key: btn.uuid,
              title: btn.label,
@@ -1034,7 +1049,6 @@
            col.elements.forEach(btn => {
              if (btn.hidden === 'true') return
              this.checkBtn(btn)
              m.children.push({
                key: btn.uuid,
                title: btn.label,
@@ -1090,7 +1104,8 @@
                menus.push({
                  MenuID: m.uuid,
                  MenuName: m.setting.name,
                  MenuNo: m.setting.MenuNo
                  // MenuNo: m.setting.MenuNo
                  MenuNo: ''
                })
              }
            } else if (m.setting.type === 'linkmenu' && menuObj[m.setting.linkMenuId]) {
@@ -1194,26 +1209,6 @@
    })
    return menus
  }
  checkBtn = (btn) => {
    if (['prompt', 'exec', 'pop'].includes(btn.OpenType) && btn.Ot === 'required' && btn.verify && btn.verify.scripts && btn.verify.scripts.length > 0) {
      let hascheck = false
      btn.verify.scripts.forEach(item => {
        if (item.status === 'false') return
        if (/\$check@|@check\$/ig.test(item.sql)) {
          hascheck = true
        }
      })
      if (hascheck) {
        notification.warning({
          top: 92,
          message: `可选择多行的按钮《${btn.label}》中 $check@ 或 @check$ 将不会生效!`,
          duration: 5
        })
      }
    }
  }
  getMiniStyle = (config) => {
@@ -1625,16 +1620,16 @@
    let searchSum = 0
    let swipes = []
    let check = (components) => {
    let check = (components, level, sign) => {
      components.forEach(item => {
        if (error) return
        if (item.type === 'tabs') {
          item.subtabs.forEach(tab => {
            check(tab.components)
            check(tab.components, level + 1, tab.uuid)
          })
          return
        } else if (item.type === 'group') {
          check(item.components)
          check(item.components, level, sign)
          return
        } else if (item.type === 'navbar' && !item.wrap.MenuNo) {
          error = `导航栏《${item.name}》未设置菜单参数!`
@@ -1649,7 +1644,8 @@
          }
        }
        if (item.wrap && item.wrap.pagestyle === 'slide' && item.pageable && item.setting.laypage !== 'false') {
          swipes.push(item.name)
          // swipes.push(item.name)
          swipes.push({level, name: item.name, sign})
        }
        item.errors && item.errors.forEach(err => {
@@ -1659,7 +1655,7 @@
      })
    }
    check(config.components)
    check(config.components, 1, 'view')
    // if (!error && viewType === 'userbind' && config.components.filter(item => item.type === 'login').length === 0) {
    //   error = '用户绑定页面必须添加登录。'
@@ -1667,8 +1663,27 @@
    if (!error && searchSum > 1) {
      error = '搜索组件与导航栏的搜索功能不可同时使用。'
    } else if (!error && swipes.length > 1) {
      error = `页面中不可同时使用多个滑动加载组件。(${swipes.join('、')})`
    } else if (!error && swipes.length > 0) {
      swipes.forEach(cell => {
        if (!error && cell.level > 2) {
          error = `不可在多层标签页中使用滑动加载组件。(${cell.name})`
        }
      })
      if (!error) {
        let levels = swipes.map(s => s.level)
        levels = Array.from(new Set(levels))
        if (levels.length > 1) {
          error = `不可在页面与标签页中同时使用滑动加载组件。(${swipes.map(s => s.name).join('、')})`
        }
      }
      if (!error) {
        let signs = swipes.map(s => s.sign)
        signs = Array.from(new Set(signs))
        if (signs.length !== swipes.length) {
          error = `页面中(或同一标签页中)不可同时使用多个滑动加载组件。(${swipes.map(s => s.name).join('、')})`
        }
      }
    }
    if (show && error) {
@@ -1921,7 +1936,7 @@
              <div className="pc-setting-tools">
                <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
                  {/* 基本信息 */}
                  <Panel header={dict['mob.basemsg']} forceRender className="basedata" key="basedata">
                  <Panel header="基本信息" forceRender className="basedata" key="basedata">
                    {/* 菜单信息 */}
                    {config ? <MenuForm
                      dict={dict}
src/views/pcdesign/index.jsx
@@ -25,7 +25,6 @@
const MenuForm = asyncComponent(() => import('./menuform'))
const Transfer = asyncComponent(() => import('@/pc/transfer'))
const PopviewController = asyncComponent(() => import('@/menu/popview'))
const Versions = asyncComponent(() => import('@/menu/versions'))
const MenuShell = asyncComponent(() => import('@/pc/menushell'))
const ViewNodes = asyncComponent(() => import('@/menu/viewnodes'))
@@ -45,15 +44,10 @@
const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
sessionStorage.setItem('isEditState', 'true')
sessionStorage.setItem('editMenuType', 'menu') // 编辑菜单类型
sessionStorage.setItem('appType', 'pc')        // 应用类型
sessionStorage.setItem('typename', 'pc')
document.body.className = ''
window.GLOB.UserComponentMap = new Map() // 缓存用户自定义组件
window.GLOB.TabsMap = new Map()          // 缓存用户操作的标签页
window.GLOB.CacheIndependent = new Map()
window.GLOB.urlFields = []               // url变量
window.GLOB.customMenu = null            // 保存菜单信息
const memberLevel = Utils.getMemberLevel()
@@ -67,13 +61,10 @@
    MenuNo: '',
    delButtons: [],
    copyButtons: [],
    thawButtons: [],
    activeKey: 'basedata',
    menuloading: false,
    oriConfig: null,
    config: null,
    popBtn: null,             // 弹窗标签页
    visible: false,
    customComponents: [],
    settingshow: sessionStorage.getItem('settingshow') !== 'false',
    controlshow: sessionStorage.getItem('controlshow') !== 'false',
@@ -84,6 +75,15 @@
  UNSAFE_componentWillMount() {
    if (memberLevel < 30) return
    sessionStorage.setItem('editMenuType', 'menu') // 编辑菜单类型
    window.GLOB.UserComponentMap = new Map() // 缓存用户自定义组件
    window.GLOB.TabsMap = new Map()          // 缓存用户操作的标签页
    window.GLOB.CacheIndependent = new Map()
    window.GLOB.urlFields = []               // url变量
    window.GLOB.customMenu = null            // 保存菜单信息
    try {
      let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
@@ -133,7 +133,6 @@
    }
    MKEmitter.addListener('delButtons', this.delButtons)
    MKEmitter.addListener('modalStatus', this.modalStatus)
    MKEmitter.addListener('thawButtons', this.thawButtons)
    MKEmitter.addListener('copyButtons', this.copyButtons)
    MKEmitter.addListener('changePopview', this.initPopview)
    MKEmitter.addListener('changeEditMenu', this.changeEditMenu)
@@ -141,9 +140,17 @@
    MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
    MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent)
    setTimeout(() => {
      this.updateCustomComponent()
      if (sessionStorage.getItem('app_custom_components')) {
        let list = sessionStorage.getItem('app_custom_components')
        list = JSON.parse(list)
        this.setCustomComponent(list)
      } else {
        this.updateCustomComponent()
      }
      this.getAppPictures()
      this.getSmStemp()
      this.getRoleFields()
      setGLOBFuncs()
    }, 1000)
@@ -200,7 +207,6 @@
    }
    MKEmitter.removeListener('delButtons', this.delButtons)
    MKEmitter.removeListener('modalStatus', this.modalStatus)
    MKEmitter.removeListener('thawButtons', this.thawButtons)
    MKEmitter.removeListener('copyButtons', this.copyButtons)
    MKEmitter.removeListener('changePopview', this.initPopview)
    MKEmitter.removeListener('changeEditMenu', this.changeEditMenu)
@@ -214,8 +220,6 @@
  }
  triggerMenuSave = () => {
    if (this.state.visible) return
    this.submitConfig()
  }
@@ -238,7 +242,7 @@
      type: 'view'
    }
    param.MenuNo = menu.MenuNo || ''
    // param.MenuNo = menu.MenuNo || ''
    param.MenuName = menu.MenuName || ''
    param = window.btoa(window.encodeURIComponent(JSON.stringify(param)))
@@ -461,50 +465,46 @@
      typename: 'pc',
      typecharone: ''
    }).then(res => {
      let coms = []
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      } else if (res.cus_list && res.cus_list.length > 0) {
        res.cus_list.forEach(item => {
          let config = ''
          try {
            config = JSON.parse(window.decodeURIComponent(window.atob(item.long_param)))
          } catch (e) {
            console.warn('Parse Failure')
            config = ''
          }
          if (!config || !item.c_name) return
          window.GLOB.UserComponentMap.set(item.c_id, item.c_name)
          coms.push({
            uuid: item.c_id,
            type: 'menu',
            title: item.c_name,
            url: item.images,
            component: config.type,
            subtype: config.subtype,
            width: config.width || 24,
            config
          })
        })
      } else if (res.cus_list) {
        sessionStorage.setItem('app_custom_components', JSON.stringify(res.cus_list))
        this.setCustomComponent(res.cus_list)
      }
      this.setState({customComponents: coms})
      this.getRoleFields()
    })
  }
  handleBack = () => {
    this.setState({popBtn: null, delButtons: [], copyButtons: [], thawButtons: []}, () => {
      sessionStorage.setItem('editMenuType', 'menu')
      window.GLOB.customMenu = this.state.config
      this.setState({visible: false})
  setCustomComponent = (cus_list) => {
    let coms = []
    cus_list.forEach(item => {
      let config = ''
      try {
        config = JSON.parse(window.decodeURIComponent(window.atob(item.long_param)))
      } catch (e) {
        console.warn('Parse Failure')
        config = ''
      }
      if (!config || !item.c_name) return
      window.GLOB.UserComponentMap.set(item.c_id, item.c_name)
      coms.push({
        uuid: item.c_id,
        type: 'menu',
        title: item.c_name,
        url: item.images,
        component: config.type,
        subtype: config.subtype,
        config
      })
    })
    this.setState({customComponents: coms})
  }
  updateComponentStyle = (parentId, keys, style) => {
@@ -536,10 +536,6 @@
  copyButtons = (items) => {
    this.setState({copyButtons: [...this.state.copyButtons, ...items]})
  }
  thawButtons = (item) => {
    this.setState({thawButtons: [...this.state.thawButtons, item]})
  }
  initPopview = (card, btn) => {
    const { oriConfig, config } = this.state
@@ -553,12 +549,11 @@
      return
    }
    btn.config = fromJS(config).toJS()
    btn.component = card
    let _btn = fromJS(btn).toJS()
    _btn.MenuName = config.MenuName + '-' + card.name + '-' + btn.label
    _btn.ParentMenuID = config.uuid
    sessionStorage.setItem('editMenuType', 'popview') // 编辑弹窗标签
    this.setState({popBtn: btn, visible: true})
    this.props.history.push('/popdesign/' + window.btoa(window.encodeURIComponent((JSON.stringify(_btn)))))
  }
  closeView = () => {
@@ -640,7 +635,7 @@
            Template: 'webPage',
            enabled: false,
            MenuName: urlParam.MenuName || '',
            MenuNo: urlParam.MenuNo || '',
            MenuNo: '',
            tables: [],
            components: [],
            viewType: 'menu',
@@ -777,7 +772,7 @@
      config.MenuID = MenuId
      config.open_edition = ''
      config.MenuName = urlParam.MenuName || ''
      config.MenuNo = urlParam.MenuNo || ''
      config.MenuNo = ''
      let indeComs = []
      config.components.forEach(item => {
@@ -933,7 +928,6 @@
          item.action && item.action.forEach(btn => {
            if (btn.hidden === 'true') return
            this.checkBtn(btn)
            m.children.push({
              key: btn.uuid,
              title: btn.label,
@@ -947,7 +941,6 @@
              if (cell.eleType !== 'button') return
              if (cell.hidden === 'true') return
              this.checkBtn(cell)
              m.children.push({
                key: cell.uuid,
                title: cell.label,
@@ -960,7 +953,6 @@
              if (cell.eleType !== 'button') return
              if (cell.hidden === 'true') return
              this.checkBtn(cell)
              m.children.push({
                key: cell.uuid,
                title: cell.label,
@@ -976,7 +968,6 @@
              if (cell.eleType !== 'button') return
              if (cell.hidden === 'true') return
              this.checkBtn(cell)
              m.children.push({
                key: cell.uuid,
                title: cell.label,
@@ -991,7 +982,6 @@
            if (cell.eleType !== 'button') return
            if (cell.hidden === 'true') return
            this.checkBtn(cell)
            m.children.push({
              key: cell.uuid,
              title: cell.label,
@@ -1024,7 +1014,6 @@
          item.action && item.action.forEach(btn => {
            if (btn.hidden === 'true') return
            this.checkBtn(btn)
            m.children.push({
              key: btn.uuid,
              title: btn.label,
@@ -1038,7 +1027,6 @@
            col.elements.forEach(btn => {
              if (btn.hidden === 'true') return
              
              this.checkBtn(btn)
              m.children.push({
                key: btn.uuid,
                title: btn.label,
@@ -1071,26 +1059,6 @@
    }
    return nodes
  }
  checkBtn = (btn) => {
    if (['prompt', 'exec', 'pop'].includes(btn.OpenType) && btn.Ot === 'required' && btn.verify && btn.verify.scripts && btn.verify.scripts.length > 0) {
      let hascheck = false
      btn.verify.scripts.forEach(item => {
        if (item.status === 'false') return
        if (/\$check@|@check\$/ig.test(item.sql)) {
          hascheck = true
        }
      })
      if (hascheck) {
        notification.warning({
          top: 92,
          message: `可选择多行的按钮《${btn.label}》中 $check@ 或 @check$ 将不会生效!`,
          duration: 5
        })
      }
    }
  }
  getSubMenus = () => {
@@ -1209,7 +1177,7 @@
  }
  submitConfig = () => {
    const { delButtons, copyButtons, thawButtons } = this.state
    const { delButtons, copyButtons } = this.state
    let config = fromJS(this.state.config).toJS()
    if (!config.MenuName || !config.MenuNo || (config.cacheUseful === 'true' && !config.cacheTime)) {
@@ -1445,27 +1413,6 @@
          }
          return Api.getSystemConfig(_param)
        }
      }).then(res => { // 按钮解除冻结
        if (!res) return
        if (!res.status) {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
          return false
        } else if (!res.nonexec) { // 执行删除后刷新菜单列表
          this.getAppMenus()
        }
        if (thawButtons.length === 0) {
          return { status: true }
        } else {
          return Api.getSystemConfig({
            func: 'sPC_MainMenu_ReDel',
            MenuID: thawButtons.join(',')
          })
        }
      }).then(res => { // 页面保存
        if (!res) return
@@ -1604,7 +1551,6 @@
          this.setState({
            delButtons: [],
            copyButtons: [],
            thawButtons: [],
            menuloading: false
          })
          notification.success({
@@ -1883,13 +1829,13 @@
  }
  render () {
    const { localedict, loading, visible, popBtn, comloading, activeKey, settingshow, controlshow, dict, MenuId, config, menuloading, customComponents, eyeopen } = this.state
    const { localedict, loading, comloading, activeKey, settingshow, controlshow, dict, MenuId, config, menuloading, customComponents, eyeopen } = this.state
    return (
      <ConfigProvider locale={localedict}>
        <div className={'mk-pc-view '} id="mk-pc-design-view">
          {loading ? <Spin className="view-spin" size="large" /> : null}
          {!popBtn && !visible ? <DndProvider backend={HTML5Backend}>
          <DndProvider backend={HTML5Backend}>
            <div className={'menu-setting ' + (!settingshow ? 'hidden' : '')}>
              <div className="draw">
                {settingshow ? <DoubleLeftOutlined onClick={() => {sessionStorage.setItem('settingshow', 'false'); this.setState({settingshow: false})}}/> : null}
@@ -1898,7 +1844,7 @@
              <div className="pc-setting-tools">
                <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
                  {/* 基本信息 */}
                  <Panel header={dict['mob.basemsg']} key="basedata">
                  <Panel header="基本信息" key="basedata">
                    {/* 菜单信息 */}
                    {config ? <MenuForm
                      dict={dict}
@@ -1953,8 +1899,7 @@
            <div className={'menu-body menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
              {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
            </div>
          </DndProvider> : null}
          {popBtn && visible ? <PopviewController btn={popBtn} handleBack={this.handleBack}/> : null}
          </DndProvider>
          <StyleController />
          <StyleCombController />
          <ModalController />
src/views/popdesign/index.jsx
File was renamed from src/menu/popview/index.jsx
@@ -1,21 +1,21 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { DndProvider } from 'react-dnd'
import { is, fromJS } from 'immutable'
import moment from 'moment'
import HTML5Backend from 'react-dnd-html5-backend'
import { notification, Modal, Collapse, Card, Switch, Button } from 'antd'
import { ConfigProvider, notification, Modal, Collapse, Card, Switch, Button } from 'antd'
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/mob.js'
import enUS from '@/locales/en-US/mob.js'
import Utils, { setGLOBFuncs } from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
// import antdEnUS from 'antd/es/locale/en_US'
import antdZhCN from 'antd/es/locale/zh_CN'
import './index.scss'
const _locale = antdZhCN
const { Panel } = Collapse
const { confirm } = Modal
@@ -25,22 +25,22 @@
const SourceWrap = asyncComponent(() => import('@/menu/modulesource'))
const MenuShell = asyncComponent(() => import('@/menu/menushell'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const BgController = asyncComponent(() => import('@/menu/bgcontroller'))
const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
const PaddingController = asyncComponent(() => import('@/menu/padcontroller'))
const StyleCombControlButton = asyncComponent(() => import('@/menu/stylecombcontrolbutton'))
const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller'))
const StyleCombController = asyncComponent(() => import('@/menu/stylecombcontroller'))
sessionStorage.setItem('isEditState', 'true')
class MenuDesign extends Component {
  static propTpyes = {
    btn: PropTypes.object,
    handleBack: PropTypes.func
  }
document.body.className = ''
class PopViewDesign extends Component {
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    btn: null,
    MenuId: '',
    delButtons: [],
    activeKey: 'basedata',
@@ -53,13 +53,29 @@
  }
  UNSAFE_componentWillMount() {
    const { btn } = this.props
    sessionStorage.setItem('editMenuType', 'popview')
    this.setState({
      MenuId: btn.uuid,
    }, () => {
      this.getMenuParam()
    })
    window.GLOB.UserComponentMap = new Map() // 缓存用户自定义组件
    window.GLOB.TabsMap = new Map()          // 缓存用户操作的标签页
    window.GLOB.urlFields = []               // url变量
    window.GLOB.customMenu = null            // 保存菜单信息
    try {
      let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
      this.setState({
        btn: param,
        MenuId: param.uuid,
      }, () => {
        this.getMenuParam()
      })
    } catch (e) {
      notification.warning({
        top: 92,
        message: '菜单信息解析错误!',
        duration: 5
      })
    }
  }
  componentDidMount () {
@@ -67,7 +83,57 @@
    MKEmitter.addListener('triggerMenuSave', this.submitConfig)
    MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
    MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent)
    this.updateCustomComponent()
    setTimeout(() => {
      if (sessionStorage.getItem('app_custom_components')) {
        let list = sessionStorage.getItem('app_custom_components')
        list = JSON.parse(list)
        this.setCustomComponent(list)
      } else {
        this.updateCustomComponent()
      }
      setGLOBFuncs()
    }, 1000)
    document.onkeydown = (event) => {
      let e = event || window.event
      let keyCode = e.keyCode || e.which || e.charCode
      let preKey = ''
      if (e.ctrlKey) {
        preKey = 'ctrl'
      }
      if (e.shiftKey) {
        preKey = 'shift'
      } else if (e.altKey) {
        preKey = 'alt'
      }
      if (!preKey || !keyCode) return
      let _shortcut = `${preKey}+${keyCode}`
      if (_shortcut === 'ctrl+83') {
        if (this.state.modalStatus) {
          notification.warning({
            top: 92,
            message: '请保存' + this.state.modalStatus,
            duration: 5
          })
          return false
        }
        let node = document.getElementById('save-modal-config')
        if (!node) {
          node = document.getElementById('save-pop-config')
        }
        if (node) {
          node.click()
        }
        return false
      }
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -93,34 +159,46 @@
      typename: sessionStorage.getItem('appType'),
      typecharone: ''
    }).then(res => {
      let coms = []
      if (res.cus_list && res.cus_list.length > 0) {
        res.cus_list.forEach(item => {
          let config = ''
          try {
            config = JSON.parse(window.decodeURIComponent(window.atob(item.long_param)))
          } catch (e) {
            console.warn('Parse Failure')
            config = ''
          }
          if (!config || !item.c_name) return
          window.GLOB.UserComponentMap.set(item.c_id, item.c_name)
          coms.push({
            uuid: item.c_id,
            type: 'menu',
            title: item.c_name,
            url: item.images,
            component: config.type,
            subtype: config.subtype,
            config
          })
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      } else if (res.cus_list) {
        sessionStorage.setItem('app_custom_components', JSON.stringify(res.cus_list))
        this.setCustomComponent(res.cus_list)
      }
      this.setState({customComponents: coms})
    })
  }
  setCustomComponent = (cus_list) => {
    let coms = []
    cus_list.forEach(item => {
      let config = ''
      try {
        config = JSON.parse(window.decodeURIComponent(window.atob(item.long_param)))
      } catch (e) {
        console.warn('Parse Failure')
        config = ''
      }
      if (!config || !item.c_name) return
      window.GLOB.UserComponentMap.set(item.c_id, item.c_name)
      coms.push({
        uuid: item.c_id,
        type: 'menu',
        title: item.c_name,
        url: item.images,
        component: config.type,
        subtype: config.subtype,
        config
      })
    })
    this.setState({customComponents: coms})
  }
  updateComponentStyle = (parentId, keys, style) => {
@@ -153,29 +231,26 @@
    const { oriConfig, config } = this.state
    if (!config) {
      this.props.handleBack()
      window.history.back()
      return
    }
    const _this = this
    if (!is(fromJS(oriConfig), fromJS(config))) {
      confirm({
        title: '配置已修改,放弃保存吗?',
        content: '',
        onOk() {
          _this.props.handleBack()
          window.history.back()
        },
        onCancel() {}
      })
    } else {
      this.props.handleBack()
      window.history.back()
    }
  }
  getMenuParam = () => {
    const { btn } = this.props
    const { MenuId } = this.state
    const { MenuId, btn } = this.state
    let param = {
      func: 'sPC_Get_LongParam',
@@ -205,7 +280,7 @@
            MenuID: MenuId,
            Template: 'CustomPage',
            enabled: false,
            MenuName: btn.config.MenuName + '-' + btn.label,
            MenuName: btn.MenuName,
            MenuNo: '',
            tables: [],
            components: [],
@@ -258,7 +333,6 @@
              delButtons.push(btn.uuid)
              return
            }
            this.checkBtn(btn)
            buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
            _sort++
          })
@@ -269,7 +343,6 @@
                delButtons.push(cell.uuid)
                return
              }
              this.checkBtn(cell)
              buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
              _sort++
            })
@@ -279,7 +352,6 @@
                delButtons.push(cell.uuid)
                return
              }
              this.checkBtn(cell)
              buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
              _sort++
            })
@@ -292,7 +364,6 @@
                delButtons.push(cell.uuid)
                return
              }
              this.checkBtn(cell)
              buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
              _sort++
            })
@@ -304,7 +375,6 @@
              delButtons.push(cell.uuid)
              return
            }
            this.checkBtn(cell)
            buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
            _sort++
          })
@@ -314,7 +384,6 @@
              delButtons.push(btn.uuid)
              return
            }
            this.checkBtn(btn)
            buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
            _sort++
          })
@@ -324,7 +393,6 @@
              delButtons.push(btn.uuid)
              return
            }
            this.checkBtn(btn)
            buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
            _sort++
          })
@@ -335,7 +403,6 @@
                delButtons.push(btn.uuid)
                return
              }
              this.checkBtn(btn)
              buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
              _sort++
            })
@@ -347,26 +414,6 @@
    traversal(config.components)
    return buttons
  }
  checkBtn = (btn) => {
    if (['prompt', 'exec', 'pop'].includes(btn.OpenType) && btn.Ot === 'required' && btn.verify && btn.verify.scripts && btn.verify.scripts.length > 0) {
      let hascheck = false
      btn.verify.scripts.forEach(item => {
        if (item.status === 'false') return
        if (/\$check@|@check\$/ig.test(item.sql)) {
          hascheck = true
        }
      })
      if (hascheck) {
        notification.warning({
          top: 92,
          message: `可选择多行的按钮《${btn.label}》中 $check@ 或 @check$ 将不会生效!`,
          duration: 5
        })
      }
    }
  }
  filterConfig = (components) => {
@@ -387,7 +434,7 @@
  }
  submitConfig = () => {
    const { btn } = this.props
    const { btn } = this.state
    let config = fromJS(this.state.config).toJS()
    if ((config.cacheUseful === 'true' && !config.cacheTime) || !config.MenuNo || !config.MenuName) {
@@ -410,15 +457,13 @@
        config.enabled = false
      }
      let _name = (btn.component.name ? btn.component.name + '-' : '') + btn.label
      let param = {
        func: 'sPC_ButtonParam_AddUpt',
        ParentID: btn.config.uuid,
        ParentID: btn.ParentMenuID,
        MenuID: config.uuid,
        MenuNo: config.MenuNo || '',
        Template: 'CustomPage',
        MenuName: _name,
        MenuName: config.MenuName,
        PageParam: JSON.stringify({Template: 'CustomPage'}),
        LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(config))),
        open_edition: config.open_edition
@@ -643,61 +688,62 @@
  }
  render () {
    const { btn } = this.props
    const { activeKey, comloading, dict, config, menuloading, customComponents, MenuId, eyeopen } = this.state
    const { activeKey, comloading, config, menuloading, customComponents, MenuId, eyeopen } = this.state
    return (
      <div className="pc-poper-view">
        <Header />
        <DndProvider backend={HTML5Backend}>
          <div className="menu-body">
            <div className="menu-setting">
              <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
                {/* 基本信息 */}
                <Panel header={dict['mob.basemsg']} key="basedata">
                  {/* 菜单信息 */}
                  {config ? <MenuForm dict={dict} config={config} btn={btn} updateConfig={this.updateConfig}/> : null}
                  {/* 表名添加 */}
                  {config ? <TableComponent config={config} updatetable={this.updatetable}/> : null}
                </Panel>
                {/* 组件添加 */}
                <Panel header={dict['mob.component']} key="component">
                  <SourceWrap MenuType="" />
                </Panel>
                {customComponents && customComponents.length ? <Panel header="自定义组件" key="cuscomponent">
                  <SourceWrap components={customComponents} MenuType="" />
                </Panel> : null}
                <Panel header={'页面背景'} key="background">
                  {config ? <BgController config={config} updateConfig={this.updateConfig} /> : null}
                </Panel>
                <Panel header={'页面内边距'} key="padding">
                  {config ? <PaddingController config={config} updateConfig={this.updateConfig} /> : null}
                </Panel>
              </Collapse>
      <ConfigProvider locale={_locale}>
        <div className="pc-poper-view">
          <Header />
          <DndProvider backend={HTML5Backend}>
            <div className="menu-body">
              <div className="menu-setting">
                <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
                  {/* 基本信息 */}
                  <Panel header="基本信息" key="basedata">
                    {/* 菜单信息 */}
                    {config ? <MenuForm config={config} updateConfig={this.updateConfig}/> : null}
                    {/* 表名添加 */}
                    {config ? <TableComponent config={config} updatetable={this.updatetable}/> : null}
                  </Panel>
                  {/* 组件添加 */}
                  <Panel header="组件" key="component">
                    <SourceWrap MenuType="" />
                  </Panel>
                  {customComponents && customComponents.length ? <Panel header="自定义组件" key="cuscomponent">
                    <SourceWrap components={customComponents} MenuType="" />
                  </Panel> : null}
                  <Panel header="页面样式" key="background">
                    {config ? <BgController config={config} updateConfig={this.updateConfig} /> : null}
                  </Panel>
                </Collapse>
              </div>
              <div className={'menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
                <Card title={
                  <div> {config && config.MenuName} </div>
                } bordered={false} extra={
                  <div>
                    <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button>
                    <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''} updateConfig={this.refreshConfig}/>
                    <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                    <StyleCombControlButton menu={config} />
                    <PasteController insert={this.insert} />
                    {config ? <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                    <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>保存</Button>
                    <Button type="default" onClick={this.closeView}>返回</Button>
                  </div>
                } style={{ width: '100%' }}>
                  {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
                </Card>
              </div>
            </div>
            <div className={'menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
              <Card title={
                <div> {config && config.MenuName} </div>
              } bordered={false} extra={
                <div>
                  <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button>
                  <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''} updateConfig={this.refreshConfig}/>
                  <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                  <StyleCombControlButton menu={config} />
                  <PasteController insert={this.insert} />
                  {config ? <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                  <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>{dict['mob.save']}</Button>
                  <Button type="default" onClick={this.closeView}>{dict['mob.return']}</Button>
                </div>
              } style={{ width: '100%' }}>
                {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
              </Card>
            </div>
          </div>
        </DndProvider>
      </div>
          </DndProvider>
          <StyleController />
          <StyleCombController />
          <ModalController />
        </div>
      </ConfigProvider>
    )
  }
}
export default MenuDesign
export default PopViewDesign
src/views/popdesign/index.scss
File was renamed from src/menu/popview/index.scss
@@ -10,6 +10,38 @@
      display: none;
    }
  }
  .component-name {
    position: absolute;
    z-index: 9;
    display: none;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    background: rgba(255, 255, 255, 0.9);
    border: 1px solid #1890ff;
    .center {
      position: absolute;
      font-size: 16px;
      left: 50%;
      top: 50%;
      color: #1890ff;
      transform: translate(-50%, -50%);
      max-width: 70%;
      .title {
        text-align: center;
      }
    }
    .error {
      text-align: center;
      color: red;
      display: block;
    }
    .waring {
      color: orange;
    }
  }
  
  >.menu-body {
    width: 100vw;
src/views/popdesign/menuform/index.jsx
File was renamed from src/menu/popview/menuform/index.jsx
@@ -7,8 +7,6 @@
class CustomMenuForm extends Component {
  static propTpyes = {
    dict: PropTypes.object, // 字典项
    btn: PropTypes.object,
    config: PropTypes.object,
    updateConfig: PropTypes.func
  }
@@ -41,7 +39,7 @@
  }
  render() {
    const { dict, config } = this.props
    const { config } = this.props
    const { getFieldDecorator } = this.props.form
    const formItemLayout = {
      labelCol: {
@@ -58,26 +56,26 @@
      <Form {...formItemLayout}>
        <Row>
        <Col span={24}>
            <Form.Item label={dict['mob.menu'] + dict['mob.name']}>
            <Form.Item label="菜单名称">
              {getFieldDecorator('MenuName', {
                initialValue: config.MenuName,
                rules: [
                  {
                    required: true,
                    message: dict['mob.required.input'] + dict['mob.menu'] + dict['mob.name'] + '!'
                    message: '请输入菜单名称!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" onChange={this.changeName}/>)}
            </Form.Item>
          </Col>
          <Col span={24}>
            <Form.Item label={dict['mob.menu'] + dict['mob.param']}>
            <Form.Item label="菜单参数">
              {getFieldDecorator('MenuNo', {
                initialValue: config.MenuNo,
                rules: [
                  {
                    required: true,
                    message: dict['mob.required.input'] + dict['mob.menu'] + dict['mob.param'] + '!'
                    message: '请输入菜单参数!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" onChange={this.changeNo}/>)}
@@ -119,7 +117,7 @@
                rules: [
                  {
                    required: true,
                    message: dict['mob.required.input'] + '时长!'
                    message: '请输入时长!'
                  }
                ]
              })(
src/views/popdesign/menuform/index.scss