king
2022-12-09 cb9ade2afd2a367ad767bc605ab7086c695dd010
2022-12-09
23 文件已重命名
551个文件已修改
16 文件已复制
133个文件已添加
38个文件已删除
90622 ■■■■■ 已修改文件
package-lock.json 1205 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/README.txt 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/admin.html 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/options.json 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cacheutils.js 317 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/direct.js 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 764 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/design.scss 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/main.scss 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/viewstyle.scss 95 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/img/newpage.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mobimg/guanzhu.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mobimg/indent.jfif 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mobimg/kapmap.jfif 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mobimg/mindmap.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mobimg/moblogin.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mobimg/share.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mobimg/simple-form.png 补丁 | 查看 | 原始文档 | blame | 历史
src/components/breadview/index.jsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/editor/index.jsx 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/encrypts/index.jsx 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/encrypts/index.scss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.jsx 470 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.scss 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/loginform.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/keyInterface/index.jsx 311 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/keyInterface/index.scss 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/mk-icon/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/mkIcon/index.jsx 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/mkIcon/index.scss 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/mkPicture/index.jsx 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/mkPicture/index.scss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/index.jsx 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/mkCheckbox/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/mkRadio/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/mkSelect/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/mkTable/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/styleInput/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/styleInput/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/qrcode/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/querylog/index.jsx 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/index.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tabview/index.jsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/thawmenu/index.jsx 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/thawmenu/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/components/video/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/video/index.scss 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index.js 65 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/mob.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/model.js 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/mob.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/model.js 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/bgcontroller/index.jsx 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/bgcontroller/index.scss 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/balcony/index.jsx 169 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/balcony/index.scss 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/balcony/options.jsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/dragaction/action.jsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/dragaction/card.jsx 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/dragaction/index.jsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/dragaction/index.scss 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/elementform/index.jsx 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/elementform/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/formconfig.jsx 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.jsx 359 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.scss 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/index.jsx 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/options.jsx 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardsimplecomponent/index.jsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardsimplecomponent/node-wrap/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardsimplecomponent/node-wrap/menus/columnform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardsimplecomponent/options.jsx 92 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.jsx 348 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.scss 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/options.jsx 100 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/prop-card/index.jsx 410 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/prop-card/index.scss 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/table-card/index.jsx 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/table-card/index.scss 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/data-card/index.jsx 217 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/data-card/index.scss 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/data-card/options.jsx 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/prop-card/index.jsx 289 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/prop-card/index.scss 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx 356 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-G6/chartcompile/index.jsx 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-G6/chartcompile/index.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-G6/index.jsx 1461 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-G6/index.scss 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/index.jsx 222 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/index.scss 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.jsx 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.scss 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-dashboard/chartcompile/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-dashboard/chartcompile/index.scss 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-dashboard/index.jsx 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-dashboard/index.scss 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/chartcompile/index.jsx 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/chartcompile/index.scss 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/index.jsx 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/index.scss 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-scatter/chartcompile/index.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-scatter/chartcompile/index.scss 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-scatter/index.jsx 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-scatter/index.scss 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/chart-custom/chartcompile/formconfig.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/chart-custom/chartcompile/index.jsx 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/chart-custom/chartcompile/index.scss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/chart-custom/index.jsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/chart-custom/index.scss 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/code/sandbox/codecontent/index.jsx 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/code/sandbox/editorcode/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/code/sandbox/index.jsx 109 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/code/sandbox/options.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/editor/braft-editor/editorcontent/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/editor/braft-editor/index.jsx 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragtitle/card.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragtitle/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragtitle/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragtitle/options.jsx 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/actionform/index.jsx 105 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/actionform/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/formconfig.jsx 135 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/index.jsx 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/index.scss 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/index.jsx 725 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/index.scss 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/options.jsx 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/step-form/index.jsx 282 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/step-form/index.scss 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/step-form/options.jsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/tab-form/index.jsx 308 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/tab-form/index.scss 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/groupcomponents/card.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/groupcomponents/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/normal-group/index.jsx 71 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/normal-group/options.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/paste/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/iframe/index.jsx 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/iframe/index.scss 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/iframe/options.jsx 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/module/voucher/index.jsx 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/module/voucher/options.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/dategroup/index.scss 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/dragsearch/card.jsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/dragsearch/index.jsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/index.jsx 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/index.scss 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/options.jsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/actionform/index.jsx 322 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/actionform/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/dragaction/card.jsx 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/dragaction/index.jsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/formconfig.jsx 1122 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/index.jsx 269 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/index.scss 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/clockcomponent/index.jsx 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/clockcomponent/index.scss 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/clockcomponent/settingform/index.jsx 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/copycomponent/index.jsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/logcomponent/index.jsx 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/logcomponent/index.scss 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/markcomponent/index.jsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/markcomponent/markform/index.jsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/normalform/index.jsx 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/normalform/index.scss 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/normalheader/index.jsx 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/normalheader/index.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/pastebasetable/index.jsx 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/pastebasetable/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/pastecomponent/index.jsx 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/searchcomponent/dragsearch/card.jsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/searchcomponent/dragsearch/index.jsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/searchcomponent/index.jsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/sourcecomponent/index.jsx 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/sourcecomponent/index.scss 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/sourcecomponent/inputform/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/usercomponent/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/usercomponent/settingform/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/editColumn/formconfig.jsx 424 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/editColumn/index.jsx 397 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/editColumn/index.scss 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/index.jsx 653 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/index.scss 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/index.jsx 382 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/index.scss 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/options.jsx 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/editColumn/index.jsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/index.jsx 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/index.scss 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/index.jsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/uniqueform/index.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/index.jsx 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/index.scss 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/options.jsx 84 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/index.jsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/index.jsx 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/index.scss 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/index.jsx 306 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/index.scss 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/options.jsx 90 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/dragabletabs.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/index.jsx 147 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/options.jsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/paste/index.jsx 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/tabcomponents/card.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/tabcomponents/index.jsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/table-tabs/dragabletabs.jsx 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/table-tabs/index.jsx 271 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/table-tabs/index.scss 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/table-tabs/options.jsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/timeline/normal-timeline/index.jsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/timeline/normal-timeline/index.scss 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/timeline/normal-timeline/options.jsx 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tree/antd-tree/index.jsx 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tree/antd-tree/options.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/index.jsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/columnform/index.jsx 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/customscript/index.jsx 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/index.jsx 349 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/index.scss 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/settingform/index.jsx 317 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/utils.jsx 59 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/menushell/card.jsx 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/menushell/index.jsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/menushell/index.scss 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/controller.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.jsx 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.scss 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modulecell/dragsource/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modulecell/dragsource/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modulecell/index.jsx 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modulecell/index.scss 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modulesource/option.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/padcontroller/index.jsx 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/padcontroller/index.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/pastecontroller/index.jsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/picturecontroller/editform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/picturecontroller/index.jsx 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/picturecontroller/index.scss 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/popview/index.jsx 686 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/replaceField/index.jsx 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/replaceField/settingform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecombcontrolbutton/index.jsx 171 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecombcontrolbutton/index.scss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecombcontroller/index.jsx 112 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecombcontroller/styleInput/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecombcontroller/styleInput/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecontroller/index.jsx 181 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecontroller/styleInput/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecontroller/styleInput/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/sysinterface/index.jsx 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/sysinterface/index.scss 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/sysinterface/settingform/baseform/index.jsx 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/sysinterface/settingform/baseform/index.scss 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/sysinterface/settingform/index.jsx 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/sysinterface/settingform/index.scss 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/sysinterface/settingform/simplescript/index.jsx 451 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/sysinterface/settingform/simplescript/index.scss 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/sysinterface/settingform/utils.jsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/tablenodes/index.jsx 493 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/tablenodes/index.scss 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/tableshell/card.jsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/tableshell/index.jsx 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/tableshell/index.scss 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/transfer/index.jsx 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/transfer/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/urlfieldcomponent/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/versions/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/viewnodes/index.jsx 344 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/viewnodes/index.scss 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/colorsketch/index.jsx 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/formdragelement/card.jsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/formdragelement/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/formdragelement/index.scss 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/menubar/common-menubar/index.jsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/menubar/normal-menubar/index.jsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/menubar/normal-menubar/index.scss 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/menubar/normal-menubar/menucomponent/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/menubar/normal-menubar/menucomponent/options.jsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/navbar/normal-navbar/index.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/navbar/normal-navbar/index.scss 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/navbar/normal-navbar/menus/drags/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/official/index.jsx 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/official/index.scss 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/official/options.jsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/search/single-search/index.jsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/sharecode/index.jsx 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/sharecode/index.scss 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/sharecode/options.jsx 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/antv-tabs/dragabletabs.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/antv-tabs/index.jsx 176 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/antv-tabs/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/antv-tabs/options.jsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/tabcomponents/card.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/tabcomponents/index.jsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/topbar/normal-navbar/index.jsx 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/topbar/normal-navbar/index.scss 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/topbar/normal-navbar/options.jsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/mobshell/card.jsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/mobshell/index.jsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modalconfig/controller.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modalconfig/index.jsx 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modalconfig/index.scss 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modalconfig/source.jsx 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modulesource/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modulesource/option.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/searchconfig/groupdragelement/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/searchconfig/index.jsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/searchconfig/index.scss 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/searchconfig/searchdragelement/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/searchconfig/settingform/index.jsx 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/bgcontroller/index.jsx 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/normal-login/index.jsx 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/normal-login/index.scss 93 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/normal-login/loginform.jsx 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/normal-login/options.jsx 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/normal-login/signform.jsx 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/index.jsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/index.scss 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/linksetting/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/menusetting/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | 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/createview/index.jsx 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/createview/settingform/index.jsx 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/menushell/card.jsx 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/menushell/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/menushell/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/modulesource/option.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/quotecomponent/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/quotecomponent/settingform/index.jsx 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/setupProxy.js 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/action-type.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/action.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/reducer.js 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/basetable/index.jsx 630 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/basetable/index.scss 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/calendar/index.jsx 81 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx 248 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/balcony/index.jsx 194 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardItem/index.jsx 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardcellList/asyncButtonComponent.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardcellList/index.jsx 1402 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardcellList/index.scss 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/data-card/index.jsx 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/data-card/index.scss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/prop-card/index.jsx 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/table-card/index.jsx 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/table-card/index.scss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/cardItem/index.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/data-card/index.jsx 214 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/data-card/index.scss 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/prop-card/index.jsx 245 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/prop-card/index.scss 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-G6/index.jsx 1573 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-G6/index.scss 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-bar-line/asyncButtonComponent.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-bar-line/index.jsx 281 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-bar-line/index.scss 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-dashboard/index.jsx 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-dashboard/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-pie/index.jsx 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-pie/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-scatter/asyncButtonComponent.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-scatter/index.jsx 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-scatter/index.scss 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/custom-chart/index.jsx 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/custom-chart/index.scss 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/code/sand-box/index.jsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/editor/braft-editor/index.jsx 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/form/simple-form/index.jsx 325 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/form/simple-form/index.scss 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/form/step-form/index.jsx 201 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/form/step-form/index.scss 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/form/tab-form/index.jsx 165 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/form/tab-form/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/group/normal-group/index.jsx 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/group/normal-group/index.scss 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/iframe/index.jsx 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/iframe/index.scss 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/interfaces/index.jsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/interfaces/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/interfaces/interItem/index.jsx 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/interfaces/interItem/index.scss 补丁 | 查看 | 原始文档 | 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/module/voucher/index.jsx 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.jsx 322 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.scss 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalheader/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalheader/index.scss 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/tabtransfer/index.jsx 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/base-table/index.jsx 616 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/base-table/index.scss 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/index.jsx 126 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/normalTable/index.jsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/normalTable/index.scss 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/normal-table/index.jsx 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/normal-table/index.scss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/tabs/antv-tabs/index.jsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/timeline/normal-timeline/index.jsx 216 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/timeline/normal-timeline/index.scss 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/tree/antd-tree/index.jsx 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/tree/antd-tree/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 1047 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/popview/index.jsx 1022 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/popview/index.scss 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/debugtable/index.jsx 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/debugtable/index.scss 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/formtab/actionList/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/formtab/formgroup/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/formtab/index.jsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/home/defaulthome/index.jsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/home/defaulthome/index.scss 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/home/index.jsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/rolemanage/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/rolemanage/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/actionList/index.jsx 312 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/actionList/index.scss 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/config.jsx 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/index.jsx 349 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/index.scss 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtable/index.jsx 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtabtable/index.jsx 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/treepage/index.jsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/actionList/index.jsx 817 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/actionList/index.scss 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/config.jsx 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/index.jsx 521 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/index.scss 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/subtabtable/index.jsx 468 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/subtabtable/index.scss 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/asyncButtonComponent.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/changeuserbutton/index.jsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/excelInbutton/excelin/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/excelInbutton/index.jsx 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/exceloutbutton/index.jsx 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/funcMegvii/index.jsx 546 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/funcMegvii/index.scss 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/funcMegvii/mock.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/funczip/index.jsx 441 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/funczip/index.scss 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/funczip/mock.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/index.jsx 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/newpagebutton/index.jsx 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/normalbutton/index.jsx 1692 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/popupbutton/index.jsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/popupbutton/index.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/printbutton/index.jsx 642 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/tabbutton/index.jsx 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/automatic/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/cardcomponent/asyncButtonComponent.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/cardcomponent/index.jsx 65 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/cardcomponent/index.scss 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/chartcomponent/asyncButtonComponent.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/chartcomponent/index.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/fileupload-pice/index.jsx 491 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/fileupload-pice/index.scss 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/fileupload/index.jsx 282 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/fileupload/index.scss 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.jsx 307 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.scss 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkCascader/data.json 408 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkCascader/index.jsx 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkCascader/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkCheckCard/index.jsx 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkCheckCard/index.scss 172 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkColor/index.jsx 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkDatePicker/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkFormula/index.jsx 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkFormula/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkInput/index.jsx 77 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkNumberInput/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkSelect/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkTextArea/index.jsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/normalTable/index.jsx 248 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/normalTable/index.scss 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/pageMessage/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/settingcomponent/editTable/index.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/settingcomponent/index.jsx 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/settingcomponent/index.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/tablenodes/index.jsx 451 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/tablenodes/index.scss 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/advanceform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/advanceform/index.scss 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/dategroup/index.scss 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/index.jsx 289 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/index.scss 68 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/calendarconfig/calcomponent/calendarform/index.jsx 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/calendarconfig/calcomponent/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/calendarconfig/index.jsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/calendarconfig/index.scss 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/calendarconfig/source.jsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/calendarconfig/tabcomponent/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/calendarconfig/tabcomponent/tabform/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 360 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.scss 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/menuform/index.jsx 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/source.jsx 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/updatetable/index.jsx 1123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/updatetable/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/actionform/index.jsx 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/dragelement/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/groupform/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.jsx 425 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.scss 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/settingform/index.jsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/source.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/menuconfig/editfirstmenu/index.jsx 411 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/menuconfig/editfirstmenu/index.scss 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/menuconfig/editsecmenu/index.jsx 463 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/menuconfig/editsecmenu/index.scss 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/menuconfig/editthdmenu/index.jsx 980 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/menuconfig/editthdmenu/index.scss 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/menuconfig/menuelement/card.jsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/menuconfig/menuform/index.scss 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/checkCard/index.jsx 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/checkCard/index.scss 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/card.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/index.jsx 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/index.scss 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.jsx 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.scss 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/menuform/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/settingform/index.jsx 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/settingform/index.scss 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/source.jsx 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/actionform/index.jsx 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/actionform/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/dragaction/card.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/dragaction/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/index.jsx 122 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/index.scss 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/columnform/index.jsx 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/uniqueform/index.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/columnform/index.jsx 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx 354 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/datasource/index.jsx 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/datasource/index.scss 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx 754 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.scss 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx 244 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifymegvii/index.jsx 248 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifymegvii/index.scss 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx 141 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/carddetailform/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/dragdetail/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/index.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/chartcomponent/chartcompile/index.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/chartcomponent/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/chartgroupcomponent/chartform/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/chartgroupcomponent/dragchartview/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/chartgroupcomponent/index.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/colspanform/index.jsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/columnform/index.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/dragcolumn/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/gridbtnform/index.jsx 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/index.jsx 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/markcolumn/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/markcolumn/markform/index.jsx 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/fieldscomponent/editcard/index.jsx 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/fieldscomponent/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/dategroup/index.scss 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/index.jsx 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/index.scss 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/searchform/index.jsx 75 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/searchform/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/settingform/index.jsx 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/settingform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/index.scss 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/verifycard/columnform/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/verifycard/index.jsx 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.jsx 303 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.scss 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/index.jsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/index.scss 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx 1078 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/datasource/index.scss 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/index.jsx 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/index.scss 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/utils.jsx 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/tablecomponent/index.jsx 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/tablecomponent/index.scss 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/tabscomponent/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/tabscomponent/tabdragelement/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/tabscomponent/tabdragelement/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/tabscomponent/tabform/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/treesettingcomponent/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/treesettingcomponent/index.scss 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/treesettingcomponent/settingform/datasource/index.jsx 634 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/treesettingcomponent/settingform/datasource/index.scss 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/index.jsx 112 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/index.scss 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/menuform/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/source.jsx 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/treepageconfig/index.jsx 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/treepageconfig/index.scss 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/treepageconfig/source.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/codemirror/index.jsx 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/codemirror/index.scss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/createfunc/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/createinterface/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/createinterface/mutilform/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/customscript/index.jsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editTable/index.jsx 63 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editcard/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editcomponent/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 1189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/menuform/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/datatable/index.jsx 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/datatable/index.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/fieldtable/index.jsx 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.jsx 232 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/pasteform/index.jsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/unattended/index.jsx 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/unattended/settingform/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/baseform/index.jsx 464 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/baseform/index.scss 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/billcodeform/index.jsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/callbackcustomscript/index.jsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/contrastform/index.jsx 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/customform/index.jsx 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/customscript/index.jsx 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 526 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.scss 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/uniqueform/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/voucherform/index.jsx 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/asyncComponent.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/asyncIconComponent.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/asyncLoadComponent.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/asyncSpinComponent.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/option.js 59 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/sqlFormatter-origin.js 3381 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/sqlFormatter.js 3387 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/timer-task.js 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-custom.js 694 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-datamanage.js 309 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-update.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 313 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/appcheck/index.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/appmanage/index.jsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/appmanage/scriptform/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/appmanage/scriptform/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/appmanage/submutilform/index.jsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/appmanage/submutilform/index.scss 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basedesign/index.jsx 244 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basedesign/index.scss 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/billprint/index.jsx 349 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/billprint/index.scss 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/editfirstmenu/dragelement/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/editfirstmenu/dragelement/index.jsx 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/editfirstmenu/dragelement/index.scss 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/editfirstmenu/dragelement/itemtypes.js 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/editfirstmenu/index.jsx 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/editfirstmenu/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/editfirstmenu/menuform/index.jsx 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/editfirstmenu/menuform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/index.jsx 393 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/index.scss 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/versions/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/index.scss 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/editsecmenu/index.jsx 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/editsecmenu/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/editthdmenu/index.jsx 316 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/editthdmenu/index.scss 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/index.jsx 444 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/index.scss 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/menuelement/card.jsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/menuelement/index.jsx 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/menuelement/index.scss 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/menuelement/itemtypes.js 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/menuform/index.jsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/menuform/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/thdmenuform/index.jsx 59 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/thdmenuform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/thdmenuplus/index.jsx 369 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/thdmenuplus/index.scss 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/thdmenuplus/preview/index.jsx 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/thdmenuplus/preview/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/views/imdesign/index.jsx 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/imdesign/index.scss 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/imdesign/menuform/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/interface/header/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/interface/history/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/interface/workspace/request/index.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 182 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/logincodeform.jsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/loginform.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/main/index.jsx 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mainparams/index.jsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mainparams/index.scss 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/homeform/index.jsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 1000 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.scss 142 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/menuform/index.jsx 103 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/popview/index.jsx 297 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/popview/index.scss 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/popview/menuform/index.jsx 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/popview/menuform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/printmenuform/index.jsx 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/index.jsx 1148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/index.scss 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/menuform/index.jsx 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/menuform/index.scss 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pay/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.jsx 1433 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.scss 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/menuform/index.jsx 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/printTemplate/mutilform/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/printTemplate/option.js 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/printTemplate/print.js 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/rolemanage/index.jsx 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/sso/index.jsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemfunc/header/index.jsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemfunc/header/index.scss 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemfunc/index.jsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemfunc/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemfunc/sidemenu/config.jsx 128 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemfunc/sidemenu/index.jsx 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemfunc/sidemenu/index.scss 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemproc/index.jsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemproc/index.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemproc/proc/index.jsx 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemproc/proc/index.scss 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/index.jsx 837 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/index.scss 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/menuform/index.jsx 369 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/menuform/index.scss 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/popview/index.jsx 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/popview/index.scss 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/source.jsx 253 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/tablesource/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/tablesource/index.scss 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -4,15 +4,6 @@
  "lockfileVersion": 1,
  "requires": true,
  "dependencies": {
    "@ahooksjs/use-request": {
      "version": "2.8.15",
      "resolved": "https://registry.npmjs.org/@ahooksjs/use-request/-/use-request-2.8.15.tgz",
      "integrity": "sha512-xhVaM4fyIiAMdVFuuU5i3CFUdFa/IblF+fvITVMFaUEO3w/V5tVCAF6WIA3T03n1/RPuzRkA7Ao1PFtSGtGelw==",
      "requires": {
        "lodash.debounce": "^4.0.8",
        "lodash.throttle": "^4.1.1"
      }
    },
    "@ant-design/colors": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-3.2.2.tgz",
@@ -106,6 +97,22 @@
      "requires": {
        "@antv/util": "~2.0.0",
        "tslib": "^1.10.0"
      }
    },
    "@antv/algorithm": {
      "version": "0.1.23",
      "resolved": "https://registry.npmjs.org/@antv/algorithm/-/algorithm-0.1.23.tgz",
      "integrity": "sha512-ncAfXwpO9angkGlZ/4LYsFk+T2hvQI6A+mEEGMslj8wF7ddPdtZ+DK3KFbhfJvQ4iz9Z44sJfdJ/fybwt0g0kA==",
      "requires": {
        "@antv/util": "^2.0.13",
        "tslib": "^2.0.0"
      },
      "dependencies": {
        "tslib": {
          "version": "2.4.0",
          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
          "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
        }
      }
    },
    "@antv/attr": {
@@ -309,6 +316,55 @@
        }
      }
    },
    "@antv/g-webgpu": {
      "version": "0.5.5",
      "resolved": "https://registry.npmjs.org/@antv/g-webgpu/-/g-webgpu-0.5.5.tgz",
      "integrity": "sha512-TxtBniINFq1jFGEPo46xjJfrbJbUqkFd5wmsRs3tcg/7J7xoldOP1kEadpI3AJG9knMYdE92VpILw1VPd6DgzQ==",
      "requires": {
        "@antv/g-webgpu-core": "^0.5.5",
        "@antv/g-webgpu-engine": "^0.5.5",
        "@webgpu/types": "^0.0.31",
        "gl-matrix": "^3.1.0",
        "gl-vec2": "^1.3.0",
        "hammerjs": "^2.0.8",
        "inversify": "^5.0.1",
        "inversify-inject-decorators": "^3.1.0",
        "polyline-miter-util": "^1.0.1",
        "polyline-normals": "^2.0.2",
        "probe.gl": "^3.1.1",
        "reflect-metadata": "^0.1.13"
      }
    },
    "@antv/g-webgpu-core": {
      "version": "0.5.6",
      "resolved": "https://registry.npmjs.org/@antv/g-webgpu-core/-/g-webgpu-core-0.5.6.tgz",
      "integrity": "sha512-DPiH3GkAUiT0Q+LAKeImpI+IOQ/gP2w6HstYKivpFIpBPIvZ/9equM3icVrn1iDfDkZANVXQ1PppcO3xBv1ZTw==",
      "requires": {
        "eventemitter3": "^4.0.0",
        "gl-matrix": "^3.1.0",
        "inversify": "^5.0.1",
        "inversify-inject-decorators": "^3.1.0",
        "probe.gl": "^3.1.1",
        "reflect-metadata": "^0.1.13"
      }
    },
    "@antv/g-webgpu-engine": {
      "version": "0.5.6",
      "resolved": "https://registry.npmjs.org/@antv/g-webgpu-engine/-/g-webgpu-engine-0.5.6.tgz",
      "integrity": "sha512-D311qYUefdEFwLayutIHqucrAY3cAGH3BdnXS37nq+0nsglrHcNP0Ab1YTinn9RihLoY3yXFTLzrYkJHJbZXDg==",
      "requires": {
        "@antv/g-webgpu-core": "^0.5.6",
        "@webgpu/glslang": "^0.0.15",
        "@webgpu/types": "^0.0.31",
        "gl-matrix": "^3.1.0",
        "hammerjs": "^2.0.8",
        "inversify": "^5.0.1",
        "inversify-inject-decorators": "^3.1.0",
        "probe.gl": "^3.1.1",
        "reflect-metadata": "^0.1.13",
        "regl": "^1.3.11"
      }
    },
    "@antv/g2": {
      "version": "4.1.34",
      "resolved": "https://registry.npmjs.org/@antv/g2/-/g2-4.1.34.tgz",
@@ -338,12 +394,151 @@
        }
      }
    },
    "@antv/g6": {
      "version": "4.6.4",
      "resolved": "https://registry.npmjs.org/@antv/g6/-/g6-4.6.4.tgz",
      "integrity": "sha512-8xU96NISJ7G3Gwo6m1BTtqzfBeRd23BWcLDIpwX4v1KoE3NMHZlJkUaNvnKsoeoEoLNCDYBvTfBfEwV4C5gWfw==",
      "requires": {
        "@antv/g6-pc": "0.6.4"
      }
    },
    "@antv/g6-core": {
      "version": "0.6.4",
      "resolved": "https://registry.npmjs.org/@antv/g6-core/-/g6-core-0.6.4.tgz",
      "integrity": "sha512-8JYIZME7zaQJImlPOatmlTe/tKPxRaq8/wV2f61/7mfKON3LF9kEVvTrpJexMnXoCBuM+puxx3DbiPb64gL4LQ==",
      "requires": {
        "@antv/algorithm": "^0.1.8",
        "@antv/dom-util": "^2.0.1",
        "@antv/event-emitter": "~0.1.0",
        "@antv/g-base": "^0.5.1",
        "@antv/g-math": "^0.1.1",
        "@antv/matrix-util": "^3.1.0-beta.3",
        "@antv/path-util": "^2.0.3",
        "@antv/util": "~2.0.5",
        "ml-matrix": "^6.5.0",
        "tslib": "^2.1.0"
      },
      "dependencies": {
        "tslib": {
          "version": "2.4.0",
          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
          "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
        }
      }
    },
    "@antv/g6-element": {
      "version": "0.6.4",
      "resolved": "https://registry.npmjs.org/@antv/g6-element/-/g6-element-0.6.4.tgz",
      "integrity": "sha512-9wKogi6LnA4IoiVEWv8HmvHgHOXzbT73jDi4QrdSWjrttu7cyR2wQeKRYDp2lL2OPkHzzuNcI+ULQxbLKl3Oqg==",
      "requires": {
        "@antv/g-base": "^0.5.1",
        "@antv/g6-core": "0.6.4",
        "@antv/util": "~2.0.5"
      }
    },
    "@antv/g6-pc": {
      "version": "0.6.4",
      "resolved": "https://registry.npmjs.org/@antv/g6-pc/-/g6-pc-0.6.4.tgz",
      "integrity": "sha512-bEQ3pqHzkqDvk2aWRghj9cB73qXx0n4NRJFmL4cSJnB1SQyk7akfBHgLBzw5aqsYviL9WK7VR6uCCZRPK3PoXA==",
      "requires": {
        "@ant-design/colors": "^4.0.5",
        "@antv/algorithm": "^0.1.8",
        "@antv/dom-util": "^2.0.1",
        "@antv/event-emitter": "~0.1.0",
        "@antv/g-base": "^0.5.1",
        "@antv/g-canvas": "^0.5.2",
        "@antv/g-math": "^0.1.1",
        "@antv/g-svg": "^0.5.1",
        "@antv/g6-core": "0.6.4",
        "@antv/g6-element": "0.6.4",
        "@antv/g6-plugin": "0.6.4",
        "@antv/hierarchy": "^0.6.7",
        "@antv/layout": "^0.2.1",
        "@antv/matrix-util": "^3.1.0-beta.3",
        "@antv/path-util": "^2.0.3",
        "@antv/util": "~2.0.5",
        "color": "^3.1.3",
        "d3-force": "^2.0.1",
        "dagre": "^0.8.5",
        "insert-css": "^2.0.0",
        "ml-matrix": "^6.5.0"
      },
      "dependencies": {
        "@ant-design/colors": {
          "version": "4.0.5",
          "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-4.0.5.tgz",
          "integrity": "sha512-3mnuX2prnWOWvpFTS2WH2LoouWlOgtnIpc6IarWN6GOzzLF8dW/U8UctuvIPhoboETehZfJ61XP+CGakBEPJ3Q==",
          "requires": {
            "tinycolor2": "^1.4.1"
          }
        },
        "@antv/hierarchy": {
          "version": "0.6.8",
          "resolved": "https://registry.npmjs.org/@antv/hierarchy/-/hierarchy-0.6.8.tgz",
          "integrity": "sha512-wVzUl+pxny5gyGJ2mkWx8IiEypX6bnMHgr/NILgbxY6shoy0Vf4FhZpI3CY8Ez7bQT6js8fMkB2NymPW7d7i8A==",
          "requires": {
            "@antv/util": "^2.0.7"
          }
        },
        "color": {
          "version": "3.2.1",
          "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
          "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
          "requires": {
            "color-convert": "^1.9.3",
            "color-string": "^1.6.0"
          }
        },
        "color-string": {
          "version": "1.9.1",
          "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
          "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
          "requires": {
            "color-name": "^1.0.0",
            "simple-swizzle": "^0.2.2"
          }
        }
      }
    },
    "@antv/g6-plugin": {
      "version": "0.6.4",
      "resolved": "https://registry.npmjs.org/@antv/g6-plugin/-/g6-plugin-0.6.4.tgz",
      "integrity": "sha512-eStD6j3nB54owXdYcA6/vxVCxJfBiMUfc33p4cKnRJnomSvEHYG/7i21SbyzMQQq7dRc0RDIPubYVwSilKzLCA==",
      "requires": {
        "@antv/dom-util": "^2.0.2",
        "@antv/g-base": "^0.5.1",
        "@antv/g-canvas": "^0.5.2",
        "@antv/g-svg": "^0.5.2",
        "@antv/g6-core": "0.6.4",
        "@antv/matrix-util": "^3.1.0-beta.3",
        "@antv/scale": "^0.3.4",
        "@antv/util": "^2.0.9",
        "insert-css": "^2.0.0"
      }
    },
    "@antv/graphlib": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/@antv/graphlib/-/graphlib-1.2.0.tgz",
      "integrity": "sha512-hhJOMThec51nU4Fe5p/viLlNIL71uDEgYFzKPajWjr2715SFG1HAgiP6AVylIeqBcAZ04u3Lw7usjl/TuI5RuQ=="
    },
    "@antv/hierarchy": {
      "version": "0.6.3",
      "resolved": "https://registry.npmjs.org/@antv/hierarchy/-/hierarchy-0.6.3.tgz",
      "integrity": "sha512-91YZUiZFXK8zp2nC2C+4FEc1LDIPZ5Q4YQbzMnKhH+7nei4QCfIdXPrPh0EKRws78CVt2hxR5gHD7zq6UlokAQ==",
      "requires": {
        "@antv/util": "^2.0.7"
      }
    },
    "@antv/layout": {
      "version": "0.2.2",
      "resolved": "https://registry.npmjs.org/@antv/layout/-/layout-0.2.2.tgz",
      "integrity": "sha512-J2qRZwhA6NbR3gPrbw8Vw+6TpXtMmpW86q8LnwtCnNvdRNQQ7wSfvWAiphtFRfHqwL9ky44J51v4ysCENgTGDQ==",
      "requires": {
        "@antv/g-webgpu": "0.5.5",
        "@antv/graphlib": "^1.0.0",
        "d3-force": "^2.0.1",
        "dagre-compound": "^0.0.11",
        "ml-matrix": "^6.5.0"
      }
    },
    "@antv/matrix-util": {
@@ -426,6 +621,257 @@
          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
          "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
        }
      }
    },
    "@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": {
@@ -1607,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",
@@ -1632,6 +2086,19 @@
        "lodash.isnil": "^4.0.0",
        "lodash.isundefined": "^3.0.1",
        "lodash.uniq": "^4.5.0"
      }
    },
    "@floating-ui/core": {
      "version": "0.7.2",
      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.7.2.tgz",
      "integrity": "sha512-FRVAkSNU/vGXLIsgbggcs70GkXKEOXgBBbNpYPNHSaKsCAMMd00NrjbtKTesxkdv9xm9N3+XiDlcFGY6WnatBg=="
    },
    "@floating-ui/dom": {
      "version": "0.5.2",
      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.5.2.tgz",
      "integrity": "sha512-z1DnEa7F3d8Fm/eXSbii8UEGpcjZGkQaYYUI0WpEVgD3vBfebDW8j/3ysusxonuMexoigA+A3b/fYH7sEqiwyg==",
      "requires": {
        "@floating-ui/core": "^0.7.2"
      }
    },
    "@hapi/address": {
@@ -1909,6 +2376,31 @@
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
      "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
    },
    "@probe.gl/env": {
      "version": "3.5.0",
      "resolved": "https://registry.npmjs.org/@probe.gl/env/-/env-3.5.0.tgz",
      "integrity": "sha512-YdlpZZshhyYxvWDBmZ5RIW2pTR14Pw4p9czMlt/v7F6HbFzWfAdmH7q6xVwFRYxUpQLwhWensWyv4aFysiWl4g==",
      "requires": {
        "@babel/runtime": "^7.0.0"
      }
    },
    "@probe.gl/log": {
      "version": "3.5.0",
      "resolved": "https://registry.npmjs.org/@probe.gl/log/-/log-3.5.0.tgz",
      "integrity": "sha512-nW/qz2X1xY08WU/TsmJP6/6IPNcaY5fS/vLjpC4ahJuE2Mezga4hGM/R2X5JWE/nkPc+BsC5GnAnD13rwAxS7g==",
      "requires": {
        "@babel/runtime": "^7.0.0",
        "@probe.gl/env": "3.5.0"
      }
    },
    "@probe.gl/stats": {
      "version": "3.5.0",
      "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-3.5.0.tgz",
      "integrity": "sha512-IH2M+F3c8HR1DTroBARePUFG7wIewumtKA0UFqx51Z7S4hKrD60wFbpMmg0AcF4FvHAXMBoC+kYi1UKW9XbAOw==",
      "requires": {
        "@babel/runtime": "^7.0.0"
      }
    },
    "@react-native-community/cli-debugger-ui": {
      "version": "4.9.0",
@@ -2294,52 +2786,53 @@
      "integrity": "sha512-ael2f1onoPF3vF7YqHGWy7NnafzGu+yp88BbFbP0ydoCP2xGSUzmZVw0zakPTC040Id+JQ9WeFczujMkDy6jYQ=="
    },
    "@react-spring/animated": {
      "version": "9.3.1",
      "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.3.1.tgz",
      "integrity": "sha512-23YaERZ++BwZ8F8PxPFqrpOwp/JZun1Pj6aHZtPAU42j5LycBRasT9XMw7Eyr7zNFhT+rl3R3wFfd4WX6Ax+UA==",
      "version": "9.4.5",
      "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.4.5.tgz",
      "integrity": "sha512-KWqrtvJSMx6Fj9nMJkhTwM9r6LIriExDRV6YHZV9HKQsaolUFppgkOXpC+rsL1JEtEvKv6EkLLmSqHTnuYjiIA==",
      "requires": {
        "@react-spring/shared": "~9.3.0",
        "@react-spring/types": "~9.3.0"
        "@react-spring/shared": "~9.4.5",
        "@react-spring/types": "~9.4.5"
      }
    },
    "@react-spring/core": {
      "version": "9.3.1",
      "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.3.1.tgz",
      "integrity": "sha512-8rmfmEHLHGtF1CUiXRn64YJqsXNxv2cGX8oNnBnsuoE33c48Zc34t2VIMB4R9q5zwIUCvDBGfiEenA8ZAPxqOQ==",
      "version": "9.4.5",
      "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.4.5.tgz",
      "integrity": "sha512-83u3FzfQmGMJFwZLAJSwF24/ZJctwUkWtyPD7KYtNagrFeQKUH1I05ZuhmCmqW+2w1KDW1SFWQ43RawqfXKiiQ==",
      "requires": {
        "@react-spring/animated": "~9.3.0",
        "@react-spring/shared": "~9.3.0",
        "@react-spring/types": "~9.3.0"
        "@react-spring/animated": "~9.4.5",
        "@react-spring/rafz": "~9.4.5",
        "@react-spring/shared": "~9.4.5",
        "@react-spring/types": "~9.4.5"
      }
    },
    "@react-spring/rafz": {
      "version": "9.3.1",
      "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.3.1.tgz",
      "integrity": "sha512-fEBMCarGVl+/2kdO+g6Zig4F+3ymwmcGN8S71gb1c7Cbbxb87kviPz8EhshfIHoiLeJPGlqwcuGbxNmZbBamvA=="
      "version": "9.4.5",
      "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.4.5.tgz",
      "integrity": "sha512-swGsutMwvnoyTRxvqhfJBtGM8Ipx6ks0RkIpNX9F/U7XmyPvBMGd3GgX/mqxZUpdlsuI1zr/jiYw+GXZxAlLcQ=="
    },
    "@react-spring/shared": {
      "version": "9.3.1",
      "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.3.1.tgz",
      "integrity": "sha512-jhPpxzURGo6Nty90ex1lkxmZae7w/VAbnGmb/nXcYoZwSoNR+W2aAd00iXsh2ZGz6MgoJOsc495JeG3uC7Am8A==",
      "version": "9.4.5",
      "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.4.5.tgz",
      "integrity": "sha512-JhMh3nFKsqyag0KM5IIM8BQANGscTdd0mMv3BXsUiMZrcjQTskyfnv5qxEeGWbJGGar52qr5kHuBHtCjQOzniA==",
      "requires": {
        "@react-spring/rafz": "~9.3.0",
        "@react-spring/types": "~9.3.0"
        "@react-spring/rafz": "~9.4.5",
        "@react-spring/types": "~9.4.5"
      }
    },
    "@react-spring/types": {
      "version": "9.3.1",
      "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.3.1.tgz",
      "integrity": "sha512-W/YMJMX35XgGGzX0gKORBTwnvQ+1loDOFN3XlZkW5fgpEY+7VkRUpPyqPWXQr3n6lHrsLmHIGdpznqZi54ACTQ=="
      "version": "9.4.5",
      "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.4.5.tgz",
      "integrity": "sha512-mpRIamoHwql0ogxEUh9yr4TP0xU5CWyZxVQeccGkHHF8kPMErtDXJlxyo0lj+telRF35XNihtPTWoflqtyARmg=="
    },
    "@react-spring/web": {
      "version": "9.3.1",
      "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.3.1.tgz",
      "integrity": "sha512-sisZIgFGva/Z+xKWPSfXpukF0AP3kR9ALTxlHL87fVotMUCJX5vtH/YlVcywToEFwTHKt3MpI5Wy2M+vgVEeaw==",
      "version": "9.4.5",
      "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.4.5.tgz",
      "integrity": "sha512-NGAkOtKmOzDEctL7MzRlQGv24sRce++0xAY7KlcxmeVkR7LRSGkoXHaIfm9ObzxPMcPHQYQhf3+X9jepIFNHQA==",
      "requires": {
        "@react-spring/animated": "~9.3.0",
        "@react-spring/core": "~9.3.0",
        "@react-spring/shared": "~9.3.0",
        "@react-spring/types": "~9.3.0"
        "@react-spring/animated": "~9.4.5",
        "@react-spring/core": "~9.4.5",
        "@react-spring/shared": "~9.4.5",
        "@react-spring/types": "~9.4.5"
      }
    },
    "@svgr/babel-plugin-add-jsx-attribute": {
@@ -2699,9 +3192,9 @@
      }
    },
    "@types/resize-observer-browser": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.6.tgz",
      "integrity": "sha512-61IfTac0s9jvNtBCpyo86QeaN8qqpMGHdK0uGKCCIy2dt5/Yk84VduHIdWAcmkC5QvdkPL0p5eWYgUZtHKKUVg=="
      "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",
@@ -2785,16 +3278,16 @@
      }
    },
    "@use-gesture/core": {
      "version": "10.2.4",
      "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.2.4.tgz",
      "integrity": "sha512-fk1LjCBj43BKb8NE05qkdtPOR0ngA7PwgvEqfFap/h+s7QHi+JTv4/mtDQ4wI9zzem+Ry5EKrHS/cVdBehI4wA=="
      "version": "10.2.15",
      "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.2.15.tgz",
      "integrity": "sha512-R8k5GHKR6J3n48K1xiWCBSnTsxmfiVCp+MYPMhFaoHT1/oIjrFA6SeMmWDl0REwP/CpBfNdQ0FwOo/0dGjPhwA=="
    },
    "@use-gesture/react": {
      "version": "10.2.4",
      "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.2.4.tgz",
      "integrity": "sha512-CbqyRj+qNbRBOGmS8OWtaOa29fxEr7bKTYHvPuMQ1wsgQDh2/DqQxbp7cFxAg6WZ8oZjppDj/EkWnw22WpIIWQ==",
      "version": "10.2.15",
      "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.2.15.tgz",
      "integrity": "sha512-Hdfp17a3iHDo33jasd8GIPlIjM4wxNzn1O9apNX2VrF7X2ewzXp4wCCQ4aPqsnyvBA1WhR8KHMrBS/XWQZxTHQ==",
      "requires": {
        "@use-gesture/core": "10.2.4"
        "@use-gesture/core": "10.2.15"
      }
    },
    "@webassemblyjs/ast": {
@@ -2955,6 +3448,16 @@
        "@xtuc/long": "4.2.2"
      }
    },
    "@webgpu/glslang": {
      "version": "0.0.15",
      "resolved": "https://registry.npmjs.org/@webgpu/glslang/-/glslang-0.0.15.tgz",
      "integrity": "sha512-niT+Prh3Aff8Uf1MVBVUsaNjFj9rJAKDXuoHIKiQbB+6IUP/3J3JIhBNyZ7lDhytvXxw6ppgnwKZdDJ08UMj4Q=="
    },
    "@webgpu/types": {
      "version": "0.0.31",
      "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.0.31.tgz",
      "integrity": "sha512-cvvCMSZBT4VsRNtt0lI6XQqvOIIWw6+NRUtnPUMDVDgsI4pCZColz3qzF5QcP9wIYOHEc3jssIBse8UWONKhlQ=="
    },
    "@xmldom/xmldom": {
      "version": "0.7.5",
      "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.5.tgz",
@@ -3090,28 +3593,36 @@
      "integrity": "sha512-LKQwcxVWbfJj+gtdHYeq+nqUIg3+NkYS7LCMZ3hMk1eZkFjJqG5RiPsXiYZV5vOQESUZwoY0e9k9Kz/GfhoVEw=="
    },
    "ahooks": {
      "version": "2.10.14",
      "resolved": "https://registry.npmjs.org/ahooks/-/ahooks-2.10.14.tgz",
      "integrity": "sha512-axWa7VoAgu7bxA56dDl0CXW4rvaQmDBiov/d3tAy0x1YNYywYMKokL8TdLgJ5zO/oXGiWmG7BxlGOQGkqE/zkQ==",
      "version": "3.4.1",
      "resolved": "https://registry.npmjs.org/ahooks/-/ahooks-3.4.1.tgz",
      "integrity": "sha512-PMxCDO6JsFdNrAyN3cW1J/2qt/vy2EJ/9KhxGOxj41hJhQddjgaBJjZKf/FrrnZmL+3yGPioZtbC4C7q7ru3yA==",
      "requires": {
        "@ahooksjs/use-request": "^2.8.14",
        "@types/js-cookie": "^2.2.6",
        "@types/js-cookie": "^2.x.x",
        "ahooks-v3-count": "^1.0.0",
        "dayjs": "^1.9.1",
        "intersection-observer": "^0.7.0",
        "js-cookie": "^2.2.1",
        "lodash.debounce": "^4.0.8",
        "lodash.isequal": "^4.5.0",
        "lodash.throttle": "^4.1.1",
        "intersection-observer": "^0.12.0",
        "js-cookie": "^2.x.x",
        "lodash": "^4.17.21",
        "resize-observer-polyfill": "^1.5.1",
        "screenfull": "^5.0.0"
      },
      "dependencies": {
        "dayjs": {
          "version": "1.10.7",
          "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz",
          "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig=="
          "version": "1.11.3",
          "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.3.tgz",
          "integrity": "sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A=="
        },
        "lodash": {
          "version": "4.17.21",
          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
          "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
        }
      }
    },
    "ahooks-v3-count": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/ahooks-v3-count/-/ahooks-v3-count-1.0.0.tgz",
      "integrity": "sha512-V7uUvAwnimu6eh/PED4mCDjE7tokeZQLKlxg9lCTMPhN+NjsSbtdacByVlR1oluXQzD3MOw55wylDmQo4+S9ZQ=="
    },
    "ajv": {
      "version": "6.10.2",
@@ -3142,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",
@@ -3331,32 +3842,31 @@
      }
    },
    "antd-mobile": {
      "version": "5.0.0-rc.6",
      "resolved": "https://registry.npmjs.org/antd-mobile/-/antd-mobile-5.0.0-rc.6.tgz",
      "integrity": "sha512-D4y/Ofo8nyG1OZwpEbwPH9k4cY5DdBXhZIxZafQ58VGC8ZY792qS1ykml75KfY/57YXn0sBgdbFkoet4TiLPZg==",
      "version": "5.14.2",
      "resolved": "https://registry.npmjs.org/antd-mobile/-/antd-mobile-5.14.2.tgz",
      "integrity": "sha512-qyd+afJc+tYwCdguW/DhjTFDzpM/TYmgXVcrqSu8+jvVyRva7VuLEquosRw3oxPpjOoJ/l+Ig+p07zPS8CDHXA==",
      "requires": {
        "@react-spring/web": "^9.3.1",
        "@types/resize-observer-browser": "^0.1.6",
        "@use-gesture/react": "^10.2.4",
        "ahooks": "^2.10.14",
        "@floating-ui/dom": "^0.5.2",
        "@react-spring/web": "^9.4.5",
        "@use-gesture/react": "10.2.15",
        "ahooks": "^3.4.1",
        "antd-mobile-icons": "^0.2.2",
        "antd-mobile-v5-count": "^1.0.1",
        "big.js": "^6.1.1",
        "classnames": "^2.3.1",
        "dayjs": "^1.10.7",
        "dayjs": "^1.11.3",
        "lodash": "^4.17.21",
        "rc-field-form": "^1.22.0",
        "rc-tooltip": "^5.1.1",
        "staged-components": "^1.1.2",
        "use-async-memo": "^1.2.3"
        "rc-field-form": "^1.26.7",
        "react-is": "^17.0.2",
        "staged-components": "^1.1.3",
        "tslib": "^2.4.0",
        "use-sync-external-store": "^1.1.0"
      },
      "dependencies": {
        "@babel/runtime": {
          "version": "7.16.5",
          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz",
          "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==",
          "requires": {
            "regenerator-runtime": "^0.13.4"
          }
        "big.js": {
          "version": "6.2.0",
          "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.0.tgz",
          "integrity": "sha512-paIKvJiAaOYdLt6MfnvxkDo64lTOV257XYJyX3oJnJQocIclUn+48k6ZerH/c5FxWE6DGJu1TKDYis7tqHg9kg=="
        },
        "classnames": {
          "version": "2.3.1",
@@ -3364,68 +3874,24 @@
          "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
        },
        "dayjs": {
          "version": "1.10.7",
          "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz",
          "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig=="
          "version": "1.11.3",
          "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.3.tgz",
          "integrity": "sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A=="
        },
        "lodash": {
          "version": "4.17.21",
          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
          "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
        },
        "rc-align": {
          "version": "4.0.11",
          "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.11.tgz",
          "integrity": "sha512-n9mQfIYQbbNTbefyQnRHZPWuTEwG1rY4a9yKlIWHSTbgwI+XUMGRYd0uJ5pE2UbrNX0WvnMBA1zJ3Lrecpra/A==",
          "requires": {
            "@babel/runtime": "^7.10.1",
            "classnames": "2.x",
            "dom-align": "^1.7.0",
            "lodash": "^4.17.21",
            "rc-util": "^5.3.0",
            "resize-observer-polyfill": "^1.5.1"
          }
        },
        "rc-tooltip": {
          "version": "5.1.1",
          "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.1.1.tgz",
          "integrity": "sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==",
          "requires": {
            "@babel/runtime": "^7.11.2",
            "rc-trigger": "^5.0.0"
          }
        },
        "rc-trigger": {
          "version": "5.2.10",
          "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.10.tgz",
          "integrity": "sha512-FkUf4H9BOFDaIwu42fvRycXMAvkttph9AlbCZXssZDVzz2L+QZ0ERvfB/4nX3ZFPh1Zd+uVGr1DEDeXxq4J1TA==",
          "requires": {
            "@babel/runtime": "^7.11.2",
            "classnames": "^2.2.6",
            "rc-align": "^4.0.0",
            "rc-motion": "^2.0.0",
            "rc-util": "^5.5.0"
          }
        },
        "rc-util": {
          "version": "5.16.1",
          "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.16.1.tgz",
          "integrity": "sha512-kSCyytvdb3aRxQacS/71ta6c+kBWvM1v8/2h9d/HaNWauc3qB8pLnF20PJ8NajkNN8gb+rR1l0eWO+D4Pz+LLQ==",
          "requires": {
            "@babel/runtime": "^7.12.5",
            "react-is": "^16.12.0",
            "shallowequal": "^1.1.0"
          }
        },
        "react-is": {
          "version": "16.13.1",
          "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
          "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
          "version": "17.0.2",
          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
        },
        "regenerator-runtime": {
          "version": "0.13.9",
          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
          "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
        "tslib": {
          "version": "2.4.0",
          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
          "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
        }
      }
    },
@@ -3522,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"
@@ -3580,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",
@@ -3703,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",
@@ -4450,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"
      }
@@ -4913,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"
@@ -4922,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=="
        }
      }
    },
@@ -4938,9 +5404,9 @@
      }
    },
    "caniuse-lite": {
      "version": "1.0.30001319",
      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001319.tgz",
      "integrity": "sha512-xjlIAFHucBRSMUo1kb5D4LYgcN1M45qdKP++lhqowDpwJwGkpIRTt5qQqnhxjj1vHcI7nrJxWhCC1ATrCEBTcw=="
      "version": "1.0.30001399",
      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001399.tgz",
      "integrity": "sha512-4vQ90tMKS+FkvuVWS5/QY1+d805ODxZiKFzsU8o/RsVJz49ZSRR8EjykLJbqhzdPgadbX6wB538wOzle3JniRA=="
    },
    "capture-exit": {
      "version": "2.0.0",
@@ -5078,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",
@@ -5140,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",
@@ -5437,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",
@@ -5620,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"
@@ -5648,6 +6119,11 @@
        "randombytes": "^2.0.0",
        "randomfill": "^1.0.3"
      }
    },
    "crypto-js": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
      "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
    },
    "css": {
      "version": "2.2.4",
@@ -5926,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"
      }
@@ -5979,6 +6455,11 @@
        }
      }
    },
    "d3-dispatch": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz",
      "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA=="
    },
    "d3-dsv": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.2.0.tgz",
@@ -5993,6 +6474,16 @@
      "version": "1.0.7",
      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.7.tgz",
      "integrity": "sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ=="
    },
    "d3-force": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-2.1.1.tgz",
      "integrity": "sha512-nAuHEzBqMvpFVMf9OX75d00OxvOXdxY+xECIXjW6Gv8BRrXu6gAWbv/9XKrvfJ5i5DCokDW7RYE50LRoK092ew==",
      "requires": {
        "d3-dispatch": "1 - 2",
        "d3-quadtree": "1 - 2",
        "d3-timer": "1 - 2"
      }
    },
    "d3-geo": {
      "version": "1.6.4",
@@ -6038,6 +6529,11 @@
      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
      "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
    },
    "d3-quadtree": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-2.0.0.tgz",
      "integrity": "sha512-b0Ed2t1UUalJpc3qXzKi+cPGxeXRr4KU9YSlocN74aTzp6R/Ud43t79yLLqxHRWZfsvWXmbDWPpoENK1K539xw=="
    },
    "d3-sankey": {
      "version": "0.9.1",
      "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.9.1.tgz",
@@ -6074,6 +6570,11 @@
        "graphlib": "^2.1.8",
        "lodash": "^4.17.15"
      }
    },
    "dagre-compound": {
      "version": "0.0.11",
      "resolved": "https://registry.npmjs.org/dagre-compound/-/dagre-compound-0.0.11.tgz",
      "integrity": "sha512-UrSgRP9LtOZCYb9e5doolZXpc7xayyszgyOs7uakTK4n4KsLegLVTRRtq01GpQd/iZjYw5fWMapx9ed+c80MAQ=="
    },
    "damerau-levenshtein": {
      "version": "1.0.5",
@@ -6283,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",
@@ -6404,6 +6905,11 @@
          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
        }
      }
    },
    "discontinuous-range": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
      "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ=="
    },
    "dnd-core": {
      "version": "9.4.0",
@@ -9029,6 +9535,11 @@
        "schema-utils": "^1.0.0"
      }
    },
    "file-saver": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
      "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
    },
    "filename-regex": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
@@ -9797,7 +10308,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",
@@ -9830,7 +10341,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",
@@ -9857,6 +10368,11 @@
      "version": "3.4.3",
      "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz",
      "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="
    },
    "gl-vec2": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/gl-vec2/-/gl-vec2-1.3.0.tgz",
      "integrity": "sha512-YiqaAuNsheWmUV0Sa8k94kBB0D6RWjwZztyO+trEYS8KzJ6OQB/4686gdrf59wld4hHFIvaxynO3nRxpk1Ij/A=="
    },
    "glob": {
      "version": "7.1.4",
@@ -9978,13 +10494,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": {
@@ -10102,7 +10625,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",
@@ -10509,7 +11032,7 @@
    "immediate": {
      "version": "3.0.6",
      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
      "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
      "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
    },
    "immer": {
      "version": "1.10.0",
@@ -10569,14 +11092,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"
      }
@@ -10681,6 +11204,11 @@
        }
      }
    },
    "insert-css": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz",
      "integrity": "sha1-610Ql7dUL0x56jBg067gfQU4gPQ="
    },
    "internal-ip": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz",
@@ -10691,9 +11219,9 @@
      }
    },
    "intersection-observer": {
      "version": "0.7.0",
      "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.7.0.tgz",
      "integrity": "sha512-Id0Fij0HsB/vKWGeBe9PxeY45ttRiBmhFyyt/geBdDHBYNctMRTE3dC1U3ujzz3lap+hVXlEcVaB56kZP/eEUg=="
      "version": "0.12.0",
      "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.12.0.tgz",
      "integrity": "sha512-2Vkz8z46Dv401zTWudDGwO7KiGHNDkMv417T5ItcNYfmvHR/1qCTVBO9vwH8zZmQ0WkA/1ARwpysR9bsnop4NQ=="
    },
    "invariant": {
      "version": "2.2.4",
@@ -10702,6 +11230,16 @@
      "requires": {
        "loose-envify": "^1.0.0"
      }
    },
    "inversify": {
      "version": "5.1.1",
      "resolved": "https://registry.npmjs.org/inversify/-/inversify-5.1.1.tgz",
      "integrity": "sha512-j8grHGDzv1v+8T1sAQ+3boTCntFPfvxLCkNcxB1J8qA0lUN+fAlSyYd+RXKvaPRL4AGyPxViutBEJHNXOyUdFQ=="
    },
    "inversify-inject-decorators": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/inversify-inject-decorators/-/inversify-inject-decorators-3.1.0.tgz",
      "integrity": "sha512-/seBlVp5bXrLQS3DpKEmlgeZL6C7Tf/QITd+IMQrbBBGuCbxb7k3hRAWu9XSreNpFzLgSboz3sClLSEmGwHphw=="
    },
    "invert-kv": {
      "version": "1.0.0",
@@ -10735,6 +11273,11 @@
      "requires": {
        "kind-of": "^3.0.2"
      }
    },
    "is-any-array": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/is-any-array/-/is-any-array-2.0.0.tgz",
      "integrity": "sha512-WdPV58rT3aOWXvvyuBydnCq4S2BM1Yz8shKxlEpk/6x+GX202XRvXOycEFtNgnHVLoc46hpexPFx8Pz1/sMS0w=="
    },
    "is-arguments": {
      "version": "1.0.4",
@@ -11986,10 +12529,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",
@@ -12173,14 +12726,14 @@
      }
    },
    "jszip": {
      "version": "3.6.0",
      "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.6.0.tgz",
      "integrity": "sha512-jgnQoG9LKnWO3mnVNBnfhkh0QknICd1FGSrXcgrl67zioyJ4wgx25o9ZqwNtrROSflGBCGYnJfjrIyRIby1OoQ==",
      "version": "3.10.0",
      "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.0.tgz",
      "integrity": "sha512-LDfVtOLtOxb9RXkYOwPyNBTQDL4eUbqahtoY6x07GiDJHwSYvn8sHHIw8wINImV3MqbMNve2gSuM1DDqEKk09Q==",
      "requires": {
        "lie": "~3.3.0",
        "pako": "~1.0.2",
        "readable-stream": "~2.3.6",
        "set-immediate-shim": "~1.0.1"
        "setimmediate": "^1.0.5"
      }
    },
    "killable": {
@@ -12374,6 +12927,11 @@
      "version": "4.17.15",
      "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",
@@ -12700,7 +13258,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"
@@ -12754,6 +13312,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",
@@ -12770,7 +13341,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",
@@ -12861,7 +13432,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",
@@ -13887,10 +14458,55 @@
        }
      }
    },
    "ml-array-max": {
      "version": "1.2.4",
      "resolved": "https://registry.npmjs.org/ml-array-max/-/ml-array-max-1.2.4.tgz",
      "integrity": "sha512-BlEeg80jI0tW6WaPyGxf5Sa4sqvcyY6lbSn5Vcv44lp1I2GR6AWojfUvLnGTNsIXrZ8uqWmo8VcG1WpkI2ONMQ==",
      "requires": {
        "is-any-array": "^2.0.0"
      }
    },
    "ml-array-min": {
      "version": "1.2.3",
      "resolved": "https://registry.npmjs.org/ml-array-min/-/ml-array-min-1.2.3.tgz",
      "integrity": "sha512-VcZ5f3VZ1iihtrGvgfh/q0XlMobG6GQ8FsNyQXD3T+IlstDv85g8kfV0xUG1QPRO/t21aukaJowDzMTc7j5V6Q==",
      "requires": {
        "is-any-array": "^2.0.0"
      }
    },
    "ml-array-rescale": {
      "version": "1.3.7",
      "resolved": "https://registry.npmjs.org/ml-array-rescale/-/ml-array-rescale-1.3.7.tgz",
      "integrity": "sha512-48NGChTouvEo9KBctDfHC3udWnQKNKEWN0ziELvY3KG25GR5cA8K8wNVzracsqSW1QEkAXjTNx+ycgAv06/1mQ==",
      "requires": {
        "is-any-array": "^2.0.0",
        "ml-array-max": "^1.2.4",
        "ml-array-min": "^1.2.3"
      }
    },
    "ml-matrix": {
      "version": "6.10.0",
      "resolved": "https://registry.npmjs.org/ml-matrix/-/ml-matrix-6.10.0.tgz",
      "integrity": "sha512-wU+jacx1dcP1QArV1/Kv49Ah6y2fq+BiQl2BnNVBC+hoCW7KgBZ4YZrowPopeoY164TB6Kes5wMeDjY8ODHYDg==",
      "requires": {
        "is-any-array": "^2.0.0",
        "ml-array-rescale": "^1.3.7"
      }
    },
    "moment": {
      "version": "2.24.0",
      "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
      "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
    },
    "moo": {
      "version": "0.5.2",
      "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
      "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q=="
    },
    "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",
@@ -13969,6 +14585,17 @@
      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
    },
    "nearley": {
      "version": "2.20.1",
      "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz",
      "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==",
      "requires": {
        "commander": "^2.19.0",
        "moo": "^0.5.0",
        "railroad-diagrams": "^1.0.0",
        "randexp": "0.4.6"
      }
    },
    "negotiator": {
      "version": "0.6.2",
      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
@@ -14033,7 +14660,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=="
        }
      }
    },
@@ -14158,12 +14785,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",
@@ -14175,7 +14802,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=="
        }
      }
    },
@@ -14187,7 +14814,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"
      }
@@ -14576,7 +15203,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"
      }
@@ -15007,6 +15634,22 @@
        "abs-svg-path": "~0.1.1",
        "isarray": "~0.0.1",
        "parse-svg-path": "~0.1.1"
      }
    },
    "polyline-miter-util": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/polyline-miter-util/-/polyline-miter-util-1.0.1.tgz",
      "integrity": "sha1-tpPyOJ6g3tNqa89ezS7OS2kX2Vc=",
      "requires": {
        "gl-vec2": "^1.0.0"
      }
    },
    "polyline-normals": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/polyline-normals/-/polyline-normals-2.0.2.tgz",
      "integrity": "sha1-oXN+ddjA3MsaWR+csn8J7vS30TU=",
      "requires": {
        "polyline-miter-util": "^1.0.1"
      }
    },
    "portfinder": {
@@ -16029,6 +16672,17 @@
      "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
      "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg=="
    },
    "probe.gl": {
      "version": "3.5.0",
      "resolved": "https://registry.npmjs.org/probe.gl/-/probe.gl-3.5.0.tgz",
      "integrity": "sha512-KWj8u0PNytr/rVwcQFcN7O8SK7n/ITOsUZ91l4fSX95oHhKvVCI7eadrzFUzFRlXkFfBWpMWZXFHITsHHHUctw==",
      "requires": {
        "@babel/runtime": "^7.0.0",
        "@probe.gl/env": "3.5.0",
        "@probe.gl/log": "3.5.0",
        "@probe.gl/stats": "3.5.0"
      }
    },
    "process": {
      "version": "0.11.10",
      "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -16194,6 +16848,20 @@
      "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
      "requires": {
        "performance-now": "^2.1.0"
      }
    },
    "railroad-diagrams": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
      "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A=="
    },
    "randexp": {
      "version": "0.4.6",
      "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
      "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
      "requires": {
        "discontinuous-range": "1.0.0",
        "ret": "~0.1.10"
      }
    },
    "randomatic": {
@@ -16450,34 +17118,34 @@
      }
    },
    "rc-field-form": {
      "version": "1.22.0",
      "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.22.0.tgz",
      "integrity": "sha512-IQBNeF4i64lBNLz8HbfXqUpAnrpBtfu2xU6q/wXMfdQm1AfKjiHyMNOxmiA5ZKMOOQPi+YOSzDbictfQP94hUA==",
      "version": "1.26.7",
      "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.26.7.tgz",
      "integrity": "sha512-CIb7Gw+DG9R+g4HxaDGYHhOjhjQoU2mGU4y+UM2+KQ3uRz9HrrNgTspGvNynn3UamsYcYcaPWZJmiJ6VklkT/w==",
      "requires": {
        "@babel/runtime": "^7.8.4",
        "async-validator": "^4.0.2",
        "@babel/runtime": "^7.18.0",
        "async-validator": "^4.1.0",
        "rc-util": "^5.8.0"
      },
      "dependencies": {
        "@babel/runtime": {
          "version": "7.16.5",
          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz",
          "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==",
          "version": "7.18.3",
          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz",
          "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==",
          "requires": {
            "regenerator-runtime": "^0.13.4"
          }
        },
        "async-validator": {
          "version": "4.0.7",
          "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.0.7.tgz",
          "integrity": "sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ=="
          "version": "4.1.1",
          "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.1.1.tgz",
          "integrity": "sha512-p4DO/JXwjs8klJyJL8Q2oM4ks5fUTze/h5k10oPPKMiLe1fj3G1QMzPHNmN1Py4ycOk7WlO2DcGXv1qiESJCZA=="
        },
        "rc-util": {
          "version": "5.16.1",
          "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.16.1.tgz",
          "integrity": "sha512-kSCyytvdb3aRxQacS/71ta6c+kBWvM1v8/2h9d/HaNWauc3qB8pLnF20PJ8NajkNN8gb+rR1l0eWO+D4Pz+LLQ==",
          "version": "5.21.5",
          "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.21.5.tgz",
          "integrity": "sha512-ip7HqX37Cy/RDl9MlrFp+FbcKnsWZ22sF5MS5eSpYLtg5MpC0TMqGb5ukBatoOhgjnLL+eJGR6e7YAJ/dhK09A==",
          "requires": {
            "@babel/runtime": "^7.12.5",
            "@babel/runtime": "^7.18.3",
            "react-is": "^16.12.0",
            "shallowequal": "^1.1.0"
          }
@@ -16613,29 +17281,29 @@
      }
    },
    "rc-motion": {
      "version": "2.4.4",
      "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.4.4.tgz",
      "integrity": "sha512-ms7n1+/TZQBS0Ydd2Q5P4+wJTSOrhIrwNxLXCZpR7Fa3/oac7Yi803HDALc2hLAKaCTQtw9LmQeB58zcwOsqlQ==",
      "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.2.1"
        "rc-util": "^5.21.0"
      },
      "dependencies": {
        "@babel/runtime": {
          "version": "7.16.5",
          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz",
          "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==",
          "version": "7.18.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.16.1",
          "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.16.1.tgz",
          "integrity": "sha512-kSCyytvdb3aRxQacS/71ta6c+kBWvM1v8/2h9d/HaNWauc3qB8pLnF20PJ8NajkNN8gb+rR1l0eWO+D4Pz+LLQ==",
          "version": "5.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.12.5",
            "@babel/runtime": "^7.18.3",
            "react-is": "^16.12.0",
            "shallowequal": "^1.1.0"
          }
@@ -17685,6 +18353,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",
@@ -17813,7 +18498,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"
@@ -17832,6 +18517,11 @@
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
      "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw=="
    },
    "reflect-metadata": {
      "version": "0.1.13",
      "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
      "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
    },
    "regenerate": {
      "version": "1.4.0",
@@ -17931,6 +18621,11 @@
          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0="
        }
      }
    },
    "regl": {
      "version": "1.7.0",
      "resolved": "https://registry.npmjs.org/regl/-/regl-1.7.0.tgz",
      "integrity": "sha512-bEAtp/qrtKucxXSJkD4ebopFZYP0q1+3Vb2WECWv/T8yQEgKxDxJ7ztO285tAMaYZVR6mM1GgI6CCn8FROtL1w=="
    },
    "regression": {
      "version": "2.0.1",
@@ -18300,9 +18995,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",
@@ -18397,7 +19092,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"
@@ -18406,7 +19101,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"
          }
@@ -18553,11 +19248,6 @@
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
    },
    "set-immediate-shim": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
    },
    "set-value": {
      "version": "2.0.1",
@@ -19188,6 +19878,22 @@
      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
    },
    "sql-formatter": {
      "version": "11.0.2",
      "resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-11.0.2.tgz",
      "integrity": "sha512-6QumAdGHEnI5dXEq1d0aBRP876AyA9Wp/UE7wopKNA2Mp9sKGRKVqGgoWHk4dr0J0nceesC85Y0p36qmGoNqhw==",
      "requires": {
        "argparse": "^2.0.1",
        "nearley": "^2.20.1"
      },
      "dependencies": {
        "argparse": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
          "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
        }
      }
    },
    "ssf": {
      "version": "0.10.2",
      "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.10.2.tgz",
@@ -19239,9 +19945,9 @@
      }
    },
    "staged-components": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/staged-components/-/staged-components-1.1.2.tgz",
      "integrity": "sha512-Fzf0qhYau/zn1pEsZSZml0b8vvGvdC+xo71jM0TE8vtM/2VjRCGLWaPb3vH3csaLv4qcoXVMMcRIeSO+HTHehQ=="
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/staged-components/-/staged-components-1.1.3.tgz",
      "integrity": "sha512-9EIswzDqjwlEu+ymkV09TTlJfzSbKgEnNteUnZSTxkpMgr5Wx2CzzA9WcMFWBNCldqVPsHVnRGGrApduq2Se5A=="
    },
    "static-extend": {
      "version": "0.1.2",
@@ -19438,7 +20144,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"
      }
@@ -19879,6 +20585,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",
@@ -19911,7 +20622,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",
@@ -20470,11 +21181,6 @@
      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
    },
    "use-async-memo": {
      "version": "1.2.3",
      "resolved": "https://registry.npmjs.org/use-async-memo/-/use-async-memo-1.2.3.tgz",
      "integrity": "sha512-AjZ1Wy1vfOSlaxohqoLIpauV+jwph/p0N72PBzxeEcjrZ4Mf/4o1Vav4bLaAPYuHLJZo+4M/4TIcAk7XC6H98g=="
    },
    "use-subscription": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.4.1.tgz",
@@ -20482,6 +21188,11 @@
      "requires": {
        "object-assign": "^4.1.1"
      }
    },
    "use-sync-external-store": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.1.0.tgz",
      "integrity": "sha512-SEnieB2FPKEVne66NpXPd1Np4R1lTNKfjuy3XdIoPQKYBAFdzbzSZlSn1KJZUiihQLQC5Znot4SBz1EOTBwQAQ=="
    },
    "util": {
      "version": "0.10.3",
@@ -20516,6 +21227,11 @@
      "version": "0.4.0",
      "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",
@@ -20994,14 +21710,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": {
@@ -21323,9 +22039,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",
@@ -21339,28 +22055,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
@@ -6,14 +6,16 @@
    "@ant-design/icons": "^4.6.2",
    "@antv/data-set": "^0.11.4",
    "@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",
    "@typescript-eslint/parser": "1.13.0",
    "@uiw/react-codemirror": "^2.2.1",
    "antd": "^3.26.20",
    "antd-mobile": "^5.0.0-rc.6",
    "antd-mobile": "^5.14.2",
    "axios": "^0.19.0",
    "babel-eslint": "10.0.2",
    "babel-jest": "^24.8.0",
@@ -27,6 +29,7 @@
    "camelcase": "^5.2.0",
    "case-sensitive-paths-webpack-plugin": "2.2.0",
    "codemirror": "^5.52.2",
    "crypto-js": "^4.1.1",
    "css-loader": "2.1.1",
    "dotenv": "6.2.0",
    "dotenv-expand": "4.2.0",
@@ -43,6 +46,7 @@
    "eslint-plugin-react-hooks": "^1.6.1",
    "exceljs": "^4.2.1",
    "file-loader": "3.0.1",
    "file-saver": "^2.0.5",
    "fs-extra": "7.0.1",
    "html-webpack-plugin": "4.0.0-beta.5",
    "html2canvas": "^1.0.0-rc.7",
@@ -58,6 +62,7 @@
    "js-table2excel": "^1.0.3",
    "jsbarcode": "^3.11.3",
    "jssha": "^3.2.0",
    "jszip": "^3.10.0",
    "md5": "^2.2.1",
    "mini-css-extract-plugin": "0.5.0",
    "moment": "^2.24.0",
@@ -91,6 +96,7 @@
    "sass-loader": "7.2.0",
    "semver": "6.3.0",
    "spark-md5": "^3.0.1",
    "sql-formatter": "^11.0.2",
    "style-loader": "1.0.0",
    "terser-webpack-plugin": "1.4.1",
    "ts-pnp": "1.1.2",
public/README.txt
@@ -4,13 +4,17 @@
appkey            -- 云端生成的应用密钥
mainSystemApi     -- 业务系统的单点登录链接地址,开发系统地址为http://sso.mk9h.cn/cloud/webapi/dostars,生产系统需要依据搭建的单点登录系统自行修改配置
systemType        -- 系统类型,正式系统是填production,开发系统为空,开发系统会有一部分的数据模糊化
externalDatabase  -- 外联库,不使用时默认为false
externalDatabase  -- 外联库,不使用时默认为 false
lineColor         -- 登录页分割线颜色
filter            -- 页面滤镜,值为"true"时,页面显示为黑白色;当设置为日期时(YYYY-MM-DD),截止到当前日期,页面显示为黑白色
filter            -- 页面滤镜,值为 true 时,页面显示为黑白色;当设置为日期时(YYYY-MM-DD),截止到当前日期,页面显示为黑白色
defaultApp        -- 默认应用,系统默认打开某个子应用时需填写应用编码
defaultLang       -- 打开的子应用语言类型,默认为zh-CN
WXAppID           -- 使用公众号时,绑定的公众号ID
debugger          -- 值为true时开启调试模式,开启后移动端子应用中会有控制台
WXminiAppID       -- 使用微信小程序时,绑定的小程序ID
nginx             -- 是否开启了nginx服务,值为 true 时开启,如需使用微信模板消息等服务,请先设置nginx服务并开启此配置
debugger          -- 值为 true 时开启调试模式,开启后移动端子应用中会有控制台
licenseKey        -- 许可密钥,在内部网络中使用系统时,会跳过epc验证
probation         -- 试用期(YYYY-MM-DD),在正式系统中,试用期内调用系统接口的脚本会记录下来
keepPassword      -- 记住密码,默认开启,当值为"false"时禁用
transfer          -- 是否使用转接口,使用转接口时请设置为 true, 使用转接口时,外部接口调用前不会做登录验证
keepPassword      -- 记住密码,默认开启,当值为 false 时禁用
platforms         -- 移动端可使用的平台类型,默认为 ["H5", "wechat", "android", "ios", "wxMiniProgram"] 分别代表H5页面、微信公众号、安卓APP、苹果APP、微信小程序
public/admin.html
@@ -20,13 +20,14 @@
            if (!config) {
              document.body.innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh;">系统配置信息获取失败,请联系管理员!</div>'
            } else {
              var url = window.location.href.split(/(index.html)+/ig)[0]
              var appPort = 'admin/index.html'
              var url = window.location.href.split(/index\.html|#/ig)[0].replace(/\/$/ig, '')
              var appPort = '/admin/index.html'
              if (config.defaultApp) {
                if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
                  appPort = 'mob/index.html#/index'
                  appPort = '/mob/index.html#/index'
                } else {
                  appPort = 'pc/index.html#/index'
                  appPort = '/pc/index.html#/index'
                }
              }
              window.location.replace(url + appPort)
public/options.json
@@ -6,12 +6,17 @@
  "externalDatabase": "mkdata_kress_test",
  "lineColor": "",
  "filter": "false",
  "defaultApp": "mk",
  "defaultApp": "",
  "defaultLang": "zh-CN",
  "WXAppID": "",
  "WXAppID": "wxa5dd6f28cae613fc",
  "WXminiAppID": "",
  "nginx": "true",
  "debugger": false,
  "licenseKey": "",
  "probation": "",
  "transfer": "false",
  "keepPassword": "true",
  "platforms": ["H5", "wechat", "android", "ios", "wxMiniProgram"],
  "host": "http://bms-test.kresstools.cn",
  "service": "oc/"
}
src/api/cacheutils.js
@@ -5,10 +5,9 @@
  /**
   * @description 打开websql
   */
  static openWebSql (sysType) {
    let service = window.GLOB.service ? '-' + window.GLOB.service.replace('/', '') : ''
  static openWebSql (db) {
    try {
      window.GLOB.WebSql = openDatabase(`mkdb${service}`, '1', 'mk-pc-database', 50 * 1024 * 1024)
      window.GLOB.WebSql = openDatabase(db, '1', 'mk-pc-database', 50 * 1024 * 1024)
      window.GLOB.WebSql.transaction(tx => {
        tx.executeSql('CREATE TABLE IF NOT EXISTS VERSIONS (version varchar(50), createDate varchar(50), CDefine1 varchar(50), CDefine2 varchar(50), CDefine3 varchar(50))', [], () => {
        
@@ -23,7 +22,7 @@
          throw 'CREATE TABLE ERROR'
        })
        if (sysType === 'local' && window.GLOB.systemType === '') {
        if (window.GLOB.systemType === '') {
          tx.executeSql('CREATE TABLE IF NOT EXISTS FUNCS (func_code varchar(50), key_sql text, CDefine1 varchar(50), CDefine2 varchar(50), CDefine3 varchar(50))', [], () => {
          }, () => {
@@ -45,8 +44,9 @@
  /**
   * @description 清空函数
   */
  static clearFuncs (sysType) {
    if (sysType !== 'local' || window.GLOB.systemType !== '') return
  static clearFuncs () {
    if (window.GLOB.systemType !== '') return
    if (window.GLOB.WebSql) {
      window.GLOB.WebSql.transaction(tx => {
        tx.executeSql('DELETE FROM FUNCS')
@@ -57,8 +57,7 @@
      let objectStore = window.GLOB.IndexDB.transaction(['funcs'], 'readwrite').objectStore('funcs')
      objectStore.clear()
      let funcStore = window.GLOB.IndexDB.transaction(['version'], 'readwrite').objectStore('version')
      funcStore.put({id: 'funcs', version: '1.0', createDate: '1970-01-01 14:59:09.000'})
      window.GLOB.IndexDB.transaction(['version'], 'readwrite').objectStore('version').delete('funcs')
    }
  }
@@ -69,32 +68,55 @@
    if (!window.GLOB.WebSql) {
      return Promise.reject()
    }
    return new Promise((resolve, reject) => {
      window.GLOB.WebSql.transaction(tx => {
        tx.executeSql("SELECT * FROM VERSIONS where CDefine1='LongParam'", [], (tx, results) => {
          if (results.rows.length === 0) {
            tx.executeSql('DELETE FROM VERSIONS')
            tx.executeSql('DELETE FROM CONFIGS')
    let deffers = []
    deffers.push(
      new Promise((resolve) => {
        window.GLOB.WebSql.transaction(tx => {
          tx.executeSql("SELECT * FROM VERSIONS where CDefine1='LongParam'", [], (tx, results) => {
            if (results.rows[0]) {
              resolve(results.rows[0])
            } else {
              resolve({version: '', createDate: ''})
            }
          }, (tx, results) => {
            console.warn(results)
            resolve({version: '', createDate: ''})
          } else {
            resolve(results.rows[0])
          }
        }, (tx, results) => {
          window.GLOB.WebSql = null
          reject()
          console.warn(results)
          })
        })
      })
    })
  }
    )
  /**
   * @description 清空websql中保存的配置信息
   */
  static clearWebSqlConfig () {
    if (!window.GLOB.WebSql) return
    window.GLOB.WebSql.transaction(tx => {
      tx.executeSql(`DELETE FROM CONFIGS`, [], () => {}, () => { window.GLOB.WebSql = null })
    deffers.push(
      new Promise((resolve) => {
        window.GLOB.WebSql.transaction(tx => {
          tx.executeSql(`SELECT * FROM CONFIGS`, [], (tx, results) => {
            let menus = []
            for (let i = 0; i < results.rows.length; i++) {
              menus.push(`'${results.rows[i].menuid}','${results.rows[i].openEdition || 'mk'}'`)
            }
            resolve(menus)
          }, (tx, results) => {
            console.warn(results)
            resolve([])
          })
        })
      })
    )
    return new Promise((resolve) => {
      Promise.all(deffers).then(res => {
        let result = res[0]
        if (result.createDate && !/^\d{4}-\d{2}-\d{2}/.test(result.createDate)) {
          result.createDate = ''
        }
        result.menuids = res[1].join(';')
        resolve(result)
      })
    })
  }
@@ -102,12 +124,21 @@
   * @description 删除websql中保存的配置信息
   */
  static delWebSqlConfig (keys) {
    if (!window.GLOB.WebSql || !keys) return
    window.GLOB.WebSql.transaction(tx => {
      tx.executeSql(`DELETE FROM CONFIGS where menuid in (${keys})`, [], () => {}, () => {
        window.GLOB.WebSql = null
    if (!window.GLOB.WebSql) return
    if (!keys) {
      window.GLOB.WebSql.transaction(tx => {
        tx.executeSql(`DELETE FROM CONFIGS`, [], () => {}, (tx, results) => {
          console.warn(results)
        })
      })
    })
    } else {
      window.GLOB.WebSql.transaction(tx => {
        tx.executeSql(`DELETE FROM CONFIGS where menuid in (${keys})`, [], () => {}, (tx, results) => {
          console.warn(results)
        })
      })
    }
  }
  /**
@@ -119,22 +150,10 @@
      window.GLOB.WebSql.transaction(tx => {
        tx.executeSql(`DELETE FROM CONFIGS where menuid='${menuId}'`, [], () => {
          resolve()
        }, () => {
          window.GLOB.WebSql = null
        }, (tx, results) => {
          console.warn(results)
          resolve()
        })
      })
    })
  }
  /**
   * @description 更新websql中配置信息的保存时间
   */
  static updateWebSqlTime (curTime) {
    if (!window.GLOB.WebSql || !curTime) return
    window.GLOB.WebSql.transaction(tx => {
      tx.executeSql(`UPDATE VERSIONS SET createDate='${curTime}' where CDefine1='LongParam'`, [], () => {}, () => {
        window.GLOB.WebSql = null
      })
    })
  }
@@ -143,23 +162,16 @@
   * @description 更新websql中配置信息的版本
   */
  static updateWebSqlversion (version, curTime) {
    if (!window.GLOB.WebSql || !curTime || !version) return
    if (!window.GLOB.WebSql) return
    window.GLOB.WebSql.transaction(tx => {
      tx.executeSql(`UPDATE VERSIONS SET version='${version}', createDate='${curTime}' where CDefine1='LongParam'`, [], () => {}, () => {
        window.GLOB.WebSql = null
      })
    })
  }
  /**
   * @description 创建websql中配置信息的版本
   */
  static createWebSqlversion (version, curTime) {
    if (!window.GLOB.WebSql || !curTime || !version) return
    window.GLOB.WebSql.transaction(tx => {
      tx.executeSql('INSERT INTO VERSIONS (version, createDate, CDefine1) VALUES (?, ?, ?)', [version, curTime, 'LongParam'], () => {}, () => {
        window.GLOB.WebSql = null
      })
      tx.executeSql(`DELETE FROM VERSIONS where CDefine1='LongParam'`)
      if (version) {
        tx.executeSql('INSERT INTO VERSIONS (version, createDate, CDefine1) VALUES (?, ?, ?)', [version, curTime, 'LongParam'], () => {}, (tx, results) => {
          console.warn(results)
        })
      }
    })
  }
@@ -187,7 +199,6 @@
            reject()
          }
        }, (tx, results) => {
          window.GLOB.WebSql = null
          console.warn(results)
          reject()
        })
@@ -208,10 +219,9 @@
  /**
   * @description 打开IndexedDB
   */
  static openIndexDB (sysType) {
    let service = window.GLOB.service ? '-' + window.GLOB.service.replace('/', '') : ''
  static openIndexDB (db) {
    try {
      let request = window.indexedDB.open(`mkdb${service}`, 1)
      let request = window.indexedDB.open(db, 1)
      request.onerror = () => {
        console.warn('IndexedDB 初始化失败!')
      }
@@ -228,7 +238,7 @@
          objectStore.createIndex('menuid', 'menuid', { unique: false })
          objectStore.createIndex('userid', 'userid', { unique: false })
        }
        if (window.GLOB.systemType === '' && sysType === 'local' && !window.GLOB.IndexDB.objectStoreNames.contains('funcs')) {
        if (window.GLOB.systemType === '' && !window.GLOB.IndexDB.objectStoreNames.contains('funcs')) {
          window.GLOB.IndexDB.createObjectStore('funcs', { keyPath: 'id' })
        }
      }
@@ -245,38 +255,66 @@
    if (!window.GLOB.IndexDB) {
      return Promise.reject()
    }
    return new Promise((resolve, reject) => {
      let request = window.GLOB.IndexDB.transaction(['version'])
        .objectStore('version')
        .get('mksoft')
      request.onerror = (event) => {
        window.GLOB.IndexDB = null
        console.warn(event)
        reject()
      }
    let deffers = []
      request.onsuccess = () => {
        if (request.result) {
          resolve(request.result)
        } else {
          this.clearIndexDBConfig()
    deffers.push(
      new Promise((resolve) => {
        let request = window.GLOB.IndexDB.transaction(['version'])
          .objectStore('version')
          .get('mksoft')
        request.onerror = (event) => {
          window.GLOB.IndexDB = null
          console.warn(event)
          resolve({version: '', createDate: ''})
        }
      }
        request.onsuccess = () => {
          if (request.result) {
            resolve(request.result)
          } else {
            resolve({version: '', createDate: ''})
          }
        }
      })
    )
    deffers.push(
      new Promise((resolve) => {
        let request = window.GLOB.IndexDB.transaction(['configs']).objectStore('configs').openCursor()
        let menus = []
        request.onerror = () => {
          window.GLOB.IndexDB = null
          resolve(menus)
        }
        request.onsuccess = (e) => {
          let cursor = e.target.result
          if (cursor) {
            menus.push(`'${cursor.value.menuid}','${cursor.value.open_edition || 'mk'}'`)
            cursor.continue()
          } else {
            resolve(menus)
          }
        }
      })
    )
    return new Promise((resolve) => {
      Promise.all(deffers).then(res => {
        let result = res[0]
        if (result.createDate && !/^\d{4}-\d{2}-\d{2}/.test(result.createDate)) {
          result.createDate = ''
        }
        result.menuids = res[1].join(';')
        resolve(result)
      })
    })
  }
  /**
   * @description 清空IndexedDB中保存的配置信息
   */
  static clearIndexDBConfig () {
    if (!window.GLOB.IndexDB) return
    let request = window.GLOB.IndexDB.transaction(['configs'], 'readwrite').objectStore('configs').clear()
    request.onerror = () => {
      window.GLOB.IndexDB = null
    }
  }
  /**
@@ -285,29 +323,35 @@
  static updateIndexDBversion (version) {
    if (!window.GLOB.IndexDB || !version) return
    version.id = 'mksoft'
    if (!version) {
      let request = window.GLOB.IndexDB.transaction(['configs'], 'readwrite').objectStore('configs').delete('mksoft')
      request.onerror = () => {
        window.GLOB.IndexDB = null
      }
    } else {
      version.id = 'mksoft'
    let objectStore = window.GLOB.IndexDB.transaction(['version'], 'readwrite').objectStore('version')
    let request = objectStore.get('mksoft')
    request.onerror = () => {
      window.GLOB.IndexDB = null
    }
    request.onsuccess = () => {
      if (request.result) {
        let put = objectStore.put(version)
        put.onerror = () => {
          window.GLOB.IndexDB = null
        }
      } else {
        this.clearIndexDBConfig()
        let add = objectStore.add(version)
        add.onerror = () => {
          window.GLOB.IndexDB = null
      let objectStore = window.GLOB.IndexDB.transaction(['version'], 'readwrite').objectStore('version')
      let request = objectStore.get('mksoft')
      request.onerror = () => {
        window.GLOB.IndexDB = null
      }
      request.onsuccess = () => {
        if (request.result) {
          let put = objectStore.put(version)
          put.onerror = () => {
            window.GLOB.IndexDB = null
          }
        } else {
          let add = objectStore.add(version)
          add.onerror = () => {
            window.GLOB.IndexDB = null
          }
        }
      }
    }
@@ -337,24 +381,30 @@
  /**
   * @description 删除IndexedDB中保存的配置信息-批量
   */
  static delIndexDBConfig (keys) {
    if (!window.GLOB.IndexDB || !keys) return
  static delIndexDBConfig (menuids) {
    if (!window.GLOB.IndexDB) return
    let objectStore = window.GLOB.IndexDB.transaction(['configs'], 'readwrite').objectStore('configs')
    if (!menuids) {
      let request = window.GLOB.IndexDB.transaction(['configs'], 'readwrite').objectStore('configs').clear()
      request.onerror = () => {
        window.GLOB.IndexDB = null
      }
    } else {
      let request = window.GLOB.IndexDB.transaction(['configs'], 'readwrite').objectStore('configs').openCursor()
      request.onerror = () => {
        window.GLOB.IndexDB = null
      }
    objectStore.openCursor().onsuccess = (event) => {
      let cursor = event.target.result
      if (cursor) {
        if (cursor.value && keys.includes(cursor.value.menuid)) {
          let request = objectStore.delete(cursor.key)
          request.onerror = () => {
            window.GLOB.IndexDB = null
      request.onsuccess = (e) => {
        let cursor = e.target.result
        if (cursor) {
          if (menuids.includes(cursor.value.menuid)) {
            cursor.delete()
          }
          cursor.continue()
        }
        cursor.continue()
      }
    }
  }
@@ -365,6 +415,7 @@
  static getIndexDBMenuConfig (MenuID, userid) {
    if (!window.GLOB.IndexDB || !MenuID || !userid) return Promise.reject()
    let key = MenuID + userid
    return new Promise((resolve, reject) => {
      let request = window.GLOB.IndexDB.transaction(['configs']).objectStore('configs').get(key)
src/api/direct.js
New file
@@ -0,0 +1,113 @@
import axios from 'axios'
import jsSHA from 'jssha'
class DirectApi {
  /**
   * @description 鉴权挑战
   * @param {Object} param 查询及提交参数
   */
  w4kLogin (ip, username = 'admin', password) {
    return new Promise((resolve, reject) => {
      let challurl = ip + '/api/auth/login/challenge?username=' + username
      challurl = '/trans/redirect?rd=' + challurl + '&method=get'
      let loginurl = ip + '/api/auth/login'
      loginurl = '/trans/redirect?rd=' + loginurl + '&method=post'
      axios({
        url: challurl,
        method: 'post' // get
      }).then(res => {
        if (res.errors) {
          reject(res)
        } else {
          const shaObj = new jsSHA('SHA-256', 'TEXT', { encoding: 'UTF8' })
          shaObj.update(password + res.salt + res.challenge)
          const hash = shaObj.getHash('HEX')
          axios({
            url: loginurl,
            method: 'post',
            data: {
              session_id: res.session_id,
              username: username,
              password: hash
            }
          }).then(result => {
            resolve(result)
          }, (err) => {
            reject(err)
          })
        }
      }, (err) => {
        reject(err)
      })
    })
  }
  w4kQueryUsers (ip) {
    let url = ip + '/api/persons/query'
    url = '/trans/redirect?rd=' + url + '&method=post'
    return axios({
      url: url,
      method: 'POST',
      withCredentials: true,
      headers: { 'Content-Type': 'application/json' },
      data: {
        limit: 100,
        offset: 0,
        sort: 'desc',
        query_id: '',
        query_string: ''
      }
    })
  }
  w4kAddUsers (ip, data) {
    return new Promise((resolve, reject) => {
      let delurl = ip + '/api/persons/item/' + data.id
      delurl = '/trans/redirect?rd=' + delurl + '&method=DELETE'
      let addurl = ip + '/api/persons/item'
      addurl = '/trans/redirect?rd=' + addurl + '&method=post'
      if (data.deleted) {
        delete data.deleted
        axios({
          url: delurl,
          method: 'post' // DELETE
        }).then(res => {
          if (res.errors) {
            reject(res)
          } else {
            axios({
              url: addurl,
              method: 'post',
              data: data
            }).then(result => {
              resolve(result)
            }, (err) => {
              reject(err)
            })
          }
        }, (err) => {
          reject(err)
        })
      } else {
        delete data.deleted
        axios({
          url: addurl,
          method: 'post',
          data: data
        }).then(result => {
          resolve(result)
        }, (err) => {
          reject(err)
        })
      }
    })
  }
}
export default new DirectApi()
src/api/index.js
@@ -2,6 +2,7 @@
import qs from 'qs'
import { notification } from 'antd'
import md5 from 'md5'
import CryptoJS from 'crypto-js'
import jsSHA from 'jssha'
import moment from 'moment'
import Utils from '@/utils/utils.js'
@@ -10,16 +11,20 @@
window.GLOB.WebSql = null
window.GLOB.IndexDB = null
const systemMenuKeys = `1581067625930haged11ieaivpavv77k,1581734956310scks442ul2d955g9tu5,1583991994144ndddg0bhh0is6shi0v1,1583979633842550imkchl4qt4qppsiv,1578900109100np8aqd0a77q3na46oas,16044812935562g807p3p12huk8kokmb,
window.GLOB.OuterToken = {}
const systemMenuKeys = `1581067625930haged11ieaivpavv77k,1581734956310scks442ul2d955g9tu5,1583991994144ndddg0bhh0is6shi0v1,1583979633842550imkchl4qt4qppsiv,1578900109100np8aqd0a77q3na46oas,
  1585192949946f3et2ts8tn82krmumdf,15855615451212m12ip23vpcm79kloro,1587005717541lov40vg61q7l1rbveon,1590458676585agbbr63t6ihighg2i1g,1602315375262ikd33ii0nii34pt861o,1582771068837vsv54a089lgp45migbg,
  1582777675954ifu05upurs465omoth7,158294809668898cklbv6c5bou8e1fpu,1584676379094iktph45fb8imhg96bql,1584695125339vo5g7iqgfn01qmrd6s2,1584699661372vhmpp9dn9foo0eob722,15848421131551gg04ie8sitsd3f7467,
  1589782279158ngr675kk3oksin35sul,1589788042787ffdt9hle4s45k9r1nvs,15900310928174dro07ihfckghpb5h13,1594095599055qicg2eb642v5qglhnuo,1599613340050c8nu6rbst9d4emnnbsq,1577972969199lei1g0qkvlh4tkc908m,
  1589782279158ngr675kk3oksin35sul,1589788042787ffdt9hle4s45k9r1nvs,1594095599055qicg2eb642v5qglhnuo,1577972969199lei1g0qkvlh4tkc908m,16044812935562g807p3p12huk8kokmb,
  1578479100252lfbp29v1kafk4s4q4ig,1577971621421tg4v0i1ur8873k7e0ob,1577929944419lgc5h3hepum765e2k7u,1588493493409k9guqp067d31lu7blsv,15827879285193g85m3i2uprektpgmpf`
let service = window.GLOB.service ? '-' + window.GLOB.service.replace('/', '') : ''
let db = `mkdb${service}`
if (window.openDatabase) {
  CacheUtils.openWebSql(options.sysType)
  CacheUtils.openWebSql(db)
} else if (window.indexedDB) {
  CacheUtils.openIndexDB(options.sysType)
  CacheUtils.openIndexDB(db)
}
axios.defaults.crossDomain = true
@@ -27,9 +32,9 @@
axios.defaults.withCredentials = false
axios.interceptors.request.use((config) => {
  if (config.url.includes('LoginAndRedirect') || config.url.includes('getjsonresult') || config.url.includes('wxNativePay')) {
  if (/LoginAndRedirect|getjsonresult|wxNativePay|postek/ig.test(config.url)) {
    config.data = qs.stringify(config.data)
  } else if (config.url.includes('Upload') || 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)
@@ -55,6 +60,7 @@
    localStorage.removeItem('localDataM')
    localStorage.removeItem('debug')
    localStorage.removeItem('role_id')
    localStorage.removeItem('mk_user_type')
    localStorage.removeItem('localRole_id')
    sessionStorage.clear()
@@ -76,25 +82,27 @@
    return Promise.resolve(response.data)
  }
}, (error) => {
  if (error && error.response) {
    notification.error({
      className: 'notification-custom-error',
      bottom: 0,
      message: '状态码-' + error.response.status + ',请联系管理员',
      placement: 'bottomRight',
      duration: 15
    })
  let response = error.response
  if (response) {
    if (!response.data || !response.data.errors) { // 过滤旷视报错信息
      notification.error({
        className: 'notification-custom-error',
        bottom: 0,
        message: '状态码-' + response.status + ',请联系管理员',
        placement: 'bottomRight',
        duration: 15
      })
    }
    return Promise.reject(response)
  } else {
    return Promise.reject()
  }
  return Promise.reject(error.response)
})
class Api {
  constructor() {
    if (process.env.NODE_ENV === 'production') {
      axios.defaults.baseURL = document.location.origin + '/' + window.GLOB.service
    } else {
      axios.defaults.baseURL = window.GLOB.location + '/' + window.GLOB.service
    }
    axios.defaults.baseURL = window.GLOB.baseurl
  }
  
  /**
@@ -105,13 +113,14 @@
    param.userid = param.userid || ''
    return axios({
      url: '/webapi/dostar',
      url: `/webapi/dostar${param.func ? '/' + param.func : ''}`,
      method: 'post',
      data: param
    })
  }
  /**
<<<<<<< HEAD
   * @description 使用dostar接口,跳过验证
   * @param {Object} param 查询及提交参数
   */
@@ -131,6 +140,72 @@
  }
  /* @description 直接请求
=======
   * @description 微信业务请求
   */
  wxAccessToken () {
    let _url = window.GLOB.baseurl + 'wxpay/getaccesstoken'
    if (process.env.NODE_ENV !== 'production') {
      _url = document.location.origin + '/wxpay/getaccesstoken'
    }
    return new Promise(resolve => {
      if (window.GLOB.accessToken.accessTime && (parseInt(new Date().getTime() / 1000) - window.GLOB.accessToken.accessTime < 30)) {
        resolve(window.GLOB.accessToken)
      } else {
        window.GLOB.accessToken = {}
        axios({
          url: _url,
          method: 'get'
        }).then(res => {
          if (res.oa_access_token || res.mini_access_token) {
            window.GLOB.accessToken.accessTime = parseInt(new Date().getTime() / 1000)
            window.GLOB.accessToken.oa_access_token = res.oa_access_token
            window.GLOB.accessToken.mini_access_token = res.mini_access_token
          }
          resolve(res)
        })
      }
    })
  }
  /**
   * @description 微信业务请求
   */
  wxNginxRequest (url, method, param) {
    let _url = window.GLOB.location + '/' + url
    if (process.env.NODE_ENV === 'production') {
      _url = document.location.origin + '/' + url
    }
    if (/^http:\/\/(qingqiumarket.cn|cloud.mk9h.cn|sso.mk9h.cn)/.test(_url)) {
      _url = window.GLOB.location + ':8080/' + url
      if (process.env.NODE_ENV === 'production') {
        _url = document.location.origin + ':8080/' + url
      }
    } else if (/^https:\/\/(qingqiumarket.cn|cloud.mk9h.cn|sso.mk9h.cn)/.test(_url)) {
      _url = window.GLOB.location + ':8443/' + url
      if (process.env.NODE_ENV === 'production') {
        _url = document.location.origin + ':8443/' + url
      }
    }
    if (param) {
      return axios({
        url: _url,
        method,
        data: param
      })
    }
    return axios({
      url: _url,
      method
    })
  }
  /**
   * @description 直接请求
>>>>>>> positec
   * @param {Object} param 查询及提交参数
   */
  directRequest (url, method = 'post', param, cross) {
@@ -169,7 +244,7 @@
  /**
   * @description 游客登录
   */
  getTouristMsg (appid, openid, memberid, scanId) {
  getTouristMsg (binding_type, appid, openid, memberid, scanId) {
    let _SessionUid = localStorage.getItem('SessionUid')
    if (!_SessionUid) { // 手动清除SessionUid时,实时生成
@@ -182,27 +257,40 @@
      timestamp: moment().format('YYYY-MM-DD HH:mm:ss'), 
      SessionUid: _SessionUid,
      TypeCharOne: 'pc',
      kei_id: window.btoa(window.encodeURIComponent(window.GLOB.host))
      kei_id: window.btoa(window.encodeURIComponent(window.GLOB.host)),
      appkey: window.GLOB.appkey || ''
    }
    param.LText = md5(window.btoa(_SessionUid + param.timestamp))
    param.secretkey = md5(param.LText + 'mingke' + param.timestamp)
    param.appkey = window.GLOB.appkey || ''
    let url = '/webapi/dologon/s_visitor_login'
    if (window.GLOB.mainSystemApi) {
      param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon/s_visitor_login')
    }
    if (appid) {
    if (binding_type === 'mk') {
      param.binding_type = 'mk'
      param.thd_party_member_id = memberid
      param.thd_party_openid = openid
      param.thd_party_appid = appid
      param.id = scanId
    }
    } else if (binding_type === 'login_check') { // appid 此时为目标
      param.v_type = 'login_check'
      param.LoginUID = sessionStorage.getItem('LoginUID') || ''
      url = appid.replace(/\/webapi(.*)/, '/webapi/dologon/s_visitor_login')
    let url = '/webapi/dologon/s_visitor_login'
    if (window.GLOB.mainSystemApi) {
      // url = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon/s_visitor_login')
      param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon/s_visitor_login')
      if (!param.rduri) {
        param.rduri = window.GLOB.baseurl + 'webapi/dologon/s_visitor_login'
      }
      param.linkurl = appid.replace(/\/webapi(.*)/, '/index.html')
    }
    param.LText = md5(window.btoa(_SessionUid + param.timestamp + (param.linkurl || '')))
    // param.secretkey = md5(param.LText + 'mingke' + param.timestamp) // v_type 为空时
    let solt = md5((window.GLOB.appkey + window.btoa(window.GLOB.appkey + 'mingke') + 'mingke').toLowerCase()).slice(-6).toUpperCase()
    param.v_type = param.v_type || 'Y'
    param.secretkey = md5(param.LText + solt + param.timestamp)
    return axios({
      url: url,
@@ -226,23 +314,20 @@
      login_city: city,
      login_id_address: ipAddress,
      kei_id: window.btoa(window.encodeURIComponent(window.GLOB.host)),
      device_id: localStorage.getItem('SessionUid')
      device_id: localStorage.getItem('SessionUid'),
      appkey: window.GLOB.appkey || ''
    }
    param.appkey = window.GLOB.appkey || ''
    let url = '/webapi/dologon'
    if (isCloud) {
      param.debug = 'Y'
      if (options.cloudServiceApi) {
        // url = options.cloudServiceApi.replace(/\/webapi(.*)/, '/webapi/dologon')
        param.rduri = options.cloudServiceApi.replace(/\/webapi(.*)/, '/webapi/dologon')
      }
    } else if (window.GLOB.mainSystemApi) {
      if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'production') {
        param.linkurl = window.GLOB.linkurl
      }
      // url = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon')
      param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon')
    }
@@ -265,10 +350,10 @@
      login_city: city,
      login_id_address: ipAddress,
      kei_id: window.btoa(window.encodeURIComponent(window.GLOB.host)),
      device_id: localStorage.getItem('SessionUid')
      device_id: localStorage.getItem('SessionUid'),
      timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
      appkey: window.GLOB.appkey || ''
    }
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    let sys_datetime = sessionStorage.getItem('sys_datetime')
    let app_datetime = sessionStorage.getItem('app_datetime')
@@ -293,20 +378,22 @@
    // Type: 'X' 时
    // param.Password = Utils.formatOptions(password)
    param.appkey = window.GLOB.appkey || ''
    // positecgroup
    if (window.GLOB.appkey === '202011021844144334E823A3011414082AD77') {
      param.svccode = 'oms'
    }
    let url = '/webapi/dologon'
    if (isCloud) {
      param.debug = 'Y'
      if (options.cloudServiceApi) {
        // url = options.cloudServiceApi.replace(/\/webapi(.*)/, '/webapi/dologon')
        param.rduri = options.cloudServiceApi.replace(/\/webapi(.*)/, '/webapi/dologon')
      }
    } else if (window.GLOB.mainSystemApi) {
      if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'production') {
        param.linkurl = window.GLOB.linkurl
      }
      // url = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon')
      param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon')
    }
@@ -318,9 +405,39 @@
  }
  /**
   * @description 登录二次验证 // positecgroup
   */
  verifycode (verify) {
    let param = {
      certificate: 'certificate',
      captcha: verify.code,
      token: verify.token,
      ati: verify.ati,
      vid: verify.vid,
      uid: verify.uid,
      shopId: verify.shopId,
      loginId: verify.loginId,
      phone: verify.phone,
      sellerNick: verify.sellerNick,
      isRisk: verify.isRisk,
      requestId: verify.requestId,
      riskNum: verify.riskNum,
      username: verify.username
    }
    let url = '/webapi/dologon'
    return axios({
      url,
      method: 'post',
      data: param
    })
  }
  /**
   * @description 获取系统版本信息,启用或更新websql
   */
  getAppVersion (_resolve, _reject) {
  getAppVersion (reload) {
    if (!window.GLOB.WebSql && !window.GLOB.IndexDB) {
      return Promise.reject()
    }
@@ -330,20 +447,38 @@
    let app_datetime = sessionStorage.getItem('app_datetime')
    if (sys_datetime && app_datetime) {
      let seconds = Math.floor((new Date().getTime() - app_datetime) / 1000)
      curTime = moment(sys_datetime, 'YYYY-MM-DD HH:mm:ss').add(seconds, 'seconds').format('YYYY-MM-DD HH:mm:ss') + '.000'
      let _curTime = moment(sys_datetime, 'YYYY-MM-DD HH:mm:ss').add(seconds, 'seconds').format('YYYY-MM-DD HH:mm:ss') + '.000'
      if (/^\d{4}-\d{2}-\d{2}/.test(_curTime)) {
        curTime = _curTime
      }
    }
    if (window.GLOB.WebSql) {
      return new Promise((resolve, reject) => {
        CacheUtils.getWebSqlVersion().then(msg => {
          let modifydate = msg.createDate || curTime
          if (modifydate.indexOf('Invalid date') > -1) {
            modifydate = curTime
          }
          let param = {
            func: 's_get_app_version',
            modifydate
            modifydate: msg.createDate
          }
          param.TypeCharOne = ''
          param.typename = ''
          if (!msg.createDate && !msg.menuids) {
            CacheUtils.updateWebSqlversion('1.00', curTime)
            resolve()
            return
          } else if (!msg.createDate || reload === true) {
            param.modifydate = curTime
            param.menuids = window.btoa(msg.menuids)
          } else if (msg.menuids) {
            let d = localStorage.getItem(db)
            if (!d || curTime.indexOf(d) === -1) {
              param.menuids = window.btoa(msg.menuids)
            }
            localStorage.setItem(db, curTime.substr(0, 10))
          }
  
          this.getSystemConfig(param).then(res => {
@@ -351,29 +486,35 @@
              reject()
              return
            }
            let clear = false
            let version = '1.00'
            if (res.menu_data && res.menu_data.length > 0) {
              res.menu_data.forEach(mid => {
                if (systemMenuKeys.indexOf(mid.menuid) > -1) {
            let list = res.menu_data || []
            if (res.menu_del) {
              list.push(...res.menu_del)
            }
            list = list.map(mid => mid.menuid)
            if (typeof(reload) === 'string' && !list.includes(reload)) {
              list.push(reload)
            }
            if (list.length > 0) {
              let clear = false
              list.forEach(mid => {
                if (systemMenuKeys.indexOf(mid) > -1) {
                  clear = true
                }
              })
              if (clear) {
                CacheUtils.clearWebSqlConfig()
                list = ''
              } else {
                let keys = res.menu_data.map(mid => `'${mid.menuid}'`).join(',')
                CacheUtils.delWebSqlConfig(keys)
                list = list.map(mid => `'${mid}'`).join(',')
              }
              CacheUtils.delWebSqlConfig(list)
            }
            if (msg.version) {
              CacheUtils.updateWebSqlTime(curTime)
            } else {
              CacheUtils.createWebSqlversion(version, curTime)
            }
            CacheUtils.updateWebSqlversion(res.app_version || '1.00', curTime)
  
            resolve()
          })
@@ -384,13 +525,29 @@
    } else {
      return new Promise((resolve, reject) => {
        CacheUtils.getIndexDBVersion().then(msg => {
          let modifydate = msg.createDate || curTime
          if (modifydate.indexOf('Invalid date') > -1) {
            modifydate = curTime
          }
          let param = {
            func: 's_get_app_version',
            modifydate
            modifydate: msg.createDate
          }
          param.TypeCharOne = ''
          param.typename = ''
          if (!msg.createDate && !msg.menuids) {
            CacheUtils.updateIndexDBversion({version: '1.00', createDate: curTime})
            resolve()
            return
          } else if (!msg.createDate || reload === true) {
            param.modifydate = curTime
            param.menuids = window.btoa(msg.menuids)
          } else if (msg.menuids) {
            let d = localStorage.getItem(db)
            if (!d || curTime.indexOf(d) === -1) {
              param.menuids = window.btoa(msg.menuids)
            }
            localStorage.setItem(db, curTime.substr(0, 10))
          }
          this.getSystemConfig(param).then(res => {
@@ -398,25 +555,33 @@
              reject()
              return
            }
            let clear = false
            let version = '1.00'
  
            if (res.menu_data && res.menu_data.length > 0) {
              res.menu_data.forEach(mid => {
                if (systemMenuKeys.indexOf(mid.menuid) > -1) {
            let list = res.menu_data || []
            if (res.menu_del) {
              list.push(...res.menu_del)
            }
            list = list.map(mid => mid.menuid)
            if (typeof(reload) === 'string' && !list.includes(reload)) {
              list.push(reload)
            }
            if (list.length > 0) {
              let clear = false
              list.forEach(mid => {
                if (systemMenuKeys.indexOf(mid) > -1) {
                  clear = true
                }
              })
              if (clear) {
                CacheUtils.clearIndexDBConfig()
              } else {
                let keys = res.menu_data.map(mid => `'${mid.menuid}'`)
                CacheUtils.delIndexDBConfig(keys)
                list = ''
              }
              CacheUtils.delIndexDBConfig(list)
            }
            CacheUtils.updateIndexDBversion({version: version, createDate: curTime})
            CacheUtils.updateIndexDBversion({version: res.app_version || '1.00', createDate: curTime})
  
            resolve()
          })
@@ -431,12 +596,11 @@
   * @description 更新系统版本信息,清空配置信息
   */
  updateAppVersion () {
    let curTime = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
    CacheUtils.clearWebSqlConfig()
    CacheUtils.updateWebSqlversion('1.00', curTime)
    CacheUtils.clearIndexDBConfig()
    CacheUtils.updateIndexDBversion({version: '1.00', createDate: curTime})
    CacheUtils.clearFuncs(options.sysType)
    CacheUtils.delWebSqlConfig()
    CacheUtils.updateWebSqlversion()
    CacheUtils.delIndexDBConfig()
    CacheUtils.updateIndexDBversion()
    CacheUtils.clearFuncs()
  }
  /**
@@ -445,11 +609,6 @@
  deleteMenuStorage (menuId) {
    if (window.GLOB.IndexDB) {
      let key = menuId + (sessionStorage.getItem('UserID') || '')
      if (sessionStorage.getItem('isEditState') === 'true' && options.cloudServiceApi) {
        key = menuId + (sessionStorage.getItem('CloudUserID') || '')
      }
      return CacheUtils.delMenuIndexDBConfig(key)
    } else {
      return CacheUtils.delMenuWebSqlConfig(menuId)
@@ -520,32 +679,11 @@
      param.userid = sessionStorage.getItem('CloudUserID') || ''
      param.LoginUID = sessionStorage.getItem('CloudLoginUID') || ''
    } else if (window.GLOB.mainSystemApi) {
      url = window.GLOB.mainSystemApi
    }
    param = this.encryptParam(param)
    return axios({
      url: `${url}${param.func ? '/' + param.func : ''}`,
      method: 'post',
      data: param
    })
  }
  /**
   * @description 获取或修改本地配置,增加appkey
   */
  getLocalConfig (param) {
    param.userid = param.userid || sessionStorage.getItem('UserID') || ''
    param.lang = param.lang || sessionStorage.getItem('lang') || ''
    param.SessionUid = localStorage.getItem('SessionUid') || ''
    param.LoginUID = param.LoginUID || sessionStorage.getItem('LoginUID') || ''
    param.appkey = window.GLOB.appkey || ''
    let url = '/webapi/dostars'
    if (param.rduri) {
      url = param.rduri
      delete param.rduri
      if (!window.GLOB.transfer) {
        url = window.GLOB.mainSystemApi
      } else {
        param.rduri = window.GLOB.mainSystemApi
      }
    }
    param = this.encryptParam(param)
@@ -559,7 +697,6 @@
  /**
   * @description 获取系统配置,取值优先等级websql、缓存、服务器
   * @param {Object}  param   请求参数
   */
  getCacheConfig (param) {
    param.userid = sessionStorage.getItem('UserID') || ''
@@ -576,7 +713,11 @@
        param.LoginUID = sessionStorage.getItem('CloudLoginUID') || ''
      }
    } else if (window.GLOB.mainSystemApi) {
      url = window.GLOB.mainSystemApi
      if (!window.GLOB.transfer) {
        url = window.GLOB.mainSystemApi
      } else {
        param.rduri = window.GLOB.mainSystemApi
      }
    }
    let _param = JSON.parse(JSON.stringify(param)) // 缓存校验,去除时间和加密字符
@@ -671,11 +812,10 @@
  /**
   * @description 获取本地系统配置
   * @param {Object}  param   请求参数
   */
  getLocalCacheConfig (param) {
    param.userid = sessionStorage.getItem('UserID') || ''
    param.lang = param.lang || sessionStorage.getItem('lang') || ''
    param.lang = sessionStorage.getItem('lang') || ''
    param.SessionUid = localStorage.getItem('SessionUid') || ''
    param.LoginUID = sessionStorage.getItem('LoginUID') || ''
    param.appkey = window.GLOB.appkey || ''
@@ -742,17 +882,20 @@
    param.appkey = window.GLOB.appkey || ''
    let url = '/webapi/dostars'
    if (param.rduri) {
    if (param.rduri && !window.GLOB.transfer) { // positecgroup
      url = param.rduri
      delete param.rduri
    }
    let _param = JSON.parse(JSON.stringify(param)) // 缓存校验,去除时间和加密字符
    delete _param.timestamp
    delete _param.secretkey
    delete _param.open_key
    _param = JSON.stringify(_param)
    _param  = md5(_param)
    let _param = ''
    if (cache) {
      _param = JSON.parse(JSON.stringify(param)) // 缓存校验,去除时间和加密字符
      delete _param.timestamp
      delete _param.secretkey
      delete _param.open_key
      _param = JSON.stringify(_param)
      _param  = md5(_param)
    }
    if (cache && window.GLOB.CacheMap.has(_param)) {
      return Promise.resolve(window.GLOB.CacheMap.get(_param))
@@ -774,87 +917,257 @@
    }
  }
  /**
   * @description 获取业务通用接口
   */
  genericInterface (param) {
    param.userid = sessionStorage.getItem('UserID') || ''
    param.lang = sessionStorage.getItem('lang') || ''
    param.SessionUid = localStorage.getItem('SessionUid') || ''
    param.LoginUID = sessionStorage.getItem('LoginUID') || ''
    param.appkey = window.GLOB.appkey || ''
  visitOuterSystem (param, _resolve) {
    let token = param.$token
    delete param.$token
    if (options.cloudServiceApi && param.rduri === options.cloudServiceApi) { // HS下菜单
      param.userid = sessionStorage.getItem('CloudUserID') || param.userid || ''
      param.LoginUID = sessionStorage.getItem('CloudLoginUID') || param.LoginUID || ''
    try {
      token = JSON.parse(token)
      token = token.message
      const key = CryptoJS.enc.Utf8.parse(window.GLOB.appkey.slice(-16))
      const iv = CryptoJS.enc.Utf8.parse('mksoft')
      let encryptedHexStr = CryptoJS.enc.Hex.parse(token)
      let _srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr)
      let decrypt = CryptoJS.AES.decrypt(_srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 })
      let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)
      token = decryptedStr.toString()
      token = JSON.parse(window.decodeURIComponent(window.atob(token)))
    } catch (e) {
      token = null
      _resolve({status: false, ErrCode: 'E', message: '接口信息解析失败!'})
    }
    // 待优化,增加是否支持跨域请求
    // let url = '/webapi/dostars'
    // if (param.rduri) {
    //   url = param.rduri
    //   delete param.rduri
    // }
    if (!token) return
    param = this.encryptParam(param)
    let userid = ''
    let loginUid = ''
    let dataM = ''
    return axios({
      url: `/webapi/dostars${param.func ? '/' + param.func : ''}`,
      method: 'post',
      data: param
    })
  }
    if (window.GLOB.OuterToken[token.interface]) {
      let msg = window.GLOB.OuterToken[token.interface]
  /**
   * @description 导出Excel
   */
  getExcelOut (param, name) {
    param.userid = sessionStorage.getItem('UserID')
    param.lang = sessionStorage.getItem('lang') || ''
    param.SessionUid = localStorage.getItem('SessionUid') || ''
    param.LoginUID = sessionStorage.getItem('LoginUID') || ''
    param.appkey = window.GLOB.appkey || ''
    return new Promise(resolve => {
      let seconds = Math.floor((new Date().getTime() - msg.timestamp) / 1000)
      if (seconds >= 3600) {
        delete window.GLOB.OuterToken[token.interface]
      } else {
        userid = msg.userid
        loginUid = msg.loginUid
        dataM = msg.dataM || ''
      }
    }
    // param.appkey = token.appkey || ''
    if (userid && loginUid) {
      param.dataM = dataM
      param.userid = userid
      param.LoginUID = loginUid
      param = this.encryptParam(param)
      axios({
        url: '/webapi/doexcel',
        responseType: 'blob',
        url: token.interface,
        method: 'post',
        data: param
      }).then(res => {
        try {
          const blob = new Blob([res])
          if (res.type === 'application/json') {
            const reader = new FileReader()
            reader.onload = e => resolve(JSON.parse(e.target.result))
            reader.readAsText(blob)
          } else {
            if ('download' in document.createElement('a')) { // 非IE下载
              const elink = document.createElement('a')
              elink.download = name
              elink.style.display = 'none'
              elink.href = URL.createObjectURL(blob)
              document.body.appendChild(elink)
              elink.click()
              URL.revokeObjectURL(elink.href) // 释放URL 对象
              document.body.removeChild(elink)
            } else { // IE10+下载
              navigator.msSaveBlob(blob, name)
            }
            resolve()
        _resolve(res)
      })
    } else {
      let _param = {
        UserName: token.username,
        systemType: options.sysType,
        login_city: sessionStorage.getItem('city') || '',
        device_id: token.appkey || '',
        timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
        Type: token.publicKey,
        appkey: token.appkey || ''
      }
      let shaObj = new jsSHA('SHA-1', 'TEXT')
      shaObj.update(token.password)
      _param.Password = shaObj.getHash('HEX').toUpperCase()
      _param.Password = md5(token.privateKey + token.username + _param.Password + _param.timestamp)
      let url = token.interface.replace(/\/webapi(.*)/, '/webapi/dologon')
      if (token.ssoInterface) {
        _param.rduri = token.ssoInterface.replace(/\/webapi(.*)/, '/webapi/dologon')
      }
      axios({
        url,
        method: 'post',
        data: _param
      }).then(result => {
        if (result.status) {
          window.GLOB.OuterToken[token.interface] = {
            userid: result.UserID,
            loginUid: result.LoginUID,
            timestamp: new Date().getTime(),
            dataM: result.dataM ? 'Y' : ''
          }
        } catch (e) {
          resolve({
            ErrCode: 'E',
            ErrMesg: '文件解析错误',
            message: '',
            status: false
          param.dataM = result.dataM ? 'Y' : ''
          param.userid = result.UserID
          param.LoginUID = result.LoginUID
          param = this.encryptParam(param)
          axios({
            url: token.interface,
            method: 'post',
            data: param
          }).then(res => {
            _resolve(res)
          })
        } else {
          _resolve(result)
        }
      })
    })
    }
  }
  /**
   * @description 获取业务通用接口
   * 访问 'https://sso.mk9h.cn/webapi/dostars'或云端时,传入userid、LoginUID
   */
  genericInterface (param) {
    param.userid = param.userid || sessionStorage.getItem('UserID') || ''
    param.lang = param.lang || sessionStorage.getItem('lang') || ''
    param.SessionUid = localStorage.getItem('SessionUid') || ''
    param.LoginUID = param.LoginUID || sessionStorage.getItem('LoginUID') || ''
    param.appkey = window.GLOB.appkey || ''
    if (param.$token === '') {
      return Promise.resolve({status: false, ErrCode: 'E', message: '接口地址尚未设置!'})
    } else if (param.$token) {
      return new Promise(resolve => this.visitOuterSystem(param, resolve))
    }
    if (['sPC_Get_TableData', 'sPC_Get_TableData_debug', 'sPC_TableData_InUpDe', 'sPC_TableData_InUpDe_debug', 'sPC_Get_structured_data'].includes(param.func)) {
      if (sessionStorage.getItem('isEditState') === 'true') {
        param.username = sessionStorage.getItem('CloudUserName') || ''
        param.fullname = sessionStorage.getItem('CloudFullName') || ''
      } else {
        param.username = sessionStorage.getItem('User_Name') || ''
        param.fullname = sessionStorage.getItem('Full_Name') || ''
      }
    }
    let login = false
    let rduri = null
    if (param.rduri && /\s|\n/.test(param.rduri)) {
      param.rduri = param.rduri.replace(/\s|\n/g, '')
      if (!param.rduri) {
        delete param.rduri
      }
    }
    if (param.$login && !window.GLOB.transfer) {
      login = true
      rduri = param.rduri || ''
    }
    delete param.$login
    let url = '/webapi/dostars'
    if (param.rduri && !window.GLOB.transfer && /\/dostars/.test(param.rduri) && param.func !== 'webapi_ChangeUser') {
      url = param.rduri
      delete param.rduri
    }
    param = this.encryptParam(param)
    if (login) {
      let time = +sessionStorage.getItem(rduri)
      let c_time = Math.round(new Date().getTime() / 1000)
      if (time && c_time - time <= 60) {
        sessionStorage.setItem(rduri, c_time)
        return axios({
          url: `${url}${param.func ? '/' + param.func : ''}`,
          method: 'post',
          data: param
        })
      }
      return new Promise((resolve, reject) => {
        this.getTouristMsg('login_check', rduri).then(res => {
          if (res.status) {
            sessionStorage.setItem(rduri, c_time)
            axios({
              url: `${url}${param.func ? '/' + param.func : ''}`,
              method: 'post',
              data: param
            }).then(result => {
              resolve(result)
            })
          } else {
            resolve(res)
          }
        })
      })
    } else {
      return axios({
        url: `${url}${param.func ? '/' + param.func : ''}`,
        method: 'post',
        data: param
      })
    }
  }
  /**
   * @description 导出Excel,后台生成文件
   */
  // getExcelOut (param, name) {
  //   param.userid = sessionStorage.getItem('UserID')
  //   param.lang = sessionStorage.getItem('lang') || ''
  //   param.SessionUid = localStorage.getItem('SessionUid') || ''
  //   param.LoginUID = sessionStorage.getItem('LoginUID') || ''
  //   param.appkey = window.GLOB.appkey || ''
  //   return new Promise(resolve => {
  //     axios({
  //       url: '/webapi/doexcel',
  //       responseType: 'blob',
  //       method: 'post',
  //       data: param
  //     }).then(res => {
  //       try {
  //         const blob = new Blob([res])
  //         if (res.type === 'application/json') {
  //           const reader = new FileReader()
  //           reader.onload = e => resolve(JSON.parse(e.target.result))
  //           reader.readAsText(blob)
  //         } else {
  //           if ('download' in document.createElement('a')) { // 非IE下载
  //             const elink = document.createElement('a')
  //             elink.download = name
  //             elink.style.display = 'none'
  //             elink.href = URL.createObjectURL(blob)
  //             document.body.appendChild(elink)
  //             elink.click()
  //             URL.revokeObjectURL(elink.href) // 释放URL 对象
  //             document.body.removeChild(elink)
  //           } else { // IE10+下载
  //             navigator.msSaveBlob(blob, name)
  //           }
  //           resolve()
  //         }
  //       } catch (e) {
  //         resolve({
  //           ErrCode: 'E',
  //           ErrMesg: '文件解析错误',
  //           message: '',
  //           status: false
  //         })
  //       }
  //     })
  //   })
  // }
  /**
   * @description 上传base64
@@ -873,8 +1186,19 @@
    param = this.encryptParam(param)
    let url = '/webapi/SaveBase64Image'
    if (param.rduri) {
      url = param.rduri.replace(/webapi(.*)$/, 'webapi/SaveBase64Image')
      param.rduri = param.rduri.replace(/webapi(.*)$/, 'webapi/SaveBase64Image')
      if (/\s|\n/.test(param.rduri)) {
        param.rduri = param.rduri.replace(/\s|\n/g, '')
        if (!param.rduri) {
          delete param.rduri
        }
      }
    }
    if (param.rduri && !window.GLOB.transfer) {
      url = param.rduri
      delete param.rduri
    }
@@ -908,16 +1232,56 @@
  }
  /**
   * @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) {
    let _url = window.GLOB.baseurl + 'wxpay/wxNativePay'
    if (process.env.NODE_ENV !== 'production') {
      _url = document.location.origin + '/wxpay/wxNativePay'
    }
    return axios({
      url: '/wxpay/wxNativePay',
      url: _url,
      method: 'post',
      data: param
    })
  }
  postekPrint (data) {
    return axios({
      url: 'http://127.0.0.1:888/postek/print',
      method: 'post',
      data: data
    })
  }
  // /**
  //  * @description 文件上传
  //  */
src/assets/css/design.scss
New file
@@ -0,0 +1,88 @@
.ant-modal-wrap.mk-pop-modal {
  .ant-modal {
    top: 50px;
  }
  .ant-modal-body {
    padding: 0;
    min-height: 150px;
    .mk-com-name {
      position: absolute;
      top: 38px;
      left: 10px;
      color: rgba(0, 0, 0, 0.85);
      font-size: 15px;
    }
    .ant-tabs {
      .ant-tabs-nav-wrap {
        text-align: center;
      }
      .ant-tabs-bar {
        padding-top: 15px;
        .ant-tabs-nav-container {
          font-size: 15px;
        }
      }
      .ant-tabs-content {
        min-height: 50vh;
        max-height: calc(100vh - 210px);
        .ant-tabs-tabpane {
          position: relative;
          overflow-x: hidden;
          overflow-y: auto;
          padding: 0 24px 24px;
        }
        .ant-tabs-tabpane::-webkit-scrollbar {
          width: 7px;
        }
        .ant-tabs-tabpane::-webkit-scrollbar-thumb {
          border-radius: 5px;
          box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
          background: rgba(0, 0, 0, 0.13);
        }
        .ant-tabs-tabpane::-webkit-scrollbar-track {
          box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
          border-radius: 3px;
          border: 1px solid rgba(0, 0, 0, 0.07);
          background: rgba(0, 0, 0, 0);
        }
      }
    }
  }
}
.ant-modal {
  .ant-radio-group {
    white-space: nowrap;
    .ant-radio-wrapper {
      margin-right: 4px;
    }
  }
}
// 通行宽度
.mk-through-line2 {
  .ant-form-item-label {
    width: 16.5%;
  }
  .ant-form-item-control-wrapper {
    width: 83.5%;
  }
  .CodeMirror {
    height: 150px;
  }
}
.mk-through-line3 {
  .ant-form-item-label {
    width: 10.6%;
  }
  .ant-form-item-control-wrapper {
    width: 89.4%;
  }
  .CodeMirror {
    height: 200px;
  }
}
src/assets/css/main.scss
@@ -264,28 +264,6 @@
  }
}
.ant-modal.popview-modal {
  top: 70px;
  .ant-modal-body {
    min-height: 200px;
    max-height: calc(100vh - 210px);
    overflow-y: auto;
  }
  .ant-modal-body::-webkit-scrollbar {
    width: 7px;
  }
  .ant-modal-body::-webkit-scrollbar-thumb {
    border-radius: 5px;
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
    background: rgba(0, 0, 0, 0.13);
  }
  .ant-modal-body::-webkit-scrollbar-track {
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
    border-radius: 3px;
    border: 1px solid rgba(0, 0, 0, 0.07);
    background: rgba(0, 0, 0, 0);
  }
}
.ant-modal-wrap.popview-modal {
  .ant-modal {
    top: 70px;
@@ -310,6 +288,7 @@
    background: rgba(0, 0, 0, 0);
  }
}
// 设置模态框样式,规定最大最小高度,重置滚动条
.action-modal {
  .ant-modal {
@@ -441,12 +420,13 @@
    color: inherit!important;
  }
}
// .ant-table.ant-table-mini .ant-table-thead > tr > th {
//   padding: 8px 4px;
// }
// .ant-table.ant-table-mini .ant-table-tbody > tr > td {
//   padding: 4px 4px;
// }
.ant-table.ant-table-mini .ant-table-thead > tr > th {
  padding: 8px 8px!important;
}
.ant-table.ant-table-mini .ant-table-tbody > tr > td {
  padding: 2px 8px!important;
  line-height: 1.5;
}
.mk-date-picker.minute {
  .ant-calendar-time-picker-combobox {
    .ant-calendar-time-picker-select {
@@ -468,4 +448,28 @@
      display: none;
    }
  }
}
.mk-button-progress {
  position: fixed!important;
  top: 0px;
  left: 0px;
  z-index: 1100;
  width: 100vw!important;
  .ant-progress-outer {
    .ant-progress-inner {
      vertical-align: top;
      background-color: transparent;
      .ant-progress-bg {
        height: 4px!important;
        background-color: var(--mk-sys-color);
      }
    }
  }
}
.video-wrap {
  overflow: hidden;
  .video-react .video-react-poster {
    background-size: cover;
  }
}
src/assets/css/viewstyle.scss
@@ -237,6 +237,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 {
@@ -423,6 +451,11 @@
      border-color: $color2;
    }
  }
  .mk-time-line-wrap.system {
    .mk-timeline-item-tail {
      border-color: $color2;
    }
  }
  .custom-tab-form-box .mk-normal-form-title.mkbtn {
    .form-title {
      color: $color6;
@@ -487,133 +520,139 @@
          }
        }
      }
      .header-menu::-webkit-scrollbar-track {
        box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.05);
        border: 1px solid rgba(255, 255, 255, 0.07);
        background: rgba(255, 255, 255, 255);
        border-radius: 3px;
      }
    }
  }
}
body.mk-blue-black {
  --antd-wave-shadow-color: #1890ff;
  --mk-sys-color: #1890ff;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65), #e6f7ff, #bae7ff, #91d5ff, #69c0ff, #40a9ff, #1890ff, #096dd9, #0050b3, #003a8c, #002766);
  @include bgblack();
}
body.mk-blue-white {
  --antd-wave-shadow-color: #1890ff;
  --mk-sys-color: #1890ff;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #e6f7ff, #bae7ff, #91d5ff, #69c0ff, #40a9ff, #1890ff, #096dd9, #0050b3, #003a8c, #002766);
}
body.mk-red-black {
  --antd-wave-shadow-color: #f5222d;
  --mk-sys-color: #f5222d;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65), #fff1f0, #ffccc7, #ffa39e, #ff7875, #ff4d4f, #f5222d, #cf1322, #a8071a, #820014, #5c0011);
  @include bgblack();
}
body.mk-red-white {
  --antd-wave-shadow-color: #f5222d;
  --mk-sys-color: #f5222d;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff1f0, #ffccc7, #ffa39e, #ff7875, #ff4d4f, #f5222d, #cf1322, #a8071a, #820014, #5c0011);
}
body.mk-orange-red-black {
  --antd-wave-shadow-color: #fa541c;
  --mk-sys-color: #fa541c;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65), #fff2e8, #ffd8bf, #ffbb96, #ff9c6e, #ff7a45, #fa541c, #d4380d, #ad2102, #871400, #610b00);
  @include bgblack();
}
body.mk-orange-red-white {
  --antd-wave-shadow-color: #fa541c;
  --mk-sys-color: #fa541c;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff2e8, #ffd8bf, #ffbb96, #ff9c6e, #ff7a45, #fa541c, #d4380d, #ad2102, #871400, #610b00);
}
body.mk-orange-black {
  --antd-wave-shadow-color: #fa8c16;
  --mk-sys-color: #fa8c16;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65), #fff7e6, #ffe7ba, #ffd591, #ffc069, #ffa940, #fa8c16, #d46b08, #ad4e00, #873800, #612500);
  @include bgblack();
}
body.mk-orange-white {
  --antd-wave-shadow-color: #fa8c16;
  --mk-sys-color: #fa8c16;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff7e6, #ffe7ba, #ffd591, #ffc069, #ffa940, #fa8c16, #d46b08, #ad4e00, #873800, #612500);
}
body.mk-orange-yellow-black {
  --antd-wave-shadow-color: #faad14;
  --mk-sys-color: #faad14;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#fffbe6, #fff1b8, #ffe58f, #ffd666, #ffc53d, #faad14, #d48806, #ad6800, #874d00, #613400);
  @include bgblack();
}
body.mk-orange-yellow-white {
  --antd-wave-shadow-color: #faad14;
  --mk-sys-color: #faad14;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fffbe6, #fff1b8, #ffe58f, #ffd666, #ffc53d, #faad14, #d48806, #ad6800, #874d00, #613400);
}
body.mk-yellow-black {
  --antd-wave-shadow-color: #fadb14;
  --mk-sys-color: #fadb14;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#feffe6, #ffffb8, #fffb8f, #fff566, #ffec3d, #fadb14, #d4b106, #ad8b00, #876800, #614700);
  @include bgblack();
}
body.mk-yellow-white {
  --antd-wave-shadow-color: #fadb14;
  --mk-sys-color: #fadb14;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #feffe6, #ffffb8, #fffb8f, #fff566, #ffec3d, #fadb14, #d4b106, #ad8b00, #876800, #614700);
}
body.mk-yellow-green-black {
  --antd-wave-shadow-color: #a0d911;
  --mk-sys-color: #a0d911;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#fcffe6, #f4ffb8, #eaff8f, #d3f261, #bae637, #a0d911, #7cb305, #5b8c00, #3f6600, #254000);
  @include bgblack();
}
body.mk-yellow-green-white {
  --antd-wave-shadow-color: #a0d911;
  --mk-sys-color: #a0d911;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fcffe6, #f4ffb8, #eaff8f, #d3f261, #bae637, #a0d911, #7cb305, #5b8c00, #3f6600, #254000);
}
body.mk-green-black {
  --antd-wave-shadow-color: #52c41a;
  --mk-sys-color: #52c41a;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#f6ffed, #d9f7be, #b7eb8f, #95de64, #73d13d, #52c41a, #389e0d, #237804, #135200, #092b00);
  @include bgblack();
}
body.mk-green-white {
  --antd-wave-shadow-color: #52c41a;
  --mk-sys-color: #52c41a;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #f6ffed, #d9f7be, #b7eb8f, #95de64, #73d13d, #52c41a, #389e0d, #237804, #135200, #092b00);
}
body.mk-cyan-black {
  --antd-wave-shadow-color: #13c2c2;
  --mk-sys-color: #13c2c2;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#e6fffb, #b5f5ec, #87e8de, #5cdbd3, #36cfc9, #13c2c2, #08979c, #006d75, #00474f, #002329);
  @include bgblack();
}
body.mk-cyan-white {
  --antd-wave-shadow-color: #13c2c2;
  --mk-sys-color: #13c2c2;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #e6fffb, #b5f5ec, #87e8de, #5cdbd3, #36cfc9, #13c2c2, #08979c, #006d75, #00474f, #002329);
}
body.mk-blue-purple-black {
  --antd-wave-shadow-color: #2f54eb;
  --mk-sys-color: #2f54eb;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#f0f5ff, #d6e4ff, #adc6ff, #85a5ff, #597ef7, #2f54eb, #1d39c4, #10239e, #061178, #030852);
  @include bgblack();
}
body.mk-blue-purple-white {
  --antd-wave-shadow-color: #2f54eb;
  --mk-sys-color: #2f54eb;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #f0f5ff, #d6e4ff, #adc6ff, #85a5ff, #597ef7, #2f54eb, #1d39c4, #10239e, #061178, #030852);
}
body.mk-purple-black {
  --antd-wave-shadow-color: #722ed1;
  --mk-sys-color: #722ed1;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#f9f0ff, #efdbff, #d3adf7, #b37feb, #9254de, #722ed1, #531dab, #391085, #22075e, #120338);
  @include bgblack();
}
body.mk-purple-white {
  --antd-wave-shadow-color: #722ed1;
  --mk-sys-color: #722ed1;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #f9f0ff, #efdbff, #d3adf7, #b37feb, #9254de, #722ed1, #531dab, #391085, #22075e, #120338);
}
body.mk-magenta-black {
  --antd-wave-shadow-color: #eb2f96;
  --mk-sys-color: #eb2f96;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#fff0f6, #ffd6e7, #ffadd2, #ff85c0, #f759ab, #eb2f96, #c41d7f, #9e1068, #780650, #520339);
  @include bgblack();
}
body.mk-magenta-white {
  --antd-wave-shadow-color: #eb2f96;
  --mk-sys-color: #eb2f96;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff0f6, #ffd6e7, #ffadd2, #ff85c0, #f759ab, #eb2f96, #c41d7f, #9e1068, #780650, #520339);
}
body.mk-grass-green-black {
  --antd-wave-shadow-color: #aeb303;
  --mk-sys-color: #aeb303;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#f2efda, #e6de97, #d9d26c, #ccc845, #bfbf22, #aeb303, #838c00, #5c6600, #374000, #151a00);
  @include bgblack();
}
body.mk-grass-green-white {
  --antd-wave-shadow-color: #aeb303;
  --mk-sys-color: #aeb303;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #f2efda, #e6de97, #d9d26c, #ccc845, #bfbf22, #aeb303, #838c00, #5c6600, #374000, #151a00);
}
body.mk-deep-red-black {
  --antd-wave-shadow-color: #c32539;
  --mk-sys-color: #c32539;
  @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#fff0f0, #f5cbcb, #e89b9e, #db7077, #cf4856, #c32539, #9c162c, #750b20, #4f0315, #29010c);
  @include bgblack();
}
body.mk-deep-red-white {
  --antd-wave-shadow-color: #c32539;
  --mk-sys-color: #c32539;
  @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff0f0, #f5cbcb, #e89b9e, #db7077, #cf4856, #c32539, #9c162c, #750b20, #4f0315, #29010c);
}
src/assets/img/newpage.jpg
src/assets/mobimg/guanzhu.jpg
src/assets/mobimg/indent.jfif
Binary files differ
src/assets/mobimg/kapmap.jfif
Binary files differ
src/assets/mobimg/mindmap.png
src/assets/mobimg/moblogin.jpg
src/assets/mobimg/share.jpg
src/assets/mobimg/simple-form.png
src/components/breadview/index.jsx
@@ -1,5 +1,4 @@
import React, {Component} from 'react'
import {connect} from 'react-redux'
import { BackTop, Breadcrumb, notification} from 'antd'
import { HomeOutlined, RightOutlined, RedoOutlined } from '@ant-design/icons'
import moment from 'moment'
@@ -9,26 +8,18 @@
import NotFount from '@/components/404'
import options from '@/store/options.js'
import MKEmitter from '@/utils/events.js'
import { initActionPermission } from '@/store/action'
import Api from '@/api'
import './index.scss'
const Home = asyncComponent(() => import('@/tabviews/home'))
const CustomPage = asyncComponent(() => import('@/tabviews/custom'))
const CommonTable = asyncComponent(() => import('@/tabviews/commontable'))
const BaseTable = asyncComponent(() => import('@/tabviews/basetable'))
const CalendarPage = asyncComponent(() => import('@/tabviews/calendar'))
const TreePage = asyncComponent(() => import('@/tabviews/treepage'))
const Iframe = asyncComponent(() => import('@/tabviews/iframe'))
const RoleManage = asyncComponent(() => import('@/tabviews/rolemanage'))
const FormTab = asyncComponent(() => import('@/tabviews/formtab'))
let service = ''
if (process.env.NODE_ENV === 'production') {
  service = document.location.origin + '/' + window.GLOB.service + 'zh-CN/'
} else {
  service = window.GLOB.location + '/' + window.GLOB.service + 'zh-CN/'
}
class BreadView extends Component {
  state = {
@@ -64,7 +55,7 @@
              })
            }
  
            this.props.initActionPermission(_permAction)
            window.GLOB.mkActions = _permAction
          }
          resolve()
@@ -88,14 +79,22 @@
    }
  }
  changeTemp = (MenuID, Template) => {
    this.setState({
      tabview: {...this.state.tabview, type: Template}
    })
  }
  selectcomponent = (view) => {
    // 根据tab页中菜单信息,选择所需的组件
    if (view.type === 'Home') {
      return (<Home MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>)
    } else if (view.type === 'CommonTable' || view.type === 'ManageTable') {
      return (<CommonTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
    } else if (view.type === 'CommonTable') {
      return (<CommonTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param} changeTemp={this.changeTemp}/>)
    } else if (view.type === 'BaseTable') {
      return (<BaseTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param} changeTemp={this.changeTemp}/>)
    } else if (view.type === 'CustomPage') {
      return (<CustomPage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
      return (<CustomPage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param} changeTemp={this.changeTemp}/>)
    } else if (view.type === 'TreePage') {
      return (<TreePage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
    } else if (view.type === 'CalendarPage') {
@@ -105,7 +104,7 @@
    } else if (view.type === 'FormTab') {
      return (<FormTab MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
    } else if (view.type === 'iframe') {
      return (<Iframe key={view.MenuID} MenuID={view.MenuID} MenuNo={view.MenuNo} title={view.MenuName} MenuName={view.MenuName} url={service + view.LinkUrl}/>)
      return (<Iframe key={view.MenuID} MenuID={view.MenuID} MenuNo={view.MenuNo} title={view.MenuName} MenuName={view.MenuName} url={window.GLOB.baseurl + 'zh-CN/' + view.LinkUrl}/>)
    } else {
      return (<NotFount key={view.MenuID} />)
    }
@@ -135,11 +134,9 @@
    this.setState({tabview: home})
  }
  modifyTabs = (tab, type) => {
    if (!tab || type !== 'replace') return
  modifyTabs = (tab) => {
    this.setState({
      tabview: tab,
      tabview: tab
    })
    let node = document.getElementById('root').parentNode.parentNode
@@ -194,14 +191,4 @@
  }
}
const mapStateToProps = () => {
  return {}
}
const mapDispatchToProps = (dispatch) => {
  return {
    initActionPermission: (permAction) => dispatch(initActionPermission(permAction)),
  }
}
export default connect(mapStateToProps, mapDispatchToProps)(BreadView)
export default BreadView
src/components/editor/index.jsx
@@ -14,13 +14,6 @@
BraftEditor.use(Table())
let service = ''
if (process.env.NODE_ENV === 'production') {
  service = document.location.origin + '/' + window.GLOB.service
} else {
  service = window.GLOB.location + '/' + window.GLOB.service
}
class NormalEditor extends Component {
  static propTpyes = {
    config: PropTypes.object,
@@ -87,7 +80,7 @@
    form.append('file', _param.binary)
    form.append('fileMd5', params.file.fileMd5)
    form.append('shardingMd5', _param.chunkMd5)
    form.append('baseDomain', service)
    form.append('baseDomain', window.GLOB.baseurl)
    form.append('rootPath', 'Content/images/upload/')
    form.append('fileName', params.file.fileName)
    form.append('fileExt', params.file.fileType)
src/components/encrypts/index.jsx
New file
@@ -0,0 +1,59 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'
import './index.scss'
class Encryption extends Component {
  static propTpyes = {
    value: PropTypes.any
  }
  state = {
    eye: false
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (nextProps.value !== this.props.value) {
      this.setState({eye: false})
    }
  }
  getValue = () => {
    const { value } = this.props
    let len = value.length
    let val = ''
    if (len === 1) {
      val = '*'
    } else if (len === 2) {
      val = value.substr(0, 1) + '*'
    } else if (len <= 6) {
      val = value.substr(0, 1) + Array(len - 1).join('*') + value.substr(-1)
    } else if (len <= 10) {
      val = value.substr(0, 2) + Array(len - 3).join('*') + value.substr(-2)
    } else if (len === 11) {
      val = value.substr(0, 3) + '****' + value.substr(-4)
    } else {
      let l = Math.floor(len * 0.2)
      val = value.substr(0, l) + Array(len - 1 - 2 * l).join('*') + value.substr(-l)
    }
    return val
  }
  render() {
    const { value } = this.props
    const { eye } = this.state
    return (
      <>
        {eye ? value : this.getValue()}
        {eye ? <EyeOutlined className="mk-open-eye" onClick={(e) => {e.stopPropagation();this.setState({eye: false})}}/> : <EyeInvisibleOutlined className="mk-close-eye" onClick={(e) => {e.stopPropagation();this.setState({eye: true})}}/>}
      </>
    )
  }
}
export default Encryption
src/components/encrypts/index.scss
New file
@@ -0,0 +1,12 @@
.mk-open-eye {
  color: var(--mk-sys-color);
  cursor: pointer;
  margin-left: 3px!important;
  margin-right: 2px!important;
}
.mk-close-eye {
  color: rgba(0, 0, 0, 0.65);
  cursor: pointer;
  margin-left: 3px!important;
  margin-right: 2px!important;
}
src/components/header/index.jsx
@@ -4,17 +4,15 @@
import {connect} from 'react-redux'
import { is, fromJS } from 'immutable'
import moment from 'moment'
import { Dropdown, Menu, Modal, Form, notification, Switch, Input } from 'antd'
import { Dropdown, Menu, Modal, notification, Switch, Input } from 'antd'
import { SearchOutlined, DownOutlined, MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'
import {
  toggleCollapse,
  modifyMainMenu,
  initActionPermission,
  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'
@@ -48,9 +46,7 @@
    systems: [],
    searchkey: '',
    thdMenuList: [],
    debug: sessionStorage.getItem('debug') === 'true',
    navBar: ['linkage_navigation', 'linkage', 'menu_board', 'menu_board_navigation'].includes(window.GLOB.navBar) ? 'topmenu' : '',
    menuType: window.GLOB.navBar
    debug: sessionStorage.getItem('debug') === 'true'
  }
  handleCollapse = () => {
@@ -67,6 +63,8 @@
  }
  resetPwdSubmit = () => {
    if (!this.formRef) return
    this.formRef.handleConfirm().then(res => {
      this.setState({
        confirmLoading: true
@@ -133,7 +131,7 @@
  changeMenu (value) {
    // 主菜单切换
    if (value.OpenType === 'outpage' && value.linkUrl) {
    if (value.OpenType === 'outpage') {
      window.open(value.linkUrl)
    } else if (value.OpenType === 'menu') {
      this.props.modifyMainMenu(value)
@@ -141,117 +139,91 @@
  }
  getRolesMenu () {
    // 获取角色权限
    let roledefer = new Promise(resolve => {
      // edition_type 接口版本控制 ''、'Y'、'A'
      setTimeout(() => {
        Api.getSystemConfig({
          func: 's_Get_TrdMenu_Role',
          edition_type: 'A',
          pro_sys: window.GLOB.systemType === 'production' ? 'Y' : ''
        }).then(result => {
          let _permAction = {loaded: true} // 按钮权限
          if (result && result.status) {
            if (result.UserRoles_Menu) {
              result.UserRoles_Menu.forEach(menu => {
                if (!menu.MenuID) return
                _permAction[menu.MenuID] = true
              })
            }
          } else if (result) {
            notification.error({
              top: 92,
              message: result.message,
              duration: 10
    // 获取主菜单参数
    let _param = {func: 's_get_pc_menus', systemType: options.sysType}
    _param.pro_sys = window.GLOB.systemType === 'production' ? 'Y' : ''
    Api.getSystemConfig(_param).then(result => {
      if (!result.status) {
        notification.error({
          top: 92,
          message: result.message,
          duration: 10
        })
        return
      }
      const { menulist, thdMenuList } = this.getMenulist(result)
      let systems = []
      if ((options.sysType === 'local' || options.sysType === 'SSO') && result.sys_list) {
        systems = result.sys_list
        if (options.sysType === 'local' && window.GLOB.systemType !== 'production' && systems.length > 10) {
          systems.length = 10
        }
      }
      this.setState({
        menulist,
        thdMenuList,
        systems: systems
      })
      let mainMenu = menulist[0] || ''
      let _menu = null
      if (sessionStorage.getItem('ThirdMenu')) { // 是否为打开新页面
        let ThirdMenuId = sessionStorage.getItem('ThirdMenu')
        _menu = thdMenuList.filter(item => item.MenuID === ThirdMenuId)[0] // 通过url中menuid筛选出选中的主菜单
        sessionStorage.removeItem('ThirdMenu')
      }
      this.props.modifyMainMenu(mainMenu)
      window.GLOB.mkThdMenus = [...thdMenuList, {MenuID: 'home_page_id', EasyCode: '', MenuName: 'home', type: 'CustomPage'}]
      if (_menu) { // 延时打开,防止标签组未完成加载
        setTimeout(() => {
          MKEmitter.emit('modifyTabs', _menu)
        }, 200)
      }
      MKEmitter.emit('mkMenuLoaded')
    })
    // 获取角色权限, edition_type 接口版本控制 ''、'Y'、'A'
    setTimeout(() => {
      Api.getSystemConfig({
        func: 's_Get_TrdMenu_Role',
        edition_type: 'A',
        pro_sys: window.GLOB.systemType === 'production' ? 'Y' : ''
      }).then(result => {
        let _permAction = {loaded: true} // 按钮权限
        if (result.status) {
          if (result.UserRoles_Menu) {
            result.UserRoles_Menu.forEach(menu => {
              if (!menu.MenuID) return
              _permAction[menu.MenuID] = true
            })
          }
          this.props.initActionPermission(_permAction)
          resolve()
        })
      }, 50)
    })
    // 获取主菜单参数
    let menudefer = new Promise(resolve => {
      let _param = {func: 's_get_pc_menus', systemType: options.sysType}
      _param.pro_sys = window.GLOB.systemType === 'production' ? 'Y' : ''
      Api.getSystemConfig(_param).then(result => {
        if (!result.status) {
        } else {
          notification.error({
            top: 92,
            message: result.message,
            duration: 10
          })
          return
        }
        const { menulist, thdMenuList } = this.getMenulist(result)
        let systems = []
        if ((options.sysType === 'local' || options.sysType === 'SSO') && result.sys_list) {
          systems = result.sys_list
          if (options.sysType === 'local' && window.GLOB.systemType !== 'production' && systems.length > 10) {
            systems.length = 10
          }
        }
        this.setState({
          menulist,
          thdMenuList,
          systems: systems
        })
        let mainMenu = menulist[0] || ''
        let _menu = null
        if (mainMenu === '') { // 是否显示侧边栏控制
          let _url = window.location.href.split('#')[0]
          localStorage.setItem(_url + '-sideHidden', 'true')
        } else {
          let _url = window.location.href.split('#')[0]
          localStorage.removeItem(_url + '-sideHidden')
        }
        if (sessionStorage.getItem('ThirdMenu')) { // 是否为打开新页面
          let ThirdMenuId = sessionStorage.getItem('ThirdMenu')
          _menu = thdMenuList.filter(item => item.MenuID === ThirdMenuId)[0] // 通过url中menuid筛选出选中的主菜单
          if (_menu) {
            mainMenu = menulist.filter(item => item.MenuID === _menu.FstId)[0]
            mainMenu = fromJS(mainMenu).toJS()
            mainMenu.openId = _menu.ParentId
          }
          sessionStorage.removeItem('ThirdMenu')
        }
        this.props.modifyMainMenu(mainMenu)
        this.props.initMenuPermission([...thdMenuList, {MenuID: 'home_page_id', EasyCode: '', MenuName: 'home', type: 'CustomPage'}])
        resolve(_menu)
        MKEmitter.emit('mkActionLoaded')
        window.GLOB.mkActions = _permAction
      })
    })
    Promise.all([roledefer, menudefer]).then(response => {
      if (response[1]) {
        let menu = fromJS(response[1]).toJS()
        if (this.state.navBar === 'topmenu' && this.state.menuType !== 'menu_board_navigation') {
          MKEmitter.emit('modifyTabs', menu, 'replace')
        } else {
          MKEmitter.emit('modifyTabs', menu, 'plus')
        }
      }
    })
    }, 50)
  }
  getMenulist = (result) => {
    let thdMenuList = []
    let iframes = ['Main/Index', 'bda/rdt', 'Home/rdt']
    let menulist = []
    result.fst_menu && result.fst_menu.forEach(fst => {
      let fstItem = {
@@ -262,14 +234,13 @@
      }
      if (fst.PageParam) {
        try {
          fstItem.PageParam = JSON.parse(fst.PageParam)
        } catch (e) {
          fstItem.PageParam = null
        }
        if (fstItem.PageParam && fstItem.PageParam.OpenType === 'outpage' && fstItem.PageParam.linkUrl) {
          fstItem.OpenType = 'outpage'
          fstItem.linkUrl = fstItem.PageParam.linkUrl
        }
          let PageParam = JSON.parse(fst.PageParam)
          if (PageParam.OpenType === 'outpage' && PageParam.linkUrl) {
            fstItem.OpenType = 'outpage'
            fstItem.linkUrl = PageParam.linkUrl
          }
        } catch (e) {}
      }
      if (fst.snd_menu) {
@@ -278,31 +249,16 @@
            ParentId: fst.MenuID,
            MenuID: snd.MenuID,
            MenuName: snd.MenuName,
            PageParam: {Icon: 'folder'},
            Icon: 'folder',
            children: []
          }
          if (snd.PageParam) {
            try {
              sndItem.PageParam = JSON.parse(snd.PageParam)
            } catch (e) {
              sndItem.PageParam = {Icon: 'folder'}
            }
          }
              let PageParam = JSON.parse(snd.PageParam)
          let msg = {
            UserID: sessionStorage.getItem('UserID'),
            LoginUID: sessionStorage.getItem('LoginUID'),
            User_Name: sessionStorage.getItem('User_Name'),
            Full_Name: sessionStorage.getItem('Full_Name'),
            Member_Level: sessionStorage.getItem('Member_Level'),
            dataM: sessionStorage.getItem('dataM'),
            avatar: sessionStorage.getItem('avatar'),
            debug: sessionStorage.getItem('debug'),
            role_id: sessionStorage.getItem('role_id'),
            mainlogo: window.GLOB.mainlogo,
            navBar: window.GLOB.navBar || '',
            mstyle: window.GLOB.style
              sndItem.Icon = PageParam.Icon || 'folder'
            } catch (e) {}
          }
          if (snd.trd_menu) {
@@ -319,46 +275,26 @@
                OpenType: 'newtab',
                hidden: 'false'
              }
              if (trd.LinkUrl && iframes.includes(trd.LinkUrl.split('?')[0])) {
                trdItem.type = 'iframe'
                trdItem.LinkUrl = trd.LinkUrl.replace('&amp;', '&')
              } else {
              if (trd.PageParam) {
                try {
                  trdItem.PageParam = trd.PageParam ? JSON.parse(trd.PageParam) : {OpenType: 'newtab'}
                } catch (e) {
                  trdItem.PageParam = {OpenType: 'newtab'}
                }
                  let PageParam = JSON.parse(trd.PageParam)
                trdItem.type = trdItem.PageParam.Template || trdItem.type
                trdItem.OpenType = trdItem.PageParam.OpenType || trdItem.OpenType
                trdItem.hidden = trdItem.PageParam.hidden || trdItem.hidden
                  trdItem.type = PageParam.Template || 'CommonTable'
                  trdItem.OpenType = PageParam.OpenType || 'newtab'
                  trdItem.hidden = PageParam.hidden || 'false'
                if (trdItem.type === 'NewPage') {
                  trdItem.src = trdItem.PageParam.url || ''
                  if (trdItem.src.indexOf('paramsmain/') > -1) {
                    try {
                      let _url = trdItem.src.split('paramsmain/')[0] + 'paramsmain/'
                      let _param = JSON.parse(window.decodeURIComponent(window.atob(trdItem.src.split('paramsmain/')[1])))
                      _param.UserID = sessionStorage.getItem('UserID')
                      _param.LoginUID = sessionStorage.getItem('LoginUID')
                      _param.User_Name = sessionStorage.getItem('User_Name')
                      _param.Full_Name = sessionStorage.getItem('Full_Name')
                      trdItem.src = _url + window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
                    } catch (e) {
                      console.warn('菜单参数解析错误!')
                    }
                  if (trdItem.type === 'NewPage') {
                    trdItem.src = PageParam.url || ''
                  }
                } else {
                  // 打开新页面链接
                  trdItem.src = '#/paramsmain/' + window.btoa(window.encodeURIComponent(JSON.stringify({
                    ...msg,
                    ThirdMenu: trd.MenuID
                  })))
                }
                } catch (e) {}
              }
              if (trdItem.type !== 'NewPage') {
                trdItem.src = '#/tab/' + trd.MenuID
              }
              trdItem.OpenType = trdItem.OpenType.toLowerCase() // NewPage为打开外部页面地址
              thdMenuList.push(trdItem)
@@ -399,12 +335,31 @@
  }
  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) {
          this.setState({
            loginLoading: false
          })
          if (res.modifydate) {
            let s = (new Date().getTime() - new Date(res.modifydate).getTime()) / (1000 * 24 * 60 * 60)
            if (!isNaN(s) && s > 90) {
              Modal.warning({
                width: 520,
                title: <span>系统检测到您的账户存在风险,请及时到<a target="_blank" rel="noopener noreferrer" href="https://cloud.mk9h.cn/admin/index.html">云中心</a>修改密码!</span>,
                okText: '知道了'
              })
              return
            }
          }
          sessionStorage.setItem('CloudUserID', res.UserID)
          sessionStorage.setItem('CloudLoginUID', res.LoginUID)
          sessionStorage.setItem('CloudUserName', res.UserName)
@@ -423,7 +378,6 @@
            localStorage.setItem(_url, window.btoa(window.encodeURIComponent(JSON.stringify({time: new Date().getTime(), username: param.username, password: param.password}))))
          }
          this.setSystemFuncs()
          this.props.modifyMainMenu(null)
          this.props.history.replace('/design')
        } else {
@@ -441,106 +395,6 @@
          })
        }
      })
    })
  }
  setSystemFuncs = () => {
    if (!window.GLOB.WebSql && !window.GLOB.IndexDB) {
      return
    }
    this.getfuncTime().then(res => {
      Api.getSystemFuncs(res.createDate).then(result => {
        if (!result.status) {
          notification.error({
            top: 92,
            message: result.message,
            duration: 10
          })
        } else if (result.func_detail && result.func_detail.length > 0) {
          this.writeFuncs(result.func_detail)
        }
      })
    })
  }
  writeFuncs = (funcs) => {
    let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    let sys_datetime = sessionStorage.getItem('sys_datetime')
    let app_datetime = sessionStorage.getItem('app_datetime')
    if (sys_datetime && app_datetime) {
      let seconds = Math.floor((new Date().getTime() - app_datetime) / 1000)
      timestamp = moment(sys_datetime, 'YYYY-MM-DD HH:mm:ss').add(seconds, 'seconds').format('YYYY-MM-DD HH:mm:ss')
    }
    if (window.GLOB.WebSql) {
      window.GLOB.WebSql.transaction(tx => {
        tx.executeSql('DELETE FROM FUNCS')
        funcs.forEach(item => {
          if (!item.key_sql) return
          tx.executeSql('INSERT INTO FUNCS (func_code, key_sql) VALUES (?, ?)', [item.func_code, item.key_sql])
        })
        tx.executeSql(`UPDATE VERSIONS SET createDate='${timestamp}' where CDefine1='funcs'`)
      })
    } else {
      let objectStore = window.GLOB.IndexDB.transaction(['funcs'], 'readwrite').objectStore('funcs')
      objectStore.clear()
      funcs.forEach(item => {
        if (!item.key_sql) return
        item.id = item.func_code
        objectStore.add(item)
      })
      let funcStore = window.GLOB.IndexDB.transaction(['version'], 'readwrite').objectStore('version')
      funcStore.put({id: 'funcs', version: '1.0', createDate: timestamp})
    }
  }
  getfuncTime = () => {
    return new Promise((resolve, reject) => {
      if (window.GLOB.WebSql) {
        window.GLOB.WebSql.transaction(tx => {
          tx.executeSql("SELECT * FROM VERSIONS where CDefine1='funcs'", [], (tx, results) => {
            let rows = results.rows
            if (rows.length === 0) {
              tx.executeSql('DELETE FROM FUNCS')
              tx.executeSql('INSERT INTO VERSIONS (version, createDate, CDefine1) VALUES (?, ?, ?)', ['1.0', '1970-01-01 14:59:09.000', 'funcs'])
              resolve({createDate: '1970-01-01 14:59:09.000'})
            } else {
              resolve(rows[0])
            }
          }, (tx, results) => {
            reject()
            console.warn(results)
          })
        })
      } else {
        let objectStore = window.GLOB.IndexDB.transaction(['version'], 'readwrite').objectStore('version')
        let request = objectStore.get('funcs')
        request.onerror = (event) => {
          console.warn(event)
          reject()
        }
        request.onsuccess = () => {
          if (request.result) {
            resolve(request.result)
          } else {
            let add = objectStore.add({id: 'funcs', version: '1.0', createDate: '1970-01-01 14:59:09.000'})
            add.onerror = () => {
              reject()
            }
            add.onsuccess = () => {
              resolve({id: 'funcs', version: '1.0', createDate: '1970-01-01 14:59:09.000'})
            }
          }
        }
      }
    })
  }
@@ -624,7 +478,7 @@
  componentDidMount () {
    // 获取系统的版本信息,延时查询
    setTimeout(() => {
      Api.getAppVersion().then(() => {}, () => {})
      Api.getAppVersion()
    }, 1000)
    // Api.genericInterface({
    //   func: 's_get_fcc_account_data',
@@ -632,6 +486,20 @@
    //   search_type: ''
    // }).then(res => {
    // })
    // sessionStorage 跨页面共享
    window.addEventListener('storage', (e) => {
      if (e.key === 'getSessionStorage' && e.newValue === window.GLOB.appkey) {
        localStorage.setItem('sessionStorage', JSON.stringify(sessionStorage))
      } else if (e.key === 'menuUpdate') {
        let menuId = e.newValue.split(',')[1]
        if (menuId) {
          Api.getAppVersion(menuId).then(() => {
            MKEmitter.emit('reloadMenuView', menuId)
          })
        }
      }
    })
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -653,26 +521,20 @@
      let url = `${ssodomain}/doc/index.html#?appkey=${window.GLOB.appkey}&LoginUID=${sessionStorage.getItem('LoginUID')}`
      window.open(url)
    } else if (options.sysType === 'SSO' || options.sysType === 'cloud') {
      window.open(`${window.location.href.replace(/\/index.html(.*)|\/#(.*)/ig, '')}/doc/index.html#?appkey=${window.GLOB.appkey}&LoginUID=${sessionStorage.getItem('LoginUID')}`)
      window.open(`${window.location.href.replace(/\/admin(.*)|\/index.html(.*)|\/#(.*)/ig, '')}/doc/index.html#?appkey=${window.GLOB.appkey}&LoginUID=${sessionStorage.getItem('LoginUID')}`)
    }
  }
  changeVerMenu(menu, type) {
    if (type === 'first') {
      if (menu.OpenType === 'outpage' && menu.linkUrl) {
      if (menu.OpenType === 'outpage') {
        window.open(menu.linkUrl)
      } else if (menu.OpenType === 'menu') {
      }
    } else {
      if (menu.OpenType === 'newpage' || menu.OpenType === 'NewPage') { // NewPage为打开外部页面地址,newpage为打开系统菜单
      if (menu.OpenType === 'newpage') {
        window.open(menu.src)
      } else if (menu.OpenType === 'blank') {
        MKEmitter.emit('modifyTabs', menu, 'replace')
      } else if (this.state.navBar === 'topmenu' && this.state.menuType !== 'menu_board_navigation') {
        MKEmitter.emit('modifyTabs', menu, 'replace')
      } else {
        MKEmitter.emit('modifyTabs', menu, 'plus')
        MKEmitter.emit('modifyTabs', menu)
      }
  
      if (window.GLOB.systemType === 'production') {
@@ -717,9 +579,16 @@
    })
  }
  changeToHome = () => {
    if (!['linkage', 'menu_board'].includes(window.GLOB.navBar)) return
    MKEmitter.emit('modifyTabs', {MenuID: 'home_page_id', EasyCode: '', MenuName: 'home', type: 'CustomPage'})
  }
  render () {
    const { mainMenu, collapse } = this.props
    const { thdMenuList, searchkey, debug, menulist, navBar, menuType, appVersion } = this.state
    const { thdMenuList, searchkey, debug, menulist, appVersion } = this.state
    const navBar = window.GLOB.navBar
    const menu = (
      <Menu className="header-dropdown">
@@ -746,12 +615,14 @@
    return (
      <header className="header-container ant-menu-dark" id="main-header-container">
        <div className={'header-logo ' + (collapse && navBar !== 'topmenu' ? 'collapse' : '')}><img src={this.state.logourl} alt=""/></div>
        <div className={'header-collapse ' + (collapse && navBar !== 'topmenu' ? 'collapse' : '')}>
          {navBar !== 'topmenu' ? (collapse ? <MenuUnfoldOutlined onClick={this.handleCollapse}/> : <MenuFoldOutlined onClick={this.handleCollapse}/>) : null}
        </div>
        {navBar === 'shutter' ?
          <div className={'header-logo ' + (collapse ? 'collapse' : '')}><img src={this.state.logourl} alt=""/></div> :
          <div className="header-logo" onClick={this.changeToHome}><img src={this.state.logourl} alt=""/></div>}
        {navBar === 'shutter' ? <div className={'header-collapse ' + (collapse ? 'collapse' : '')}>
          {collapse ? <MenuUnfoldOutlined onClick={this.handleCollapse}/> : <MenuFoldOutlined onClick={this.handleCollapse}/>}
        </div> : <div style={{width: '20px', height: '45px'}}></div>}
        {/* 正常菜单 */}
        {navBar !== 'topmenu' && menulist ?
        {navBar === 'shutter' && menulist ?
          <ul className="header-menu">{
            menulist.map(item => {
              return (
@@ -762,7 +633,7 @@
            })}
          </ul> : null
        }
        {navBar === 'topmenu' && menuType !== 'menu_board' && menuType !== 'menu_board_navigation' && menulist ?
        {(navBar === 'linkage' || navBar === 'linkage_navigation') && menulist ?
          <ul className="header-menu vertical-menu">{
            menulist.map(item => {
              if (item.children && item.children.length > 0) {
@@ -805,7 +676,7 @@
            })}
          </ul> : null
        }
        {navBar === 'topmenu' && (menuType === 'menu_board' || menuType === 'menu_board_navigation') && menulist ?
        {(navBar === 'menu_board' || navBar === 'menu_board_navigation') && menulist ?
          <ul className="header-menu vertical-menu">{
            menulist.map(item => {
              if (item.children && item.children.length > 0) {
@@ -843,15 +714,9 @@
            })}
          </ul> : null
        }
        {/* 头像、用户名 */}
        <Dropdown className="header-setting" overlay={menu}>
          <div>
            <img src={this.state.avatar || avatar} alt=""/>
            <span>
              <span className="username"><span>{this.state.fullName}</span>{this.state.userName ? <span>{this.state.userName}</span> : null}</span> <DownOutlined />
            </span>
          </div>
        </Dropdown>
        {!menulist ?
          <div className="header-menu"></div> : null
        }
        {/* 菜单搜索 */}
        {thdMenuList.length > 0 ?
          <Dropdown overlayClassName="menu-select-dropdown" getPopupContainer={() => document.getElementById('main-header-container')} overlay={
@@ -888,6 +753,15 @@
            <SearchOutlined className="search-menu" />
          </Dropdown> : null
        }
        {/* 头像、用户名 */}
        <Dropdown className="header-setting" overlay={menu}>
          <div>
            <img src={this.state.avatar || avatar} alt=""/>
            <span>
              <span className="username"><span>{this.state.fullName}</span>{this.state.userName ? <span>{this.state.userName}</span> : null}</span> <DownOutlined />
            </span>
          </div>
        </Dropdown>
        {/* 修改密码 */}
        <Modal
          title={this.state.dict['main.password']}
@@ -927,10 +801,8 @@
  return {
    toggleCollapse: (collapse) => dispatch(toggleCollapse(collapse)),
    modifyMainMenu: (mainMenu) => dispatch(modifyMainMenu(mainMenu)),
    initActionPermission: (permAction) => dispatch(initActionPermission(permAction)),
    initMenuPermission: (permMenus) => dispatch(initMenuPermission(permMenus)),
    logout: () => dispatch(logout())
  }
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Form.create()(Header)))
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Header))
src/components/header/index.scss
@@ -6,9 +6,9 @@
  font-weight: bold!important;
  width: 100%;
  height: 48px;
  display: flex;
  .header-logo {
    float: left;
    width: 180px;
    line-height: 48px;
    text-align: center;
@@ -28,7 +28,6 @@
  }
  .header-collapse {
    float: left;
    width: 35px;
    min-height: 48px;
    line-height: 48px;
@@ -48,13 +47,17 @@
    padding-left: 20px;
  }
  .header-menu {
    float: left;
    margin: 0;
    min-height: 20px;
    line-height: 48px;
    flex: 1;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    li {
      float: left;
      font-size: 1.3rem;
      cursor: pointer;
      display: inline-block;
      span {
        padding: 0 10px;
        height: 42px;
@@ -83,8 +86,22 @@
    }
  }
  .header-menu::-webkit-scrollbar {
    height: 5px;
  }
  .header-menu::-webkit-scrollbar-thumb {
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
    background: rgba(0, 0, 0, 0.13);
    border-radius: 5px;
  }
  .header-menu::-webkit-scrollbar-track {
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
    border: 1px solid rgba(0, 0, 0, 0.07);
    background: rgba(0, 0, 0, 0);
    border-radius: 3px;
  }
  .header-setting {
    float: right;
    line-height: 48px;
    margin-right: 10px;
    img {
@@ -117,10 +134,10 @@
  }
  .search-menu {
    float: right;
    font-size: 18px;
    margin-top: 17px;
    margin-right: 20px;
    margin-left: 10px;
    cursor: pointer;
  }
  .menu-select-dropdown {
@@ -196,7 +213,7 @@
  border-radius: 4px;
  box-shadow: 0 0 3px #959595;
  position: relative;
  left: 11.8%;
  // left: 11.8%;
  .menu-wrap {
    .title {
      color: #1890ff;
@@ -205,21 +222,23 @@
    }
    .menu-detail {
      max-width: 60vw;
      padding: 5px 0 10px 15px;
      padding: 5px 0 5px 15px;
      div {
        float: left;
        margin-bottom: 5px;
        // float: left;
        display: inline-block;
        vertical-align: top;
        margin-bottom: 8px;
        width: 120px;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        // overflow: hidden;
        // white-space: nowrap;
        // text-overflow: ellipsis;
        cursor: pointer;
      }
      div:hover {
        color: #40a9ff;
      }
      div:not(:last-child) {
        margin-right: 20px;
        margin-right: 15px;
      }
    }
    .menu-detail::after {
src/components/header/loginform.jsx
@@ -16,7 +16,8 @@
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    remember: false,
    username: '',
    password: ''
    password: '',
    delay: +sessionStorage.getItem('mkDelay')
  }
  UNSAFE_componentWillMount () {
@@ -87,10 +88,13 @@
  render() {
    const { getFieldDecorator } = this.props.form
    const { remember, username, password } = this.state
    const { remember, username, password, delay } = this.state
    return (
      <Form style={{margin: '0px 10px'}}>
        {delay > 1000 ? <Form.Item style={{marginBottom: '0px', marginTop: '-10px'}}>
          升级到<a target="_blank" rel="noopener noreferrer" href="https://cloud.mk9h.cn/admin/index.html">企业版</a>,获得更高效的开发体验。
        </Form.Item> : null}
        <Form.Item style={{marginBottom: '0px', height: '60px'}}>
          {getFieldDecorator('username', {
            rules: [{ required: true, message: this.state.dict['login.username.empty'] }],
src/components/keyInterface/index.jsx
New file
@@ -0,0 +1,311 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import CryptoJS from 'crypto-js'
import { Input, Modal, Form, notification } from 'antd'
import { EditOutlined, DeleteOutlined } from '@ant-design/icons'
import './index.scss'
const { TextArea } = Input
const { confirm } = Modal
class KeyInterface extends Component {
  static propTpyes = {
    type: PropTypes.string,
    onChange: PropTypes.func
  }
  state = {
    url: '',
    key: '',
    visible: false,
    setting: null
  }
  componentDidMount() {
    const { value, type } = this.props
    if (value) {
      let content = value
      try {
        content = JSON.parse(content)
      } catch (e) {
        content = {}
      }
      this.setState({setting: content.message || null, url: content.url || ''})
    }
    if (type === 'develop') {
      this.setState({key: window.GLOB.appkey.slice(-16)})
    }
  }
  editKey = () => {
    let _setting = this.state.setting
    if (this.state.key && _setting && typeof(_setting) === 'string') {
      _setting = this.decrypt(this.state.key, _setting)
      if (!_setting) {
        notification.warning({
          top: 92,
          message: '信息解析失败!',
          duration: 5
        })
        this.props.onChange('')
      }
    }
    this.setState({visible: true, setting: _setting || {}})
  }
  decrypt = (token, value) => {
    let setting = null
    try {
      const key = CryptoJS.enc.Utf8.parse(token)
      const iv = CryptoJS.enc.Utf8.parse('mksoft')
      let encryptedHexStr = CryptoJS.enc.Hex.parse(value)
      let _srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr)
      let decrypt = CryptoJS.AES.decrypt(_srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 })
      let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)
      setting = decryptedStr.toString()
      setting = JSON.parse(window.decodeURIComponent(window.atob(setting)))
    } catch (e) {
      setting = null
    }
    return setting
  }
  handleConfirm = () => {
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (err) return
      if (values.apptoken) {
        let key = values.apptoken.slice(-16)
        let _setting = this.state.setting
        if (_setting && typeof(_setting) === 'string') {
          _setting = this.decrypt(key, _setting)
          if (!_setting) {
            const that = this
            confirm({
              title: '信息解析失败!',
              content: '点击确定会清除配置信息,点击取消可重新输入appkey。',
              onOk() {
                that.setState({key: key, setting: {}, url: ''})
                that.props.onChange('')
              },
              onCancel() {}
            })
            return
          }
        }
        this.setState({key: key, setting: _setting})
        return
      }
      if (!/\/dostars$/.test(values.interface)) {
        notification.warning({
          top: 92,
          message: '接口地址请填写dostars接口!',
          duration: 5
        })
        return
      } else if (values.ssoInterface && !/\/dostars$/.test(values.ssoInterface)) {
        notification.warning({
          top: 92,
          message: 'sso地址请填写dostars接口!',
          duration: 5
        })
        return
      }
      let _values = window.btoa(window.encodeURIComponent(JSON.stringify(values)))
      const key = CryptoJS.enc.Utf8.parse(this.state.key)
      const iv = CryptoJS.enc.Utf8.parse('mksoft')
      let srcs = CryptoJS.enc.Utf8.parse(_values)
      let encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 })
      let message = encrypted.ciphertext.toString()
      let content = JSON.stringify({message: message, url: values.interface})
      this.props.onChange(content)
      this.setState({setting: message, url: values.interface, visible: false})
      if (this.props.type !== 'develop') {
        this.setState({key: ''})
      }
    })
  }
  delKey = () => {
    const { url } = this.state
    const { type } = this.props
    if (!url) return
    if (type === 'develop') {
      this.setState({setting: null, url: ''})
    } else {
      this.setState({key: '', setting: null, url: ''})
    }
    this.props.onChange('')
  }
  cancel = () => {
    const { type } = this.props
    if (type !== 'develop') {
      this.setState({key: ''})
    }
    this.setState({visible: false})
  }
  render() {
    const { getFieldDecorator } = this.props.form
    const { url, visible, setting, key } = this.state
    return (
      <div className="mk-key-wrap">
        <TextArea value={url} rows={2} readOnly={true}/>
        <div className="mk-key-edit">
          <EditOutlined onClick={this.editKey}/>
          <DeleteOutlined className={!url ? 'disable' : ''} onClick={this.delKey}/>
        </div>
        <Modal
          wrapClassName='mk-key-modal'
          visible={visible}
          closable={false}
          maskClosable={false}
          width={650}
          onOk={this.handleConfirm}
          onCancel={this.cancel}
          destroyOnClose
        >
          {key && setting ?
            <Form>
              <Form.Item label="接口地址">
                {getFieldDecorator('interface', {
                  initialValue: setting.interface,
                  rules: [
                    {
                      required: true,
                      message: '请输入接口地址!'
                    },
                    {
                      pattern: /^[0-9a-zA-Z:_./]+$/,
                      message: '只可使用英文、数字以及:_./'
                    }
                  ]
                })(<TextArea rows={2}/>)}
              </Form.Item>
              <Form.Item label="sso地址">
                {getFieldDecorator('ssoInterface', {
                  initialValue: setting.ssoInterface || '',
                  rules: [
                    {
                      pattern: /^[0-9a-zA-Z:_./]+$/,
                      message: '只可使用英文、数字以及:_./'
                    }
                  ]
                })(<TextArea rows={2}/>)}
              </Form.Item>
              <Form.Item label="appkey">
                {getFieldDecorator('appkey', {
                  initialValue: setting.appkey || '',
                  rules: [
                    {
                      required: true,
                      message: '请输入appkey!'
                    },
                    {
                      pattern: /^[0-9a-zA-Z]+$/,
                      message: '只可输入英文及数字。'
                    },
                    {
                      min: 16,
                      message: '不可小于16位!'
                    }
                  ]
                })(<Input placeholder="请输入目标系统appkey" autoComplete="off" />)}
              </Form.Item>
              <Form.Item label="用户名">
                {getFieldDecorator('username', {
                  initialValue: setting.username,
                  rules: [
                    {
                      required: true,
                      message: '请输入用户名!'
                    }
                  ]
                })(<Input placeholder="请输入用户名" autoComplete="off" />)}
              </Form.Item>
              <Form.Item label="密码">
                {getFieldDecorator('password', {
                  initialValue: setting.password,
                  rules: [
                    {
                      required: true,
                      message: '请输入密码!'
                    }
                  ]
                })(<Input.Password placeholder="请输入密码" />)}
              </Form.Item>
              <Form.Item label="公钥">
                {getFieldDecorator('publicKey', {
                  initialValue: setting.publicKey,
                  rules: [
                    {
                      required: true,
                      message: '请输入公钥!'
                    }
                  ]
                })(<Input.Password placeholder={''} autoComplete="off" />)}
              </Form.Item>
              <Form.Item label="私钥">
                {getFieldDecorator('privateKey', {
                  initialValue: setting.privateKey,
                  rules: [
                    {
                      required: true,
                      message: '请输入私钥!'
                    }
                  ]
                })(<Input.Password placeholder={''} autoComplete="off" />)}
              </Form.Item>
            </Form> : null}
          {!key ? <Form style={{marginTop: '20px', marginBottom: '50px'}}>
            <Form.Item label="appkey">
              {getFieldDecorator('apptoken', {
                initialValue: '',
                rules: [
                  {
                    required: true,
                    message: '请输入正式系统appkey!'
                  },
                  {
                    pattern: /^[0-9a-zA-Z]+$/,
                    message: '只可输入英文及数字。'
                  },
                  {
                    min: 16,
                    message: '不可小于16位!'
                  }
                ]
              })(<Input placeholder="请输入正式系统appkey" autoComplete="off" />)}
            </Form.Item>
          </Form> : null}
        </Modal>
      </div>
    )
  }
}
export default Form.create()(KeyInterface)
src/components/keyInterface/index.scss
New file
@@ -0,0 +1,52 @@
.mk-key-wrap {
  position: relative;
  margin-bottom: 5px;
  .mk-key-edit {
    position: absolute;
    right: 0px;
    line-height: 1;
    .anticon {
      margin-left: 10px;
      cursor: pointer;
      padding: 0px 5px;
    }
    .anticon-edit {
      color: #1890ff;
    }
    .anticon-delete {
      color: #f5222d;
    }
    .anticon-delete.disable {
      opacity: 0.5;
      cursor: not-allowed;
    }
  }
}
.mk-key-modal {
  .ant-modal {
    top: 85px;
  }
  .ant-modal-body {
    padding-top: 35px;
    padding-bottom: 0px;
  }
  .ant-modal-footer {
    border-top: none;
    text-align: center;
    padding-bottom: 30px;
    button + button {
      margin-left: 15px;
    }
  }
  .ant-form-item {
    display: flex;
    .ant-form-item-label {
      width: 20%;
    }
    .ant-form-item-control-wrapper {
      width: 70%;
    }
  }
}
src/components/mk-icon/index.jsx
@@ -464,11 +464,15 @@
  render() {
    const { type, ...resProps } = this.props
    if (!type || !MkIcons[type]) return null
    return (
      MkIcons[type](resProps)
    )
    if (!type) {
      return null
    } else if (MkIcons[type]) {
      return (
        MkIcons[type](resProps)
      )
    } else {
      return <span className={'anticon anticon-mk ' + (resProps.className || '')} style={resProps.style || null} dangerouslySetInnerHTML={{ __html: type }}></span>
    }
  }
}
export default MkIcon
src/components/mkIcon/index.jsx
@@ -1,13 +1,15 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Modal, Row, Col, Button } from 'antd'
import { CloseCircleFilled } from '@ant-design/icons'
import { Modal, Row, Col, Button, Tabs, notification } from 'antd'
import { CloseCircleFilled, RedoOutlined } from '@ant-design/icons'
import Api from '@/api'
import { minkeIconSystem } from '@/utils/option.js'
import MkIcon from '@/components/mk-icon'
import './index.scss'
const { TabPane } = Tabs
// ['direction', 'edit', 'normal', 'data', 'hint']
class MkEditIcon extends Component {
@@ -19,6 +21,7 @@
    selectIcon: '',
    allowClear: false,
    icons: [],
    cusicons: [],
    visible: false
  }
@@ -42,6 +45,16 @@
    this.setState({selectIcon: val, allowClear: this.props.allowClear === true, icons})
  }
  componentDidMount() {
    if (!window.GLOB.designView) {
      if (sessionStorage.getItem('systemIcons')) {
        this.setState({cusicons: JSON.parse(sessionStorage.getItem('systemIcons'))})
      } else {
        this.getIcons()
      }
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
@@ -51,17 +64,55 @@
    this.props.onChange(val)
  }
  getIcons = () => {
    Api.getSystemConfig({ func: 's_get_icons' }).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        sessionStorage.setItem('systemIcons', JSON.stringify([]))
        return
      } else if (!res.data) {
        return
      }
      let icons = res.data.map(item => {
        item.icon_svg = window.decodeURIComponent(window.atob(item.icon_svg))
        return item
      })
      sessionStorage.setItem('systemIcons', JSON.stringify(icons))
      this.setState({cusicons: icons})
    })
  }
  trigger = () => {
    const { selectIcon, cusicons } = this.state
    this.setState({visible: true})
    if (cusicons.length > 0 && selectIcon && /<svg/.test(selectIcon)) {
      setTimeout(() => {
        let node = document.getElementById('mk-custom-tab')
        node && node.click()
      }, 200)
    }
  }
  render() {
    const { selectIcon, visible, icons, allowClear } = this.state
    const { selectIcon, visible, icons, allowClear, cusicons } = this.state
    return (
      <div className="mk-icon-box">
        {selectIcon ? <MkIcon type={selectIcon}/> : <span style={{color: '#bcbcbc'}}>请选择</span>}
        <MkIcon className="trigger" onClick={() => this.setState({visible: true})} type="swap"/>
        <MkIcon className="trigger" onClick={this.trigger} type="swap"/>
        {allowClear && selectIcon ? <CloseCircleFilled className="close" onClick={() => this.checkIcon('')}/> : null}
        <Modal
          wrapClassName="popview-modal mk-icon-wrap"
          title={'图标选择'}
          wrapClassName="mk-pop-modal mk-icon-wrap"
          // title={'图标选择'}
          visible={visible}
          width={800}
          maskClosable={false}
@@ -71,11 +122,27 @@
          ]}
          destroyOnClose
        >
          <Row>
            {icons.map(icon => <Col className={icon === selectIcon ? 'active' : ''} key={icon} span={4}>
              <MkIcon onClick={() => this.checkIcon(icon)} type={icon} />
            </Col>)}
          </Row>
          <Tabs className={cusicons.length > 0 ? 'dubble-tabs' : ''}>
            <TabPane tab="系统" key="setting">
              <Row>
                {icons.map(icon => <Col className={icon === selectIcon ? 'active' : ''} key={icon} span={4}>
                  <MkIcon onClick={() => this.checkIcon(icon)} type={icon} />
                </Col>)}
              </Row>
            </TabPane>
            <TabPane tab={
              <span className="tab-control" id="mk-custom-tab">
                <RedoOutlined onClick={(e) => {this.getIcons()}}/>
                自定义
              </span>
            } key="scripts">
              <Row>
                {cusicons.map(icon => <Col className={icon.icon_svg === selectIcon ? 'active' : ''} key={icon.id} span={4} onClick={() => this.checkIcon(icon.icon_svg)}>
                  <MkIcon type={icon.icon_svg} />
                </Col>)}
              </Row>
            </TabPane>
          </Tabs>
        </Modal>
      </div>
    )
src/components/mkIcon/index.scss
@@ -49,9 +49,6 @@
  clear: both;
}
.mk-icon-wrap {
  .ant-modal {
    top: 50px!important;
  }
  .ant-col {
    text-align: center;
    line-height: 55px;
@@ -65,4 +62,39 @@
      color: #1890ff;
    }
  }
  .tab-control {
    position: relative;
    .anticon-redo {
      display: none;
      position: absolute;
      left: -20px;
      top: 0px;
    }
  }
  .ant-tabs-tab-active.ant-tabs-tab {
    .tab-control {
      .anticon-redo {
        display: inline-block;
      }
    }
  }
  .ant-tabs-nav .ant-tabs-tab {
    padding: 12px 20px;
  }
  .ant-tabs-top.dubble-tabs {
    .ant-tabs-bar {
      padding-top: 10px!important;
    }
  }
  .ant-tabs-top:not(.dubble-tabs) {
    .ant-tabs-top-bar {
      border-bottom: 0px;
      .ant-tabs-nav-container {
        display: none;
      }
    }
    .ant-tabs-content {
      max-height: calc(100vh - 180px)!important;
    }
  }
}
src/components/mkPicture/index.jsx
New file
@@ -0,0 +1,74 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import LostPng from '@/assets/img/lost.png'
import MKEmitter from '@/utils/events.js'
import './index.scss'
class MkPicture extends Component {
  static propTpyes = {
    style: PropTypes.object,
    scale: PropTypes.bool,
    url: PropTypes.string,
    urls: PropTypes.array,
  }
  state = {
    url: '',
    lost: false
  }
  UNSAFE_componentWillMount() {
    const { url } = this.props
    if (url) {
      this.setState({url: url, lost: false})
      this.checkUrl(url)
    } else {
      this.setState({url: LostPng, lost: true})
    }
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    if (nextProps.url) {
      if (nextProps.url !== this.state.url) {
        this.setState({url: nextProps.url, lost: false})
        this.checkUrl(nextProps.url)
      }
    } else {
      this.setState({url: LostPng, lost: true})
    }
  }
  checkUrl = (url) => {
    let img = new Image()
    img.addEventListener('error', this.loadHandler)
    img.src = url
  }
  loadHandler = (e) => {
    this.setState({url: LostPng, lost: true})
  }
  render() {
    const { style, scale, urls } = this.props
    const { url, lost } = this.state
    return (
      <div
        className={'ant-mk-picture' + (scale ? ' scale' : '') + (lost ? ' lost' : '')}
        onClick={(e) => {
          if (!scale) return
          e.stopPropagation()
          MKEmitter.emit('mkImageScale', url, urls)
        }}
        style={{...style, backgroundImage: `url('${url}')`}}
      ></div>
    )
  }
}
export default MkPicture
src/components/mkPicture/index.scss
New file
@@ -0,0 +1,11 @@
.ant-mk-picture {
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
}
.ant-mk-picture.lost {
  background-size: contain!important;
}
.ant-mk-picture.scale {
  cursor: zoom-in;
}
src/components/normalform/index.jsx
@@ -3,8 +3,6 @@
import { is, fromJS } from 'immutable'
import { Modal } from 'antd'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import ModalForm from './modalform'
class NormalFormComponent extends Component {
@@ -17,7 +15,6 @@
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    visible: false,
    formlist: []
  }
@@ -62,7 +59,7 @@
  render () {
    const { title, width, children, double } = this.props
    const { visible, dict, formlist } = this.state
    const { visible, formlist } = this.state
    return (
      <>
@@ -73,7 +70,7 @@
          visible={visible}
          width={width}
          maskClosable={false}
          okText={dict['model.confirm']}
          okText="确定"
          onOk={this.submit}
          onCancel={this.cancel}
          destroyOnClose
src/components/normalform/modalform/index.jsx
@@ -57,6 +57,10 @@
          required: item.required,
          message: item.label + '不可为空!'
        }]
        if (item.rules) {
          _rules.push(...item.rules)
        }
        
        item.rules = _rules
      } else if (item.type === 'number') {
@@ -263,21 +267,41 @@
      } else if (item.type === 'source') {
        content = (<SourceComponent type="" placement="right"/>)
      } else if (item.type === 'table') {
        content = (<MKTable columns={item.columns || []} actions={item.actions || []}/>)
        content = (<MKTable tip={item.tip || ''} columns={item.columns || []} actions={item.actions || []}/>)
      } else if (item.type === 'hint') {
        fields.push(
          <Col span={24} key={index}>
            <div style={{color: '#1890ff', borderBottom: '1px solid #e9e9e9', marginBottom: '15px', paddingLeft: '10px'}}>{item.label}</div>
          </Col>
        )
        return
      }
      if (!content) return
      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/components/normalform/modalform/mkCheckbox/index.jsx
@@ -34,7 +34,7 @@
    const { value, options } = this.state
    return (
      <Checkbox.Group defaultValue={value} onChange={this.onChange}>
      <Checkbox.Group style={{whiteSpace: 'nowrap'}} defaultValue={value} onChange={this.onChange}>
        {options.map(option => <Checkbox key={option.value} title={option.label} disabled={option.disabled} value={option.value}>{option.label}</Checkbox>)}
      </Checkbox.Group>
    )
src/components/normalform/modalform/mkRadio/index.jsx
@@ -80,10 +80,10 @@
  }
  render() {
    const { value, options } = this.state
    const { value, options, config } = this.state
    return (
      <Radio.Group style={{whiteSpace: 'nowrap'}} value={value} onChange={this.onChange}>
      <Radio.Group style={{whiteSpace: 'nowrap'}} disabled={config.disabled} value={value} onChange={this.onChange}>
        {options.map(option => <Radio key={option.value} disabled={option.disabled} value={option.value}>{option.label}</Radio>)}
      </Radio.Group>
    )
src/components/normalform/modalform/mkSelect/index.jsx
@@ -112,13 +112,14 @@
            showSearch
            allowClear
            value={value}
            dropdownMatchSelectWidth={config.dropdown !== 'false'}
            filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
              option.props.extend.toLowerCase().indexOf(input.toLowerCase()) >= 0}
            onSelect={this.selectChange}
            onChange={(val) => val === undefined && this.selectChange('')}
          >
            {options.map((option, i) =>
              <Select.Option key={i} disabled={option.disabled} extend={option[config.extendName] || ''} value={option.value || option.field || ''}>{option.label || option.text}</Select.Option>
              <Select.Option key={i} disabled={option.disabled} title={option.label || option.text} extend={option[config.extendName] || ''} value={option.value || option.field || ''}>{option.label || option.text}</Select.Option>
            )}
          </Select>
        )
@@ -128,6 +129,7 @@
            showSearch
            allowClear
            value={value}
            dropdownMatchSelectWidth={config.dropdown !== 'false'}
            filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
            onSelect={this.selectChange}
            onChange={(val) => val === undefined && this.selectChange('')}
src/components/normalform/modalform/mkTable/index.jsx
@@ -75,14 +75,14 @@
class EditableCell extends Component {
  getInput = (form) => {
    const { inputType, options, min, max, unlimit } = this.props
    const { inputType, options, min, max, unlimit, allowClear } = this.props
    if (inputType === 'number' && unlimit) {
      return <InputNumber onPressEnter={() => this.getValue(form)} />
    } else if (inputType === 'number') {
      return <InputNumber min={min} max={max} precision={0} onPressEnter={() => this.getValue(form)} />
    } else if (inputType === 'color') {
      return <ColorSketch />
      return <ColorSketch allowClear={allowClear}/>
    } else if (inputType === 'icon') {
      return <MkEditIcon allowClear/>
    } else if (inputType === 'select') {
@@ -420,6 +420,7 @@
          unlimit: col.unlimit,
          required: col.required !== false ? true : false,
          title: col.title,
          allowClear: col.allowClear === true,
          editing: this.isEditing(record),
          onSave: this.execSave,
        }),
@@ -452,6 +453,7 @@
              })}
            />
          </DndProvider>
          {this.props.tip ? this.props.tip : null}
        </div>
      </EditableContext.Provider>
    )
src/components/normalform/modalform/styleInput/index.jsx
@@ -23,11 +23,11 @@
  UNSAFE_componentWillMount () {
    const { config } = this.props
    let val = config.initval || ''
    let val = config.initval || config.initVal || ''
    let options = config.options || ['px', 'vh', 'vw', '%']
    let unit = options[0]
    if (val) {
    if (val && typeof(val) === 'string') {
      if (val.indexOf('px') > -1) {
        unit = 'px'
      } else if (val.indexOf('%') > -1) {
src/components/normalform/modalform/styleInput/index.scss
@@ -8,4 +8,7 @@
    text-align: left;
    color: rgba(255, 255, 255, 0.65);
  }
  div[title="vh"], div[title="vw"] {
    color: #1890ff;
  }
}
src/components/qrcode/index.scss
@@ -1,5 +1,6 @@
.qrcode-box {
  display: inline-block;
  position: relative;
  canvas {
    vertical-align: top;
    max-width: 100%;
src/components/querylog/index.jsx
@@ -1,4 +1,5 @@
import { Component } from 'react'
import { notification } from 'antd'
import moment from 'moment'
import Api from '@/api'
@@ -6,7 +7,7 @@
import MKEmitter from '@/utils/events.js'
/**
 * @description 操作记录,每隔六分钟更新一次
 * @description 操作记录,每隔10分钟更新一次
 */
class QueryLog extends Component {
  state = {
@@ -14,12 +15,10 @@
  }
  componentDidMount () {
    if (window.GLOB.systemType === 'production') {
      MKEmitter.addListener('queryTrigger', this.queryTrigger)
      setTimeout(() => {
        this.sendLog()
      }, 300000)
    }
    MKEmitter.addListener('queryTrigger', this.queryTrigger)
    setTimeout(() => {
      this.sendLog()
    }, 600000)
  }
  /**
@@ -35,40 +34,66 @@
  sendLog = () => {
    const { logs } = this.state
    if (logs && logs.length > 0 && sessionStorage.getItem('isEditState') !== 'true') {
      let logMap = new Map()
    let logMap = new Map()
      logs.forEach(item => {
        if (logMap.has(item.menuId)) {
          let _item = logMap.get(item.menuId)
          _item.times++
          logMap.set(item.menuId, _item)
        } else {
          item.times = 1
          logMap.set(item.menuId, item)
        }
      })
      let userid = sessionStorage.getItem('UserID') || ''
      let LText = [...logMap.values()].map(item => `select '${item.menuId}','${item.times}','${item.name}','${window.GLOB.appkey}','${userid}'`)
    logs.forEach(item => {
      if (logMap.has(item.menuId)) {
        let _item = logMap.get(item.menuId)
        _item.times++
        logMap.set(item.menuId, _item)
      } else {
        item.times = 1
        logMap.set(item.menuId, item)
      }
    })
    let userid = sessionStorage.getItem('UserID') || ''
    let LText = [...logMap.values()].map(item => `select '${item.menuId}','${item.times}','${item.name}','${window.GLOB.appkey}','${userid}'`)
    Api.genericInterface({func: 's_get_local_users_operation_log'}).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 3
        })
        return
      }
      if (LText.length === 0 && !res.long_param) {
        setTimeout(() => {
          this.sendLog()
        }, 600000)
        return
      }
      let param = {
        func: 's_get_users_operation_log',
        exec_type: 'y', // 后台解码
        LText: LText.join(' union all ')
        exec_type: 'y',
        LText: LText.join(' union all '),
        long_param: res.long_param
      }
      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      param.secretkey = Utils.encrypt('', param.timestamp)
      param.LText = Utils.formatOptions(param.LText)
      Api.getSystemConfig(param)
      Api.getSystemConfig(param).then(result => {
        if (!result.status) {
          notification.warning({
            top: 92,
            message: result.message,
            duration: 3
          })
          return
        }
      this.setState({logs: []})
    }
    setTimeout(() => {
      this.sendLog()
    }, 300000)
        setTimeout(() => {
          this.sendLog()
        }, 600000)
        this.setState({logs: []})
      })
    })
  }
  queryTrigger = (item) => {
src/components/sidemenu/index.jsx
@@ -36,7 +36,7 @@
    let openKey = ''
    if (menu.children[0]) {
      openKey = menu.openId || menu.children[0].MenuID
      openKey = menu.children[0].MenuID
    }
    this.setState({
@@ -49,12 +49,10 @@
  changemenu(e, menu) {
    e.preventDefault()
    if (menu.OpenType === 'newpage' || menu.OpenType === 'NewPage') {
    if (menu.OpenType === 'newpage') {
      window.open(menu.src)
    } else if (menu.OpenType === 'blank') {
      MKEmitter.emit('modifyTabs', menu, 'replace')
    } else {
      MKEmitter.emit('modifyTabs', menu, 'plus')
      MKEmitter.emit('modifyTabs', menu)
    }
    if (window.GLOB.systemType === 'production') {
@@ -103,7 +101,7 @@
                key={item.MenuID}
                title={
                  <span>
                    <MkIcon type={item.PageParam.Icon} />
                    <MkIcon type={item.Icon} />
                    <span>{item.MenuName}</span>
                  </span>
                }
src/components/tabview/index.jsx
@@ -7,7 +7,6 @@
import moment from 'moment'
import 'moment/locale/zh-cn'
import { initActionPermission } from '@/store/action'
import asyncComponent from '@/utils/asyncLoadComponent'
import NotFount from '@/components/404'
import options from '@/store/options.js'
@@ -18,22 +17,13 @@
const Home = asyncComponent(() => import('@/tabviews/home'))
const CustomPage = asyncComponent(() => import('@/tabviews/custom'))
const CommonTable = asyncComponent(() => import('@/tabviews/commontable'))
const BaseTable = asyncComponent(() => import('@/tabviews/basetable'))
const CalendarPage = asyncComponent(() => import('@/tabviews/calendar'))
const TreePage = asyncComponent(() => import('@/tabviews/treepage'))
const VerupTable = asyncComponent(() => import('@/tabviews/verupmanage'))
const ScriptTable = asyncComponent(() => import('@/tabviews/scriptmanage'))
const TabManage = asyncComponent(() => import('@/tabviews/tabmanage'))
const Iframe = asyncComponent(() => import('@/tabviews/iframe'))
const RoleManage = asyncComponent(() => import('@/tabviews/rolemanage'))
const FormTab = asyncComponent(() => import('@/tabviews/formtab'))
let service = ''
if (process.env.NODE_ENV === 'production') {
  service = document.location.origin + '/' + window.GLOB.service + 'zh-CN/'
} else {
  service = window.GLOB.location + '/' + window.GLOB.service + 'zh-CN/'
}
const TabManage = asyncComponent(() => import('@/tabviews/tabmanage'))
class TabViews extends Component {
  static propTpyes = {
@@ -110,7 +100,7 @@
              })
            }
  
            this.props.initActionPermission(_permAction)
            window.GLOB.mkActions = _permAction
          }
          resolve()
@@ -119,7 +109,7 @@
  
      // 获取主菜单参数
      let menudefer = new Promise(resolve => {
        Api.getAppVersion().then(() => {
        Api.getAppVersion(menu.MenuID).then(() => {
          resolve()
        }, () => {
          resolve()
@@ -134,10 +124,10 @@
    }
  }
  modifyTabs = (tab, type, fixed) => {
  modifyTabs = (tab, fixed) => {
    const { tabviews, activeId } = this.state
    if (type === 'plus' && fixed) {
    if (fixed) {
      let _tabs = tabviews.filter(item => item.MenuID !== tab.MenuID)
      let index = _tabs.findIndex(item => item.MenuID === activeId)
@@ -154,7 +144,7 @@
          activeId: tab.MenuID
        })
      })
    } else if (type === 'plus') {
    } else {
      if (tabviews.findIndex(item => item.MenuID === tab.MenuID) > -1) {
        let _tabs = tabviews.filter(item => item.MenuID !== tab.MenuID)
        this.setState({
@@ -171,11 +161,6 @@
          activeId: tab.MenuID
        })
      }
    } else if (type === 'replace') {
      this.setState({
        tabviews: tab ? [tab] : [],
        activeId: tab ? tab.MenuID : ''
      })
    }
    let node = document.getElementById('root').parentNode.parentNode
@@ -195,32 +180,41 @@
    })
  }
  changeTemp = (MenuID, Template) => {
    let tabs = fromJS(this.state.tabviews).toJS()
    this.setState({
      tabviews: tabs.map(item => {
        if (item.MenuID === MenuID) {
          item.type = Template
        }
        return item
      })
    })
  }
  selectcomponent = (view) => {
    // 根据tab页中菜单信息,选择所需的组件
    if (view.type === 'Home') {
      return (<Home MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>)
    } else if (view.type === 'CommonTable' || view.type === 'ManageTable') {
      return (<CommonTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
    } else if (view.type === 'CommonTable') {
      return (<CommonTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param} changeTemp={this.changeTemp}/>)
    } else if (view.type === 'BaseTable') {
      return (<BaseTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param} changeTemp={this.changeTemp}/>)
    } else if (view.type === 'CustomPage') {
      return (<CustomPage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
      return (<CustomPage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param} changeTemp={this.changeTemp}/>)
    } else if (view.type === 'TreePage') {
      return (<TreePage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
    } else if (view.type === 'CalendarPage') {
      return (<CalendarPage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
    } else if (view.type === 'VerupTable') {
      return (<VerupTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>)
    } else if (view.type === 'ScriptTable') {
      return (<ScriptTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>)
    } else if (view.type === 'TabManage') {
      return (<TabManage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>)
    } else if (view.type === 'RolePermission') {
      return (<RoleManage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>)
    } else if (view.type === 'appRolePermission') {
      return (<RoleManage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>)
    } else if (view.type === 'FormTab') {
      return (<FormTab MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
    } else if (view.type === 'TabManage') {
      return (<TabManage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
    } else if (view.type === 'iframe') {
      return (<Iframe key={view.MenuID} MenuID={view.MenuID} MenuNo={view.MenuNo} title={view.MenuName} MenuName={view.MenuName} url={service + view.LinkUrl}/>)
      return (<Iframe key={view.MenuID} MenuID={view.MenuID} MenuNo={view.MenuNo} title={view.MenuName} MenuName={view.MenuName} url={window.GLOB.baseurl + 'zh-CN/' + view.LinkUrl}/>)
    } else {
      return (<NotFount key={view.MenuID} />)
    }
@@ -317,9 +311,7 @@
}
const mapDispatchToProps = (dispatch) => {
  return {
    initActionPermission: (permAction) => dispatch(initActionPermission(permAction))
  }
  return {}
}
export default connect(mapStateToProps, mapDispatchToProps)(TabViews)
src/components/thawmenu/index.jsx
New file
@@ -0,0 +1,133 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Modal, notification, Spin } from 'antd'
import { UnlockOutlined } from '@ant-design/icons'
import Api from '@/api'
import MKEmitter from '@/utils/events.js'
import TransferForm from '@/templates/zshare/basetransferform'
class ThawMenu extends Component {
  static propTpyes = {
    ParentId: PropTypes.string,
    Type: PropTypes.string
  }
  state = {
    visible: false,
    targetKeys: [],
    menulist: null,
    loading: false
  }
  trigger = () => {
    this.setState({
      visible: true,
      targetKeys: [],
      menulist: null,
      loading: false
    })
    Api.getSystemConfig({
      func: 'sPC_Get_FrozenMenu',
      ParentID: this.props.ParentId,
      TYPE: +this.props.Type
    }).then(res => {
      if (res.status) {
        this.setState({
          menulist: res.data.map(menu => {
            return {
              key: menu.MenuID,
              title: menu.MenuName
            }
          })
        })
      } else {
        this.setState({
          menulist: []
        })
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      }
    })
  }
  submit = () => {
    const { targetKeys } = this.state
    // 三级菜单解除冻结
    if (targetKeys.length === 0) {
      notification.warning({
        top: 92,
        message: '请选择菜单',
        duration: 5
      })
      return
    }
    this.setState({
      loading: true
    })
    let defers = targetKeys.map(item => {
      return new Promise((resolve) => {
        Api.getSystemConfig({
          func: 'sPC_MainMenu_ReDel',
          MenuID: item
        }).then(res => {
          if (res.status) {
            resolve('')
          } else {
            resolve(res.message)
          }
        })
      })
    })
    Promise.all(defers).then(res => {
      let msg = res.filter(Boolean)[0]
      if (msg) {
        notification.error({
          top: 92,
          message: msg,
          duration: 10
        })
      } else {
        this.setState({
          loading: false,
          visible: false,
          targetKeys: [],
          thawmenulist: null
        })
        MKEmitter.emit('mkUpdateMenuList')
      }
    })
  }
  render() {
    const { visible, menulist, loading } = this.state
    return (
      <>
        <UnlockOutlined onClick={this.trigger} style={{color: 'orange'}}/>
        <Modal
          title="解冻菜单"
          visible={visible}
          width={600}
          onOk={this.submit}
          confirmLoading={loading}
          onCancel={() => this.setState({visible: false})}
          destroyOnClose
        >
          {!menulist ?
            <Spin style={{marginLeft: 'calc(50% - 22px)', marginTop: '70px', marginBottom: '70px'}} size="large" /> :
            <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={menulist}/>
          }
        </Modal>
      </>
    )
  }
}
export default ThawMenu
src/components/thawmenu/index.scss
copy from src/menu/popview/menuform/index.scss copy to src/components/thawmenu/index.scss
src/components/video/index.jsx
@@ -15,8 +15,9 @@
class Video extends Component {
  static propTpyes = {
    card: PropTypes.object,  // 条码设置
    value: PropTypes.any,    // 条码值
    poster: PropTypes.string,
    card: PropTypes.object,
    value: PropTypes.any,
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -24,15 +25,15 @@
  }
  render() {
    const { value, card } = this.props
    const { value, card, poster } = this.props
    return (
      <div style={{overflow: 'hidden'}}>
        <Player poster="" autoPlay={card.autoPlay === 'true'} aspectRatio={card.aspectRatio || '16:9'} loop={card.loop === 'true'}>
        <Player startTime={card.startTime || 0} poster={poster || ''} currentTime={10} autoPlay={card.autoPlay === 'true'} aspectRatio={card.aspectRatio || '16:9'} loop={card.loop === 'true'}>
          <source src={value} />
          <BigPlayButton position="center" />
          <ControlBar>
            <VolumeMenuButton />
            <VolumeMenuButton vertical />
            <CurrentTimeDisplay />
            <TimeDivider />
            <PlaybackRateMenuButton rates={[5, 2, 1, 0.5, 0.1]} order={7.1} />
src/components/video/index.scss
@@ -25,7 +25,7 @@
.video-react .video-react-volume-menu-button, .video-react .video-react-play-control, .video-react .video-react-play-progress, .video-react .video-react-big-play-button {
  /* use !important to prevent issues with browser extensions that change fonts */
  font-family: "video-react" !important;
  speak: none;
  // speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
@@ -703,8 +703,7 @@
 ginormous. If you'd like to enable the current time tooltip all the time, this should be disabled
 to avoid a weird hitch when you roll off the hover. */
.video-react .video-react-progress-control:hover .video-react-time-tooltip,
.video-react .video-react-progress-control:hover .video-react-mouse-display:after,
.video-react .video-react-progress-control:hover .video-react-play-progress:after {
.video-react .video-react-progress-control:hover .video-react-mouse-display:after {
  visibility: visible;
  font-size: 0.6em;
}
@@ -728,14 +727,13 @@
}
.video-react .video-react-play-progress:before {
  position: absolute;
  top: -0.3333333333em;
  top: -4px;
  right: -0.5em;
  font-size: 0.9em;
}
.video-react .video-react-time-tooltip,
.video-react .video-react-mouse-display:after,
.video-react .video-react-play-progress:after {
.video-react .video-react-mouse-display:after {
  visibility: hidden;
  pointer-events: none;
  position: absolute;
@@ -753,8 +751,7 @@
}
.video-react .video-react-time-tooltip,
.video-react .video-react-play-progress:before,
.video-react .video-react-play-progress:after {
.video-react .video-react-play-progress:before {
  z-index: 1;
}
@@ -930,13 +927,13 @@
}
.video-react .video-react-slider-vertical .video-react-volume-level:before {
  top: -0.5em;
  left: -0.3em;
  left: -4px;
}
.video-react .video-react-slider-horizontal .video-react-volume-level {
  height: 0.3em;
}
.video-react .video-react-slider-horizontal .video-react-volume-level:before {
  top: -0.3em;
  top: -4px;
  right: -0.5em;
}
.video-react .video-react-menu-button-popup.video-react-volume-menu-button .video-react-menu {
@@ -1046,4 +1043,17 @@
.video-react video::-webkit-media-text-track-container {
  -webkit-transform: translateY(-30px);
  transform: translateY(-30px);
}
.video-react .video-react-play-progress:after {
  display: none;
}
.video-react .video-react-current-time {
  padding-left: 0px;
  padding-right: 4px;
}
.video-react .video-react-duration {
  padding-left: 4px;
  padding-right: 10px;
}
src/index.js
@@ -2,6 +2,7 @@
import ReactDOM from 'react-dom'
import Route from './router'
import { Provider } from 'react-redux'
import md5 from 'md5'
import store from '@/store'
import * as serviceWorker from './serviceWorker'
import options, { styles } from '@/store/options.js'
@@ -55,6 +56,7 @@
sessionStorage.setItem('role_id', localStorage.getItem('role_id') || '')
sessionStorage.setItem('departmentcode', localStorage.getItem('departmentcode') || '')
sessionStorage.setItem('organization', localStorage.getItem('organization') || '')
sessionStorage.setItem('mk_user_type', localStorage.getItem('mk_user_type') || '')
sessionStorage.setItem('localRole_id', localStorage.getItem('localRole_id') || '')
sessionStorage.setItem('lang', 'zh-CN')
@@ -91,10 +93,18 @@
    GLOB.lineColor = config.lineColor || ''
    GLOB.licenseKey = config.licenseKey || ''
    GLOB.probation = false
    GLOB.watermark = config.watermark !== false
    GLOB.keepKey = config.keepPassword !== 'false'
    GLOB.watermark = config.watermark + '' !== 'false'
    GLOB.transfer = config.transfer + '' === 'true'
    GLOB.keepKey = config.keepPassword + '' !== 'false'
    GLOB.nginx = config.nginx + '' === 'true'
    GLOB.WXAppID = config.WXAppID || ''
    GLOB.WXminiAppID = config.WXminiAppID || ''
    GLOB.accessToken = {}
    GLOB.mkHS = false
    if (config.externalDatabase !== false && config.externalDatabase !== 'false' && config.externalDatabase !== undefined) {
    if (sessionStorage.getItem('externalDatabase')) {
      GLOB.externalDatabase = `[${sessionStorage.getItem('externalDatabase')}]..`
    } else if (config.externalDatabase + '' !== 'false' && config.externalDatabase !== undefined) {
      GLOB.externalDatabase = config.externalDatabase ? `[${config.externalDatabase}]..` : ''
    } else {
      GLOB.externalDatabase = null
@@ -135,6 +145,10 @@
    GLOB.debugger = options.sysType === 'local' && GLOB.systemType !== 'production'
    if (/#\/hs$/.test(window.location.href)) { // hs下不打印脚本
      GLOB.debugger = false
    }
    if (options.sysType !== 'cloud') {
      if (config.appkey === options.cakey) {
        document.getElementById('root').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh;">不可使用云端appkey,请联系管理员!</div>'
@@ -164,6 +178,8 @@
    let _systemMsg = localStorage.getItem(_href + 'system')
    GLOB.navBar = 'shutter' // 默认为百叶窗
    if (_systemMsg) {
      try {
        _systemMsg = JSON.parse(window.decodeURIComponent(window.atob(_systemMsg)))
@@ -180,7 +196,7 @@
        GLOB.webSite = _systemMsg.webSite
        GLOB.style = _systemMsg.style
        GLOB.showline = _systemMsg.showline || ''
        GLOB.navBar = _systemMsg.navBar || ''
        GLOB.navBar = _systemMsg.navBar || 'shutter'
        GLOB.appVersion = _systemMsg.app_version || ''
        if (GLOB.favicon) {
@@ -198,7 +214,7 @@
      }
    }
    if (/^https/.test(window.location.protocol)) { // https转换
    if (/^https/.test(window.location.protocol) || (process.env.NODE_ENV !== 'production' && /^https/.test(config.host))) { // https转换
      let meta = document.createElement('meta')
      meta.content = 'upgrade-insecure-requests'
      meta.httpEquiv = 'Content-Security-Policy'
@@ -208,26 +224,21 @@
    document.title = GLOB.platTitle || ''
    if (config.filter === 'true' || (/^20\d{2}-\d{2}-\d{2}$/.test(config.filter) && new Date(config.filter).getTime() + 86400000 >= new Date().getTime())) {
      let html = document.getElementsByTagName('html')[0]
      if (html) {
        html.style.filter = 'grayscale(100%)'
      }
      GLOB.filter = true
    }
    if (process.env.NODE_ENV === 'production') { // 用于校验是否存在开发权限
      let _service = window.location.href.replace(/(\/admin)?\/index.html(.*)|(\/admin)?\/#(.*)/ig, '').replace(new RegExp(document.location.origin + '/?', 'ig'), '')
      GLOB.linkurl = _href
      if (!/index.html/ig.test(GLOB.linkurl)) {
        GLOB.linkurl = GLOB.linkurl + 'index.html'
      }
      let _service = window.location.href.replace(/\/admin(.*)/ig, '').replace(new RegExp(document.location.origin + '/?', 'ig'), '')
      GLOB.service = _service ? _service + '/' : ''
      GLOB.host = window.location.host + (_service ? '_' + _service : '')
      GLOB.baseurl = document.location.origin + '/' + GLOB.service
      GLOB.linkurl = GLOB.baseurl + 'index.html'
    } else {
      GLOB.linkurl = ''
      GLOB.location = config.host
      GLOB.service = config.service
      GLOB.host = config.host.replace(/http(s)?:\/\//ig, '') + (config.service ? '_' + config.service.replace(/\//ig, '') : '')
      GLOB.baseurl = GLOB.location + '/' + GLOB.service
    }
    let mark = sessionStorage.getItem('system_mark')
@@ -241,6 +252,29 @@
      sessionStorage.setItem('lang', localStorage.getItem(_href + 'lang'))
    } else {
      sessionStorage.setItem('lang', config.defaultLang !== 'en-US' ? 'zh-CN' : 'en-US')
    }
    let _level = 10
    let _Mlevel = sessionStorage.getItem('Member_Level')
    if (_Mlevel) {
      if (_Mlevel === md5('mksoft' + GLOB.appkey + new Date().getFullYear() + new Date().getMonth() + 10)) {
        _level = 10
      } else if (_Mlevel === md5('mksoft' + GLOB.appkey + new Date().getFullYear() + new Date().getMonth() + 20)) {
        _level = 20
      } else if (_Mlevel === md5('mksoft' + GLOB.appkey + new Date().getFullYear() + new Date().getMonth() + 30)) {
        _level = 30
      }
    }
    GLOB.memberLevel = _level
    GLOB.mkThdMenus = [] // 三级菜单
    GLOB.mkActions = {}  // 按钮权限集
    if (sessionStorage.getItem('breakpoint')) {
      window.debugger = true
      GLOB.breakpoint = sessionStorage.getItem('breakpoint')
    } else {
      GLOB.breakpoint = false
    }
    Object.defineProperty(GLOB, 'appId', {
@@ -274,6 +308,7 @@
    window.GLOB.CacheMap = new Map()     // 缓存配置信息
    window.GLOB.UserCacheMap = new Map() // 缓存用户自定义设置
    window.GLOB.CacheData = new Map()    // 存储选中数据
    render(Route)
  })
src/locales/en-US/mob.js
File was deleted
src/locales/en-US/model.js
File was deleted
src/locales/zh-CN/mob.js
File was deleted
src/locales/zh-CN/model.js
File was deleted
src/menu/bgcontroller/index.jsx
File was deleted
src/menu/bgcontroller/index.scss
File was deleted
src/menu/components/card/balcony/index.jsx
@@ -2,11 +2,11 @@
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, Checkbox } from 'antd'
import { PlusOutlined, PlusSquareOutlined, EditOutlined, FontColorsOutlined, DeleteOutlined, SettingOutlined, ToolOutlined } from '@ant-design/icons'
import { PlusOutlined, PlusSquareOutlined, EditOutlined, FontColorsOutlined, DeleteOutlined, SettingOutlined, ToolOutlined, ClockCircleOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle } from '@/utils/utils-custom.js'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import Utils from '@/utils/utils.js'
import getWrapForm from './options'
@@ -39,12 +39,9 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: 'object',   // 组件属性 - 数据格式
        pageable: false,    // 组件属性 - 是否可分页
        switchable: false,  // 组件属性 - 数据是否可切换
        dataName: card.dataName || '',
        width: card.width || 24,
        name: card.name,
        subtype: card.subtype,
@@ -72,10 +69,8 @@
          return elem
        })
      }
      this.setState({
        card: _card
      })
      this.props.updateConfig(_card)
      this.updateComponent(_card)
    } else {
      this.setState({
        card: fromJS(card).toJS()
@@ -83,12 +78,12 @@
    }
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  componentDidMount () {
    MKEmitter.addListener('mkUpdateInter', this.mkUpdateInter)
  }
  /**
@@ -98,21 +93,91 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('mkUpdateInter', this.mkUpdateInter)
  }
  mkUpdateInter = (inter, split) => {
    const { card } = this.state
    if (card.wrap.datatype === 'public' && card.wrap.publicId === inter.uuid) {
      let _card = {...card, columns: fromJS(inter.columns).toJS()}
      split.delay = split.delay + 10
      setTimeout(() => {
        this.updateComponent(_card)
      }, split.delay)
    }
  }
  /**
   * @description 卡片行外层信息更新(数据源,样式等)
   */
  updateComponent = (component) => {
  updateComponent = (card) => {
    card.width = card.wrap.width
    card.name = card.wrap.name
    if (window.GLOB.styling && card.errors) { // 样式修改时不做筛查
      this.setState({
        card: card
      })
      this.props.updateConfig(card)
      return
    }
    card.errors = []
    if (card.wrap.datatype === 'static') {
      card.elements.forEach(cell => {
        if (cell.eleType === 'button') {
          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
            if (!cell.modal || cell.modal.fields.length === 0) {
              card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
            }
          }
        } else if (cell.datatype === 'dynamic' && cell.field) {
          card.errors.push({ level: 1, detail: `卡片中动态字段“${cell.field}”无效`})
        }
      })
      card.$tables = getTables(card)
    } else {
      let columns = card.columns.map(c => c.field)
      if (card.wrap.datatype === 'dynamic') {
        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: '主键已失效!'})
        }
      }
      if (card.errors.length === 0) {
        card.$tables = getTables(card)
      }
      card.elements.forEach(cell => {
        if (cell.eleType === 'button') {
          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
            if (!cell.modal || cell.modal.fields.length === 0) {
              card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
            }
          }
        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
          card.errors.push({ level: 1, detail: `卡片中动态字段“${cell.field}”无效`})
        }
      })
    }
    this.setState({
      card: component
      card: card
    })
    component.width = component.wrap.width
    component.name = component.wrap.name
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  updateCard = (elements) => {
@@ -120,31 +185,19 @@
    let _card = {...card, elements: elements}
    this.setState({
      card: _card,
    })
    this.props.updateConfig(_card)
    this.updateComponent(_card)
  }
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    if (comIds.length !== 1 || comIds[0] !== card.uuid) return
    let _card = {...card, style}
    this.setState({
      card: _card
    })
    this.props.updateConfig(_card)
    this.updateComponent(_card)
  }
  addElement = () => {
@@ -159,7 +212,7 @@
    newcard.height = 1
    // 注册事件-添加元素
    MKEmitter.emit('cardAddElement', [card.uuid, card.uuid], newcard)
    MKEmitter.emit('cardAddElement', card.uuid, newcard)
  }
  addButton = () => {
@@ -170,7 +223,7 @@
    newcard.focus = true
    // 注册事件-添加元素
    MKEmitter.emit('cardAddElement', [card.uuid, card.uuid], newcard)
    MKEmitter.emit('cardAddElement', card.uuid, newcard)
  }
  pasteComponent = (res, resolve) => {
@@ -183,10 +236,10 @@
    res.focus = true
    if (type === 'customCardElement') {
      MKEmitter.emit('cardAddElement', [card.uuid, card.uuid], res)
      MKEmitter.emit('cardAddElement', card.uuid, res)
    } else {
      res.eleType = 'button'
      MKEmitter.emit('cardAddElement', [card.uuid, card.uuid], res)
      MKEmitter.emit('cardAddElement', card.uuid, res)
    }
    resolve({status: true})
  }
@@ -199,7 +252,20 @@
  updateWrap = (res) => {
    delete res.quick
    this.updateComponent({...this.state.card, wrap: res})
    let _card = {...this.state.card, wrap: res}
    if (res.datatype === 'public') {
      let interfaces = window.GLOB.customMenu.interfaces || []
      let d = interfaces.filter(m => m.uuid === res.publicId && m.status === 'true')[0]
      if (d) {
        _card.columns = fromJS(d.columns).toJS()
      }
    }
    this.updateComponent(_card)
  }
  render() {
@@ -219,17 +285,30 @@
            <CopyComponent type="balcony" card={card}/>
            <PasteComponent options={['action', 'customCardElement']} updateConfig={this.pasteComponent} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle} />
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
            {card.wrap.datatype === 'dynamic' ? <ClockComponent config={card} updateConfig={this.updateComponent}/> : <ClockCircleOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/>}
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)} />
            {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
            {card.wrap.datatype === 'static' ? <SettingOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/> : null}
            {card.wrap.datatype === 'dynamic' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : <SettingOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/>}
          </div>
        } trigger="hover">
          <ToolOutlined />
        </Popover>
        {card.wrap.checkAll === 'show' ? <div className="check-all"><Checkbox>全选</Checkbox></div> : null}
        <CardCellComponent cards={card} cardCell={card} elements={card.elements} updateElement={this.updateCard}/>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/card/balcony/index.scss
@@ -57,24 +57,6 @@
    right: -30px;
    font-size: 16px;
  }
  .model-menu-action-list {
    line-height: 40px;
    .ant-row > .anticon-plus {
      position: absolute;
      right: -30px;
      font-size: 16px;
    }
  }
  .card-add-button {
    text-align: right;
    clear: left;
    .anticon-plus {
      font-size: 20px;
      color: #26C281;
      padding: 5px;
      margin-right: 10px;
    }
  }
}
.menu-balcony-edit-box::after {
  display: block;
src/menu/components/card/balcony/options.jsx
@@ -1,15 +1,28 @@
import React from 'react'
import { fromJS } from 'immutable'
import MenuUtils from '@/utils/utils-custom.js'
/**
 * @description Wrap表单配置信息
 */
export default function (wrap) {
  let modules = MenuUtils.getLinkModules(fromJS(window.GLOB.customMenu).toJS().components) || []
  let supmodules = MenuUtils.getSupModules(fromJS(window.GLOB.customMenu).toJS().components, '') || []
  let menu = window.GLOB.customMenu
  let modules = MenuUtils.getLinkModules(menu.components) || []
  let supmodules = MenuUtils.getSupModules(menu.components, '', menu.interfaces)
  let roleList = sessionStorage.getItem('sysRoles')
  let appType = sessionStorage.getItem('appType')
  let interfaces = []
  if (menu.interfaces) {
    menu.interfaces.forEach(item => {
      if (item.status === 'true') {
        interfaces.push({
          value: item.uuid,
          label: item.name
        })
      }
    })
  }
  if (roleList) {
    try {
@@ -51,7 +64,20 @@
      options: [
        {value: 'dynamic', label: '动态'},
        {value: 'static', label: '静态'},
        {value: 'public', label: '公共数据源'},
      ],
      controlFields: [
        {field: 'empty', values: ['dynamic']},
        {field: 'publicId', values: ['public']},
      ]
    },
    {
      type: 'select',
      field: 'publicId',
      label: '数据源',
      initval: wrap.publicId || '',
      required: true,
      options: interfaces
    },
    {
      type: 'radio',
@@ -81,7 +107,7 @@
      type: 'cascader',
      field: 'supModule',
      label: '上级组件',
      initval: wrap.supModule || '',
      initval: wrap.supModule || [],
      // tooltip: '当上级组件不存在或没有权限时,当前组件不显示。',
      required: true,
      options: supmodules
@@ -210,6 +236,19 @@
    },
    {
      type: 'radio',
      field: 'empty',
      label: '空值隐藏',
      initval: wrap.empty || 'show',
      tooltip: '当查询数据为空时,隐藏该组件。',
      required: false,
      skip: true,
      options: [
        {value: 'show', label: '否'},
        {value: 'hidden', label: '是'},
      ],
    },
    {
      type: 'radio',
      field: 'permission',
      label: '权限验证',
      initval: wrap.permission || 'false',
src/menu/components/card/cardcellcomponent/dragaction/action.jsx
@@ -18,7 +18,13 @@
  const [, drop] = useDrop({
    accept: 'action',
    canDrop: () => true,
    drop({ id: draggedId }) {
    drop(item) {
      const { id: draggedId } = item
      if (item.$init) {
        item.overIndex = id
      }
      if (!draggedId || draggedId === id) return
      const { index: originIndex } = findCard(draggedId)
@@ -47,8 +53,10 @@
  if (card.OpenType === 'form') {
    if (card.formType === 'switch') {
      btnElement = (<Switch style={_style} className={card.size === 'large' ? 'ant-switch-large' : ''} size={card.size} checkedChildren={card.openText || ''} unCheckedChildren={card.closeText || ''}/>)
    } else {
    } else if (card.formType === 'radio') {
      btnElement = (<Checkbox style={_style}></Checkbox>)
    } else {
      btnElement = (<Button style={_style} type="link"><MkIcon type="scan"/></Button>)
    }
  } else if (card.show === 'icon') {
    btnElement = (<Button style={_style} type="link"><MkIcon type={card.icon}/>{warning}</Button>)
@@ -56,6 +64,12 @@
    btnElement = (<Button style={_style} type="link">{card.label}{card.icon ? <MkIcon type={card.icon}/> : null}{warning}</Button>)
  } else {
    btnElement = (<Button style={_style}>{card.icon ? <MkIcon type={card.icon}/> : null}{card.label}{warning}</Button>)
  }
  let _style_ = null
  if (card.style && card.style.clear === 'left') {
    _style_ = {clear: 'left'}
  }
  return (
@@ -68,8 +82,8 @@
        {hasProfile ? <ProfileOutlined className="profile" title="setting" onClick={() => profileCard(id)} /> : null}
      </div>
    } trigger="hover">
      <div ref={node => drag(drop(node))} className={'ant-col card-button-cell ant-col-' + card.width} onDoubleClick={(e) => {e.stopPropagation(); doubleClickCard(id)}}>
        <div style={{opacity: isDragging ? 0 : 1, ...card.wrapStyle}}>
      <div ref={node => drag(drop(node))} style={_style_} className={'ant-col card-button-cell ant-col-' + card.width + (card.hidden === 'true' ? ' mk-hidden' : '')} onDoubleClick={(e) => {e.stopPropagation(); doubleClickCard(id)}}>
        <div style={{opacity: isDragging ? 0.3 : 1, ...card.wrapStyle}}>
          {btnElement}
        </div>
      </div>
src/menu/components/card/cardcellcomponent/dragaction/card.jsx
@@ -40,7 +40,13 @@
  const [, drop] = useDrop({
    accept: 'action',
    canDrop: () => true,
    drop({ id: draggedId }) {
    drop(item) {
      const { id: draggedId } = item
      if (item.$init) {
        item.overIndex = id
      }
      if (!draggedId || draggedId === id) return
      const { index: originIndex } = findCard(draggedId)
@@ -51,10 +57,10 @@
    },
  })
  let _style = {opacity: isDragging ? 0 : 1}
  let _style = {opacity: isDragging ? 0.3 : 1}
  
  if (card.style) {
    _style = {...card.style, opacity: isDragging ? 0 : 1}
    _style = {...card.style, opacity: isDragging ? 0.3 : 1}
    _style = resetStyle(_style)
  }
  if (card.eleType === 'picture' && card.maxWidth) {
@@ -71,7 +77,7 @@
  const getContent = () => {
    if (card.eleType === 'sequence') {
      return (
        <div className={'ant-mk-text'}>1</div>
        <div style={{height: card.innerHeight || 'auto'}} className="ant-mk-text">1</div>
      )
    } else if (card.eleType === 'text' || card.eleType === 'number') {
      let val = `${card.prefix || ''}${card.datatype === 'static' ? (card.value || '') : (card.field || '')}${card.postfix || ''}`
@@ -83,7 +89,7 @@
        <div className={'ant-mk-text line' + (card.height || '')} style={{height: card.innerHeight || 'auto'}}>{val}</div>
      )
    } else if (card.eleType === 'icon') {
      return (<MkIcon type={card.icon}/>)
      return (<MkIcon style={{height: card.innerHeight || 'auto'}} className="ant-mk-icon" type={card.icon || 'bell'}/>)
    } else if (card.eleType === 'slider') {
      let val = card.value ? (card.value / card.maxValue) * 100 : 30
      return <MkProgress value={val} config={card}/>
@@ -96,9 +102,11 @@
      // )
    } else if (card.eleType === 'picture') {
      let _imagestyle = {}
      let url = card.url !== '@icon@' ? card.url : sessionStorage.getItem('CloudAvatar')
      if (card.url) {
        _imagestyle = {backgroundImage: `url('${card.url}')`}
      if (url) {
        url = url.replace(/@mywebsite@\//ig, window.GLOB.baseurl)
        _imagestyle = {backgroundImage: `url('${url}')`}
      } else {
        let index = card.uuid.match(/\d{1}/g)
        index = index.slice(-1)[0] % 5
@@ -117,13 +125,17 @@
        _imagestyle.paddingTop = '100%'
      }
      if (card.backgroundSize) {
        _imagestyle.backgroundSize = card.backgroundSize
      }
      return (
        <div className="ant-mk-picture" style={_imagestyle}></div>
      )
    } else if (card.eleType === 'splitline') {
      let _borderWidth = card.borderWidth === undefined ? 1 : card.borderWidth
      return (
        <div style={{paddingTop: '1px'}}>
        <div style={{paddingTop: _borderWidth ? '1px' : '10px'}}>
          <div className="ant-mk-splitline" style={{borderColor: card.color, borderWidth: _borderWidth}}></div>
        </div>
      )
@@ -140,9 +152,10 @@
        </div>
      )
    } else if (card.eleType === 'video') {
      _style.overflow = 'hidden'
      return (
        <div>
          <Video card={card} value={card.url || 'http://qingqiumarket.cn/mkwms/Content/images/upload/20210104/trailer.mp4'}/>
        <div className="video-wrap">
          <Video card={card} poster={card.posterUrl || ''} value={card.url || 'http://qingqiumarket.cn/mkwms/Content/images/upload/20210104/trailer.mp4'}/>
        </div>
      )
    } else if (card.eleType === 'currentDate') {
@@ -152,7 +165,7 @@
        val = <><span style={_s}>{card.prefix || ''}</span>{moment().format(card.dateFormat)}<span style={_s}>{card.postfix || ''}</span></>
      }
      return (
        <div className="ant-mk-date">
        <div className="ant-mk-text line1" style={{height: card.innerHeight || 'auto'}}>
          {val}
        </div>
      )
@@ -163,7 +176,7 @@
        val = <><span style={_s}>{card.prefix || ''}</span>{card.formula}<span style={_s}>{card.postfix || ''}</span></>
      }
      return (
        <div className="ant-mk-date">
        <div className="ant-mk-text" style={{height: card.innerHeight || 'auto'}}>
          {val}
        </div>
      )
@@ -173,14 +186,19 @@
  const clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'cardcell') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', card, parent, 'cardcell')
      MKEmitter.emit('clickComponent', card.uuid, parent.uuid)
    }
  }
  let able = true
  if ((appType === 'mob' || appType === 'pc') && parent && (parent.setting.click === 'menu' || parent.setting.click === 'menus')) {
  // if ((appType === 'mob' || appType === 'pc') && parent && parent.setting.click === 'menu') {
  if ((appType === 'mob' || appType === 'pc') && (parent.setting.click === 'menu' || parent.setting.click === 'menus')) {
    able = false
  }
  let _style_ = null
  if (card.style && card.style.clear === 'left') {
    _style_ = {clear: 'left'}
  }
  return (
@@ -190,10 +208,10 @@
        <CopyOutlined className="copy" title="复制" onClick={() => copyCard(id)} />
        <CloseOutlined className="close" title="删除" onClick={() => delCard(id)} />
        <FontColorsOutlined className="style" title="调整样式" onClick={() => changeStyle(id)}/>
        {['text', 'number', 'slider', 'sequence', 'formula'].includes(card.eleType) ? <MarkColumn columns={fields} type={card.eleType} marks={card.marks} onSubmit={(vals) => updateMarks({...card, marks: vals})} /> : null }
        {['text', 'number', 'slider', 'sequence', 'formula'].includes(card.eleType) ? <MarkColumn field={card.field || ''} columns={fields} type={card.eleType} marks={card.marks} onSubmit={(vals) => updateMarks({...card, marks: vals})} /> : null }
      </div>
    } trigger="hover">
      <div ref={node => drag(drop(node))} className={'ant-col card-cell ant-col-' + card.width}>
      <div ref={node => drag(drop(node))} style={_style_} className={'ant-col card-cell ant-col-' + card.width}>
        <div style={_style} onClick={clickComponent} onDoubleClick={() => able && editCard(id)} id={card.uuid}>
          {getContent()}
        </div>
src/menu/components/card/cardcellcomponent/dragaction/index.jsx
@@ -48,8 +48,6 @@
    let _val = fromJS(copycard).toJS()
    if (_val.control) {
      _val.control = ''
      delete _val.controlField
      delete _val.controlVal
    }
@@ -114,6 +112,66 @@
  const [, drop] = useDrop({
    accept: 'action',
    drop(item) {
      if (item.$init) { // 拖拽添加
        let newcard = {}
        newcard.uuid = Utils.getuuid()
        newcard.focus = true
        // 显示列过滤
        if (parent.type === 'custom' && item.class !== 'element') {
          delete item.overIndex
          return
        } else if (parent.type === 'action' && item.class === 'element') {
          delete item.overIndex
          return
        }
        if (item.class === 'element') {
          newcard.eleType = item.value
          newcard.datatype = 'dynamic'
          newcard.height = 1
          if (item.value === 'splitline') {
            newcard.width = 24
            newcard.color = '#EBE9E9'
          } else if (item.value === 'slider') {
            newcard.width = 24
            newcard.color = '#1890ff'
          }
        } else {
          newcard.eleType = 'button'
          newcard.label = 'button'
          newcard.verify = null
          newcard.show = 'link'
          newcard.Ot = 'requiredSgl'
          newcard.OpenType = item.value
          newcard.class = 'primary'
          if (newcard.OpenType === 'excelIn') {
            newcard.label = item.text
            newcard.class = 'dgreen'
            newcard.Ot = 'notRequired'
          } else if (item.subType === 'excelOut') {
            newcard.label = item.text
            newcard.execSuccess = 'never'
            newcard.class = 'dgreen'
          }
        }
        if (item.overIndex) {
          const { index } = findCard(item.overIndex)
          const _cards = update(cards, { $splice: [[index + 1, 0, newcard]] })
          handleList(_cards)
        } else {
          handleList([...cards, newcard])
        }
        handleMenu(newcard)
        delete item.overIndex
        return
      }
      const { index } = findCard(item.id)
      if (index > -1) return
      dropButton(item.id)
@@ -129,7 +187,6 @@
              id={card.uuid}
              key={card.uuid}
              card={card}
              parent={parent}
              copyCard={copyCard}
              moveCard={moveCard}
              editCard={editCard}
src/menu/components/card/cardcellcomponent/dragaction/index.scss
@@ -1,4 +1,5 @@
.card-detail-row {
  line-height: 1.5;
  .ant-mk-text {
    font-style: inherit;
    font-weight: inherit;
@@ -92,14 +93,6 @@
    border-left: 0;
    border-right: 0;
  }
  .ant-mk-date {
    white-space: nowrap;
    overflow: hidden;
    word-break: break-word;
    text-overflow: ellipsis;
    font-weight: inherit;
    font-style: inherit;
  }
  .ant-mk-check {
    white-space: nowrap;
    overflow: hidden;
@@ -122,6 +115,10 @@
    background-position: center center;
    background-repeat: no-repeat;
  }
  .ant-mk-icon {
    vertical-align: top;
    line-height: inherit;
  }
  .ant-switch-large {
    min-width: 60px;
    height: 30px;
src/menu/components/card/cardcellcomponent/elementform/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber } from 'antd'
import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber, Cascader } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons'
import { formRule } from '@/utils/option.js'
@@ -15,11 +15,11 @@
const cardTypeOptions = {
  sequence: ['eleType', 'width'],
  text: ['eleType', 'datatype', 'format', 'width', 'height', 'prefix', 'postfix', 'link', 'noValue', 'bgImage', 'fixStyle'],
  number: ['eleType', 'datatype', 'format', 'width', 'height', 'prefix', 'postfix', 'noValue', 'fixStyle'],
  picture: ['eleType', 'datatype', 'width', 'lenWidRadio', 'maxWidth', 'link', 'noValue'],
  video: ['eleType', 'datatype', 'width', 'aspectRatio', 'autoPlay', 'loop', 'noValue'],
  icon: ['eleType', 'icon', 'datatype', 'width'],
  text: ['eleType', 'datatype', 'format', 'width', 'height', 'prefix', 'postfix', 'link', 'anchors', 'noValue', 'bgImage', 'fixStyle', 'copyable'],
  number: ['eleType', 'datatype', 'width', 'height', 'prefix', 'postfix', 'noValue', 'fixStyle'],
  picture: ['eleType', 'datatype', 'width', 'lenWidRadio', 'backgroundSize', 'maxWidth', 'link', 'noValue'],
  video: ['eleType', 'datatype', 'width', 'aspectRatio', 'autoPlay', 'loop', 'startTime', 'noValue', 'posterType'],
  icon: ['eleType', 'datatype', 'width', 'tooltip'],
  slider: ['eleType', 'datatype', 'width', 'color', 'maxValue', 'showInfo', 'showType', 'strokeWidth', 'strokeLinecap', 'trailColor'],
  splitline: ['eleType', 'color', 'width', 'borderWidth'],
  barcode: ['eleType', 'datatype', 'width', 'barHeight', 'displayValue', 'interval', 'noValue'],
@@ -30,7 +30,6 @@
class MainSearch extends Component {
  static propTpyes = {
    dict: PropTypes.object,      // 字典项
    config: PropTypes.object,    // 组件信息
    formlist: PropTypes.any,     // 表单信息
    card: PropTypes.any,         // 按钮信息
@@ -49,7 +48,7 @@
  UNSAFE_componentWillMount () {
    const { card, config } = this.props
    let _options = this.getOptions(card.eleType, card.datatype, card.link, (card.showType || 'line'), card.showInfo, card.fixStyle || '')
    let _options = this.getOptions(card.eleType, card.datatype, card.link, (card.showType || 'line'), card.showInfo, card.fixStyle || '', card.posterType || '')
    
    this.setState({
      link: card.link,
@@ -58,16 +57,14 @@
      showType: card.showType || 'line',
      showInfo: card.showInfo || 'false',
      fixStyle: card.fixStyle || '',
      posterType: card.posterType || '',
      formlist: this.props.formlist.map(item => {
        item.hidden = !_options.includes(item.key)
        if (item.key === 'field' || item.key === 'linkurl' || item.key === 'bgImage') {
        if (item.key === 'field' || item.key === 'linkurl' || item.key === 'bgImage' || item.key === 'posterField') {
          item.options = []
          config.columns.forEach(col => {
            let label = col.label
            if (label !== col.field) {
              label = col.field + ' ' + col.label
            }
            let label = `${col.field}(${col.label})`
            if (/^(Int|Decimal)/ig.test(col.datatype) && (card.eleType === 'number' || card.eleType === 'slider')) {
              item.options.push({
                value: col.field,
@@ -83,6 +80,9 @@
        } else if (item.key === 'value' && card.eleType === 'slider') {
          item.type = 'number'
          item.label = '值'
        } else if (item.key === 'value' && card.eleType === 'text') {
          item.type = 'textarea'
          item.label = '内容'
        } else if (item.key === 'format') {
          if (card.eleType === 'text') {
            item.options = item.oriOptions.filter(op => !['percent', 'thdSeparator', 'abs'].includes(op.value))
@@ -101,19 +101,26 @@
    })
  }
  getOptions = (eleType, datatype, link, showType, showInfo, fixStyle) => {
  getOptions = (eleType, datatype, link, showType, showInfo, fixStyle, posterType) => {
    let _options = fromJS(cardTypeOptions[eleType]).toJS() // 选项列表
    
    if (['text', 'number', 'picture', 'slider', 'barcode', 'qrcode', 'video'].includes(eleType)) {
      if (datatype === 'dynamic') {
        _options.push('field')
        if (eleType === 'number') {
          _options.push('decimal')
          _options.push('decimal', 'format')
        }
      } else if (eleType === 'picture' || eleType === 'video') {
        _options.push('url')
      } else {
        _options.push('value')
      }
      if (eleType === 'video' && posterType) {
        if (posterType === 'dynamic') {
          _options.push('posterField')
        } else {
          _options.push('posterUrl')
        }
      }
      if (['text', 'picture'].includes(eleType) && link) {
@@ -134,7 +141,7 @@
      if (datatype === 'dynamic') {
        _options.push('field')
      } else {
        _options.push('tooltip')
        _options.push('icon')
      }
    }
    if (_options.includes('fixStyle') && fixStyle === 'alone') {
@@ -152,10 +159,10 @@
   */
  selectChange = (key, value, option) => {
    const { card, config } = this.props
    const { datatype, eleType, showType, showInfo, fixStyle } = this.state
    const { datatype, eleType, showType, showInfo, fixStyle, posterType } = this.state
    if (key === 'eleType') {
      let _options = this.getOptions(value, datatype, '', showType, showInfo, fixStyle)
      let _options = this.getOptions(value, datatype, '', showType, showInfo, fixStyle, posterType)
      
      let _formlist = this.state.formlist.map(item => {
        item.hidden = !_options.includes(item.key)
@@ -163,10 +170,7 @@
        if (item.key === 'field') {
          item.options = []
          config.columns.forEach(col => {
            let label = col.label
            if (label !== col.field) {
              label = col.field + ' ' + col.label
            }
            let label = `${col.field}(${col.label})`
            if (/^(Int|Decimal)/ig.test(col.datatype) && (value === 'number' || value === 'slider')) {
              item.options.push({
@@ -184,6 +188,9 @@
          if (value === 'slider') {
            item.type = 'number'
            item.label = '值'
          } else if (value === 'text') {
            item.type = 'textarea'
            item.label = '内容'
          } else {
            item.type = 'text'
            item.label = '内容'
@@ -198,8 +205,14 @@
          item.required = value !== 'qrcode'
        } else if (item.key === 'showInfo') {
          item.initVal = showInfo
        } else if (item.key === 'posterType') {
          item.initVal = posterType
        } else if (item.key === 'fixStyle') {
          item.initVal = fixStyle
        } else if (item.key === 'color') {
          if (value === 'splitline') {
            item.initVal = '#EBE9E9'
          }
        }
        return item
@@ -211,10 +224,10 @@
        showType: card.showType || 'line',
        formlist: _formlist
      }, () => {
        if (value === 'slider') {
        if (value === 'splitline') {
          this.props.form.setFieldsValue({width: 24, color: '#EBE9E9'})
        } else if (value === 'slider') {
          this.props.form.setFieldsValue({width: 24, color: '#1890ff'})
        } else if (value === 'splitline') {
          this.props.form.setFieldsValue({width: 24, color: '#e8e8e8'})
        } else if (value === 'qrcode') {
          this.props.form.setFieldsValue({color: '#000000'})
        } else if (value === 'text' || value === 'number') {
@@ -229,7 +242,7 @@
        this.props.form.setFieldsValue({value: option.props.title})
      }
    } else if (key === 'link') {
      let _options = this.getOptions(eleType, datatype, value, showType, showInfo, fixStyle)
      let _options = this.getOptions(eleType, datatype, value, showType, showInfo, fixStyle, posterType)
      this.setState({
        link: value,
        formlist: this.state.formlist.map(item => {
@@ -244,11 +257,11 @@
  }
  onChange = (e, key) => {
    const { eleType, datatype, link, showType, showInfo, fixStyle } = this.state
    const { eleType, datatype, link, showType, showInfo, fixStyle, posterType } = this.state
    let value = e.target.value
    if (key === 'datatype') {
      let _options = this.getOptions(eleType, value, link, showType, showInfo, fixStyle)
      let _options = this.getOptions(eleType, value, link, showType, showInfo, fixStyle, posterType)
      this.setState({
        datatype: value,
@@ -259,7 +272,7 @@
        })
      })
    } else if (key === 'link') {
      let _options = this.getOptions(eleType, datatype, value, showType, showInfo, fixStyle)
      let _options = this.getOptions(eleType, datatype, value, showType, showInfo, fixStyle, posterType)
      this.setState({
        link: value,
        formlist: this.state.formlist.map(item => {
@@ -271,7 +284,7 @@
        })
      })
    } else if (key === 'showInfo') {
      let _options = this.getOptions(eleType, datatype, link, showType, value, fixStyle)
      let _options = this.getOptions(eleType, datatype, link, showType, value, fixStyle, posterType)
      this.setState({
        showInfo: value,
        formlist: this.state.formlist.map(item => {
@@ -283,7 +296,7 @@
      this.setState({
        showType: value
      }, () => {
        let _options = this.getOptions(eleType, datatype, link, value, showInfo, fixStyle)
        let _options = this.getOptions(eleType, datatype, link, value, showInfo, fixStyle, posterType)
        this.setState({
          formlist: this.state.formlist.map(item => {
            item.hidden = !_options.includes(item.key)
@@ -295,7 +308,19 @@
      this.setState({
        fixStyle: value
      }, () => {
        let _options = this.getOptions(eleType, datatype, link, showType, showInfo, value)
        let _options = this.getOptions(eleType, datatype, link, showType, showInfo, value, posterType)
        this.setState({
          formlist: this.state.formlist.map(item => {
            item.hidden = !_options.includes(item.key)
            return item
          })
        })
      })
    } else if (key === 'posterType') {
      this.setState({
        posterType: value
      }, () => {
        let _options = this.getOptions(eleType, datatype, link, showType, showInfo, fixStyle, value)
        this.setState({
          formlist: this.state.formlist.map(item => {
            item.hidden = !_options.includes(item.key)
@@ -335,7 +360,7 @@
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                    message: '请输入' + item.label + '!'
                  },
                  {
                    max: formRule.input.max,
@@ -360,21 +385,17 @@
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  },
                  {
                    max: formRule.input.max,
                    message: formRule.input.message
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<TextArea rows={2} disabled={item.readonly} placeholder={item.placeholder || ''} />)}
              })(<TextArea autoSize={{minRows: 2}} disabled={item.readonly} placeholder={item.placeholder || ''} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'number') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
            <Form.Item help={item.help || null} label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
@@ -384,7 +405,7 @@
                initialValue: item.initVal,
                rules: [{
                  required: item.readonly ? false : !!item.required,
                  message: this.props.dict['form.required.input'] + item.label + '!'
                  message: '请输入' + item.label + '!'
                }]
              })(<InputNumber min={item.min || 0} max={item.max || 10000} precision={item.precision || 0} onPressEnter={this.handleSubmit} />)}
            </Form.Item>
@@ -403,7 +424,7 @@
                initialValue: item.initVal || '',
                rules: [{
                  required: !!item.required,
                  message: this.props.dict['form.required.select'] + item.label + '!'
                  message: '请选择' + item.label + '!'
                }]
              })(
                <Select
@@ -436,7 +457,7 @@
                initialValue: item.initVal || '',
                rules: [{
                  required: !!item.required,
                  message: this.props.dict['form.required.select'] + item.label + '!'
                  message: '请选择' + item.label + '!'
                }]
              })(
                <MkEditIcon />
@@ -457,7 +478,7 @@
                initialValue: item.initVal,
                rules: [{
                  required: !!item.required,
                  message: this.props.dict['form.required.select'] + item.label + '!'
                  message: '请选择' + item.label + '!'
                }]
              })(
                <Radio.Group onChange={(e) => {this.onChange(e, item.key)}} disabled={item.readonly}>
@@ -480,7 +501,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
@@ -490,19 +511,51 @@
          </Col>
        )
      } else if (item.type === 'file') {
        let type = this.state.eleType
        if (item.key === 'posterUrl') {
          type = 'picture'
        }
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.label}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
                <SourceComponent type={this.state.eleType} />
                <SourceComponent type={type} />
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'cascader') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || [],
                rules: [
                  {
                    required: !!item.required,
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
                <Cascader options={item.options || []} expandTrigger="hover" placeholder=""/>
              )}
            </Form.Item>
          </Col>
src/menu/components/card/cardcellcomponent/elementform/index.scss
@@ -2,11 +2,11 @@
  min-height: 190px;
  >.ant-row {
    >.ant-col {
    >.ant-col:not(.textarea) {
      height: 65px;
    }
    .ant-col.textarea {
      height: 80px;
      min-height: 80px;
      .ant-form-item-label {
        width: 14.2%;
      }
src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -1,14 +1,11 @@
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
import MenuUtils from '@/utils/utils-custom.js'
/**
 * @description 获取元素配置信息
 * @param {*} card
 * @param {*} type
 */
export function getCardCellForm (card, type, subtype, cardCell) {
export function getCardCellForm (card, cards, cardCell) {
  let _options = [
    { value: 'text', text: '文本'},
    { value: 'number', text: '数值'},
@@ -23,36 +20,25 @@
    { value: 'formula', text: '公式'},
  ]
  if (type === 'table' || (type === 'card' && subtype === 'datacard')) {
  let anchors = []
  if (window.GLOB.customMenu.Template === 'BaseTable') {
    anchors = null
  } else {
    anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, cards.uuid) || []
  }
  if (cards.type === 'table' || (cards.type === 'card' && cards.subtype === 'datacard')) {
    _options.push({value: 'sequence', text: '序号'})
  } else if (card.eleType === 'sequence') { // 拖拽添加类型转换
    card.eleType = 'text'
  }
  let appMenus = []
  const isApp = sessionStorage.getItem('appType') === 'pc'
  if (isApp) {
    appMenus = sessionStorage.getItem('appMenus')
    if (appMenus) {
      try {
        appMenus = JSON.parse(appMenus)
      } catch (e) {
        appMenus = []
      }
    } else {
      appMenus = []
    }
  if (card.eleType === 'icon' && card.datatype === 'dynamic' && !card.field) { // 拖拽添加类型转换
    card.datatype = 'static'
  }
  let appType = sessionStorage.getItem('appType')
  let dataTypes = [
    { value: 'dynamic', text: '动态' },
    { value: 'static', text: '静态' }
  ]
  let tooltip = ''
  if (cardCell.$cardType === 'extendCard') {
    // card.datatype = 'static'
    // dataTypes = [
    //   { value: 'static', text: '静态' }
    // ]
    tooltip = '在扩展卡片中,动态数据显示值为获取到的第一行数据。'
  }
@@ -66,20 +52,16 @@
      options: _options
    },
    {
      type: 'icon',
      key: 'icon',
      label: '图标',
      initVal: card.icon,
      required: true
    },
    {
      type: 'radio',
      key: 'datatype',
      label: '数据类型',
      initVal: card.datatype || 'static',
      tooltip,
      required: true,
      options: dataTypes
      options: [
        { value: 'dynamic', text: '动态' },
        { value: 'static', text: '静态' }
      ]
    },
    {
      type: 'select',
@@ -90,18 +72,26 @@
      options: []
    },
    {
      type: 'icon',
      key: 'icon',
      label: '图标',
      initVal: card.icon,
      required: true
    },
    {
      type: 'text',
      key: 'value',
      min: 0,
      label: '内容',
      initVal: card.value || '',
      tooltip: '文本类型,会替换内容中的@username@、@fullName@、@login_city@。',
      tooltip: '文本类型,会替换内容中的@username@、@fullName@、@mk_city@、@appname@、@bid@。',
      required: true
    },
    {
      type: 'file',
      key: 'url',
      label: '图片/文件',
      tooltip: '使用静态图片时,@icon@代表头像。',
      initVal: card.url || '',
      maxfile: 1,
      required: true
@@ -129,6 +119,52 @@
      ]
    },
    {
      type: 'number',
      key: 'startTime',
      precision: 0,
      label: '开始时间',
      initVal: card.startTime || 0,
      tooltip: '视频开始播放的时间,用于调整视频初始化展示的界面。',
      required: false
    },
    {
      type: 'radio',
      key: 'posterType',
      label: '预览图',
      initVal: card.posterType || '',
      required: false,
      options: [
        { value: '', text: '无' },
        { value: 'dynamic', text: '动态' },
        { value: 'static', text: '静态' }
      ]
    },
    {
      type: 'file',
      key: 'posterUrl',
      label: '预览地址',
      initVal: card.posterUrl || '',
      maxfile: 1,
      required: true
    },
    {
      type: 'select',
      key: 'posterField',
      label: '预览地址',
      initVal: card.posterField || '',
      required: true
    },
    {
      type: 'number',
      key: 'decimal',
      min: 0,
      max: 18,
      decimal: 0,
      label: '小数位',
      initVal: card.decimal === undefined ? '' : card.decimal,
      required: false
    },
    {
      type: 'select',
      key: 'format',
      label: '格式化',
@@ -140,7 +176,10 @@
        { value: 'percent', text: '百分数' },
        { value: 'thdSeparator', text: '千分位' },
        { value: 'abs', text: '绝对值' },
        { value: 'encryption', text: '加密'},
        { value: 'YYYY-MM-DD', text: 'YYYY-MM-DD' },
        { value: 'YYYY-MM-DD HH:mm', text: 'YYYY-MM-DD HH:mm' },
        { value: 'YYYY-MM-DD HH:mm:ss', text: 'YYYY-MM-DD HH:mm:ss' },
        { value: 'MM月DD日', text: 'MM月DD日' },
        { value: 'YYYY年MM月DD日', text: 'YYYY年MM月DD日' },
        { value: 'HH:mm', text: '时分(例:16:57)' },
@@ -165,16 +204,6 @@
      ]
    },
    {
      type: 'number',
      key: 'decimal',
      min: 0,
      max: 18,
      decimal: 0,
      label: '小数位',
      initVal: card.decimal === undefined ? '' : card.decimal,
      required: false
    },
    {
      type: 'text',
      key: 'prefix',
      label: '前缀',
@@ -193,7 +222,8 @@
      key: 'tooltip',
      label: '提示信息',
      initVal: card.tooltip || '',
      tooltip: '鼠标悬浮时显示。',
      tooltip: '鼠标悬浮时显示。注:如使用动态信息,请在此处填写相应的字段名。',
      forbid: appType === 'mob',
      required: false
    },
    {
@@ -311,8 +341,8 @@
      min: 1,
      max: 10,
      label: '高度(行)',
      initVal: card.height,
      tooltip: '内容显示行数,值为空时高度自适应,注:自适应高度仅在设置卡片高度后有效。',
      initVal: card.height !== undefined ? card.height : 1,
      tooltip: '内容显示行数,值为空时高度自适应。',
      required: false
    },
    {
@@ -324,6 +354,16 @@
      required: false,
      allowClear: true,
      options: []
    },
    {
      type: 'cascader',
      key: 'anchors',
      label: '跳转锚点',
      initVal: card.anchors || [],
      tooltip: sessionStorage.getItem('appType') === 'mob' ? '注:小程序中无效' : '',
      required: false,
      options: anchors,
      forbid: !anchors
    },
    {
      type: 'number',
@@ -370,7 +410,8 @@
      min: 0,
      max: 50,
      label: '线宽',
      initVal: card.borderWidth || 1,
      initVal: card.borderWidth === undefined ? 1 : card.borderWidth,
      tooltip: '线宽为0时,为方便在开发时选中默认高度为10px,请注意调整内外边距。',
      required: true
    },
    {
@@ -399,6 +440,18 @@
      ]
    },
    {
      type: 'radio',
      key: 'backgroundSize',
      label: '图像大小',
      initVal: card.backgroundSize || 'cover',
      required: false,
      options: [
        { value: 'cover', text: '覆盖' },
        { value: 'contain', text: '包含' },
        { value: 'auto', text: '自适应' },
      ]
    },
    {
      type: 'number',
      key: 'maxWidth',
      min: 10,
@@ -406,6 +459,7 @@
      label: '最大宽度',
      initVal: card.maxWidth || '',
      tooltip: '图片宽度的最大值。',
      help: '注:此值存在时,左右外边距为0居中显示。',
      required: false,
    },
    {
@@ -426,7 +480,6 @@
      initVal: card.link || '',
      tooltip: '动态地址为绑定字段值。',
      required: false,
      // forbid: isApp,
      options: [
        { value: '', text: '无' },
        { value: 'dynamic', text: '动态' },
@@ -439,7 +492,6 @@
      label: '链接类型',
      initVal: card.linkType || 'other',
      required: false,
      // forbid: isApp,
      options: [
        { value: 'tel', text: '电话' },
        { value: 'email', text: '邮箱' },
@@ -459,27 +511,6 @@
    },
    {
      type: 'select',
      key: 'linkmenu',
      label: '关联菜单',
      initVal: card.linkmenu || '',
      required: true,
      forbid: !isApp,
      options: appMenus
    },
    // {
    //   type: 'radio',
    //   key: 'open',
    //   label: '打开方式',
    //   initVal: card.open || 'blank',
    //   required: false,
    //   forbid: !isApp,
    //   options: [
    //     { value: 'blank', text: '新页面' },
    //     { value: 'self', text: '当前页面' }
    //   ]
    // },
    {
      type: 'select',
      key: 'linkurl',
      label: '链接地址',
      initVal: card.linkurl || '',
@@ -489,15 +520,15 @@
    {
      type: 'radio',
      key: 'joint',
      label: Formdict['model.form.paramJoint'],
      label: '拼接参数',
      initVal: card.joint || 'true',
      required: false,
      options: [{
        value: 'true',
        text: Formdict['model.true']
        text: '是'
      }, {
        value: 'false',
        text: Formdict['model.false']
        text: '否'
      }]
    },
    {
@@ -509,10 +540,10 @@
      required: false,
      options: [{
        value: 'true',
        text: Formdict['model.true']
        text: '是'
      }, {
        value: 'false',
        text: Formdict['model.false']
        text: '否'
      }]
    },
    {
@@ -529,7 +560,7 @@
      key: 'noValue',
      label: '空值',
      initVal: card.noValue || 'show',
      tooltip: '当元素内容为空时,是否显示当前元素。',
      tooltip: '当元素内容为空时,是否显示当前元素。注:数值类型元素包括数字0(非文本)。',
      required: false,
      options: [
        { value: 'show', text: '显示' },
@@ -549,10 +580,22 @@
      ]
    },
    {
      type: 'radio',
      key: 'copyable',
      label: '可复制',
      initVal: card.copyable || 'false',
      tooltip: '元素是否可复制,复制内容不包括前缀与后缀。',
      required: false,
      options: [
        { value: 'true', text: '是' },
        { value: 'false', text: '否' }
      ]
    },
    {
      type: 'number',
      key: 'fixSize',
      min: 10,
      max: 100,
      max: 300,
      label: '字体大小',
      initVal: card.fixSize || 14,
      tooltip: '前缀、后缀的字体大小。',
src/menu/components/card/cardcellcomponent/index.jsx
@@ -3,15 +3,15 @@
import { is, fromJS } from 'immutable'
import { Modal, Button } from 'antd'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import asyncComponent from '@/utils/asyncComponent'
import { getCardCellForm } from './formconfig'
import { getActionForm } from '@/menu/components/share/actioncomponent/formconfig'
import { getActionForm, getBaseTableActionForm } from '@/menu/components/share/actioncomponent/formconfig'
import Utils, { FuncUtils } from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import MenuUtils from '@/utils/utils-custom.js'
import ElementForm from './elementform'
import CreateFunc from '@/templates/zshare/createfunc'
import DragElement from './dragaction'
import './index.scss'
@@ -33,7 +33,6 @@
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    appType: sessionStorage.getItem('appType'),
    card: null,          // 编辑中元素
    formlist: null,      // 表单信息
@@ -41,6 +40,7 @@
    visible: false,      // 模态框控制
    actvisible: false,   // 按钮编辑模态框
    profVisible: false,  // 验证信息编辑
    record: null
  }
  /**
@@ -64,22 +64,18 @@
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('submitModal', this.handleSave)
    MKEmitter.addListener('cardAddElement', this.cardAddElement)
    MKEmitter.addListener('cardDelElement', this.cardDelElement)
    MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props.cards), fromJS(nextProps.cards)) || !is(fromJS(this.state), fromJS(nextState))
    return !is(fromJS(this.state), fromJS(nextState)) || !is(fromJS(this.props.cards), fromJS(nextProps.cards))
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (this.props.side !== nextProps.side) {
      this.setState({
        elements: fromJS(nextProps.elements).toJS()
      })
    } else if (!is(fromJS(this.props.elements), fromJS(nextProps.elements)) && nextProps.elements.length !== this.state.elements.length) {
      this.setState({
        elements: fromJS(nextProps.elements).toJS()
      })
@@ -93,20 +89,18 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('submitModal', this.handleSave)
    MKEmitter.removeListener('cardAddElement', this.cardAddElement)
    MKEmitter.removeListener('cardDelElement', this.cardDelElement)
    MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle)
  }
  updateComponentStyle = (parentId, keys, style) => {
    const { cardCell } = this.props
    if (!cardCell || cardCell.uuid !== parentId) return
    if (cardCell.uuid !== parentId) return
    const { elements } = this.state
    let _elements = elements.map(item => {
    let _elements = this.state.elements.map(item => {
      if (keys.includes(item.uuid)) {
        return this.resetCardStyle(item, {...item.style, ...style})
      }
@@ -120,10 +114,18 @@
    })
  }
  cardAddElement = (ids, element) => {
    const { cards, cardCell } = this.props
  cardDelElement = (id, eleId) => {
    const { cardCell } = this.props
    if (!ids || ids.length !== 2 || ids[0] !== cards.uuid || ids[1] !== cardCell.uuid) return
    if (id !== cardCell.uuid) return
    this.setState({elements: this.state.elements.filter(item => item.uuid !== eleId)})
  }
  cardAddElement = (id, element) => {
    const { cardCell } = this.props
    if (id !== cardCell.uuid) return
    if (window.GLOB.$lock) return
    window.GLOB.$lock = true
@@ -139,13 +141,11 @@
  }
  handleStyle = (element) => {
    const { cards, cardCell } = this.props
    let _style = element.style ? fromJS(element.style).toJS() : {}
    let options = ['font', 'border', 'padding', 'margin', 'background']
    if (element.eleType === 'button') {
      if (element.OpenType === 'form') {
      if (element.OpenType === 'form' && element.formType !== 'scan') {
        options = ['margin', 'float']
      } else {
        options.push('width', 'minHeight', 'float')
@@ -155,24 +155,26 @@
      }
    } else if (element.eleType === 'picture') {
      options = ['border', 'margin']
    } else if (element.eleType === 'text') {
      options[0] = 'font2'
      options.push('display')
    } else if (element.eleType === 'slider') {
      options = ['padding', 'margin']
    } else if (element.eleType === 'splitline') {
      options = ['padding', 'margin']
    }
    options.push('clear')
    this.setState({
      card: element
    })
    MKEmitter.emit('changeStyle', [cards.uuid, cardCell.uuid, element.uuid], options, _style)
    MKEmitter.emit('changeStyle', options, _style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { cards, cardCell } = this.props
  getStyle = (style) => {
    const { card, elements } = this.state
    if (comIds.length !== 3 || comIds[0] !== cards.uuid || comIds[1] !== cardCell.uuid || !card) return
    // if (card.eleType === 'button') {
    //   if ((style.paddingLeft || style.paddingRight) && !style.width) {
@@ -196,35 +198,30 @@
  resetCardStyle = (card, style) => {
    let _card = fromJS(card).toJS()
    if (['text', 'number', 'formula'].includes(_card.eleType)) {
      _card.style = style
      let fontSize = 14
      let lineHeight = 1.5
    if (['text', 'number', 'formula', 'currentDate', 'sequence', 'icon'].includes(_card.eleType)) {
      _card.style = style
      let line = _card.height || null
      if (_card.style.fontSize) {
        fontSize = parseInt(_card.style.fontSize)
      }
      if (_card.style.lineHeight) {
        lineHeight = parseFloat(_card.style.lineHeight)
      if (['currentDate', 'sequence', 'icon'].includes(_card.eleType)) {
        line = 1
      }
      if (line) {
        let fontSize = 14
        let lineHeight = 1.5
        if (_card.style.fontSize) {
          fontSize = parseInt(_card.style.fontSize)
        }
        if (_card.style.lineHeight) {
          lineHeight = parseFloat(_card.style.lineHeight)
        }
        _card.innerHeight = fontSize * lineHeight * line
      } else {
        _card.innerHeight = 'auto'
      }
    } else if (_card.eleType === 'sequence') {
      _card.style = style
      let fontSize = 14
      let lineHeight = 1.5
      if (_card.style.fontSize) {
        fontSize = parseInt(_card.style.fontSize)
      }
      _card.innerHeight = fontSize * lineHeight
    } else if (_card.eleType === 'barcode') {
      _card.style = style
@@ -270,7 +267,7 @@
      this.setState({
        visible: true,
        card: card,
        formlist: getCardCellForm(card, cards.type, cards.subtype, cardCell)
        formlist: getCardCellForm(card, cards, cardCell)
      })
    }
  }
@@ -293,43 +290,49 @@
    }
    let ableField = usefulFields.join(', ')
    let msg = `函数名称需以${ableField}等字符开始;`
    let functip = <div>
      <p style={{marginBottom: '5px'}}>{this.state.dict['model.tooltip.func.innerface'].replace('@ableField', ableField)}</p>
      <p style={{marginBottom: '5px'}}>{msg}</p>
    </div>
    let menulist = sessionStorage.getItem('fstMenuList')
    if (menulist) {
      try {
        menulist = JSON.parse(menulist)
      } catch (e) {
        menulist = []
    let supId = ''
    if (cards.setting && cards.setting.supModule) {
      let pid = cards.setting.supModule[cards.setting.supModule.length - 1]
      if (pid && pid !== 'empty') {
        supId = pid
      } else {
        supId = ''
      }
    } else {
      menulist = []
    }
    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, cards.uuid) || []
    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, cards.uuid, supId)
    this.setState({
      actvisible: true,
      card: card,
      formlist: getActionForm(card, functip, cards, usefulFields, 'card', menulist, modules)
    })
    if (cards.subtype === 'basetable') {
      this.setState({
        actvisible: true,
        card: card,
        formlist: getBaseTableActionForm(card, functip, cards, usefulFields, modules)
      })
    } else {
      let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, cards.uuid) || []
      this.setState({
        actvisible: true,
        card: card,
        formlist: getActionForm(card, functip, cards, usefulFields, modules, anchors)
      })
    }
  }
  /**
   * @description 取消保存,如果元素为新添元素,则从序列中删除
   */
  editModalCancel = () => {
    const { card, elements, appType } = this.state
    const { card, elements } = this.state
    let _elements = null
    if (card.focus) {
      _elements = elements.filter(item => item.uuid !== card.uuid)
      if (card.OpenType === 'popview' && appType !== 'mob') { // 弹窗标签按钮,从复制列表中删除
        MKEmitter.emit('delButtons', [card.uuid])
      }
    } else {
      _elements = elements
    }
@@ -354,23 +357,35 @@
      let _elements = elements.map(cell => {
        if (cell.uuid === res.uuid) {
          res.style = cell.style || {}
          if (res.eleType === 'splitline' && cell.eleType !== 'splitline') {
          if (res.eleType !== 'text') {
            delete res.style.display
          }
          if (res.eleType === 'splitline' && (cell.eleType !== 'splitline' || cell.focus)) {
            res.style.paddingTop = '5px'
            res.style.paddingBottom = '5px'
          } else if (['text', 'number', 'formula'].includes(res.eleType)) {
            let fontSize = 14
            let lineHeight = 1.5
          } else if (['text', 'number', 'formula', 'currentDate', 'sequence', 'icon'].includes(res.eleType)) {
            let line = res.height || null
            if (res.style && res.style.fontSize) {
              fontSize = parseInt(res.style.fontSize)
            }
            if (res.style && res.style.lineHeight) {
              lineHeight = parseFloat(res.style.lineHeight)
            if (['currentDate', 'sequence', 'icon'].includes(res.eleType)) {
              line = 1
            }
            if (line) {
              let fontSize = 14
              let lineHeight = 1.5
              if (res.style && res.style.fontSize) {
                fontSize = parseInt(res.style.fontSize)
              }
              if (res.style && res.style.lineHeight) {
                lineHeight = parseFloat(res.style.lineHeight)
              }
              res.innerHeight = fontSize * lineHeight * line
            } else {
              res.innerHeight = 'auto'
            }
            if (res.eleType === 'text' && res.link && !res.style.color) {
@@ -405,32 +420,38 @@
   */
  handleActionSubmit = () => {
    const { elements } = this.state
    let color = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#666666' }
    let color = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#666666', default: 'rgba(0, 0, 0, 0.65)' }
    this.actionFormRef.handleConfirm().then(res => {
      let _elements = elements.map(cell => {
        if (cell.uuid === res.uuid) {
          res = {...cell, ...res}
          res.eleType = cell.eleType || null
          res.style = cell.style || null
          // res.modal = cell.modal || null
          // res.config = cell.config || null
          res.wrapStyle = cell.wrapStyle || null
          // res = {...cell, ...res}
          if (!res.control) {
            delete res.controlField
            delete res.controlVal
          }
          // if (!res.control) {
          //   delete res.controlField
          //   delete res.controlVal
          // }
          
          delete res.focus
          // delete res.focus
          if (res.OpenType === 'form') {
            if (cell.OpenType !== 'form') {
              res.style = {}
            }
          } else if (res.class !== cell.class || res.show !== cell.show || !res.style) {
            let cl = res.class.replace('border-', '')
            let style = {}
            if (res.show === 'link' || res.show === 'icon') {
              style.color = color[res.class]
              style.color = color[cl]
              style.backgroundColor = 'transparent'
            } else {
              style.color = '#ffffff'
              style.backgroundColor = color[res.class]
              style.backgroundColor = color[cl]
            }
            res.style = {...res.style, ...style}
          }
@@ -453,32 +474,19 @@
   * @description 按钮删除
   */
  deleteElement = (card) => {
    const { cards, cardCell, side } = this.props
    const { dict, elements, appType } = this.state
    const { elements } = this.state
    let _this = this
    confirm({
      content: dict['model.confirm'] + dict['model.delete'] + '元素吗?',
      content: '确定删除元素吗?',
      onOk() {
        let _elements = elements.filter(item => item.uuid !== card.uuid)
        if (card.OpenType === 'popview' || card.verify || card.modal) {
          card.$parentId = cardCell.uuid
          card.$side = side || ''
          MKEmitter.emit('logButton', cards.uuid, card)
        }
        _this.setState({
          elements: _elements
        }, () => {
          _this.props.updateElement(_elements)
        })
        if (card.eleType !== 'button') return
        if (appType === 'mob' || (appType === 'pc' && card.OpenType !== 'popview')) return
        MKEmitter.emit('delButtons', [card.uuid])
      },
      onCancel() {}
    })
@@ -540,23 +548,25 @@
      MKEmitter.emit('changePopview', cards, btn)
    } else if (btn.OpenType === 'innerpage' && btn.pageTemplate === 'linkpage') {
      MKEmitter.emit('changeEditMenu', {MenuID: btn.linkmenu})
    } else if (btn.OpenType === 'funcbutton' && (btn.funcType === 'copyurl' || btn.funcType === 'scan') && btn.linkmenu) {
      MKEmitter.emit('changeEditMenu', {MenuID: btn.linkmenu})
    } else {
      this.handleElement(item)
    }
  }
  handleSave = (_cards, btn, modal) => {
  handleSave = (componentId, btnId, modal) => {
    const { cards } = this.props
    const { elements } = this.state
    if (cards.uuid !== _cards.uuid) return
    if (cards.uuid !== componentId) return
    
    let _index = elements.findIndex(cell => cell.uuid === btn.uuid)
    let _index = elements.findIndex(cell => cell.uuid === btnId)
    if (_index === -1) return
    let _elements = elements.map(cell => {
      if (cell.uuid === btn.uuid) {
      if (cell.uuid === btnId) {
        cell.modal = modal
      }
@@ -586,9 +596,10 @@
  }
  dropButton = (id) => {
    const { cards } = this.props
    const { cards, cardCell } = this.props
    if (!cards.action) return
    if (cardCell.type === 'custom') return
    let index = cards.action.findIndex(item => item.uuid === id)
@@ -625,15 +636,96 @@
    })
  }
  /**
   * @description 创建按钮存储过程
   */
  creatFunc = () => {
    const menu = window.GLOB.customMenu
    let _config = fromJS(this.props.cards).toJS()
    this.actionFormRef.handleConfirm().then(res => {
      let btn = res         // 按钮信息
      let newLText = ''     // 创建存储过程sql
      let DelText = ''      // 删除存储过程sql
      if (btn.intertype !== 'inner') return
      if (btn.OpenType === 'pop') {
        let _param = {
          funcName: btn.innerFunc,
          name: _config.setting.tableName || '',
          fields: btn.modal ? btn.modal.fields : [],
          menuNo: menu.MenuNo
        }
        newLText = Utils.formatOptions(FuncUtils.getfunc(_param, btn, menu, _config))
        DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc))
      } else if (btn.OpenType === 'excelIn') {
        let _param = {
          funcName: btn.innerFunc,
          menuNo: menu.MenuNo
        }
        newLText = Utils.formatOptions(FuncUtils.getexcelInfunc(_param, btn, menu))
        DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc))
      } else if (btn.OpenType === 'excelOut') {
        newLText = Utils.formatOptions(FuncUtils.getTableFunc(btn.innerFunc, menu, _config)) // 创建存储过程sql
        DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc))
      } else {
        let _param = {
          funcName: btn.innerFunc,
          name: _config.setting.tableName || '',
          fields: '',
          menuNo: menu.MenuNo
        }
        newLText = Utils.formatOptions(FuncUtils.getfunc(_param, btn, menu, _config))
        DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc))
      }
      this.refs.btnCreatFunc.exec(btn.innerFunc, newLText, DelText)
    })
  }
  getVerify = (card) => {
    const { cards } = this.props
    if (!card) return null
    if (['pop', 'prompt', 'exec', 'form'].includes(card.OpenType)) {
      return <VerifyCard
        card={card}
        config={cards}
        columns={cards.columns}
        wrappedComponentRef={(inst) => this.verifyRef = inst}
      />
    } else if (card.OpenType === 'excelIn') {
      return <VerifyExcelIn
        card={card}
        columns={cards.columns}
        wrappedComponentRef={(inst) => this.verifyRef = inst}
      />
    } else if (card.OpenType === 'excelOut') {
      return <VerifyExcelOut
        card={card}
        config={cards}
        wrappedComponentRef={(inst) => this.verifyRef = inst}
      />
    } else if (card.OpenType === 'funcbutton' && card.funcType === 'print') {
      return <VerifyPrint
        card={card}
        columns={cards.columns}
        wrappedComponentRef={(inst) => this.verifyRef = inst}
      />
    }
  }
  render() {
    const { cards, cardCell } = this.props
    const { elements, visible, actvisible, profVisible, card, dict } = this.state
    const { elements, visible, actvisible, profVisible, card, record } = this.state
    return (
      <div className="model-menu-card-cell-list">
        <DragElement
          list={elements}
          parent={{...cardCell, components: elements}}
          parent={cardCell}
          fields={cards.columns}
          updateMarks={this.updateMarks}
          handleList={this.handleList}
@@ -656,7 +748,6 @@
            destroyOnClose
          >
            <ElementForm
              dict={dict}
              card={card}
              formlist={this.state.formlist}
              inputSubmit={this.handleSubmit}
@@ -668,33 +759,33 @@
          <Modal
            title="按钮·编辑"
            visible={actvisible}
            width={800}
            width={920}
            maskClosable={false}
            onCancel={this.editModalCancel}
            footer={[
              <Button key="cancel" onClick={this.editModalCancel}>{dict['model.cancel']}</Button>,
              <Button key="confirm" type="primary" onClick={this.handleActionSubmit}>{dict['model.confirm']}</Button>
              record && record.intertype === 'inner' ? <CreateFunc key="create" ref="btnCreatFunc" trigger={this.creatFunc}/> : null,
              <Button key="cancel" onClick={this.editModalCancel}>取消</Button>,
              <Button key="confirm" type="primary" onClick={this.handleActionSubmit}>确定</Button>
            ]}
            destroyOnClose
          >
            <ActionForm
              dict={dict}
              type={cards.type === 'balcony' ? '' : 'card'}
              card={card}
              formlist={this.state.formlist}
              inputSubmit={this.handleActionSubmit}
              setting={cards.setting}
              updRecord={(record) => this.setState({record: fromJS(record).toJS()})}
              wrappedComponentRef={(inst) => this.actionFormRef = inst}
            />
          </Modal>
          {/* 按钮使用系统存储过程时,验证信息模态框 */}
          <Modal
            wrapClassName="model-table-action-verify-modal"
            title={(card && card.label ? card.label + ' - ' : '') + '验证信息'}
            wrapClassName="mk-pop-modal"
            visible={profVisible}
            width={'90vw'}
            maskClosable={false}
            okText={dict['model.submit']}
            okText="提交"
            onOk={this.verifySubmit}
            onCancel={() => {
              if (this.verifyRef.handleCancel) {
@@ -707,39 +798,7 @@
            }}
            destroyOnClose
          >
            {card && !card.execMode && card.OpenType !== 'excelIn' && card.OpenType !== 'excelOut' ?
              <VerifyCard
                card={card}
                dict={dict}
                config={cards}
                columns={cards.columns}
                wrappedComponentRef={(inst) => this.verifyRef = inst}
              /> : null
            }
            {card && card.execMode ?
              <VerifyPrint
                card={card}
                dict={dict}
                columns={cards.columns}
                wrappedComponentRef={(inst) => this.verifyRef = inst}
              /> : null
            }
            {card && card.OpenType === 'excelIn' ?
              <VerifyExcelIn
                card={card}
                dict={dict}
                columns={cards.columns}
                wrappedComponentRef={(inst) => this.verifyRef = inst}
              /> : null
            }
            {card && card.OpenType === 'excelOut' ?
              <VerifyExcelOut
                card={card}
                dict={dict}
                config={cards}
                wrappedComponentRef={(inst) => this.verifyRef = inst}
              /> : null
            }
            {this.getVerify(card)}
          </Modal>
        </div>
      </div>
src/menu/components/card/cardcellcomponent/index.scss
@@ -3,9 +3,15 @@
  .ant-btn {
    padding: 0;
  }
  .card-detail-row {
    min-height: 16px;
  }
  .card-button-cell {
    float: left;
    button {
      box-shadow: none;
    }
    button:not(.ant-switch) {
      width: 100%;
      background-size: cover;
@@ -29,4 +35,4 @@
  .card-cell:hover, .card-button-cell:hover {
    box-shadow: 0px 0px 2px #1890ff;
  }
}
}
src/menu/components/card/cardcomponent/index.jsx
@@ -47,10 +47,6 @@
    })
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
  }
  shouldComponentUpdate (nextProps, nextState) {
    const { cards } = this.props
    
@@ -64,14 +60,10 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { cards } = this.props
  getStyle = (style) => {
    const { card, side } = this.state
    if (comIds.length !== 2 || comIds[0] !== cards.uuid || comIds[1] !== card.uuid) return
    let _card = fromJS(card).toJS()
    if (side === 'back') {
@@ -127,7 +119,6 @@
  }
  
  addElement = () => {
    const { cards } = this.props
    const { card } = this.state
    let newcard = {}
@@ -139,11 +130,10 @@
    newcard.height = 1
    // 注册事件-添加元素
    MKEmitter.emit('cardAddElement', [cards.uuid, card.uuid], newcard)
    MKEmitter.emit('cardAddElement', card.uuid, newcard)
  }
  addButton = () => {
    const { cards } = this.props
    const { card } = this.state
    let newcard = {eleType: 'button', label: 'button', verify: null, show: 'link', sqlType: '', Ot: 'requiredSgl', OpenType: 'prompt', icon: '', class: 'primary', intertype: 'system', execSuccess: 'grid', execError: 'never', popClose: 'never'}
@@ -151,11 +141,10 @@
    newcard.focus = true
    // 注册事件-添加元素
    MKEmitter.emit('cardAddElement', [cards.uuid, card.uuid], newcard)
    MKEmitter.emit('cardAddElement', card.uuid, newcard)
  }
  changeStyle = () => {
    const { cards } = this.props
    const { card, side } = this.state
    let _style = null
@@ -167,7 +156,7 @@
      options = ['background', 'padding']
    }
    MKEmitter.emit('changeStyle', [cards.uuid, card.uuid], options, _style)
    MKEmitter.emit('changeStyle', options, _style, this.getStyle)
  }
  getSettingForms = () => {
@@ -244,19 +233,12 @@
  }
  paste = (element, resolve) => {
    const { cards } = this.props
    const { card } = this.state
    let _uuid = Utils.getuuid()
    
    if (element.copyType === 'action') {
      element.eleType = 'button'
      if (element.OpenType === 'popview') { // 弹窗标签复制
        let _cell = fromJS(element).toJS()
        _cell.$originUuid = element.uuid
        _cell.uuid = _uuid
        MKEmitter.emit('copyButtons', [_cell])
      }
    }
    element.uuid = _uuid
@@ -265,14 +247,7 @@
    resolve({status: true})
    // 注册事件-添加元素
    MKEmitter.emit('cardAddElement', [cards.uuid, card.uuid], element)
  }
  clickComponent = (e) => {
    if ((sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'propcard') && this.props.cards.subtype === 'propcard') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card, this.props.cards, 'propcard')
    }
    MKEmitter.emit('cardAddElement', card.uuid, element)
  }
  doubleClickCard = () => {
@@ -338,14 +313,14 @@
    return (
      <Col span={card.setting.width || 6}>
        <div className={'card-item ' + (card.setting.btnControl || '')} style={_style} onClick={this.clickComponent} onDoubleClick={(e) => {e.stopPropagation(); this.doubleClickCard()}} id={card.uuid}>
        <div className={'card-item ' + (card.setting.btnControl || '')} style={_style} onDoubleClick={(e) => {e.stopPropagation(); this.doubleClickCard()}} id={card.uuid}>
          <CardCellComponent cards={cards} cardCell={card} side={side} elements={elements} updateElement={this.updateCard}/>
          <div className="card-control" onDoubleClick={(e) => e.stopPropagation()}>
            <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
              <div className="mk-popover-control">
                <PlusOutlined className="plus" title="添加元素" onClick={this.addElement} />
                <PlusSquareOutlined className="plus" title="添加按钮" onClick={this.addButton} />
                <NormalForm title="卡片设置" width={800} update={this.updateSetting} getForms={this.getSettingForms}>
                <NormalForm title="卡片设置" width={950} update={this.updateSetting} getForms={this.getSettingForms}>
                  <EditOutlined className="edit" title="编辑"/>
                </NormalForm>
                <CopyComponent type="cardcell" card={card}/>
src/menu/components/card/cardcomponent/options.jsx
@@ -40,6 +40,12 @@
  if (hasMenus) {
    ops = [{value: 'menus', label: '菜单组'}]
  }
  let adapters = sessionStorage.getItem('adapter') || ''
  if (adapters.indexOf('wxmini') > -1) {
    ops.push({value: 'miniprogram', label: '小程序'})
  } else if (setting.click === 'miniprogram') {
    setting.click = ''
  }
  const cardSettingForm = [
    {
@@ -97,11 +103,11 @@
      forbid: subtype !== 'propcard'
    },
    {
      type: !hasMenus ? 'radio' : 'select',
      type: ops.length === 0 ? 'radio' : 'select',
      field: 'click',
      label: '点击事件',
      initval: setting.click || '',
      tooltip: '当绑定点击事件时,卡片的切换功能将失效。',
      // tooltip: '当绑定点击事件时,卡片的切换功能将失效。',
      required: false,
      options: [
        {value: '', label: '无'},
@@ -114,11 +120,13 @@
        {field: 'menu', values: ['menu']},
        {field: 'linkurl', values: ['link']},
        {field: 'open', values: ['menu', 'link', 'menus']},
        {field: 'joint', values: ['menu', 'link', 'menus']},
        {field: 'joint', values: ['menu', 'link', 'menus', 'miniprogram']},
        {field: 'linkbtn', values: ['button']},
        {field: 'clickType', values: ['button']},
        {field: 'menuType', values: ['menus']},
        {field: 'menus', values: ['menus']},
        {field: 'miniAppId', values: ['miniprogram']},
        {field: 'miniPath', values: ['miniprogram']},
      ]
    },
    {
@@ -148,16 +156,31 @@
      span: 24
    },
    {
      type: 'text',
      field: 'miniAppId',
      label: '小程序AppID',
      initval: setting.miniAppId || '',
      required: true
    },
    {
      type: 'text',
      field: 'miniPath',
      label: '页面路径',
      initval: setting.miniPath || '',
      tooltip: '可指定跳转小程序页面,为空时打开首页,注:参数拼接在指定页面时有效。',
      required: false
    },
    {
      type: 'radio',
      field: 'open',
      label: '打开方式',
      initval: setting.open || 'blank',
      required: false,
      options: [
        {value: 'blank', label: '新窗口'},
        {value: 'self', label: '当前窗口'},
        {value: 'blank', label: appType !== 'mob' ? '新窗口' : '新页面'},
        {value: 'self', label: appType !== 'mob' ? '当前窗口' : '当前页面'},
      ],
      forbid: appType !== 'pc'
      forbid: appType !== 'pc' && appType !== 'mob'
    },
    {
      type: 'radio',
@@ -219,7 +242,7 @@
          editable: true,
          unique: true,
          required: false,
          width: '35%'
          width: '30%'
        },
        {
          title: '菜单',
@@ -228,7 +251,7 @@
          editable: true,
          required: true,
          extends: !appType ? 'Menu' : [{key: 'label', value: 'label'}],
          width: '35%',
          width: '40%',
          render: (text, record) => record.label,
          options: menulist
        }
src/menu/components/card/cardsimplecomponent/index.jsx
@@ -16,6 +16,7 @@
const NodesWrap = asyncComponent(() => import('./node-wrap'))
const CardCellComponent = asyncComponent(() => import('../cardcellcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteController = asyncIconComponent(() => import('@/components/paste'))
class CardBoxComponent extends Component {
  static propTpyes = {
@@ -43,10 +44,6 @@
    })
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props.cards), fromJS(nextProps.cards)) || !is(fromJS(this.state), fromJS(nextState))
  }
@@ -58,14 +55,10 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { cards } = this.props
  getStyle = (style) => {
    const { card } = this.state
    if (comIds.length !== 2 || comIds[0] !== cards.uuid || comIds[1] !== card.uuid) return
    let _card = fromJS(card).toJS()
    _card.style = style
@@ -90,7 +83,6 @@
  }
  
  addElement = () => {
    const { cards } = this.props
    const { card } = this.state
    let newcard = {}
@@ -106,11 +98,10 @@
    window.GLOB.$lock = false
    // 注册事件-添加元素
    MKEmitter.emit('cardAddElement', [cards.uuid, card.uuid], newcard)
    MKEmitter.emit('cardAddElement', card.uuid, newcard)
  }
  addButton = () => {
    const { cards } = this.props
    const { card } = this.state
    let newcard = {eleType: 'button', label: 'button', verify: null, show: 'link', sqlType: '', Ot: 'requiredSgl', OpenType: 'prompt', icon: '', class: 'primary', intertype: 'system', execSuccess: 'grid', execError: 'never', popClose: 'never'}
@@ -119,7 +110,7 @@
    
    // 注册事件-添加元素
    MKEmitter.emit('cardAddElement', [cards.uuid, card.uuid], newcard)
    MKEmitter.emit('cardAddElement', card.uuid, newcard)
  }
  changeStyle = () => {
@@ -134,7 +125,7 @@
      options = ['background', 'border', 'padding', 'margin', 'shadow']
    }
    MKEmitter.emit('changeStyle', [cards.uuid, card.uuid], options, _style)
    MKEmitter.emit('changeStyle', options, _style, this.getStyle)
  }
  getSettingForms = () => {
@@ -151,7 +142,7 @@
          })
        }
      })
      return getTableSetting(card.setting, cards.columns, buttons)
      return getTableSetting(card.setting, cards.columns, buttons, cards.action)
    } else {
      return getCarouselSetting(card.setting, cards.subtype === 'propcard')
    }
@@ -196,6 +187,24 @@
    this.props.updateElement(_card)
  }
  paste = (element, resolve) => {
    const { card } = this.state
    let _uuid = Utils.getuuid()
    if (element.copyType === 'action') {
      element.eleType = 'button'
    }
    element.uuid = _uuid
    element.focus = true
    resolve({status: true})
    // 注册事件-添加元素
    MKEmitter.emit('cardAddElement', card.uuid, element)
  }
  render() {
    const { cards } = this.props
    const { card } = this.state
@@ -226,6 +235,7 @@
                  <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
                </NormalForm> : <NodesWrap card={card} updateMenus={this.updateNodes}/>}
                {cards.type !== 'timeline' ? <CopyComponent type="cardcell" card={card}/> : null}
                <PasteController options={['action', 'customCardElement']} updateConfig={this.paste} />
                <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
                {control ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
                  <div className="mk-popover-control">
src/menu/components/card/cardsimplecomponent/node-wrap/index.jsx
@@ -53,7 +53,7 @@
          title="节点组"
          wrapClassName="nodes-field-modal"
          visible={visible}
          width={900}
          width={950}
          maskClosable={false}
          onOk={this.submit}
          onCancel={() => { this.setState({ visible: false })}}
src/menu/components/card/cardsimplecomponent/node-wrap/menus/columnform/index.jsx
@@ -61,7 +61,7 @@
          <Col span={8}>
            <Form.Item label="颜色">
              {getFieldDecorator('color', {
                initialValue: '',
                initialValue: '#e8e8e8',
                rules: [
                  {
                    required: true,
src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx
@@ -27,7 +27,7 @@
        editable: true,
        unique: true,
        required: false,
        width: '35%'
        width: '25%'
      },
      {
        title: '颜色',
@@ -35,7 +35,8 @@
        inputType: 'color',
        editable: true,
        required: true,
        width: '35%'
        width: '25%',
        render: (text, record) => <span style={{display: 'inline-block', width: '40px', height: '25px', background: text}}></span>
      },
      {
        title: '图标',
@@ -43,9 +44,19 @@
        inputType: 'icon',
        editable: true,
        required: false,
        width: '35%',
        width: '25%',
        render: (text, record) => record.icon ? <MkIcon type={record.icon}/> : ''
      }
      },
      {
        title: '连接线',
        dataIndex: 'linecolor',
        inputType: 'color',
        editable: true,
        required: false,
        allowClear: true,
        width: '25%',
        render: (text, record) => text ? <span style={{display: 'inline-block', width: '40px', height: '25px', background: text}}></span> : null
      },
    ]
  }
@@ -77,6 +88,7 @@
    return (
      <div style={{minHeight: '250px'}}>
        <ColumnForm menus={menus} columnChange={this.columnChange}/>
        <p style={{position: 'absolute', fontSize: '12px', transform: 'translate(0px, -20px)'}}>连接线在横向时间轴中有效</p>
        <EditTable actions={['edit', 'move', 'copy', 'del']} type={'timenodes'} data={menus} columns={columns} onChange={this.changeColumns}/>
      </div>
    )
src/menu/components/card/cardsimplecomponent/options.jsx
@@ -1,7 +1,7 @@
/**
 * @description tablecard setting表单配置信息
 */
export function getTableSetting (setting, columns, buttons = []) {
export function getTableSetting (setting, columns, buttons = [], action = []) {
  let _columns = columns.map(item => ({value: item.field, label: item.label}))
  _columns.push({value: '$Index', label: '序号(前端)'})
  let appType = sessionStorage.getItem('appType')
@@ -83,7 +83,7 @@
      field: 'click',
      label: '点击事件',
      initval: setting.click || '',
      tooltip: '当选择触发按钮时,只有当卡片中只存在一个按钮时有效。',
      // tooltip: '当选择触发按钮时,只有当卡片中只存在一个按钮时有效。',
      required: false,
      options: [
        {value: '', label: '无'},
@@ -111,6 +111,18 @@
      ],
    },
    {
      type: 'radio',
      field: 'open',
      label: '打开方式',
      initval: setting.open || 'blank',
      required: false,
      options: [
        {value: 'blank', label: appType !== 'mob' ? '新窗口' : '新页面'},
        {value: 'self', label: appType !== 'mob' ? '当前窗口' : '当前页面'},
      ],
      forbid: appType !== 'pc' && appType !== 'mob'
    },
    {
      type: appType ? 'select' : 'cascader',
      field: 'menu',
      label: '关联菜单',
@@ -129,24 +141,24 @@
      span: 24
    },
    {
      type: 'radio',
      field: 'open',
      label: '打开方式',
      initval: setting.open || 'blank',
      required: false,
      options: [
        {value: 'blank', label: '新窗口'},
        {value: 'self', label: '当前窗口'},
      ],
      forbid: appType !== 'pc'
    },
    {
      type: 'select',
      field: 'linkbtn',
      label: '关联按钮',
      initval: setting.linkbtn || '',
      required: true,
      options: buttons
    },
    {
      type: 'radio',
      field: 'swipe',
      label: '滑动按钮',
      initval: setting.swipe || 'true',
      required: false,
      options: [
        {value: 'true', label: '显示'},
        {value: 'false', label: '不显示'},
      ],
      forbid: action.length === 0 || appType !== 'mob'
    }
  ]
@@ -186,6 +198,14 @@
    }
  }
  let ops = []
  let adapters = sessionStorage.getItem('adapter') || ''
  if (adapters.indexOf('wxmini') > -1) {
    ops.push({value: 'miniprogram', label: '小程序'})
  } else if (setting.click === 'miniprogram') {
    setting.click = ''
  }
  const cardSettingForm = [
    {
      type: 'text',
@@ -206,12 +226,15 @@
        {value: '', label: '无'},
        {value: 'menu', label: '菜单'},
        {value: 'link', label: '链接'},
        ...ops
      ],
      controlFields: [
        {field: 'menu', values: ['menu']},
        {field: 'linkurl', values: ['link']},
        {field: 'open', values: ['menu', 'link']},
        {field: 'joint', values: ['menu', 'link']},
        {field: 'joint', values: ['menu', 'link', 'miniprogram']},
        {field: 'miniAppId', values: ['miniprogram']},
        {field: 'miniPath', values: ['miniprogram']},
      ]
    },
    {
@@ -224,25 +247,31 @@
      options: appType ? appmenulist : menulist,
    },
    {
      type: 'textarea',
      field: 'linkurl',
      label: '链接',
      initval: setting.linkurl || '',
      required: true,
      options: [],
      span: 24
    },
    {
      type: 'radio',
      field: 'open',
      label: '打开方式',
      initval: setting.open || 'blank',
      required: false,
      options: [
        {value: 'blank', label: '新窗口'},
        {value: 'self', label: '当前窗口'},
        {value: 'blank', label: appType !== 'mob' ? '新窗口' : '新页面'},
        {value: 'self', label: appType !== 'mob' ? '当前窗口' : '当前页面'},
      ],
      forbid: appType !== 'pc'
      forbid: appType !== 'pc' && appType !== 'mob'
    },
    {
      type: 'text',
      field: 'miniAppId',
      label: '小程序AppID',
      initval: setting.miniAppId || '',
      required: true
    },
    {
      type: 'text',
      field: 'miniPath',
      label: '页面路径',
      initval: setting.miniPath || '',
      tooltip: '可指定跳转小程序页面,为空时打开首页,注:参数拼接在指定页面时有效。',
      required: false
    },
    {
      type: 'radio',
@@ -255,6 +284,15 @@
        {value: 'false', label: '否'},
      ],
    },
    {
      type: 'textarea',
      field: 'linkurl',
      label: '链接',
      initval: setting.linkurl || '',
      required: true,
      options: [],
      span: 24
    },
  ]
  return cardSettingForm
src/menu/components/card/data-card/index.jsx
@@ -1,12 +1,12 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, Modal, Pagination, notification } from 'antd'
import { PlusOutlined, PlusCircleOutlined, PlusSquareOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import { Popover, Modal, Pagination } from 'antd'
import { PlusOutlined, PlusCircleOutlined, PlusSquareOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, DownOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle } from '@/utils/utils-custom.js'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import Utils from '@/utils/utils.js'
import getWrapForm from './options'
@@ -16,11 +16,11 @@
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CardComponent = asyncComponent(() => import('../cardcomponent'))
const MobPagination = asyncIconComponent(() => import('@/menu/components/share/mobPagination'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent'))
const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent'))
const { confirm } = Modal
@@ -46,12 +46,9 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: 'array',   // 组件属性 - 数据格式
        pageable: true,    // 组件属性 - 是否可分页
        switchable: true,  // 组件属性 - 数据是否可切换
        dataName: card.dataName || '',
        width: card.width || 24,
        name: card.name,
        subtype: card.subtype,
@@ -63,7 +60,6 @@
        scripts: [],
        action: [],
        search: [],
        btnlog: [],
        subcards: [{
          uuid: Utils.getuuid(),
          setting: { width: appType === 'mob' ? 24 : 6, type: 'simple'},
@@ -113,10 +109,7 @@
        })
      }
      this.setState({
        card: _card
      })
      this.props.updateConfig(_card)
      this.updateComponent(_card)
    } else {
      let _card = fromJS(card).toJS()
      _card.action = _card.action || [] // 兼容
@@ -147,12 +140,6 @@
    }
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('submitModal', this.handleSave)
    MKEmitter.addListener('logButton', this.logButton)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
@@ -164,37 +151,97 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('submitModal', this.handleSave)
    MKEmitter.removeListener('logButton', this.logButton)
  }
  logButton = (id, item) => {
    const { card } = this.state
    if (id !== card.uuid) return
    let btnlog = card.btnlog || []
    btnlog.push(item)
    this.setState({
      card: {...card, btnlog}
    })
    this.props.updateConfig({...card, btnlog})
  }
  /**
   * @description 卡片行外层信息更新(数据源,样式等)
   */
  updateComponent = (component) => {
    this.setState({
      card: component
  updateComponent = (card) => {
    const { appType } = this.state
    card.width = card.wrap.width
    card.name = card.wrap.name
    if (window.GLOB.styling && card.errors) { // 样式修改时不做筛查
      this.setState({
        card: card
      })
      this.props.updateConfig(card)
      return
    }
    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.wrap.supType !== 'multi' && !card.setting.supModule) {
      card.errors.push({ level: 0, detail: '未设置上级组件!'})
    }
    if (card.errors.length === 0) {
      card.$tables = getTables(card)
    }
    card.action.forEach(cell => {
      if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
        if (!cell.modal || cell.modal.fields.length === 0) {
          card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
        }
      }
    })
    component.width = component.wrap.width
    component.name = component.wrap.name
    card.subcards.forEach((item, i) => {
      let linkbtn = item.setting.linkbtn || ''
      item.elements.forEach(cell => {
        if (cell.eleType === 'button') {
          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
            if (!cell.modal || cell.modal.fields.length === 0) {
              card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
            }
          }
          if (linkbtn && linkbtn === cell.uuid) {
            linkbtn = ''
          }
        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
          card.errors.push({ level: 1, detail: `卡片中动态字段“${cell.field}”无效`})
        }
      })
    this.props.updateConfig(component)
      if (item.setting.type === 'multi' && appType !== 'mob') {
        item.backElements.forEach(cell => {
          if (cell.eleType === 'button') {
            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
              if (!cell.modal || cell.modal.fields.length === 0) {
                card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
              }
            }
            if (linkbtn && linkbtn === cell.uuid) {
              linkbtn = ''
            }
          } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
            card.errors.push({ level: 1, detail: `卡片中动态字段“${cell.field}”无效`})
          }
        })
      }
      if (linkbtn) {
        card.errors.push({ level: 1, detail: `第${i + 1}张卡片中绑定按钮已删除`})
      }
    })
    this.setState({
      card: card
    })
    this.props.updateConfig(card)
  }
  /**
@@ -212,16 +259,13 @@
      card.action = card.action.filter(item => item.uuid !== btn.uuid)
    }
    this.setState({card})
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  /**
   * @description 单个卡片信息更新
   */
  deleteCard = (cell) => {
    const { appType } = this.state
    let card = fromJS(this.state.card).toJS()
    let _this = this
@@ -230,31 +274,7 @@
      onOk() {
        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
        if (card.btnlog) {
          card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
        }
        _this.setState({card})
        _this.props.updateConfig(card)
        if (appType === 'mob') return
        let uuids = []
        cell.elements && cell.elements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        cell.backElements && cell.backElements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
        _this.updateComponent(card)
      },
      onCancel() {}
    })
@@ -263,21 +283,13 @@
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['background', 'height', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['background', 'height', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
    if (comIds.length !== 1 || comIds[0] !== card.uuid) return
    let _card = {...card, style}
    this.setState({
      card: _card
    })
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    
    this.props.updateConfig(_card)
    this.updateComponent(_card)
  }
  addSearch = (copy) => {
@@ -356,70 +368,6 @@
    }
  }
  handleSave = (_cards, btn, modal) => {
    let card = fromJS(this.state.card).toJS()
    if (card.uuid !== _cards.uuid) return
    let _index = card.action.findIndex(cell => cell.uuid === btn.uuid)
    if (_index === -1) return
    card.action = card.action.map(cell => {
      if (cell.uuid === btn.uuid) {
        cell.modal = modal
      }
      return cell
    })
    this.setState({card})
    this.props.updateConfig(card)
  }
  handleLog = (type, logs, item) => {
    let card = fromJS(this.state.card).toJS()
    if (type === 'revert') {
      let done = false
      if (item.$parentId) {
        card.subcards.forEach(col => {
          if (item.$parentId === col.uuid) {
            if (item.$side !== 'back') {
              col.elements = col.elements ? [...col.elements, item] : [item]
            } else {
              col.backElements = col.backElements ? [...col.backElements, item] : [item]
            }
            done = true
          }
        })
      }
      if (!done) {
        card.action = card.action ? [...card.action, item] : [item]
      }
      card.btnlog = logs
      this.setState({ card })
      this.props.updateConfig(card)
      notification.success({
        top: 92,
        message: '恢复成功!',
        duration: 2
      })
    } else {
      card.btnlog = logs
      this.setState({ card })
      this.props.updateConfig(card)
      notification.success({
        top: 92,
        message: '清除成功!',
        duration: 2
      })
    }
  }
  addCard = (copy) => {
    let card = fromJS(this.state.card).toJS()
    let newcard = {}
@@ -449,9 +397,8 @@
    }
    card.subcards.push(newcard)
    this.setState({card})
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  move = (item, direction) => {
@@ -470,18 +417,19 @@
    card.subcards.splice(hoverIndex, 0, ...card.subcards.splice(dragIndex, 1))
    this.setState({card})
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  getWrapForms = () => {
    const { card } = this.state
    return getWrapForm(card.wrap, card.subtype, card.columns, card.uuid, card.supNodes)
    return getWrapForm(card.wrap, card.subtype, card.columns, card.uuid, card.supNodes, card.setting)
  }
  updateWrap = (res) => {
    let _card = {...this.state.card, wrap: res}
    const { card } = this.state
    let _card = {...card, wrap: res}
    if (res.supNodes) {
      _card.supNodes = res.supNodes
@@ -495,11 +443,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) => {
@@ -514,8 +482,7 @@
      res.$cardType = 'extendCard'
      res.setting.width = res.setting.width || 6
      let copyBtns = []
      let mobtypes = ['pop', 'prompt', 'exec', 'innerpage']
      let mobtypes = ['pop', 'prompt', 'exec', 'innerpage', 'funcbutton']
      let elements = []
      res.elements && res.elements.forEach(cell => {
@@ -529,16 +496,7 @@
        } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
          return
        } else {
          let _uuid = Utils.getuuid()
          if (cell.OpenType === 'popview') {
            let _cell = fromJS(cell).toJS()
            _cell.$originUuid = _cell.uuid
            _cell.uuid = _uuid
            copyBtns.push(_cell)
          }
          cell.uuid = _uuid
          cell.uuid = Utils.getuuid()
          elements.push(cell)
        }
      })
@@ -559,26 +517,13 @@
          } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
            return
          } else {
            let _uuid = Utils.getuuid()
            if (cell.OpenType === 'popview') {
              let _cell = fromJS(cell).toJS()
              _cell.$originUuid = _cell.uuid
              _cell.uuid = _uuid
              copyBtns.push(_cell)
            }
            cell.uuid = _uuid
            cell.uuid = Utils.getuuid()
            backElements.push(cell)
          }
        })
      }
      res.backElements = backElements
      if (copyBtns.length > 0) {
        MKEmitter.emit('copyButtons', copyBtns)
      }
      resolve({status: true})
@@ -615,19 +560,9 @@
      if (appType === 'mob' && !['pop', 'prompt', 'exec', 'innerpage'].includes(res.OpenType)) {
        resolve({status: false, message: '移动端不支持此类型的按钮。'})
      } else {
        let _uuid = Utils.getuuid()
        if (res.OpenType === 'popview') {
          let _cell = fromJS(res).toJS()
          _cell.$originUuid = _cell.uuid
          _cell.uuid = _uuid
          MKEmitter.emit('copyButtons', [_cell])
        }
        resolve({status: true})
    
        res.uuid = _uuid
        res.uuid = Utils.getuuid()
        this.addButton(res)
      }
    }
@@ -636,7 +571,13 @@
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.setState({ card: _card })
        this.props.updateConfig(_card)
      })
    }
  }
@@ -659,7 +600,7 @@
            <CopyComponent type="datacard" card={card}/>
            <PasteComponent options={['action', 'search', 'form', 'cardcell']} updateConfig={this.pasteComponent} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)} />
            <SettingComponent config={card} updateConfig={this.updateComponent} />
@@ -667,13 +608,28 @@
        } trigger="hover">
          <ToolOutlined />
        </Popover>
        <ActionComponent config={card} type="datacard" setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/>
        <div className={'float-' + (card.wrap.cardFloat || 'left')}>
        <ActionComponent config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/>
        <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>
        {card.wrap.pagestyle === 'page' && card.setting.laypage === 'true' && appType !== 'mob' ? <Pagination total={85} size="small" showTotal={total => `共 ${total} 条`} pageSize={20} defaultCurrent={1}/> : null}
        {card.wrap.pagestyle === 'page' && card.setting.laypage === 'true' && appType === 'mob' ? <MobPagination /> : null}
        {card.wrap.pagestyle === 'more' && card.setting.laypage === 'true' ? <div className="mk-more">查看更多<DownOutlined/></div> : null}
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/card/data-card/index.scss
@@ -62,16 +62,6 @@
      font-size: 16px;
    }
  }
  .card-add-button {
    text-align: right;
    clear: left;
    .anticon-plus {
      font-size: 20px;
      color: #26C281;
      padding: 5px;
      margin-right: 10px;
    }
  }
  .ant-pagination {
    float: right;
    margin: 10px;
@@ -109,6 +99,22 @@
      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;
    }
  }
  .mk-more {
    text-align: center;
    line-height: 40px;
    .anticon-down {
      margin-left: 2px;
    }
  }
}
.menu-data-card-edit-box::-webkit-scrollbar {
@@ -133,11 +139,13 @@
}
.menu-data-card-edit-box.mob {
  .model-menu-action-list {
    position: absolute;
    top: 5px;
    right: 0px;
    // position: absolute;
    // top: 5px;
    // right: 0px;
    // padding-top: 5px;
    .page-card {
      line-height: 40px;
      margin-top: 5px;
    }
  }
}
src/menu/components/card/data-card/options.jsx
@@ -1,20 +1,38 @@
import { fromJS } from 'immutable'
import MenuUtils from '@/utils/utils-custom.js'
/**
 * @description Wrap表单配置信息
 */
export default function (wrap, subtype, columns = [], id = '', supNodes = []) {
export default function (wrap, subtype, columns = [], id = '', supNodes = [], setting, buttons = []) {
  let appType = sessionStorage.getItem('appType')
  let MenuType = ''
  let menu = fromJS(window.GLOB.customMenu).toJS()
  let menu = window.GLOB.customMenu
  let laypage = setting && setting.laypage !== 'false'
  let interfaces = []
  if (subtype === 'propcard' && menu.interfaces) {
    menu.interfaces.forEach(item => {
      if (item.status === 'true') {
        interfaces.push({
          value: item.uuid,
          label: item.name
        })
      }
    })
  }
  if (menu.parentId === 'BillPrintTemp') {
    MenuType = 'billPrint'
  }
  let modules = []
  if (subtype === 'propcard' || subtype === 'datacard') {
    modules = MenuUtils.getSupModules(menu.components, id) || []
    modules = MenuUtils.getSupModules(menu.components, id, menu.interfaces)
    if (subtype === 'propcard' && wrap.supModule && wrap.supModule.length > 0 && wrap.supModule[0] !== 'empty') {
      let has = MenuUtils.checkSupModules(modules, wrap.supModule.slice(-1)[0])
      if (!has) {
        wrap.supModule = ''
      }
    }
  }
  let roleList = sessionStorage.getItem('sysRoles')
@@ -81,14 +99,26 @@
      options: [
        {value: 'dynamic', label: '动态', priKeyType: 'static'},
        {value: 'static', label: '静态', priKeyType: 'static'},
        {value: 'public', label: '公共数据源', priKeyType: 'static'},
      ],
      linkFields: ['priKeyType'],
      controlFields: [
        {field: 'goback', values: ['dynamic']},
        {field: 'empty', values: ['dynamic']},
        {field: 'empty', values: ['dynamic', 'public']},
        {field: 'jump', values: ['dynamic']},
        {field: 'autoExec', values: ['dynamic']},
        {field: 'supModule', values: ['static']},
        {field: 'publicId', values: ['public']},
      ],
      forbid: subtype !== 'propcard'
    },
    {
      type: 'select',
      field: 'publicId',
      label: '数据源',
      initval: wrap.publicId || '',
      required: true,
      options: interfaces,
      forbid: subtype !== 'propcard'
    },
    {
@@ -113,14 +143,19 @@
      field: 'pagestyle',
      label: '分页风格',
      initval: wrap.pagestyle || 'page',
      tooltip: '数据源选择分页时有效。注:滑动加载只有第一个有效',
      tooltip: '数据源选择分页时有效。注:弹性布局时固定为页码。',
      required: false,
      disabled: !laypage,
      options: [
        {value: 'page', label: '页码'},
        {value: 'switch', label: '左右切换', forbid: appType === 'mob'},
        {value: 'switch', label: '左右切换', forbid: appType === 'mob' || subtype === 'tablecard'},
        {value: 'slide', label: '滑动加载', forbid: appType !== 'mob'},
        {value: 'more', label: '查看更多'},
      ],
      forbid: !(subtype === 'datacard' || (subtype === 'tablecard' && appType === 'mob'))
      controlFields: [
        {field: 'slidetip', values: ['slide']},
      ],
      forbid: subtype === 'propcard'
    },
    {
      type: 'radio',
@@ -154,6 +189,9 @@
        {ParentID: 'dynamic', value: 'static', label: '静态值'},
        {ParentID: 'dynamic', value: 'dynamic', label: '动态值'},
        {ParentID: 'dynamic', value: 'joint', label: '拼接值'},
        {ParentID: 'public', value: 'static', label: '静态值'},
        {ParentID: 'public', value: 'dynamic', label: '动态值'},
        {ParentID: 'public', value: 'joint', label: '拼接值'},
      ],
      forbid: subtype !== 'propcard'
    },
@@ -168,7 +206,8 @@
        {value: 'false', label: '无'},
        {value: 'init', label: '初始化'},
        {value: 'always', label: '数据加载'},
      ]
      ],
      forbid: subtype === 'tablecard'
    },
    {
      type: 'select',
@@ -182,9 +221,10 @@
        {value: 'active', label: '外阴影'},
        {value: 'backFont', label: '背景+文字'},
        {value: 'font', label: '文字'},
        {value: 'tabs', label: '标签页'},
        ...(subtype === 'datacard' && appType === 'mob' ? [{value: 'check', label: '勾选'}] : [])
      ]
      // forbid: subtype !== 'propcard'
      ],
      forbid: subtype === 'tablecard'
    },
    // {
    //   type: 'radio',
@@ -275,6 +315,21 @@
    },
    {
      type: 'radio',
      field: 'display',
      label: '显示控制',
      initval: wrap.display || 'normal',
      required: false,
      options: [
        {value: 'normal', label: '正常显示'},
        {value: 'hidden', label: '不可见'},
      ],
      controlFields: [
        {field: 'empty', values: ['normal']},
      ],
      forbid: subtype !== 'propcard'
    },
    {
      type: 'radio',
      field: 'empty',
      label: '空值隐藏',
      initval: wrap.empty || 'show',
@@ -285,6 +340,16 @@
        {value: 'show', label: '否'},
        {value: 'hidden', label: '是'},
      ],
    },
    {
      type: 'select',
      field: 'autoExec',
      label: '自动执行',
      initval: wrap.autoExec || '',
      tooltip: '数据更新时自动执行按钮。注:此按钮执行成功后谨慎选择刷新项,避免造成循环执行。',
      required: false,
      options: buttons,
      forbid: subtype !== 'propcard'
    },
    {
      type: 'radio',
@@ -387,9 +452,9 @@
    {
      type: 'text',
      field: 'controlVal',
      label: '控制值',
      label: '禁用值',
      initval: wrap.controlVal || '',
      tooltip: '当字段值与控制值相等时,行数据会禁用,多个值用逗号分隔。',
      tooltip: '当字段值与禁用值相等时,行数据会禁用,多个值用逗号分隔。',
      required: false,
      forbid: subtype !== 'datacard'
    },
@@ -431,6 +496,15 @@
      forbid: !!appType
    },
    {
      type: 'text',
      field: 'slidetip',
      label: '底部提示',
      initval: wrap.slidetip || wrap.slidetip === '' ? wrap.slidetip : '没有更多了',
      tooltip: '滑动加载至底部时的提示信息。',
      required: false,
      forbid: !laypage || appType !== 'mob' || subtype === 'propcard'
    },
    {
      type: 'table',
      field: 'supNodes',
      label: '上级组件',
src/menu/components/card/prop-card/index.jsx
@@ -1,12 +1,12 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, Modal, notification } from 'antd'
import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import { Popover, Modal } from 'antd'
import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, ClockCircleOutlined, HeatMapOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle } from '@/utils/utils-custom.js'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import Utils from '@/utils/utils.js'
import getWrapForm from '../data-card/options'
@@ -17,7 +17,6 @@
const CardComponent = asyncComponent(() => import('../cardcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
@@ -45,12 +44,9 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: 'object',   // 组件属性 - 数据格式
        pageable: false,    // 组件属性 - 是否可分页
        switchable: true,  // 组件属性 - 数据是否可切换
        dataName: card.dataName || '',
        width: card.width || 24,
        name: card.name,
        subtype: card.subtype,
@@ -72,7 +68,6 @@
          elements: [],
          backElements: []
        }],
        btnlog: [],
      }
      if (card.config) {
@@ -100,10 +95,7 @@
          return scard
        })
      }
      this.setState({
        card: _card
      })
      this.props.updateConfig(_card)
      this.updateComponent(_card)
    } else {
      this.setState({
        card: fromJS(card).toJS()
@@ -112,9 +104,7 @@
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('logButton', this.logButton)
    MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
    MKEmitter.addListener('mkUpdateInter', this.mkUpdateInter)
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -128,54 +118,155 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('logButton', this.logButton)
    MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle)
    MKEmitter.removeListener('mkUpdateInter', this.mkUpdateInter)
  }
  updateComponentStyle = (parentId, keys, style) => {
  mkUpdateInter = (inter, split) => {
    const { card } = this.state
    if (card.wrap.datatype === 'public' && card.wrap.publicId === inter.uuid) {
      let _card = {...card, columns: fromJS(inter.columns).toJS()}
    if (card.uuid !== parentId) return
      split.delay = split.delay + 10
    let subcards = card.subcards.map(item => {
      if (keys.includes(item.uuid)) {
        item.style = {...item.style, ...style}
      }
      return item
    })
    this.setState({card: {...card, subcards: []}}, () => {
      this.updateComponent({...card, subcards: subcards})
    })
  }
  logButton = (id, item) => {
    const { card } = this.state
    if (id !== card.uuid) return
    let btnlog = card.btnlog || []
    btnlog.push(item)
    this.setState({
      card: {...card, btnlog}
    })
    this.props.updateConfig({...card, btnlog})
      setTimeout(() => {
        this.updateComponent(_card)
      }, split.delay)
    }
  }
  /**
   * @description 卡片行外层信息更新(数据源,样式等)
   */
  updateComponent = (component) => {
  updateComponent = (card) => {
    const { appType } = this.state
    card.width = card.wrap.width
    card.name = card.wrap.name
    if (window.GLOB.styling && card.errors) { // 样式修改时不做筛查
      this.setState({
        card: card
      })
      this.props.updateConfig(card)
      return
    }
    card.errors = []
    if (card.subcards.length === 0) {
      card.errors.push({ level: 0, detail: '卡片不可为空!'})
    }
    if (card.wrap.datatype === 'static') {
      card.$tables = getTables(card)
      card.subcards.forEach((item, i) => {
        let linkbtn = item.setting.linkbtn || ''
        item.elements.forEach(cell => {
          if (cell.eleType === 'button') {
            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
              if (!cell.modal || cell.modal.fields.length === 0) {
                card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
              }
            }
            if (linkbtn && linkbtn === cell.uuid) {
              linkbtn = ''
            }
          } else if (cell.datatype === 'dynamic' && cell.field) {
            card.errors.push({ level: 1, detail: `卡片中动态字段“${cell.field}”无效`})
          }
        })
        if (item.setting.type === 'multi' && appType !== 'mob') {
          item.backElements.forEach(cell => {
            if (cell.eleType === 'button') {
              if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
                if (!cell.modal || cell.modal.fields.length === 0) {
                  card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
                }
              }
              if (linkbtn && linkbtn === cell.uuid) {
                linkbtn = ''
              }
            } else if (cell.datatype === 'dynamic' && cell.field) {
              card.errors.push({ level: 1, detail: `卡片中动态字段“${cell.field}”无效`})
            }
          })
        }
        if (linkbtn) {
          card.errors.push({ level: 1, detail: `第${i + 1}张卡片中绑定按钮已删除`})
        }
      })
    } else {
      let columns = card.columns.map(c => c.field)
      if (card.wrap.datatype === 'dynamic') {
        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: '未设置上级组件!'})
        }
      }
      if (card.errors.length === 0) {
        card.$tables = getTables(card)
      }
      card.subcards.forEach((item, i) => {
        let linkbtn = item.setting.linkbtn || ''
        item.elements.forEach(cell => {
          if (cell.eleType === 'button') {
            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
              if (!cell.modal || cell.modal.fields.length === 0) {
                card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
              }
            }
            if (linkbtn && linkbtn === cell.uuid) {
              linkbtn = ''
            }
          } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
            card.errors.push({ level: 1, detail: `卡片中动态字段“${cell.field}”无效`})
          }
        })
        if (item.setting.type === 'multi' && appType !== 'mob') {
          item.backElements.forEach(cell => {
            if (cell.eleType === 'button') {
              if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
                if (!cell.modal || cell.modal.fields.length === 0) {
                  card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
                }
              }
              if (linkbtn && linkbtn === cell.uuid) {
                linkbtn = ''
              }
            } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
              card.errors.push({ level: 1, detail: `卡片中动态字段“${cell.field}”无效`})
            }
          })
        }
        if (linkbtn) {
          card.errors.push({ level: 1, detail: `第${i + 1}张卡片中绑定按钮已删除`})
        }
      })
    }
    this.setState({
      card: component
      card: card
    })
    component.width = component.wrap.width
    component.name = component.wrap.name
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  /**
@@ -189,16 +280,13 @@
      return item
    })
    this.setState({card})
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  /**
   * @description 单个卡片信息更新
   */
  deleteCard = (cell) => {
    const { appType } = this.state
    let card = fromJS(this.state.card).toJS()
    let _this = this
@@ -207,31 +295,7 @@
      onOk() {
        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
        if (card.btnlog) {
          card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
        }
        _this.setState({card})
        _this.props.updateConfig(card)
        if (appType === 'mob') return
        let uuids = []
        cell.elements && cell.elements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        cell.backElements && cell.backElements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
        _this.updateComponent(card)
      },
      onCancel() {}
    })
@@ -240,21 +304,13 @@
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
    if (comIds.length !== 1 || comIds[0] !== card.uuid) return
    let _card = {...card, style}
    this.setState({
      card: _card
    })
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    
    this.props.updateConfig(_card)
    this.updateComponent(_card)
  }
  addCard = (copy) => {
@@ -292,58 +348,8 @@
    }
    card.subcards.push(newcard)
    this.setState({card})
    this.props.updateConfig(card)
  }
  handleLog = (type, logs, item) => {
    let card = fromJS(this.state.card).toJS()
    if (type === 'revert') {
      let done = false
      if (item.$parentId) {
        card.subcards.forEach(col => {
          if (item.$parentId === col.uuid) {
            if (item.$side !== 'back') {
              col.elements = col.elements ? [...col.elements, item] : [item]
            } else {
              col.backElements = col.backElements ? [...col.backElements, item] : [item]
            }
            done = true
          }
        })
      }
      card.btnlog = logs
      this.setState({ card: {...card, subcards: []} }, () => {
        this.setState({ card })
        this.props.updateConfig(card)
      })
      if (!done) {
        notification.warning({
          top: 92,
          message: '附属卡片已删除!',
          duration: 2
        })
      } else {
        notification.success({
          top: 92,
          message: '恢复成功!',
          duration: 2
        })
      }
    } else {
      card.btnlog = logs
      this.setState({ card })
      this.props.updateConfig(card)
      notification.success({
        top: 92,
        message: '清除成功!',
        duration: 2
      })
    }
    this.updateComponent(card)
  }
  move = (item, direction) => {
@@ -362,8 +368,7 @@
    card.subcards.splice(hoverIndex, 0, ...card.subcards.splice(dragIndex, 1))
    this.setState({card})
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  pasteComponent = (res, resolve) => {
@@ -376,8 +381,7 @@
    res.setting = res.setting || {}
    res.setting.width = res.setting.width || 6
    let copyBtns = []
    let mobtypes = ['pop', 'prompt', 'exec', 'innerpage']
    let mobtypes = ['pop', 'prompt', 'exec', 'innerpage', 'funcbutton']
    let elements = []
    res.elements && res.elements.forEach(cell => {
@@ -387,16 +391,7 @@
      } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
        return
      } else {
        let _uuid = Utils.getuuid()
        if (cell.OpenType === 'popview') {
          let _cell = fromJS(cell).toJS()
          _cell.$originUuid = _cell.uuid
          _cell.uuid = _uuid
          copyBtns.push(_cell)
        }
        cell.uuid = _uuid
        cell.uuid = Utils.getuuid()
        elements.push(cell)
      }
    })
@@ -413,26 +408,13 @@
        } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
          return
        } else {
          let _uuid = Utils.getuuid()
          if (cell.OpenType === 'popview') {
            let _cell = fromJS(cell).toJS()
            _cell.$originUuid = _cell.uuid
            _cell.uuid = _uuid
            copyBtns.push(_cell)
          }
          cell.uuid = _uuid
          cell.uuid = Utils.getuuid()
          backElements.push(cell)
        }
      })
    }
    res.backElements = backElements
    if (copyBtns.length > 0) {
      MKEmitter.emit('copyButtons', copyBtns)
    }
    resolve({status: true})
@@ -441,26 +423,79 @@
  getWrapForms = () => {
    const { card } = this.state
    return getWrapForm(card.wrap, card.subtype, card.columns, card.uuid)
    let buttons = []
    card.subcards.forEach(m => {
      m.elements.forEach(n => {
        if (n.eleType === 'button') {
          buttons.push({
            value: n.uuid,
            label: n.label
          })
        }
      })
    })
    return getWrapForm(card.wrap, card.subtype, card.columns, card.uuid, null, null, buttons)
  }
  updateWrap = (res) => {
    let _card = {...this.state.card, wrap: res}
    const { card } = this.state
    if (res.supModule && res.supModule.length > 0) {
      _card.setting.supModule = res.supModule
    let _card = {...card, wrap: res}
    if (res.datatype === 'static') {
      if (res.supModule && res.supModule.length > 0) {
        _card.setting.supModule = res.supModule
      } else {
        _card.setting.supModule = ''
      }
    } else if (res.datatype === 'public') {
      let interfaces = window.GLOB.customMenu.interfaces || []
      let d = interfaces.filter(m => m.uuid === res.publicId && m.status === 'true')[0]
      if (d) {
        _card.columns = fromJS(d.columns).toJS()
      }
    }
    if (res.layout === 'flex') {
      _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) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.setState({ card: _card })
        this.props.updateConfig(_card)
      })
    }
  }
@@ -481,19 +516,32 @@
            <CopyComponent type="propcard" card={card}/>
            <PasteComponent options={['cardcell']} updateConfig={this.pasteComponent} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
            {card.wrap.datatype === 'dynamic' ? <ClockComponent config={card} updateConfig={this.updateComponent}/> : <ClockCircleOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/>}
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)} />
            {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
            {card.wrap.datatype === 'static' ? <SettingOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/> : null}
            {card.wrap.datatype === 'dynamic' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : <SettingOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/>}
          </div>
        } 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>
        {card.wrap.display === 'hidden' ? <HeatMapOutlined className="prop-hidden"/> : null}
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/card/prop-card/index.scss
@@ -53,24 +53,6 @@
    right: -30px;
    font-size: 16px;
  }
  .model-menu-action-list {
    line-height: 40px;
    .ant-row > .anticon-plus {
      position: absolute;
      right: -30px;
      font-size: 16px;
    }
  }
  .card-add-button {
    text-align: right;
    clear: left;
    .anticon-plus {
      font-size: 20px;
      color: #26C281;
      padding: 5px;
      margin-right: 10px;
    }
  }
  .flex-layout {
    display: flex;
    width: 100%;
@@ -97,6 +79,20 @@
      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;
    }
  }
  .prop-hidden {
    color: orange;
    float: right;
    margin: 5px;
  }
}
.menu-prop-card-edit-box::after {
  display: block;
src/menu/components/card/table-card/index.jsx
@@ -1,12 +1,12 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, Modal, Pagination, notification } from 'antd'
import { PlusOutlined, PlusCircleOutlined, PlusSquareOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import { Popover, Modal, Pagination } from 'antd'
import { PlusOutlined, PlusCircleOutlined, PlusSquareOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, DownOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle } from '@/utils/utils-custom.js'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import Utils from '@/utils/utils.js'
import getWrapForm from '../data-card/options'
@@ -18,9 +18,9 @@
const MobPagination = asyncIconComponent(() => import('@/menu/components/share/mobPagination'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent'))
const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent'))
const { confirm } = Modal
@@ -45,12 +45,9 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: 'array',    // 组件属性 - 数据格式
        pageable: true,     // 组件属性 - 是否可分页
        switchable: false,  // 组件属性 - 数据是否可切换
        dataName: card.dataName || '',
        width: card.width || 12,
        search: [],
        name: card.name,
@@ -70,7 +67,6 @@
          elements: []
        }],
        action: [],
        btnlog: [],
      }
      
      if (card.config) {
@@ -104,10 +100,8 @@
          })
        }
      }
      this.setState({
        card: _card
      })
      this.props.updateConfig(_card)
      this.updateComponent(_card)
    } else {
      let _card = fromJS(card).toJS()
      if (!_card.action) {
@@ -138,11 +132,6 @@
    }
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('logButton', this.logButton)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
@@ -154,36 +143,80 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('logButton', this.logButton)
  }
  logButton = (id, item) => {
    const { card } = this.state
    if (id !== card.uuid) return
    let btnlog = card.btnlog || []
    btnlog.push(item)
    this.setState({
      card: {...card, btnlog}
    })
    this.props.updateConfig({...card, btnlog})
  }
  /**
   * @description 卡片行外层信息更新(数据源,样式等)
   */
  updateComponent = (component) => {
    this.setState({
      card: component
  updateComponent = (card) => {
    card.width = card.wrap.width
    card.name = card.wrap.name
    if (window.GLOB.styling && card.errors) { // 样式修改时不做筛查
      this.setState({
        card: card
      })
      this.props.updateConfig(card)
      return
    }
    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: '卡片不可为空!'})
    }
    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: '未设置上级组件!'})
    }
    if (card.errors.length === 0) {
      card.$tables = getTables(card)
    }
    card.subcards.forEach((item, i) => {
      let linkbtn = item.setting.linkbtn || ''
      item.elements.forEach(cell => {
        if (cell.eleType === 'button') {
          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
            if (!cell.modal || cell.modal.fields.length === 0) {
              card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
            }
          }
          if (linkbtn && linkbtn === cell.uuid) {
            linkbtn = ''
          }
        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
          card.errors.push({ level: 1, detail: `卡片中动态字段“${cell.field}”无效`})
        }
      })
      if (linkbtn) {
        card.errors.push({ level: 1, detail: `第${i + 1}张卡片中绑定按钮已删除`})
      }
    })
    component.width = component.wrap.width
    component.name = component.wrap.name
    this.setState({
      card: card
    })
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  /**
@@ -197,16 +230,13 @@
      return item
    })
    this.setState({card})
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  /**
   * @description 单个卡片信息更新
   */
  deleteCard = (cell) => {
    const { appType } = this.state
    let card = fromJS(this.state.card).toJS()
    let _this = this
@@ -215,26 +245,7 @@
      onOk() {
        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
        if (card.btnlog) {
          card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
        }
        _this.setState({card})
        _this.props.updateConfig(card)
        if (appType === 'mob') return
        let uuids = []
        cell.elements && cell.elements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
        _this.updateComponent(card)
      },
      onCancel() {}
    })
@@ -243,21 +254,13 @@
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    if (comIds[0] !== card.uuid || comIds.length > 1) return
    let _card = {...card, style}
    this.setState({
      card: _card
    })
    this.props.updateConfig(_card)
    this.updateComponent(_card)
  }
  addCard = (copy) => {
@@ -287,9 +290,8 @@
    }
    card.subcards.push(newcard)
    this.setState({card})
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  addSearch = (copy) => {
@@ -317,53 +319,6 @@
    MKEmitter.emit('addSearch', card.uuid, newcard)
  }
  handleLog = (type, logs, item) => {
    let card = fromJS(this.state.card).toJS()
    if (type === 'revert') {
      let done = false
      if (item.$parentId) {
        card.subcards.forEach(col => {
          if (item.$parentId === col.uuid) {
            if (item.$side !== 'back') {
              col.elements = col.elements ? [...col.elements, item] : [item]
            } else {
              col.backElements = col.backElements ? [...col.backElements, item] : [item]
            }
            done = true
          }
        })
      }
      card.btnlog = logs
      this.setState({ card })
      this.props.updateConfig(card)
      if (!done) {
        notification.warning({
          top: 92,
          message: '附属卡片已删除!',
          duration: 2
        })
      } else {
        notification.success({
          top: 92,
          message: '恢复成功!',
          duration: 2
        })
      }
    } else {
      card.btnlog = logs
      this.setState({ card })
      this.props.updateConfig(card)
      notification.success({
        top: 92,
        message: '清除成功!',
        duration: 2
      })
    }
  }
  move = (item, direction) => {
    let card = fromJS(this.state.card).toJS()
@@ -380,14 +335,13 @@
    card.subcards.splice(hoverIndex, 0, ...card.subcards.splice(dragIndex, 1))
    this.setState({card})
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  getWrapForms = () => {
    const { card } = this.state
    return getWrapForm(card.wrap, card.subtype)
    return getWrapForm(card.wrap, card.subtype, null, null, null, card.setting)
  }
  updateWrap = (res) => {
@@ -405,8 +359,7 @@
      res.setting = res.setting || {}
      res.setting.width = res.setting.width || 6
      let copyBtns = []
      let mobtypes = ['pop', 'prompt', 'exec', 'innerpage']
      let mobtypes = ['pop', 'prompt', 'exec', 'innerpage', 'funcbutton']
      let elements = []
      res.elements && res.elements.forEach(cell => {
@@ -416,16 +369,7 @@
        } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
          return
        } else {
          let _uuid = Utils.getuuid()
          if (cell.OpenType === 'popview') {
            let _cell = fromJS(cell).toJS()
            _cell.$originUuid = _cell.uuid
            _cell.uuid = _uuid
            copyBtns.push(_cell)
          }
          cell.uuid = _uuid
          cell.uuid = Utils.getuuid()
          elements.push(cell)
        }
      })
@@ -434,10 +378,6 @@
      delete res.$cardType
      delete res.backElements
      if (copyBtns.length > 0) {
        MKEmitter.emit('copyButtons', copyBtns)
      }
      resolve({status: true})
@@ -528,7 +468,13 @@
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.setState({ card: _card })
        this.props.updateConfig(_card)
      })
    }
  }
@@ -550,7 +496,7 @@
            <CopyComponent type="tablecard" card={card}/>
            <PasteComponent options={['cardcell', 'search', 'form']} updateConfig={this.pasteComponent} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)} />
            {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
@@ -558,12 +504,27 @@
        } trigger="hover">
          <ToolOutlined />
        </Popover>
        <ActionComponent config={card} type="datacard" setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/>
        <ActionComponent config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/>
        <div style={{minHeight: 'calc(100% - 90px)'}}>
          {card.subcards.map(subcard => (<CardSimpleComponent key={subcard.uuid} cards={card} card={subcard} updateElement={this.updateCard} move={this.move} deleteElement={this.deleteCard}/>))}
        </div>
        {card.setting.laypage === 'true' && card.wrap.pagestyle !== 'slide' && appType !== 'mob' ? <Pagination size="small" total={50} /> : null}
        {card.setting.laypage === 'true' && card.wrap.pagestyle !== 'slide' && appType === 'mob' ? <MobPagination /> : null}
        {card.setting.laypage === 'true' && card.wrap.pagestyle === 'page' && appType !== 'mob' ? <Pagination size="small" total={50} /> : null}
        {card.setting.laypage === 'true' && card.wrap.pagestyle === 'page' && appType === 'mob' ? <MobPagination /> : null}
        {card.setting.laypage === 'true' && card.wrap.pagestyle === 'more' ? <div className="mk-more">查看更多<DownOutlined/></div> : null}
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/card/table-card/index.scss
@@ -71,19 +71,16 @@
      font-size: 16px;
    }
  }
  .card-add-button {
    text-align: right;
    clear: left;
    .anticon-plus {
      font-size: 20px;
      color: #26C281;
      padding: 5px;
      margin-right: 10px;
    }
  }
  .ant-pagination {
    text-align: right;
  }
  .mk-more {
    text-align: center;
    line-height: 40px;
    .anticon-down {
      margin-left: 2px;
    }
  }
}
.menu-table-card-edit-box::after {
  display: block;
src/menu/components/carousel/data-card/index.jsx
@@ -1,12 +1,12 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, Modal, notification } from 'antd'
import { Popover, Modal } from 'antd'
import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle } from '@/utils/utils-custom.js'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import Utils from '@/utils/utils.js'
import getWrapForm from './options'
@@ -14,9 +14,10 @@
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const CardSimpleComponent = asyncComponent(() => import('@/menu/components/card/cardsimplecomponent'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent'))
const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
const { confirm } = Modal
@@ -29,7 +30,6 @@
  }
  state = {
    appType: sessionStorage.getItem('appType'),
    card: null,
    back: false
  }
@@ -41,21 +41,17 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: 'array',    // 组件属性 - 数据格式
        pageable: false,    // 组件属性 - 是否可分页
        switchable: false,   // 组件属性 - 数据是否可切换
        dataName: card.dataName || '',
        width: card.width || 24,
        name: card.name,
        subtype: card.subtype,
        setting: { interType: 'system' },
        wrap: { name: card.name, width: card.width || 24, autoplay: 'false', dots: 'true' },
        style: { borderWidth: '1px', borderColor: '#e8e8e8', marginTop: '8px', marginBottom: '8px', height: '300px' },
        wrap: { name: card.name, width: card.width || 24, autoplay: 'false', dots: 'true', height: '300px' },
        style: { borderWidth: '1px', borderColor: '#e8e8e8', marginTop: '8px', marginBottom: '8px' },
        columns: [],
        scripts: [],
        btnlog: [],
        subcards: [{
          uuid: Utils.getuuid(),
          setting: {},
@@ -87,20 +83,19 @@
        })
      }
      this.updateComponent(_card)
    } else {
      let _card = fromJS(card).toJS()
      if (!_card.wrap.height && _card.style.height) { // 兼容
        _card.wrap.height = _card.style.height
      }
      delete _card.style.height
      this.setState({
        card: _card
      })
      this.props.updateConfig(_card)
    } else {
      this.setState({
        card: fromJS(card).toJS()
      })
    }
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('logButton', this.logButton)
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -114,36 +109,63 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('logButton', this.logButton)
  }
  logButton = (id, item) => {
    const { card } = this.state
    if (id !== card.uuid) return
    let btnlog = card.btnlog || []
    btnlog.push(item)
    this.setState({
      card: {...card, btnlog}
    })
    this.props.updateConfig({...card, btnlog})
  }
  /**
   * @description 卡片行外层信息更新(数据源,样式等)
   */
  updateComponent = (component) => {
    this.setState({
      card: component
  updateComponent = (card) => {
    card.width = card.wrap.width
    card.name = card.wrap.name
    if (window.GLOB.styling && card.errors) { // 样式修改时不做筛查
      this.setState({
        card: card
      })
      this.props.updateConfig(card)
      return
    }
    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: '未设置上级组件!'})
    }
    if (card.errors.length === 0) {
      card.$tables = getTables(card)
    }
    card.subcards.forEach((item, i) => {
      item.elements.forEach(cell => {
        if (cell.eleType === 'button') {
          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
            if (!cell.modal || cell.modal.fields.length === 0) {
              card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
            }
          }
        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
          card.errors.push({ level: 1, detail: `卡片中动态字段“${cell.field}”无效`})
        }
      })
    })
    component.width = component.wrap.width
    component.name = component.wrap.name
    this.setState({
      card: card
    })
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  /**
@@ -157,16 +179,13 @@
      return item
    })
    this.setState({card})
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  /**
   * @description 单个卡片信息更新
   */
  deleteCard = (cell) => {
    const { appType } = this.state
    let card = fromJS(this.state.card).toJS()
    let _this = this
@@ -175,26 +194,7 @@
      onOk() {
        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
        if (card.btnlog) {
          card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
        }
        _this.setState({card})
        _this.props.updateConfig(card)
        if (appType === 'mob') return
        let uuids = []
        cell.elements && cell.elements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
        _this.updateComponent(card)
      },
      onCancel() {}
    })
@@ -203,53 +203,13 @@
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    if (comIds.length !== 1 || comIds[0] !== card.uuid) return
    let _card = {...card, style}
    this.setState({
      card: _card
    })
    this.props.updateConfig(_card)
  }
  handleLog = (type, logs, item) => {
    let card = fromJS(this.state.card).toJS()
    if (type === 'revert') {
      card.subcards.forEach(col => {
        col.elements = [...col.elements, item]
        if (item.$parentId === col.uuid) {
          col.elements = [...col.elements, item]
        }
      })
      card.btnlog = logs
      this.setState({ card })
      this.props.updateConfig(card)
      notification.success({
        top: 92,
        message: '恢复成功!',
        duration: 2
      })
    } else {
      card.btnlog = logs
      this.setState({ card })
      this.props.updateConfig(card)
      notification.success({
        top: 92,
        message: '清除成功!',
        duration: 2
      })
    }
    this.updateComponent(_card)
  }
  getWrapForms = () => {
@@ -259,13 +219,25 @@
  }
  updateWrap = (res) => {
    this.updateComponent({...this.state.card, wrap: res})
    let _card = {...this.state.card, wrap: res}
    if (res.title && !_card.headerStyle) {
      _card.headerStyle = { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }
    }
    this.updateComponent(_card)
  }
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.setState({ card: _card })
        this.props.updateConfig(_card)
      })
    }
  }
@@ -275,6 +247,7 @@
    return (
      <div className="menu-data-carousel-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <NormalForm title="轮播-动态数据" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
@@ -282,7 +255,7 @@
            </NormalForm>
            <CopyComponent type="datacard" card={card}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog}/>
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)}/>
            <SettingComponent config={card} updateConfig={this.updateComponent}/>
@@ -290,7 +263,23 @@
        } trigger="hover">
          <ToolOutlined/>
        </Popover>
        <CardSimpleComponent cards={card} card={card.subcards[0]} updateElement={this.updateCard} deleteElement={this.deleteCard}/>
        <div style={{height: card.wrap.height}}>
          <CardSimpleComponent cards={card} card={card.subcards[0]} updateElement={this.updateCard} deleteElement={this.deleteCard}/>
        </div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/carousel/data-card/index.scss
@@ -47,33 +47,9 @@
    right: -30px;
    font-size: 16px;
  }
  .model-menu-action-list {
    line-height: 40px;
    .ant-row > .anticon-plus {
      position: absolute;
      right: -30px;
      font-size: 16px;
    }
  }
  .card-add-button {
    text-align: right;
    clear: left;
    .anticon-plus {
      font-size: 20px;
      color: #26C281;
      padding: 5px;
      margin-right: 10px;
    }
  }
  .ant-pagination {
    float: right;
    margin: 10px;
  }
  .model-menu-action-list {
    .page-card {
      line-height: 55px;
    }
  }
}
.menu-data-carousel-edit-box::after {
src/menu/components/carousel/data-card/options.jsx
@@ -18,6 +18,13 @@
  const cardWrapForm = [
    {
      type: 'text',
      field: 'title',
      label: '标题',
      initval: wrap.title || '',
      required: false
    },
    {
      type: 'text',
      field: 'name',
      label: '组件名称',
      initval: wrap.name || '',
@@ -53,13 +60,72 @@
    },
    {
      type: 'radio',
      field: 'display',
      label: '显示模式',
      initval: wrap.display || 'normal',
      required: false,
      options: [
        {value: 'normal', label: '正常'},
        {value: 'modal', label: '弹窗'},
      ],
      controlFields: [
        {field: 'modalWidth', values: ['modal']},
        {field: 'modalContent', values: ['modal']},
        {field: 'code', values: ['modal']},
      ]
    },
    {
      type: 'radio',
      field: 'modalContent',
      label: '弹窗内容',
      initval: wrap.modalContent || 'message',
      required: false,
      options: [
        {value: 'message', label: '消息提醒'},
        {value: 'update', label: '系统更新'},
      ]
    },
    {
      type: 'styleInput',
      field: 'height',
      label: '组件高度',
      initval: wrap.height || '',
      required: true,
      options: ['px', 'vh']
    },
    {
      type: 'styleInput',
      field: 'modalWidth',
      label: '弹窗宽度',
      initval: wrap.modalWidth || '300px',
      required: true,
      options: ['px', 'vw'],
      forbid: appType === 'mob'
    },
    {
      type: 'text',
      field: 'code',
      label: '消息编码',
      initval: wrap.code || '',
      tooltip: '用于记录消息是否已读的标识,如果不同页面中存在相同消息,可指定固定值。',
      required: false,
      rules: [{
        pattern: /^[0-9a-zA-Z_]*$/ig,
        message: '只允许包含数字、字母以及_。'
      }]
    },
    {
      type: 'radio',
      field: 'autoplay',
      label: '自动切换',
      initval: wrap.autoplay || 'false',
      required: false,
      options: [
        {value: 'false', label: '否'},
        {value: 'true', label: '是'},
        {value: 'true', label: '是'}
      ],
      controlFields: [
        {field: 'speed', values: ['true']}
      ]
    },
    {
@@ -67,7 +133,7 @@
      field: 'speed',
      label: '时间间隔',
      initval: wrap.speed || 3,
      tooltip: '使用自动切换时有效,默认为3秒',
      tooltip: '默认为3秒',
      min: 1,
      max: 100,
      precision: 0,
src/menu/components/carousel/prop-card/index.jsx
@@ -1,12 +1,12 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, Modal, notification, Carousel } from 'antd'
import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import { Popover, Modal, Carousel } from 'antd'
import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, ClockCircleOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle } from '@/utils/utils-custom.js'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import Utils from '@/utils/utils.js'
import getWrapForm from '../data-card/options'
@@ -14,10 +14,11 @@
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const CardSimpleComponent = asyncComponent(() => import('@/menu/components/card/cardsimplecomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent'))
const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
const { confirm } = Modal
@@ -30,7 +31,6 @@
  }
  state = {
    appType: sessionStorage.getItem('appType'),
    card: null,
    back: false
  }
@@ -42,18 +42,15 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: 'object',   // 组件属性 - 数据格式
        pageable: false,    // 组件属性 - 是否可分页
        switchable: false,  // 组件属性 - 数据是否可切换
        dataName: card.dataName || '',
        width: card.width || 24,
        name: card.name,
        subtype: card.subtype,
        setting: { },
        wrap: { name: card.name, width: card.width || 24, datatype: 'static', autoplay: 'false', dots: 'true' },
        style: { borderWidth: '1px', borderColor: '#e8e8e8', marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px', height: '300px' },
        wrap: { name: card.name, width: card.width || 24, datatype: 'static', autoplay: 'false', dots: 'true', height: '300px' },
        style: { borderWidth: '1px', borderColor: '#e8e8e8', marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px' },
        columns: [],
        scripts: [],
        subcards: [{
@@ -61,8 +58,7 @@
          setting: {},
          style: {},
          elements: [],
        }],
        btnlog: [],
        }]
      }
      if (card.config) {
@@ -85,21 +81,20 @@
          return scard
        })
      }
      this.updateComponent(_card)
    } else {
      let _card = fromJS(card).toJS()
      if (!_card.wrap.height && _card.style.height) { // 兼容
        _card.wrap.height = _card.style.height
      }
      delete _card.style.height
      this.setState({
        card: _card
      })
      this.props.updateConfig(_card)
    } else {
      this.setState({
        card: fromJS(card).toJS()
      })
    }
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('logButton', this.logButton)
    MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -113,54 +108,84 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('logButton', this.logButton)
    MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle)
  }
  updateComponentStyle = (parentId, keys, style) => {
    const { card } = this.state
    if (card.uuid !== parentId) return
    let subcards = card.subcards.map(item => {
      if (keys.includes(item.uuid)) {
        item.style = {...item.style, ...style}
      }
      return item
    })
    this.setState({card: {...card, subcards: []}}, () => {
      this.updateComponent({...card, subcards: subcards})
    })
  }
  logButton = (id, item) => {
    const { card } = this.state
    if (id !== card.uuid) return
    let btnlog = card.btnlog || []
    btnlog.push(item)
    this.setState({
      card: {...card, btnlog}
    })
    this.props.updateConfig({...card, btnlog})
  }
  /**
   * @description 卡片行外层信息更新(数据源,样式等)
   */
  updateComponent = (component) => {
  updateComponent = (card) => {
    card.width = card.wrap.width
    card.name = card.wrap.name
    if (window.GLOB.styling && card.errors) { // 样式修改时不做筛查
      this.setState({
        card: card
      })
      this.props.updateConfig(card)
      return
    }
    card.errors = []
    if (card.subcards.length === 0) {
      card.errors.push({ level: 0, detail: '卡片不可为空!'})
    }
    if (card.wrap.datatype === 'static') {
      card.$tables = getTables(card)
      card.subcards.forEach(item => {
        item.elements.forEach(cell => {
          if (cell.eleType === 'button') {
            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
              if (!cell.modal || cell.modal.fields.length === 0) {
                card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
              }
            }
          } else if (cell.datatype === 'dynamic' && cell.field) {
            card.errors.push({ level: 1, detail: `卡片中动态字段“${cell.field}”无效`})
          }
        })
      })
    } else {
      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: '未设置上级组件!'})
      }
      if (card.errors.length === 0) {
        card.$tables = getTables(card)
      }
      card.subcards.forEach((item, i) => {
        item.elements.forEach(cell => {
          if (cell.eleType === 'button') {
            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
              if (!cell.modal || cell.modal.fields.length === 0) {
                card.errors.push({ level: 1, detail: `按钮“${cell.label}”中表单尚未添加`})
              }
            }
          } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
            card.errors.push({ level: 1, detail: `卡片中动态字段“${cell.field}”无效`})
          }
        })
      })
    }
    this.setState({
      card: component
      card: card
    })
    component.width = component.wrap.width
    component.name = component.wrap.name
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  /**
@@ -174,16 +199,13 @@
      return item
    })
    this.setState({card})
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  /**
   * @description 单个卡片信息更新
   */
  deleteCard = (cell) => {
    const { appType } = this.state
    let card = fromJS(this.state.card).toJS()
    let _this = this
@@ -192,26 +214,7 @@
      onOk() {
        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
        if (card.btnlog) {
          card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
        }
        _this.setState({card})
        _this.props.updateConfig(card)
        if (appType === 'mob') return
        let uuids = []
        cell.elements && cell.elements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
        _this.updateComponent(card)
      },
      onCancel() {}
    })
@@ -220,21 +223,13 @@
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
    if (comIds.length !== 1 || comIds[0] !== card.uuid) return
    let _card = {...card, style}
    this.setState({
      card: _card
    })
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    
    this.props.updateConfig(_card)
    this.updateComponent(_card)
  }
  addCard = () => {
@@ -257,54 +252,8 @@
    }
    card.subcards.push(newcard)
    this.setState({card})
    this.props.updateConfig(card)
  }
  handleLog = (type, logs, item) => {
    let card = fromJS(this.state.card).toJS()
    if (type === 'revert') {
      let done = false
      if (item.$parentId) {
        card.subcards.forEach(col => {
          if (item.$parentId === col.uuid) {
            col.elements = [...col.elements, item]
            done = true
          }
        })
      }
      card.btnlog = logs
      this.setState({ card: {...card, subcards: []} }, () => {
        this.setState({ card })
        this.props.updateConfig(card)
      })
      if (!done) {
        notification.warning({
          top: 92,
          message: '附属卡片已删除!',
          duration: 2
        })
      } else {
        notification.success({
          top: 92,
          message: '恢复成功!',
          duration: 2
        })
      }
    } else {
      card.btnlog = logs
      this.setState({ card })
      this.props.updateConfig(card)
      notification.success({
        top: 92,
        message: '清除成功!',
        duration: 2
      })
    }
    this.updateComponent(card)
  }
  move = (item, direction) => {
@@ -324,9 +273,8 @@
    card.subcards.splice(hoverIndex, 0, ...card.subcards.splice(dragIndex, 1))
    this.setState({card: {...card, subcards: []}}, () => {
      this.setState({card})
      this.updateComponent(card)
    })
    this.props.updateConfig(card)
  }
  getWrapForms = () => {
@@ -336,13 +284,25 @@
  }
  updateWrap = (res) => {
    this.updateComponent({...this.state.card, wrap: res})
    let _card = {...this.state.card, wrap: res}
    if (res.title && !_card.headerStyle) {
      _card.headerStyle = { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }
    }
    this.updateComponent(_card)
  }
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.setState({ card: _card })
        this.props.updateConfig(_card)
      })
    }
  }
@@ -352,6 +312,7 @@
    return (
      <div className="menu-prop-carousel-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <PlusOutlined className="plus" title="添加卡片" onClick={this.addCard}/>
@@ -361,18 +322,34 @@
            <CopyComponent type="propcard" card={card}/>
            <PasteComponent config={card} options={['cardcell']} updateConfig={this.updateComponent} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
            {card.wrap.datatype === 'dynamic' ? <ClockComponent config={card} updateConfig={this.updateComponent}/> : <ClockCircleOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/>}
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)} />
            {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
            {card.wrap.datatype === 'static' ? <SettingOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/> : null}
            {card.wrap.datatype === 'dynamic' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : <SettingOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/>}
          </div>
        } trigger="hover">
          <ToolOutlined/>
        </Popover>
        {card.subcards.length > 0 ? <Carousel dotPosition={card.wrap.dotPosition || 'bottom'} effect={card.wrap.effect || 'scrollx'}>
          {card.subcards.map((subcard) => (<CardSimpleComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        </Carousel> : null}
        <div style={{height: card.wrap.height}}>
          {card.subcards.length > 0 ? <Carousel dotPosition={card.wrap.dotPosition || 'bottom'} effect={card.wrap.effect || 'scrollx'}>
            {card.subcards.map((subcard) => (<CardSimpleComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
          </Carousel> : null}
        </div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/carousel/prop-card/index.scss
@@ -48,6 +48,10 @@
    }
  }
  .ant-carousel {
    height: 100%;
    .slick-slider {
      height: 100%;
    }
    .slick-dots li button {
      background: #1890ff;
    }
@@ -61,24 +65,6 @@
    position: absolute;
    right: -30px;
    font-size: 16px;
  }
  .model-menu-action-list {
    line-height: 40px;
    .ant-row > .anticon-plus {
      position: absolute;
      right: -30px;
      font-size: 16px;
    }
  }
  .card-add-button {
    text-align: right;
    clear: left;
    .anticon-plus {
      font-size: 20px;
      color: #26C281;
      padding: 5px;
      margin-right: 10px;
    }
  }
}
.menu-prop-carousel-edit-box::after {
src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx
New file
@@ -0,0 +1,356 @@
/**
 * @description 获取图表视图配置表单
 * @param {object} card       // 图表对象
 */
export function getBaseForm (card, columns) {
  let appType = sessionStorage.getItem('appType')
  let roleList = sessionStorage.getItem('sysRoles')
  if (roleList) {
    try {
      roleList = JSON.parse(roleList)
    } catch (e) {
      roleList = []
    }
  } else {
    roleList = []
  }
  let menulist = []
  if (appType === 'pc') {
    menulist = sessionStorage.getItem('appMenus')
    if (menulist) {
      try {
        menulist = JSON.parse(menulist)
      } catch (e) {
        menulist = []
      }
    } else {
      menulist = []
    }
  } else if (appType === '') {
    menulist = sessionStorage.getItem('fstMenuList')
    if (menulist) {
      try {
        menulist = JSON.parse(menulist)
      } catch (e) {
        menulist = []
      }
    } else {
      menulist = []
    }
  }
  return [
    {
      type: 'text',
      field: 'title',
      label: '标题',
      initval: card.title,
      required: false
    },
    {
      type: 'text',
      field: 'name',
      label: '组件名称',
      initval: card.name,
      tooltip: '用于组件间的区分。',
      required: true
    },
    {
      type: 'number',
      field: 'width',
      label: '宽度',
      initval: card.width,
      tooltip: '栅格布局,每行等分为24列。',
      min: 1,
      max: 24,
      decimal: 0,
      required: true
    },
    {
      type: 'styleInput',
      field: 'height',
      label: '图表高度',
      initval: card.height,
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'radio',
      field: 'permission',
      label: '权限验证',
      initval: card.permission || 'false',
      required: false,
      options: [
        {value: 'true', label: '启用'},
        {value: 'false', label: '禁用'},
      ],
      forbid: !appType
    },
    {
      type: 'multiselect',
      field: 'blacklist',
      label: '黑名单',
      initval: card.blacklist || [],
      required: false,
      options: roleList,
      forbid: !!appType
    },
    {
      type: 'radio',
      field: 'click',
      label: '点击事件',
      initval: card.click || '',
      tooltip: '点击节点时触发的事件。',
      required: false,
      options: [
        {value: '', label: '数据切换'},
        {value: 'menu', label: '菜单'},
        {value: 'menus', label: '菜单组'}
      ],
      controlFields: [
        {field: 'menu', values: ['menu']},
        {field: 'menus', values: ['menus']},
        {field: 'menuType', values: ['menus']},
        {field: 'open', values: ['menu', 'menus']},
        {field: 'joint', values: ['menu', 'menus']},
      ]
    },
    {
      type: appType === '' ? 'cascader' : 'select',
      field: 'menu',
      label: '关联菜单',
      initval: card.menu || (appType === '' ? [] : ''),
      required: true,
      extendName: 'MenuNo',
      options: menulist
    },
    {
      type: 'select',
      field: 'menuType',
      label: '菜单类型',
      initval: card.menuType || '',
      required: true,
      options: columns
    },
    {
      type: 'radio',
      field: 'open',
      label: '打开方式',
      initval: card.open || 'blank',
      required: false,
      options: [
        {value: 'blank', label: '新窗口'},
        {value: 'self', label: '当前窗口'},
      ],
      forbid: appType !== 'pc'
    },
    {
      type: 'radio',
      field: 'joint',
      label: '参数拼接',
      initval: card.joint || 'true',
      required: false,
      options: [
        {value: 'true', label: '是'},
        {value: 'false', label: '否'},
      ],
    },
    {
      type: 'table',
      field: 'menus',
      label: '菜单组',
      initval: card.menus || [],
      required: true,
      span: 24,
      actions: appType === 'pc' ? ['view'] : [],
      columns: [
        {
          title: '标识',
          dataIndex: 'sign',
          inputType: 'input',
          editable: true,
          unique: true,
          required: false,
          width: '35%'
        },
        {
          title: '菜单',
          dataIndex: 'menu',
          inputType: !appType ? 'cascader' : 'select',
          editable: true,
          required: true,
          extends: !appType ? 'Menu' : [{key: 'label', value: 'label'}],
          width: '35%',
          render: (text, record) => record.label,
          options: menulist
        }
      ]
    }
  ]
}
/**
 * @description 获取图表视图配置表单
 * @param {object} card       // 图表对象
 * @param {Array}  columns    // 显示列
 */
export function getOptionForm (card, columns) {
  return [
    {
      type: 'select',
      field: 'subtype',
      label: '类型',
      initval: card.subtype || 'mindmap',
      required: true,
      options: [{
        value: 'mindmap',
        label: '思维导图'
      }, {
        value: 'indentTree',
        label: '缩进文件树'
      }, {
        value: 'kapmap',
        label: '知识图谱树'
      }],
      controlFields: [
        {field: 'dirField', values: ['mindmap']},
        {field: 'nodeColor', values: ['mindmap']},
        {field: 'collapsed', values: ['indentTree', 'kapmap']},
      ]
    },
    {
      type: 'radio',
      field: 'rootType',
      label: '根节点取值',
      initval: card.rootType || 'fixed',
      tooltip: '选择上级时,请填写根节点的文本和值的字段名',
      required: true,
      options: [{
        value: 'fixed',
        label: '固定值'
      }, {
        value: 'supvalue',
        label: '上级组件'
      }, {
        value: 'line',
        label: '行'
      }],
      controlFields: [
        {field: 'rootLabel', values: ['fixed', 'supvalue']},
        {field: 'rootValue', values: ['fixed', 'supvalue']},
        {field: 'mark', values: ['line']},
      ]
    },
    {
      type: 'text',
      field: 'rootValue',
      label: '根节点值',
      initval: card.rootValue || '',
      required: true
    },
    {
      type: 'text',
      field: 'rootLabel',
      label: '根节点文本',
      initval: card.rootLabel || '',
      required: true
    },
    {
      type: 'select',
      field: 'valueField',
      label: '值字段',
      initval: card.valueField || '',
      required: true,
      options: columns
    },
    {
      type: 'select',
      field: 'labelField',
      label: '文本字段',
      initval: card.labelField || '',
      required: true,
      options: columns
    },
    {
      type: 'select',
      field: 'parentField',
      label: '上级字段',
      initval: card.parentField || '',
      required: true,
      options: columns
    },
    {
      type: 'text',
      field: 'mark',
      label: '顶级标识',
      initval: card.mark || '',
      tooltip: '上级字段值与顶级标识相同时,视为根节点。',
      required: true
    },
    {
      type: 'select',
      field: 'dirField',
      label: '方向控制',
      initval: card.dirField || '',
      required: false,
      options: columns,
      controlFields: [
        {field: 'dirSign', notNull: true},
        {field: 'leftColor', notNull: true},
      ]
    },
    {
      type: 'text',
      field: 'dirSign',
      label: '左向标记',
      initval: card.dirSign || '',
      tooltip: '当节点值与标记相同时节点信息位于节点左侧,多个值请用逗号分隔。',
      required: false
    },
    {
      type: 'color',
      field: 'nodeColor',
      label: '节点颜色',
      initval: card.nodeColor || '#1890ff',
      tooltip: '右侧节点的标记颜色。',
      isHex: true,
      required: false
    },
    {
      type: 'color',
      field: 'leftColor',
      label: '左节点颜色',
      initval: card.leftColor || '#26C281',
      tooltip: '左侧节点的标记颜色。',
      isHex: true,
      required: false
    },
    {
      type: 'radio',
      field: 'empty',
      label: '空值隐藏',
      initval: card.empty || 'show',
      tooltip: '当查询数据为空时,隐藏该组件。',
      required: false,
      options: [
        {value: 'show', label: '否'},
        {value: 'hidden', label: '是'},
      ],
    },
    {
      type: 'radio',
      field: 'collapsed',
      label: '节点合并',
      initval: card.collapsed || 'false',
      tooltip: '一级节点是否合并。',
      required: false,
      options: [
        {value: 'false', label: '否'},
        {value: 'true', label: '是'},
      ],
    },
  ]
}
src/menu/components/chart/antv-G6/chartcompile/index.jsx
New file
@@ -0,0 +1,179 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Modal, Form, Tabs } from 'antd'
import { EditOutlined } from '@ant-design/icons'
import { getBaseForm, getOptionForm } from './formconfig'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
const { TabPane } = Tabs
const NormalForm = asyncComponent(() => import('@/components/normalform/modalform'))
class LineChartDrawerForm extends Component {
  static propTpyes = {
    plot: PropTypes.object,
    config: PropTypes.object,
    plotchange: PropTypes.func
  }
  state = {
    view: 'normal',
    visible: false,
    plot: null,
    formlist: null,
    baseFormlist: null
  }
  showDrawer = () => {
    const { config } = this.props
    this.setState({
      visible: true,
      view: 'normal',
      plot: fromJS(config.plot).toJS(),
      baseFormlist: getBaseForm(config.plot, config.columns),
      formlist: getOptionForm(config.plot, config.columns)
    })
  }
  onSubmit = () => {
    const { config } = this.props
    const { plot, view } = this.state
    if (view === 'normal') {
      this.norRef.handleConfirm().then(res => {
        let _plot = {...plot, ...res}
        if (_plot.click !== 'menus') {
          delete _plot.menus
        }
        if (_plot.click !== 'menu') {
          delete _plot.menu
          delete _plot.MenuID
          delete _plot.MenuName
          delete _plot.MenuNo
          delete _plot.tabType
        } else if (sessionStorage.getItem('appType') === '' && _plot.menu) {
          let list = null
          try {
            list = JSON.parse(sessionStorage.getItem('thdMenuList')) || []
          } catch (e) {
            list = []
          }
          let id = _plot.menu[_plot.menu.length - 1]
          list.forEach(item => {
            if (item.MenuID === id) {
              _plot.MenuID = id
              _plot.MenuName = item.MenuName
              _plot.MenuNo = item.MenuNo
              _plot.tabType = item.type
            }
          })
        }
        this.setState({
          plot: _plot,
          visible: false
        })
        this.props.plotchange({...config, plot: _plot})
      })
    } else if (view === 'base') {
      this.baseRef.handleConfirm().then(res => {
        let _plot = {...plot, ...res}
        if (_plot.click !== 'menus') {
          delete _plot.menus
        }
        if (_plot.click !== 'menu') {
          delete _plot.menu
          delete _plot.MenuID
          delete _plot.MenuName
          delete _plot.MenuNo
          delete _plot.tabType
        } else if (sessionStorage.getItem('appType') === '' && _plot.menu) {
          let list = null
          try {
            list = JSON.parse(sessionStorage.getItem('thdMenuList')) || []
          } catch (e) {
            list = []
          }
          let id = _plot.menu[_plot.menu.length - 1]
          list.forEach(item => {
            if (item.MenuID === id) {
              _plot.MenuID = id
              _plot.MenuName = item.MenuName
              _plot.MenuNo = item.MenuNo
              _plot.tabType = item.type
            }
          })
        }
        this.setState({
          plot: _plot,
          visible: false
        })
        this.props.plotchange({...config, plot: _plot})
      })
    }
  }
  changeTab = (tab) => {
    const { plot, view } = this.state
    if (view === 'normal') {
      this.norRef.handleConfirm().then(res => {
        this.setState({
          plot: {...plot, ...res},
          view: tab
        })
      })
    } else if (view === 'base') {
      this.baseRef.handleConfirm().then(res => {
        this.setState({
          plot: {...plot, ...res},
          view: tab
        })
      })
    }
  }
  render() {
    const { config } = this.props
    const { view, visible, baseFormlist, formlist } = this.state
    return (
      <div className="line-chart-drawer-form">
        <EditOutlined title="编辑" onClick={this.showDrawer} />
        <Modal
          wrapClassName="mk-pop-modal"
          visible={visible}
          width={850}
          maskClosable={false}
          onOk={this.onSubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          {config.name ? <div className="mk-com-name">{config.name} - 编辑</div> : null}
          <Tabs activeKey={view} onChange={this.changeTab}>
            <TabPane tab="组件设置" key="base">
              <NormalForm formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
            </TabPane>
            <TabPane tab="图表设置" key="normal">
              <NormalForm formlist={formlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.norRef = inst}/>
            </TabPane>
          </Tabs>
        </Modal>
      </div>
    );
  }
}
export default Form.create()(LineChartDrawerForm)
src/menu/components/chart/antv-G6/chartcompile/index.scss
New file
@@ -0,0 +1,6 @@
.line-chart-drawer-form {
  display: inline-block;
  > .anticon-edit {
    color: #1890ff;
  }
}
src/menu/components/chart/antv-G6/index.jsx
New file
@@ -0,0 +1,1461 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover } from 'antd'
import { ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import G6 from '@antv/g6'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
import './index.scss'
const { Util } = G6
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const ChartCompileForm = asyncIconComponent(() => import('./chartcompile'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
const MindData = [
  'Modeling Methods',
  [
    'Classification',
    ['Logistic regression', 'Linear discriminant analysis', 'Rules', 'Decision trees', 'Naive Bayes', 'K nearest neighbor', 'Probabilistic neural network', 'Support vector machine']
  ],
  [
    'Consensus',
    [
      'Models diversity',
      ['Different initializations', 'Different parameter choices', 'Different architectures', 'Different modeling methods', 'Different training sets', 'Different feature sets']
    ],
    [
      'Methods',
      ['Classifier selection', 'Classifier fusion']
    ],
    [
      'Common',
      ['Bagging', 'Boosting', 'AdaBoost']
    ]
  ],
  [
    'Regression',
    ['Multiple linear regression', 'Partial least squares', 'Multi-layer feedforward neural network', 'General regression neural network', 'Support vector regression']
  ]
]
const styles = {
  blue: '#1890ff',
  red: '#f5222d',
  orange_red: '#fa541c',
  orange: '#fa8c16',
  orange_yellow: '#faad14',
  yellow: '#fadb14',
  yellow_green: '#a0d911',
  green: '#52c41a',
  cyan: '#13c2c2',
  blue_purple: '#2f54eb',
  purple: '#722ed1',
  magenta: '#eb2f96',
  grass_green: '#aeb303',
  deep_red: '#c32539'
}
let systemColor = '#1890ff'
if (window.GLOB.style) {
  let type = window.GLOB.style.replace(/bg_black_style_|bg_white_style_/, '')
  systemColor = styles[type] || '#1890ff'
}
const COLORS = ['#5B8FF9', '#F6BD16', '#5AD8A6', '#945FB9', '#E86452', '#6DC8EC', '#FF99C3', '#1E9493', '#FF9845', '#5D7092']
// 思维导图
G6.registerNode(
  'dice-mind-map-root', {
    jsx: (cfg) => {
      const width = Util.getTextSize(cfg.label, 16)[0] + 24
      return `
        <group>
          <rect style={{width: ${width}, height: 42, stroke: ${systemColor}, radius: 4}} keyshape>
            <text style={{ fontSize: 16, marginLeft: 6, marginTop: 12 }}>${cfg.label}</text>
          </rect>
        </group>
      `
    },
    getAnchorPoints() {
      return [
        [0, 0.5],
        [1, 0.5]
      ]
    }
  },
  'single-node',
)
G6.registerNode(
  'dice-mind-map-sub', {
    jsx: (cfg) => {
      const width = Util.getTextSize(cfg.label, 14)[0] + 24
      return `
        <group>
          <rect style={{width: ${width}, height: 22, cursor: pointer}}>
            <text style={{ fontSize: 14, fill: ${cfg.selected ? systemColor : '#000000'}, marginLeft: 12, marginTop: 6, cursor: pointer }}>${cfg.label}</text>
          </rect>
          <rect style={{ fill: ${cfg.color}, width: ${width}, height: 2, x: 0, y: 22, cursor: pointer }} />
        </group>
      `
    },
    getAnchorPoints() {
      return [
        [0, 0.965],
        [1, 0.965]
      ]
    }
  },
  'single-node',
)
G6.registerNode(
  'dice-mind-map-leaf', {
    jsx: (cfg) => {
      const width = Util.getTextSize(cfg.label, 12)[0] + 24
      return `
        <group>
          <rect style={{width: ${width}, height: 26, fill: 'transparent', cursor: pointer }}>
            <text style={{ fontSize: 12, fill: ${cfg.selected ? systemColor : '#000000'}, marginLeft: 12, marginTop: 6, cursor: pointer }}>${cfg.label}</text>
          </rect>
          <rect style={{ fill: ${cfg.color}, width: ${width}, height: 2, x: 0, y: 32, cursor: pointer }} />
        </group>
      `
    },
    getAnchorPoints() {
      return [
        [0, 0.965],
        [1, 0.965]
      ]
    }
  },
  'single-node',
)
G6.registerBehavior('dice-mindmap', {
  getEvents() {
    return {
      'node:click': 'editNode',
      'canvas:click': 'onCanvasClick'
    }
  },
  editNode(evt) {
    const item = evt.item
    const model = item.get('model')
    this.graph.getNodes().forEach(node => {
      let _model = node.get('model')
      if (_model.selected) {
        _model.selected = false
        this.graph.updateItem(node, _model, false)
      }
    })
    model.selected = true
    this.graph.updateItem(item, model, false)
  },
  onCanvasClick(e) {
    this.graph.getNodes().forEach(node => {
      let _model = node.get('model')
      if (_model.selected) {
        _model.selected = false
        this.graph.updateItem(node, _model, false)
      }
    })
  }
})
G6.registerBehavior('scroll-canvas', {
  getEvents: function getEvents() {
    return {
      wheel: 'onWheel'
    }
  },
  onWheel: function onWheel(ev) {
    const { graph } = this
    if (!graph) {
      return
    }
    if (ev.ctrlKey) {
      const canvas = graph.get('canvas')
      const point = canvas.getPointByClient(ev.clientX, ev.clientY)
      let ratio = graph.getZoom()
      if (ev.wheelDelta > 0) {
        ratio += ratio * 0.05
      } else {
        ratio *= ratio * 0.05
      }
      graph.zoomTo(ratio, {
        x: point.x,
        y: point.y
      })
    } else {
      const x = ev.deltaX || ev.movementX
      const y = ev.deltaY || ev.movementY || (-ev.wheelDelta * 125) / 3
      graph.translate(-x, -y)
    }
    ev.preventDefault()
  }
})
const dataMapTransform = (data) => {
  const changeData = (d, level = 0, color) => {
    const data = { ...d }
    switch (level) {
      case 0:
        data.type = 'dice-mind-map-root'
        break
      case 1:
        data.type = 'dice-mind-map-sub'
        break
      default:
        data.type = 'dice-mind-map-leaf'
        break
    }
    if (color) {
      data.color = color
    }
    if (level === 1 && !d.direction) {
      data.direction = 'right'
    }
    if (d.children) {
      data.children = d.children.map((child) => changeData(child, level + 1, data.color))
    }
    return data
  }
  return changeData(data)
}
// 缩进文件树
G6.registerNode('indentedRoot', {
  draw(model, group) {
    const keyShape = group.addShape('rect', {
      attrs: {
        x: -46,
        y: -16,
        width: 92,
        height: 32,
        fill: systemColor,
        radius: 2,
        stroke: '#5B8FF9',
        lineWidth: 0
      },
      name: 'key-shape'
    })
    const text = group.addShape('text', {
      attrs: {
        text: model.label || 'root',
        fill: "#fff",
        fontSize: 12,
        x: 0,
        y: 0,
        textAlign: 'center',
        textBaseline: 'middle'
      },
      name: 'root-text-shape'
    })
    const textBBox = text.getBBox()
    const width = textBBox.width + 24
    const height = textBBox.height + 12
    keyShape.attr({
      x: -width / 2,
      y: -height / 2,
      width,
      height
    })
    return keyShape
  },
  getAnchorPoints() {
    return [
      [0.5, 1]
    ]
  },
  update: undefined
})
G6.registerNode('indentedNode', {
  addChildCount(group, tag, props) {
    const { collapsed, branchColor, count } = props
    let clickCircleY = 10
    // 子类数量 icon,绘制圆点在节点正下方
    if (tag) {
      const childCountGroup = group.addGroup({
        name: 'child-count-group'
      })
      childCountGroup.setMatrix([1, 0, 0, 0, 1, 0, 0, clickCircleY, 1])
      const countBackWidth = collapsed ? 26 : 12
      childCountGroup.addShape('rect', {
        attrs: {
          width: countBackWidth,
          height: 12,
          radius: 6,
          stroke: branchColor,
          lineWidth: 2,
          fill: collapsed ? branchColor : '#fff',
          x: -countBackWidth / 2,
          y: -6,
          cursor: 'pointer',
        },
        name: 'child-count-rect-shape'
      })
      const childCountText = childCountGroup.addShape('text', {
        attrs: {
          text: count,
          fill: '#fff',
          x: 0,
          y: 0,
          fontSize: 10,
          textAlign: 'center',
          textBaseline: 'middle',
          cursor: 'pointer',
        },
        name: 'child-count-text-shape'
      })
      const childHoverIcon = childCountGroup.addShape('path', {
        attrs: {
          stroke: '#fff',
          lineWidth: 1,
          cursor: 'pointer',
          path: [['M', -3, 2], ['L', 0, -2], ['L', 3, 2]]
        },
        name: 'child-count-expand-icon',
        capture: false
      })
      childHoverIcon.hide()
      // 连接 count 的线段
      const countLink = group.addShape('path', {
        attrs: {
          path: [['M', 0, 0], ['L', 0, 11]],
          stroke: branchColor,
          lineWidth: 2,
        },
        name: 'count-link'
      })
      countLink.toBack()
      if (collapsed) {
        childCountGroup.show()
        childCountText.show()
        countLink.show()
      }
      else {
        childCountGroup.hide()
        childCountText.hide()
        countLink.hide()
      }
      clickCircleY += 16
    }
  },
  addBottomLine(group, props) {
    const { x, width, stroke, lineWidth } = props
    return group.addShape('path', {
      attrs: {
        path: [
          ['M', x - 1, 0],
          ['L', width, 0],
        ],
        stroke,
        lineWidth,
      },
      name: 'node-path-shape'
    })
  },
  addName(group, props) {
    const { label, x = 0, y, fill } = props
    return group.addShape('text', {
      attrs: {
        text: label,
        x,
        y,
        textAlign: 'start',
        textBaseline: 'top',
        fill,
        fontSize: 14,
        fontFamily: 'PingFangSC-Regular',
        cursor: 'pointer',
      },
      name: 'not-root-text-shape'
    })
  },
  draw(model, group) {
    const { collapsed, depth, label, children, selected } = model
    // 是否为根节点
    const rootNode = depth === 0
    // 子节点数量
    const childCount = children ? children.length : 0
    let width = 0
    const height = 24
    const x = 0
    const y = -height / 2
    const borderRadius = 4
    // 名称文本
    const text = this.addName(group, { label, x, y })
    let textWidth = text.getBBox().width
    width = textWidth + 20
    const keyShapeAttrs = {
      x,
      y,
      width,
      height,
      radius: borderRadius,
      fill: undefined,
      stroke: undefined,
    }
    const keyShape = group.addShape('rect', {
      attrs: keyShapeAttrs,
      name: 'root-key-shape-rect-shape'
    })
    // 底部横线
    const bottomLine = this.addBottomLine(group, {
      stroke: model.branchColor || '#AAB7C4',
      lineWidth: 3,
      x,
      width
    })
    let nameColor = 'rgba(0, 0, 0, 0.85)'
    if (selected) {
      nameColor = systemColor
    }
    // 名称
    text.attr({
      y: y - 12,
      fill: nameColor
    })
    text.toFront()
    textWidth = text.getBBox().width
    if (bottomLine) bottomLine.toFront()
    this.addChildCount(group, childCount && !rootNode, {
      collapsed,
      branchColor: model.branchColor,
      count: childCount ? `${childCount}` : undefined
    })
    const bbox = group.getBBox()
    const backContainer = group.addShape('path', {
      attrs: {
        path: childCount ? [
          ['M', bbox.minX, bbox.minY],
          ['L', bbox.maxX, bbox.minY],
          ['L', bbox.maxX, bbox.maxY],
          ['L', bbox.minX + 20, bbox.maxY],
          ['L', bbox.minX + 20, bbox.maxY + 20],
          ['L', bbox.minX, bbox.maxY + 20],
          ['Z']
        ] : [
          ['M', bbox.minX, bbox.minY],
          ['L', bbox.maxX, bbox.minY],
          ['L', bbox.maxX, bbox.maxY],
          ['L', bbox.minX, bbox.maxY],
          ['Z']
        ],
        fill: '#fff',
        opacity: 0
      }
    })
    backContainer.toBack()
    return keyShape
  }
})
G6.registerEdge('indentedEdge', {
  afterDraw: (cfg, group) => {
    const sourceNode = cfg.sourceNode && cfg.sourceNode.getModel()
    const targetNode = cfg.targetNode && cfg.targetNode.getModel()
    const color = sourceNode.branchColor || targetNode.branchColor || cfg.color || '#000'
    const keyShape = group.get('children')[0]
    keyShape.attr({
      stroke: color,
      lineWidth: 3 // branchThick
    })
    group.toBack()
  },
  getControlPoints: (cfg) => {
    const startPoint = cfg.startPoint
    const endPoint = cfg.endPoint
    return [
      startPoint,
      {
        x: startPoint.x,
        y: endPoint.y,
      },
      endPoint
    ]
  },
  update: undefined
}, 'polyline')
G6.registerBehavior('wheel-scroll', {
  getDefaultCfg() {
    return {
      direction: 'y',
      zoomKey: 'ctrl',
      sensitivity: 3,
      scalableRange: -64
    }
  },
  getEvents() {
    return {
      wheel: 'onWheel'
    }
  },
  onWheel(ev) {
    const graph = this.graph
    let keyDown = ev[`${this.zoomKey}Key`]
    if (this.zoomKey === 'control') keyDown = ev.ctrlKey
    if (keyDown) {
      const sensitivity = this.get('sensitivity')
      const canvas = graph.get('canvas')
      const point = canvas.getPointByClient(ev.clientX, ev.clientY)
      let ratio = graph.getZoom()
      if (ev.wheelDelta > 0) {
        ratio *= (1 + 0.01 * sensitivity)
      } else {
        ratio *= (1 - 0.01 * sensitivity)
      }
      graph.zoomTo(ratio, {
        x: point.x,
        y: point.y
      })
      graph.emit('wheelzoom', ev)
    } else {
      let dx = ev.deltaX || ev.movementX
      let dy = ev.deltaY || ev.movementY
      if (!dy && navigator.userAgent.indexOf('Firefox') > -1) dy = (-ev.wheelDelta * 125) / 3
      const width = this.graph.get('width')
      const height = this.graph.get('height')
      const graphCanvasBBox = this.graph.get('group').getCanvasBBox()
      let expandWidth = this.scalableRange
      let expandHeight = this.scalableRange
      // 若 scalableRange 是 0~1 的小数,则作为比例考虑
      if (expandWidth < 1 && expandWidth > -1) {
        expandWidth = width * expandWidth
        expandHeight = height * expandHeight
      }
      const { minX, maxX, minY, maxY } = graphCanvasBBox
      if (dx > 0) {
        if (maxX < -expandWidth) {
          dx = 0
        } else if (maxX - dx < -expandWidth) {
          dx = maxX + expandWidth
        }
      } else if (dx < 0) {
        if (minX > width + expandWidth) {
          dx = 0
        } else if (minX - dx > width + expandWidth) {
          dx = minX - (width + expandWidth)
        }
      }
      if (dy > 0) {
        if (maxY < -expandHeight) {
          dy = 0
        } else if (maxY - dy < -expandHeight) {
          dy = maxY + expandHeight
        }
      } else if (dy < 0) {
        if (minY > height + expandHeight) {
          dy = 0
        } else if (minY - dy > height + expandHeight) {
          dy = minY - (height + expandHeight)
        }
      }
      if (this.get('direction') === 'x') {
        dy = 0
      } else if (this.get('direction') === 'y') {
        dx = 0
      }
      graph.translate(-dx, -dy)
    }
    ev.preventDefault()
  }
})
G6.registerBehavior('hover-node', {
  getEvents() {
    return {
      'node:mouseover': 'onNodeMouseOver',
      'node:mouseleave': 'onNodeMouseLeave',
      'node:mouseenter': 'onNodeMouseEnter'
    }
  },
  onNodeMouseEnter(ev) {
    const { item } = ev
    if (!item || item.get('destroyed')) return
    item.toFront()
    const model = item.getModel()
    const { collapsed, depth } = model
    const rootNode = depth === 0 || model.isRoot
    const group = item.getContainer()
    if (rootNode) return
    // 控制子节点个数标记
    if (!collapsed) {
      const childCountGroup = group.find(e => e.get('name') === 'child-count-group')
      if (childCountGroup) {
        childCountGroup.show()
      }
    }
  },
  onNodeMouseOver(ev) {
    const shape = ev.target
    // tooltip显示、隐藏
    this.graph.emit('tooltip: show', ev)
    // expand 状态下,若 hover 到子节点个数标记,填充背景+显示收起 icon
    const { item } = ev
    const group = item.getContainer()
    const model = item.getModel()
    if (!model.collapsed) {
      const childCountGroup = group.find(e => e.get('name') === 'child-count-group')
      if (childCountGroup) {
        childCountGroup.show()
        const back = childCountGroup.find(e => e.get('name') === 'child-count-rect-shape')
        const expandIcon = childCountGroup.find(e => e.get('name') === 'child-count-expand-icon')
        const rootNode = model.depth === 0 || model.isRoot
        const branchColor = rootNode ? '#576286' : model.branchColor
        if (shape.get('parent').get('name') === 'child-count-group') {
          if (back) {
            back.attr('fill', branchColor || '#fff')
          }
          if (expandIcon) {
            expandIcon.show()
          }
        } else {
          if (back) {
            back.attr('fill', '#fff')
          }
          if (expandIcon) {
            expandIcon.hide()
          }
        }
      }
    }
  },
  onNodeMouseLeave(ev) {
    const { item } = ev
    const model = item.getModel()
    const group = item.getContainer()
    const { collapsed } = model
    if (!collapsed) {
      const childCountGroup = group.find(e => e.get('name') === 'child-count-group')
      if (childCountGroup) {
        childCountGroup.hide()
      }
      const iconsLinkPath = group.find(e => e.get('name') === 'icons-link-path')
      if (iconsLinkPath) {
        iconsLinkPath.hide()
      }
    }
    this.graph.emit('tooltip: hide', ev)
  }
})
G6.registerBehavior('click-node', {
  getEvents() {
    return {
      'node:click': 'onNodeClick',
      'canvas:click': 'onCanvasClick'
    }
  },
  onNodeClick(e) {
    const { item, target } = e
    const shape = target
    const shapeName = shape.cfg.name
    let model = item.getModel()
    // 点击收起/展开 icon
    if (shapeName === 'child-count-rect-shape' || shapeName === 'child-count-text-shape') {
      const updatedCollapsed = !model.collapsed
      this.graph.updateItem(item, { collapsed: updatedCollapsed })
      this.graph.layout()
      return
    }
    // 选中节点
    this.graph.getNodes().forEach(node => {
      let _model = node.get('model')
      if (_model.selected) {
        _model.selected = false
        this.graph.updateItem(node, _model, false)
      }
    })
    model.selected = true
    this.graph.updateItem(item, model, false)
    return
  },
  onCanvasClick(e) {
    this.graph.getNodes().forEach(node => {
      let _model = node.get('model')
      if (_model.selected) {
        _model.selected = false
        this.graph.updateItem(node, _model, false)
      }
    })
  }
})
const dataIndTransform = (data) => {
  const changeData = (d) => {
    let data = { ...d }
    data.type = data.isRoot ? 'indentedRoot' : 'indentedNode'
    if (d.children) {
      data.children = d.children.map((child) => changeData(child))
    }
    // 给定 branchColor 和 0-2 层节点 depth
    if (data.children && data.children.length) {
      data.depth = 0
      data.children.forEach((subtree, i) => {
        subtree.branchColor = COLORS[i % COLORS.length]
        // dfs
        let currentDepth = 1
        subtree.depth = currentDepth
        Util.traverseTree(subtree, child => {
          child.branchColor = COLORS[i % COLORS.length]
          if (!child.depth) {
            child.depth = currentDepth + 1
          }
          else currentDepth = subtree.depth
          if (child.children) {
            child.children.forEach(subChild => {
              subChild.depth = child.depth + 1
            })
          }
          if (!data.isRoot) {
            child.collapsed = data.collapsed || false
          }
          return true
        })
      })
    }
    return data
  }
  return changeData(data)
}
// 知识图谱树
G6.registerNode('treeNode', {
  draw: (cfg, group) => {
    const { label, selected, children, isRoot } = cfg
    const rootNode = !!isRoot
    const hasChildren = children && children.length !== 0
    let width = 0
    const height = 28
    const x = 0
    const y = -height / 2
    // 名称文本
    const text = group.addShape('text', {
      attrs: {
        text: label,
        x: x * 2,
        y,
        textAlign: 'left',
        textBaseline: 'top',
        fontFamily: 'PingFangSC-Regular',
      },
      cursor: 'pointer',
      name: 'name-text-shape',
    })
    const textWidth = text.getBBox().width
    width = textWidth + 20
    width = width < 60 ? 60 : width
    if (!rootNode && hasChildren) {
      width += 22
    }
    const keyShapeAttrs = {
      x,
      y,
      width,
      height,
      radius: 4
    }
    const keyShape = group.addShape('rect', {
      attrs: keyShapeAttrs,
      name: 'root-key-shape-rect-shape'
    })
    if (!rootNode) {
      // 底部横线
      group.addShape('path', {
        attrs: {
          path: [
            ['M', x - 1, 0],
            ['L', width, 0],
          ],
          stroke: '#AAB7C4',
          lineWidth: 1,
        },
        name: 'node-path-shape'
      })
    }
    const mainX = x - 10
    const mainY = -height + 15
    if (rootNode) {
      group.addShape('rect', {
        attrs: {
          x: mainX,
          y: mainY,
          width: width + 12,
          height,
          radius: 14,
          fill: systemColor,
          cursor: 'pointer',
        },
        name: 'main-shape'
      })
    }
    let nameColor = 'rgba(0, 0, 0, 0.85)'
    if (selected) {
      nameColor = systemColor
    }
    // 名称
    if (rootNode) {
      group.addShape('text', {
        attrs: {
          text: label,
          x: mainX + 18,
          y: 1,
          textAlign: 'left',
          textBaseline: 'middle',
          fill: '#ffffff',
          fontSize: 12,
          fontFamily: 'PingFangSC-Regular',
          cursor: 'pointer',
        },
        name: 'root-text-shape'
      })
    } else {
      group.addShape('text', {
        attrs: {
          text: label,
          x: mainX + 6,
          y: y - 5,
          textAlign: 'start',
          textBaseline: 'top',
          fill: nameColor,
          fontSize: 12,
          fontFamily: 'PingFangSC-Regular',
          cursor: 'pointer',
        },
        name: 'not-root-text-shape'
      })
    }
    // 子类数量
    if (hasChildren && !rootNode) {
      const childCountHeight = 12
      const childCountX = width - 22
      const childCountY = -childCountHeight / 2
      group.addShape('rect', {
        attrs: {
          width: 22,
          height: 12,
          stroke: systemColor,
          fill: '#fff',
          x: childCountX,
          y: childCountY,
          radius: 6,
          cursor: 'pointer',
        },
        name: 'child-count-rect-shape',
      })
      group.addShape('text', {
        attrs: {
          text: `${children.length}`,
          fill: 'rgba(0, 0, 0, .65)',
          x: childCountX + 11,
          y: childCountY + 12,
          fontSize: 10,
          width: 22,
          textAlign: 'center',
          cursor: 'pointer',
        },
        name: 'child-count-text-shape'
      })
    }
    return keyShape
  }
})
G6.registerEdge('smooth', {
  draw(cfg, group) {
    const { startPoint, endPoint } = cfg
    const hgap = Math.abs(endPoint.x - startPoint.x)
    const path = [
      ['M', startPoint.x, startPoint.y],
      [
        'C',
        startPoint.x + hgap / 4,
        startPoint.y,
        endPoint.x - hgap / 2,
        endPoint.y,
        endPoint.x,
        endPoint.y,
      ],
    ]
    const shape = group.addShape('path', {
      attrs: {
        stroke: '#AAB7C4',
        path,
      },
      name: 'smooth-path-shape',
    })
    return shape
  },
})
G6.registerBehavior('click-item', {
  getEvents() {
    return {
      'node:click': 'onNodeClick',
      'canvas:click': 'onCanvasClick'
    }
  },
  onNodeClick(e) {
    const { item } = e
    let model = item.getModel()
    if (model.children) return
    // 选中节点
    this.graph.getNodes().forEach(node => {
      let _model = node.get('model')
      if (_model.selected) {
        _model.selected = false
        this.graph.updateItem(node, _model, false)
      }
    })
    model.selected = true
    this.graph.updateItem(item, model, false)
    return
  },
  onCanvasClick(e) {
    this.graph.getNodes().forEach(node => {
      let _model = node.get('model')
      if (_model.selected) {
        _model.selected = false
        this.graph.updateItem(node, _model, false)
      }
    })
  }
})
class antvG6Chart extends Component {
  static propTpyes = {
    card: PropTypes.object,
    updateConfig: PropTypes.func,
    deletecomponent: PropTypes.func,
  }
  state = {
    card: null,
    eventListener: null
  }
  UNSAFE_componentWillMount () {
    const { card } = this.props
    if (card.isNew) {
      let _plot = {
        width: card.width || 24,
        height: 400,
        subtype: card.subtype,
        name: card.name
      }
      let _card = {
        uuid: card.uuid,
        type: card.type,
        format: 'array',   // 组件属性 - 数据格式
        pageable: false,   // 组件属性 - 是否可分页
        switchable: true,  // 组件属性 - 数据是否可切换
        width: _plot.width,
        name: _plot.name,
        subtype: card.subtype,
        setting: { interType: 'system' },
        style: {
          borderWidth: '1px', borderColor: 'rgb(217, 217, 217)',
          marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px'
        },
        headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
        columns: [],
        scripts: [],
        search: [],
        action: [],
        plot: _plot,
      }
      if (card.config) {
        let config = fromJS(card.config).toJS()
        _card.plot = config.plot
        _card.plot.name = card.name
        _card.style = config.style
        _card.headerStyle = config.headerStyle
        _card.setting = config.setting
        _card.columns = config.columns
        _card.scripts = config.scripts
      }
      this.updateComponent(_card)
    } else {
      this.setState({
        card: fromJS(card).toJS()
      })
    }
  }
  componentDidMount () {
    MKEmitter.addListener('tabsChange', this.handleTabsChange)
    setTimeout(() => {
      this.viewrender()
    }, 1000)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('tabsChange', this.handleTabsChange)
  }
  handleTabsChange = (parentId) => {
    const { card } = this.state
    if (parentId.indexOf(card.uuid) > -1 || parentId === 'all') {
      let _element = document.getElementById(card.uuid + 'canvas')
      if (_element) {
        _element.innerHTML = ''
      }
      this.$timer && clearTimeout(this.$timer)
      this.$timer = setTimeout(this.viewrender, 100)
    }
  }
  getdata = () => {
    const { card } = this.state
    const setData = (list) => {
      let item = {
        label: list[0],
        id: list[0],
        children: []
      }
      if (!list[1]) {
        delete item.children
        return item
      } else if (!Array.isArray(list[1])) {
        return list.map(m => ({label: m, id: m}))
      }
      for (let i = 1; i < list.length; i++) {
        let cell = setData(list[i])
        if (Array.isArray(cell)) {
          item.children.push(...cell)
        } else {
          item.children.push(cell)
        }
      }
      return item
    }
    let data = setData(MindData)
    if (card.plot.subtype === 'mindmap') {
      if (card.plot.dirField) {
        data.children[0].direction = 'left'
        data.children[2].direction = 'left'
      }
      data.children.forEach(item => {
        if (item.direction === 'left') {
          item.color = card.plot.leftColor || '#26C281'
        } else {
          item.color = card.plot.nodeColor || '#1890ff'
        }
      })
    } else if (card.plot.subtype === 'indentTree') {
      data.isRoot = true
      data.collapsed = false
      data.children.forEach(item => {
        item.collapsed = card.plot.collapsed === 'true'
      })
    } else if (card.plot.subtype === 'kapmap') {
      data.isRoot = true
      data.collapsed = false
      if (card.plot.collapsed === 'true') {
        const collapse = (item) => {
          if (!item.children) return
          item.children.forEach(cell => {
            cell.collapsed = true
            collapse(cell)
          })
        }
        collapse(data)
      }
    }
    return data
  }
  viewrender = () => {
    const { card } = this.state
    if (card.plot.subtype === 'mindmap') {
      this.ponitrender()
    } else if (card.plot.subtype === 'indentTree') {
      this.indentrender()
    } else if (card.plot.subtype === 'kapmap') {
      this.kapmaprender()
    }
  }
  kapmaprender = () => {
    const { card } = this.state
    const plot = card.plot
    const data = this.getdata()
    const graph = new G6.TreeGraph({
      container: card.uuid + 'canvas',
      width: this.wrap.scrollWidth - 30,
      height: getHeight(plot.height),
      modes: {
        default: [
          {
            type: 'collapse-expand',
          },
          'drag-canvas',
          'zoom-canvas',
          'click-item'
        ],
      },
      defaultNode: {
        type: 'treeNode',
        anchorPoints: [
          [0, 0.5],
          [1, 0.5],
        ],
      },
      defaultEdge: {
        type: 'smooth',
      },
      layout: {
        type: 'compactBox',
        direction: 'LR',
        getId: function getId(d) {
          return d.id
        },
        getHeight: function getHeight() {
          return 16
        },
        getWidth: function getWidth(d) {
          const labelWidth = G6.Util.getTextSize(d.label, 12)[0]
          const width = 60 + labelWidth
          return width
        },
        getVGap: function getVGap() {
          return 15
        },
        getHGap: function getHGap() {
          return 30
        }
      }
    })
    graph.data(data)
    graph.render()
    graph.fitView()
  }
  indentrender = () => {
    const { card } = this.state
    const plot = card.plot
    const data = this.getdata()
    const tree = new G6.TreeGraph({
      container: card.uuid + 'canvas',
      width: this.wrap.scrollWidth - 30,
      height: getHeight(plot.height),
      layout: {
        type: 'indented',
        direction: 'LR',
        isHorizontal: true,
        indent: 40,
        getHeight: (d) => {
          if (d.isRoot) {
            return 30
          }
          if (d.collapsed && d.children && d.children.length) {
            return 36
          }
          return 22
        },
        getVGap: () => {
          return 10
        },
      },
      defaultEdge: {
        type: 'indentedEdge',
        style: {
          lineWidth: 2,
          radius: 16
        }
      },
      minZoom: 0.5,
      modes: {
        default: [
          'drag-canvas',
          'wheel-scroll',
          'hover-node',
          'click-node'
        ]
      }
    })
    tree.on('afterrender', e => {
      tree.getEdges().forEach(edge => {
        const targetNode = edge.getTarget().getModel()
        const color = targetNode.branchColor
        tree.updateItem(edge, { color })
      })
      setTimeout(() => {
        tree.moveTo(32, 32)
        tree.zoomTo(0.7)
      }, 16)
    })
    tree.data(dataIndTransform(data))
    tree.render()
  }
  /**
   * @description 散点图
   */
  ponitrender = () => {
    const { card } = this.state
    const plot = card.plot
    const data = this.getdata()
    const tree = new G6.TreeGraph({
      container: card.uuid + 'canvas',
      width: this.wrap.scrollWidth - 30,
      height: getHeight(plot.height),
      fitView: true,
      layout: {
        type: 'mindmap',
        direction: 'H',
        getHeight: () => {
          return 16
        },
        getWidth: (node) => {
          return node.level === 0 ?
            Util.getTextSize(node.label, 16)[0] + 12 :
            Util.getTextSize(node.label, 12)[0]
        },
        getVGap: () => {
          return 10
        },
        getHGap: () => {
          return 60
        },
        getSide: (node) => {
          return node.data.direction
        }
      },
      defaultEdge: {
        type: 'cubic-horizontal',
        style: {
          lineWidth: 2
        }
      },
      minZoom: 0.5,
      modes: {
        default: ['drag-canvas', 'zoom-canvas', 'dice-mindmap']
      }
    })
    tree.data(dataMapTransform(data))
    tree.render()
  }
  updateComponent = (card) => {
    if (this.state.card && (!is(fromJS(card.plot), fromJS(this.state.card.plot)) || !is(fromJS(card.style), fromJS(this.state.card.style)))) {
      let _element = document.getElementById(card.uuid + 'canvas')
      if (_element) {
        _element.innerHTML = ''
      }
      this.$timer && clearTimeout(this.$timer)
      this.$timer = setTimeout(() => {
        this.viewrender()
      }, 150)
    }
    card.width = card.plot.width
    card.name = card.plot.name
    card.subtype = card.plot.subtype
    card.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: '未设置上级组件!'})
    }
    if (card.errors.length === 0) {
      card.$tables = getTables(card)
    }
    if (!card.plot.valueField) {
      card.errors.push({ level: 0, detail: '图表信息尚未设置!'})
    }
    this.setState({
      card: card
    })
    this.props.updateConfig(card)
  }
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    this.updateComponent(_card)
  }
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.updateComponent(_card)
      })
    }
  }
  render() {
    const { card } = this.state
    let _style = resetStyle(card.style)
    return (
      <div className="menu-scatter-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <ChartCompileForm config={card} plotchange={this.updateComponent}/>
            <CopyComponent type="antvG6" card={card}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(card.uuid)}/>
            <SettingComponent config={card} updateConfig={this.updateComponent}/>
          </div>
        } trigger="hover">
          <ToolOutlined/>
        </Popover>
        <NormalHeader config={card} updateComponent={this.updateComponent}/>
        <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
}
export default antvG6Chart
src/menu/components/chart/antv-G6/index.scss
New file
@@ -0,0 +1,68 @@
.menu-scatter-chart-edit-box {
  position: relative;
  box-sizing: border-box;
  background: #ffffff;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  .canvas {
    margin: 0px;
    padding: 15px;
    letter-spacing: 0px;
  }
  .chart-header {
    position: relative;
    height: 45px;
    border-bottom: 1px solid #e8e8e8;
    overflow: hidden;
    padding-right: 35px;
    .chart-title {
      text-decoration: inherit;
      font-weight: inherit;
      font-style: inherit;
      float: left;
      line-height: 45px;
      margin-left: 10px;
      position: relative;
      z-index: 1;
    }
  }
  >.anticon-tool {
    position: absolute;
    right: 1px;
    top: 1px;
    z-index: 3;
    font-size: 16px;
    padding: 5px;
    cursor: pointer;
    color: rgba(0, 0, 0, 0.85);
    background: rgba(255, 255, 255, 0.55);
  }
  .model-menu-action-list {
    position: absolute;
    right: 0px;
    top: 30px;
    z-index: 4;
    font-size: 16px;
    .ant-row .anticon-plus {
      float: right;
    }
    .page-card {
      float: right;
    }
  }
  .normal-header + .canvas + .model-menu-action-list {
    top: 45px;
  }
}
.menu-scatter-chart-edit-box:hover {
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -1,13 +1,8 @@
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
/**
 * @description 获取图表视图配置表单
 * @param {object} card       // 图表对象
 */
export function getBaseForm (card) {
export function getBaseForm (card, columns = []) {
  let appType = sessionStorage.getItem('appType')
  let roleList = sessionStorage.getItem('sysRoles')
  if (roleList) {
@@ -18,6 +13,32 @@
    }
  } else {
    roleList = []
  }
  let menulist = []
  if (appType === 'pc') {
    menulist = sessionStorage.getItem('appMenus')
    if (menulist) {
      try {
        menulist = JSON.parse(menulist)
      } catch (e) {
        menulist = []
      }
    } else {
      menulist = []
    }
  } else if (appType === '') {
    menulist = sessionStorage.getItem('fstMenuList')
    if (menulist) {
      try {
        menulist = JSON.parse(menulist)
      } catch (e) {
        menulist = []
      }
    } else {
      menulist = []
    }
  }
  return [
@@ -48,14 +69,13 @@
      required: true
    },
    {
      type: 'number',
      type: 'styleInput',
      key: 'height',
      label: '高度',
      label: '图表高度',
      initVal: card.height,
      min: 100,
      max: 1000,
      decimal: 0,
      required: true
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'radio',
@@ -79,38 +99,100 @@
      options: roleList,
      forbid: !!appType
    },
    // {
    //   type: 'cascader',
    //   key: 'linkmenu',
    //   label: '关联菜单',
    //   initVal: card.linkmenu || [],
    //   tooltip: '在使用柱形图且未启用自定义设置时有效。',
    //   required: false,
    //   forbid: appType === 'pc' || appType === 'mob',
    //   options: menulist
    // },
    // {
    //   type: 'select',
    //   key: 'linkmenu',
    //   label: '关联菜单',
    //   initVal: card.linkmenu || '',
    //   tooltip: '双击柱状图,会打开关联的菜单。',
    //   required: false,
    //   forbid: appType !== 'pc',
    //   options: menulist
    // },
    // {
    //   type: 'radio',
    //   key: 'open',
    //   label: '打开方式',
    //   initVal: card.open || 'blank',
    //   required: false,
    //   forbid: appType !== 'pc',
    //   options: [
    //     { value: 'blank', text: '新窗口' },
    //     { value: 'self', text: '当前窗口' }
    //   ]
    // }
    {
      type: 'radio',
      key: 'click',
      label: '点击事件',
      initVal: card.click || '',
      tooltip: '点击柱子时触发的事件,启用自定义设置时无效。',
      required: false,
      forbid: appType === 'mob' || card.chartType !== 'bar',
      options: [
        {value: '', label: '数据切换'},
        {value: 'menu', label: '菜单'},
        {value: 'menus', label: '菜单组'}
      ]
    },
    {
      type: appType === '' ? 'cascader' : 'select',
      key: 'menu',
      label: '关联菜单',
      initVal: card.menu || (appType === '' ? [] : ''),
      tooltip: '在使用柱形图且未启用自定义设置时有效。',
      required: true,
      forbid: appType === 'mob' || card.chartType !== 'bar',
      hidden: card.click !== 'menu',
      options: menulist
    },
    {
      type: 'select',
      key: 'menuType',
      label: '菜单类型',
      initVal: card.menuType || '',
      required: true,
      forbid: appType === 'mob' || card.chartType !== 'bar',
      hidden: card.click !== 'menus',
      options: columns,
    },
    {
      type: 'radio',
      key: 'open',
      label: '打开方式',
      initVal: card.open || 'blank',
      required: false,
      options: [
        {value: 'blank', label: '新窗口'},
        {value: 'self', label: '当前窗口'},
      ],
      forbid: appType !== 'pc' || card.chartType !== 'bar',
      hidden: card.click !== 'menu' && card.click !== 'menus'
    },
    {
      type: 'radio',
      key: 'joint',
      label: '参数拼接',
      initVal: card.joint || 'true',
      required: false,
      options: [
        {value: 'true', label: '是'},
        {value: 'false', label: '否'},
      ],
      forbid: appType === 'mob' || card.chartType !== 'bar',
      hidden: card.click !== 'menu' && card.click !== 'menus'
    },
    {
      type: 'table',
      key: 'menus',
      label: '菜单组',
      initVal: card.menus || [],
      required: true,
      span: 24,
      actions: ['view'],
      forbid: appType === 'mob' || card.chartType !== 'bar',
      hidden: card.click !== 'menus',
      columns: [
        {
          title: '标识',
          dataIndex: 'sign',
          inputType: 'input',
          editable: true,
          unique: true,
          required: false,
          width: '35%'
        },
        {
          title: '菜单',
          dataIndex: 'menu',
          inputType: !appType ? 'cascader' : 'select',
          editable: true,
          required: true,
          extends: !appType ? 'Menu' : [{key: 'label', value: 'label'}],
          width: '35%',
          render: (text, record) => record.label,
          options: menulist
        }
      ]
    }
  ]
}
@@ -125,23 +207,23 @@
  if (card.chartType === 'line') {
    shapes = [
      { field: 'smooth', label: 'smooth' },
      { field: 'line', label: 'line' },
      { field: 'dot', label: 'dot' },
      { field: 'dash', label: 'dash' },
      { field: 'hv', label: 'hv' },
      { field: 'vh', label: 'vh' },
      { field: 'hvh', label: 'hvh' },
      { field: 'vhv', label: 'vhv' }
      { field: 'smooth', label: 'smooth(平滑线)' },
      { field: 'line', label: 'line(直线)' },
      { field: 'dot', label: 'dot(点状线)' },
      { field: 'dash', label: 'dash(虚线)' },
      { field: 'hv', label: 'hv(水平-垂直线)' },
      { field: 'vh', label: 'vh(垂直-水平线)' },
      { field: 'hvh', label: 'hvh(水平-垂直-水平线)' },
      { field: 'vhv', label: 'vhv(垂直-水平-垂直线)' }
    ]
  } else if (card.chartType === 'bar') {
    shapes = [
      { field: 'rect', label: 'rect' },
      { field: 'hollow-rect', label: 'hollow-rect' },
      { field: 'line', label: 'line' },
      { field: 'tick', label: 'tick' },
      { field: 'funnel', label: 'funnel' },
      { field: 'pyramid', label: 'pyramid' }
      { field: 'rect', label: 'rect(矩形)' },
      { field: 'hollow-rect', label: 'hollow-rect(空心矩形)' },
      { field: 'line', label: 'line(线条)' },
      { field: 'tick', label: 'tick(波动)' },
      // { field: 'funnel', label: 'funnel' },
      { field: 'pyramid', label: 'pyramid(角锥)' }
    ]
  }
@@ -169,6 +251,8 @@
      text: '底部'
    }])
  }
  let _label = card.label || 'false'
  return [
    {
@@ -278,16 +362,17 @@
      required: false,
      options: [{
        value: 'true',
        text: Formdict['model.true']
        text: '是'
      }, {
        value: 'false',
        text: Formdict['model.false']
        text: '否'
      }]
    }, {
      type: 'radio',
      key: 'show',
      label: '显示',
      initVal: card.show || 'value',
      tooltip: '当使用自定义设置时,可在显示(值/%)处单独设置显示类型。注:自定义为空时使用此处设置。',
      required: false,
      options: [{
        value: 'value',
@@ -299,17 +384,19 @@
    }, {
      type: labelOptions.length > 20 ? 'select' : 'radio',
      key: 'label',
      label: '标签',
      initVal: card.label || 'false',
      label: '标注',
      initVal: _label,
      tooltip: '图形节点处的数值。',
      required: false,
      options: labelOptions
    }, {
      type: 'radio',
      key: 'labelColor',
      label: '标签颜色',
      label: '标注颜色',
      initVal: card.labelColor || 'system',
      tooltip: '使用系统色时,使用色系选项设置的系统颜色,使用自定义为颜色设置中定义的图形颜色。',
      required: false,
      hidden: _label !== 'true',
      options: [{
        value: 'system',
        text: '系统'
@@ -317,20 +404,21 @@
        value: 'custom',
        text: '自定义'
      }]
    // }, {
    //   type: 'radio',
    //   key: 'offset',
    //   label: '标注位置',
    //   initVal: card.offset || 'outer',
    //   required: false,
    //   options: [{
    //     value: 'outer',
    //     text: '外部'
    //   }, {
    //     value: 'inner',
    //     text: '内部'
    //   }],
    //   forbid: card.chartType !== 'bar'
    }, {
      type: 'radio',
      key: 'labelValue',
      label: '标注值',
      initVal: card.labelValue || 'default',
      tooltip: '标注值的显示规则。',
      required: false,
      hidden: _label === 'false',
      options: [{
        value: 'default',
        text: '默认'
      }, {
        value: 'zero',
        text: '隐藏 0 值'
      }],
    }, {
      type: 'radio',
      key: 'adjust',
@@ -478,6 +566,15 @@
      initVal: card.max,
      required: false
    }, {
      type: 'number',
      key: 'XLimit',
      min: 2,
      label: '字符限制',
      tooltip: 'X轴最大字符限制。',
      initVal: card.XLimit || 11,
      forbid: appType === 'mob',
      required: false
    }, {
      type: 'color',
      key: 'color',
      label: '色系',
src/menu/components/chart/antv-bar/chartcompile/index.jsx
@@ -17,7 +17,6 @@
class LineChartDrawerForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,
    plot: PropTypes.object,
    config: PropTypes.object,
    plotchange: PropTypes.func
@@ -218,7 +217,7 @@
        }
      },
      {
        title: '显示',
        title: '显示(值/%)',
        dataIndex: 'show',
        inputType: 'select',
        editable: true,
@@ -262,20 +261,41 @@
      }
    })
    if (config.plot.correction) {
      delete config.plot.correction // 数据修正(已弃用)
      config.plot.barSize = 35
    let plot = fromJS(config.plot).toJS()
    if (plot.correction) {
      delete plot.correction // 数据修正(已弃用)
      plot.barSize = 35
    }
    if (plot.datatype !== 'statistics') {
      if (plot.colors) {
        plot.colors = plot.colors.map(item => {
          if (fieldName[item.type]) {
            item.label = fieldName[item.type]
          }
          return item
        })
      }
      if (plot.customs) {
        plot.customs = plot.customs.map(item => {
          if (fieldName[item.type]) {
            item.name = fieldName[item.type]
          }
          return item
        })
      }
    }
    this.setState({
      visible: true,
      view: 'normal',
      ramp: config.plot.ramp || 'false',
      datatype: config.plot.datatype || 'query',
      ramp: plot.ramp || 'false',
      datatype: plot.datatype || 'query',
      fieldName: fieldName,
      plot: fromJS(config.plot).toJS(),
      baseFormlist: getBaseForm(config.plot),
      formlist: getOptionForm(config.plot, config.columns)
      plot: plot,
      baseFormlist: getBaseForm(plot, config.columns),
      formlist: getOptionForm(plot, config.columns)
    })
  }
@@ -286,7 +306,7 @@
    if (key === 'datatype') {
      this.setState({
        datatype: val,
        formlist: formlist.map(item => {
        formlist: fromJS(formlist).toJS().map(item => {
          if (['Yaxis'].includes(item.key)) {
            item.hidden = val === 'statistics'
          } else if (['InfoType', 'InfoValue'].includes(item.key)) {
@@ -295,6 +315,26 @@
          return item
        })
      })
    } else if (key === 'label') {
      this.setState({formlist: fromJS(formlist).toJS().map(cell => {
        if (!['labelColor', 'labelValue'].includes(cell.key)) return cell
        if (cell.key === 'labelColor') {
          if (val !== 'true') {
            cell.hidden = true
          } else {
            cell.hidden = false
          }
        } else {
          if (val === 'false') {
            cell.hidden = true
          } else {
            cell.hidden = false
          }
        }
        return cell
      })})
    }
  }
@@ -324,7 +364,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.onSubmit}/>)}
@@ -345,7 +385,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<InputNumber min={item.min} max={item.max} precision={item.decimal} onPressEnter={this.onSubmit}/>)}
@@ -366,7 +406,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
@@ -395,7 +435,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
@@ -477,17 +517,39 @@
        if (!err) {
          let _plot = {...plot, ...values}
          if (values.datatype === 'statistics' || values.datatype !== plot.datatype) {
            _plot.enabled = 'false'
            _plot.customs = []
          } else if (!values.Yaxis || !plot.Yaxis || !is(fromJS(values.Yaxis), fromJS(plot.Yaxis))) {
            _plot.enabled = 'false'
            _plot.customs = []
            _plot.colors = null
          }
          if (values.datatype !== plot.datatype) {
            _plot.colors = null
          }
          if (values.datatype === 'statistics') {
            _plot.enabled = 'false'
            _plot.customs = []
            delete _plot.Yaxis
          } else if (!is(fromJS(values.Yaxis), fromJS(plot.Yaxis || []))) {
            _plot.enabled = 'false'
            _plot.colors = null
            let labels = {}
            config.columns.forEach(col => {
              labels[col.field] = col.label
            })
            let cus = {}
            _plot.customs && _plot.customs.forEach(m => {
              cus[m.type] = m
            })
            _plot.customs = _plot.Yaxis.map((item, i) => {
              if (cus[item]) return cus[item]
              return {
                uuid: Utils.getuuid(),
                type: item,
                name: labels[item] || item,
                axis: i === 0 ? 'true' : 'false',
                label: 'false',
                title: 'true',
                shape: _plot.chartType === 'bar' && i === 0 ? ['bar', 'rect'] : ['line', 'smooth']
              }
            })
          }
          this.setState({
@@ -501,6 +563,40 @@
    } else if (view === 'base') {
      this.baseRef.handleConfirm().then(res => {
        let _plot = {...plot, ...res}
        if (res.click === 'menu') {
          delete _plot.menus
        } else if (res.click === 'menus') {
          delete _plot.menu
        } else {
          delete _plot.menus
          delete _plot.menu
        }
        delete _plot.MenuID
        delete _plot.MenuName
        delete _plot.MenuNo
        delete _plot.tabType
        if (_plot.click === 'menu' && sessionStorage.getItem('appType') === '' && _plot.menu) {
          let list = null
          try {
            list = JSON.parse(sessionStorage.getItem('thdMenuList')) || []
          } catch (e) {
            list = []
          }
          let id = _plot.menu[_plot.menu.length - 1]
          list.forEach(item => {
            if (item.MenuID === id) {
              _plot.MenuID = id
              _plot.MenuName = item.MenuName
              _plot.MenuNo = item.MenuNo
              _plot.tabType = item.type
            }
          })
        }
        this.setState({
          plot: _plot,
@@ -526,22 +622,29 @@
        if (!err) {
          let _plot = {...plot, ...values}
          if (values.datatype === 'statistics' || values.datatype !== plot.datatype) {
            _plot.enabled = 'false'
            _plot.customs = []
          } else if (!values.Yaxis || !plot.Yaxis || !is(fromJS(values.Yaxis), fromJS(plot.Yaxis))) {
            _plot.enabled = 'false'
            _plot.customs = []
            _plot.colors = null
          }
          let labels = {}
          config.columns.forEach(col => {
            labels[col.field] = col.label
          })
          if (values.datatype !== 'statistics' && (!_plot.customs || _plot.customs.length === 0)) {
          if (values.datatype !== plot.datatype) {
            _plot.colors = null
          }
          if (values.datatype === 'statistics') {
            _plot.enabled = 'false'
            _plot.customs = []
            delete _plot.Yaxis
          } else if (!is(fromJS(values.Yaxis), fromJS(plot.Yaxis || []))) {
            _plot.enabled = 'false'
            _plot.colors = null
            let cus = {}
            _plot.customs && _plot.customs.forEach(m => {
              cus[m.type] = m
            })
            _plot.customs = _plot.Yaxis.map((item, i) => {
              if (cus[item]) return cus[item]
              return {
                uuid: Utils.getuuid(),
                type: item,
@@ -553,7 +656,8 @@
              }
            })
          }
          if (values.datatype !== plot.datatype || !_plot.colors) {
          if (!_plot.colors) {
            _plot.colors = []
            if (_plot.datatype === 'query') {
              let limit = chartColors.length
@@ -579,8 +683,44 @@
      })
    } else if (view === 'base') {
      this.baseRef.handleConfirm().then(res => {
        let _plot = {...plot, ...res}
        if (res.click === 'menu') {
          delete _plot.menus
        } else if (res.click === 'menus') {
          delete _plot.menu
        } else {
          delete _plot.menus
          delete _plot.menu
        }
        delete _plot.MenuID
        delete _plot.MenuName
        delete _plot.MenuNo
        delete _plot.tabType
        if (_plot.click === 'menu' && sessionStorage.getItem('appType') === '' && _plot.menu) {
          let list = null
          try {
            list = JSON.parse(sessionStorage.getItem('thdMenuList')) || []
          } catch (e) {
            list = []
          }
          let id = _plot.menu[_plot.menu.length - 1]
          list.forEach(item => {
            if (item.MenuID === id) {
              _plot.MenuID = id
              _plot.MenuName = item.MenuName
              _plot.MenuNo = item.MenuNo
              _plot.tabType = item.type
            }
          })
        }
        this.setState({
          plot: {...plot, ...res},
          plot: _plot,
          view: tab
        })
      })
@@ -635,18 +775,18 @@
      <div className="line-chart-drawer-form">
        <EditOutlined title="编辑" onClick={this.showDrawer}/>
        <Modal
          wrapClassName="popview-modal menu-chart-edit-modal"
          title={config.type === 'bar' ? '柱状图编辑' : '折线图编辑'}
          wrapClassName="mk-pop-modal"
          visible={visible}
          width={950}
          width={1000}
          maskClosable={false}
          onOk={this.onSubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          {config.name ? <div className="mk-com-name">{config.name} - 编辑</div> : null}
          <Tabs activeKey={view} className="menu-chart-edit-box" onChange={this.changeTab}>
            <TabPane tab="组件设置" key="base">
              <NormalForm dict={this.props.dict} formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
              <NormalForm formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
            </TabPane>
            <TabPane tab="图表设置" key="normal">
              <Form {...formItemLayout}>
@@ -675,7 +815,7 @@
                    </Form.Item>
                  </Form>
                </Col> : null}
                {datatype === 'statistics' ? <Button className="color-add mk-green" onClick={this.addColor}>{this.props.dict['model.add']}</Button> : null}
                {datatype === 'statistics' ? <Button className="color-add mk-green" onClick={this.addColor}>添加</Button> : null}
                {datatype === 'statistics' ? <EditTable actions={['edit', 'move', 'del']} data={plot.colors || []} columns={ramp ==='true' ? rampStatColorColumns : statColorColumns} onChange={this.changeColor}/> : null}
                {datatype !== 'statistics' ? <EditTable actions={['edit']} data={plot.colors || []} columns={ramp ==='true' ? rampColorColumns : colorColumns} onChange={this.changeColor}/> : null}
              </div>
src/menu/components/chart/antv-bar/chartcompile/index.scss
@@ -4,33 +4,24 @@
    color: #1890ff;
  }
}
.menu-chart-edit-modal {
  .ant-modal {
    top: 50px;
    .ant-modal-body {
      max-height: calc(100vh - 190px);
      min-height: 50vh;
      padding-top: 10px;
      .menu-chart-edit-box {
        .ant-radio-wrapper {
          margin-right: 5px;
        }
        .ant-tabs-nav-wrap {
          text-align: center;
        }
        .color-sketch-block {
          position: relative;
          top: 5px;
          width: 240px;
        }
        .color-add {
          float: right;
          margin-bottom: 10px;
          position: relative;
          z-index: 1;
        }
      }
    }
.menu-chart-edit-box {
  .ant-radio-wrapper {
    margin-right: 5px;
  }
  .color-sketch-block {
    position: relative;
    top: 5px;
    width: 240px;
  }
  .color-add {
    float: right;
    margin-bottom: 10px;
    position: relative;
    z-index: 1;
  }
  .ant-table-column-title {
    white-space: nowrap;
  }
}
src/menu/components/chart/antv-bar/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, notification } from 'antd'
import { Popover } from 'antd'
import { PlusCircleOutlined, PlusSquareOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import { Chart } from '@antv/g2'
import DataSet from '@antv/data-set'
@@ -9,16 +9,13 @@
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle } from '@/utils/utils-custom.js'
import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
import Utils from '@/utils/utils.js'
import { chartColors } from '@/utils/option.js'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import './index.scss'
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const ChartCompileForm = asyncIconComponent(() => import('./chartcompile'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
@@ -34,7 +31,6 @@
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    card: null,
    appType: sessionStorage.getItem('appType'),
    eventListener: null
@@ -71,12 +67,9 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: 'array',   // 组件属性 - 数据格式
        pageable: false,   // 组件属性 - 是否可分页
        switchable: card.type === 'bar' ? true : false, // 组件属性 - 数据是否可切换
        dataName: card.dataName || '',
        width: _plot.width,
        name: _plot.name,
        subtype: card.subtype,
@@ -91,7 +84,6 @@
        search: [],
        action: [],
        plot: _plot,
        btnlog: [],
      }
      if (card.config) {
@@ -114,10 +106,8 @@
          return col
        })
      }
      this.setState({
        card: _card
      })
      this.props.updateConfig(_card)
      this.updateComponent(_card, true)
    } else {
      this.setState({
        card: fromJS(card).toJS()
@@ -126,7 +116,7 @@
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('plusSearch', this.plusSearch)
    MKEmitter.addListener('tabsChange', this.handleTabsChange)
    setTimeout(() => {
      this.viewrender()
@@ -144,14 +134,14 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('plusSearch', this.plusSearch)
    MKEmitter.removeListener('tabsChange', this.handleTabsChange)
  }
  handleTabsChange = (parentId) => {
    const { card } = this.state
    if (parentId === card.parentId) {
    if (parentId.indexOf(card.uuid) > -1 || parentId === 'all') {
      let _element = document.getElementById(card.uuid + 'canvas')
      if (_element) {
        _element.innerHTML = ''
@@ -238,7 +228,7 @@
      const chart = new Chart({
        container: card.uuid + 'canvas',
        autoFit: true,
        height: this.wrap.offsetHeight - 25
        height: getHeight(plot.height)
      })
  
      chart.data(dv.rows)
@@ -564,7 +554,7 @@
    const chart = new Chart({
      container: card.uuid + 'canvas',
      autoFit: true,
      height: this.wrap.offsetHeight - 25,
      height: getHeight(plot.height)
    })
    // chart.axis(plot.Xaxis, { label: { style: { fill: color } }, tickLine: {style: { stroke: color }}, line: { style: { stroke: color } } })
@@ -675,7 +665,7 @@
      }
      view1.axis('value', yc)
  
      view1.legend(false)
      // view1.legend(false)
  
      if (plot.mutilBar !== 'stack') {
        let _chart = view1
@@ -788,17 +778,21 @@
      }
    }
    const view2 = chart.createView({
      region: {
        start: { x: 0, y: 0 },
        end: { x: 1, y: 1 }
      },
      padding
    })
    let view2 = chart // 无独立柱状图时不做分面
    if (Bar_axis.length) {
      view2 = chart.createView({
        region: {
          start: { x: 0, y: 0 },
          end: { x: 1, y: 1 }
        },
        padding
      })
    }
    view2.data(dv.rows)
    view2.legend(false)
    // view2.legend(false)
    fields.forEach(item => {
      if (item.chartType === 'bar' && !Bar_axis.length) {
@@ -954,7 +948,7 @@
      const chart = new Chart({
        container: card.uuid + 'canvas',
        autoFit: true,
        height: this.wrap.offsetHeight - 25
        height: getHeight(plot.height)
      })
      chart.data(dv.rows)
@@ -1210,26 +1204,71 @@
    }
  }
  updateComponent = (component) => {
    const card = fromJS(this.state.card).toJS()
    if (!is(fromJS(component.plot), fromJS(card.plot)) || !is(fromJS(component.style), fromJS(card.style)) || !is(fromJS(component.search), fromJS(card.search))) {
      let _element = document.getElementById(card.uuid + 'canvas')
      if (_element) {
        _element.innerHTML = ''
  updateComponent = (card, init) => {
    if (!init) {
      if (!is(fromJS({plot: card.plot, style: card.style, search: card.search}), fromJS({plot: this.state.card.plot, style: this.state.card.style, search: this.state.card.search}))) {
        let _element = document.getElementById(this.state.card.uuid + 'canvas')
        if (_element) {
          _element.innerHTML = ''
        }
        this.$timer && clearTimeout(this.$timer)
        this.$timer = setTimeout(() => {
          this.viewrender()
        }, 150)
      }
      this.$timer && clearTimeout(this.$timer)
      this.$timer = setTimeout(() => {
        this.viewrender()
      }, 150)
    }
    component.width = component.plot.width
    component.name = component.plot.name
    card.width = card.plot.width
    card.name = card.plot.name
    card.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: '未设置上级组件!'})
    }
    if (card.errors.length === 0) {
      card.$tables = getTables(card)
    }
    
    if (!card.plot.Xaxis) {
      card.errors.push({ level: 0, detail: '坐标轴尚未设置!'})
    } else if (card.plot.datatype === 'query') {
      if (!columns.includes(card.plot.Xaxis)) {
        card.errors.push({ level: 1, detail: 'X轴在字段集中不存在'})
      }
      if (card.plot.Yaxis) {
        card.plot.Yaxis.forEach(m => {
          if (!columns.includes(m)) {
            card.errors.push({ level: 1, detail: `Y轴中字段“${m}”已失效`})
          }
        })
      }
    } else if (card.plot.datatype === 'statistics') {
      if (!columns.includes(card.plot.Xaxis)) {
        card.errors.push({ level: 1, detail: 'X轴在字段集中不存在'})
      }
      if (!columns.includes(card.plot.InfoType)) {
        card.errors.push({ level: 1, detail: '图表中统计类型字段已失效'})
      }
      if (!columns.includes(card.plot.InfoValue)) {
        card.errors.push({ level: 1, detail: '图表中统计值字段已失效'})
      }
    }
    this.setState({
      card: component
      card: card
    })
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  addSearch = () => {
@@ -1249,6 +1288,16 @@
    // 注册事件-添加搜索
    MKEmitter.emit('addSearch', card.uuid, newcard)
  }
  plusSearch = (uuid, search, type) => {
    const { card } = this.state
    if (card.uuid !== uuid || type !== 'simple') return
    search.uuid = Utils.getuuid()
    search.focus = true
    MKEmitter.emit('addSearch', card.uuid, search)
  }
  addButton = () => {
@@ -1282,67 +1331,43 @@
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
    if (comIds[0] !== card.uuid || comIds.length > 1) return
    let _card = {...card, style}
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    this.updateComponent(_card)
  }
  handleLog = (type, logs, item) => {
    let card = fromJS(this.state.card).toJS()
    if (type === 'revert') {
      card.action = card.action ? [...card.action, item] : [item]
      card.btnlog = logs
      this.setState({ card })
      this.props.updateConfig(card)
      notification.success({
        top: 92,
        message: '恢复成功!',
        duration: 2
      })
    } else {
      card.btnlog = logs
      this.setState({ card })
      this.props.updateConfig(card)
      notification.success({
        top: 92,
        message: '清除成功!',
        duration: 2
      })
    }
  }
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.updateComponent(_card)
      })
    }
  }
  render() {
    const { card, appType } = this.state
    let _style = resetStyle(card.style)
    _style.height = 'auto'
    return (
      <div className="menu-line-chart-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
      <div className="menu-line-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
            {appType !== 'mob' ? <PlusSquareOutlined className="plus" title="添加按钮" onClick={this.addButton}/> : null}
            <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
            <ChartCompileForm config={card} plotchange={this.updateComponent}/>
            <CopyComponent type="line" card={card}/>
            <PasteComponent config={card} options={['action']} updateConfig={this.updateComponent} />
            <PasteComponent config={card} options={['action', 'search']} updateConfig={this.updateComponent} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
@@ -1352,12 +1377,25 @@
          <ToolOutlined/>
        </Popover>
        <NormalHeader config={card} updateComponent={this.updateComponent}/>
        <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
        <div className="canvas" id={card.uuid + 'canvas'}></div>
        {appType !== 'mob' ? <ActionComponent
          type="chart"
          config={card}
          updateaction={this.updateComponent}
        /> : null}
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/chart/antv-bar/index.scss
@@ -5,14 +5,11 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  flex-flow: column;
  .canvas {
    margin: 0px;
    padding: 15px 10px 10px;
    padding: 15px;
    letter-spacing: 0px;
    flex: 1;
  }
  .chart-header {
src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx
@@ -1,8 +1,3 @@
// import zhCN from '@/locales/zh-CN/model.js'
// import enUS from '@/locales/en-US/model.js'
// const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
/**
 * @description 获取图表视图配置表单
 * @param {object} card       // 图表对象
@@ -48,14 +43,13 @@
      required: true
    },
    {
      type: 'number',
      type: 'styleInput',
      key: 'height',
      label: '高度',
      label: '图表高度',
      initVal: card.height,
      min: 100,
      max: 1000,
      decimal: 0,
      required: true
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'radio',
@@ -239,7 +233,7 @@
      label: '字体大小',
      initVal: card.fontSize || 28,
      min: 12,
      max: 200,
      max: 300,
      decimal: 0,
      required: true
    },
src/menu/components/chart/antv-dashboard/chartcompile/index.jsx
@@ -17,7 +17,6 @@
class LineChartDrawerForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,
    plot: PropTypes.object,
    config: PropTypes.object,
    plotchange: PropTypes.func
@@ -88,7 +87,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.onSubmit}/>)}
@@ -109,7 +108,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<InputNumber min={item.min} max={item.max} precision={item.decimal} onPressEnter={this.onSubmit}/>)}
@@ -130,7 +129,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
@@ -159,7 +158,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
@@ -300,8 +299,7 @@
      <div className="line-chart-drawer-form">
        <EditOutlined title="编辑" onClick={this.showDrawer} />
        <Modal
          wrapClassName="popview-modal menu-chart-edit-modal"
          title={config.subtype === 'ratioboard' ? '占比图编辑' : '仪表盘编辑'}
          wrapClassName="mk-pop-modal"
          visible={visible}
          width={850}
          maskClosable={false}
@@ -309,9 +307,10 @@
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          {config.name ? <div className="mk-com-name">{config.name} - 编辑</div> : null}
          <Tabs activeKey={view} className="menu-chart-edit-box" onChange={this.changeTab}>
            <TabPane tab="组件设置" key="base">
              <NormalForm dict={this.props.dict} formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
              <NormalForm formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
            </TabPane>
            <TabPane tab="图表设置" key="normal">
              <Form {...formItemLayout}>
@@ -320,7 +319,7 @@
            </TabPane>
            {plot ? <TabPane tab="颜色设置" key="color">
              <div>
                <Button className="color-add mk-green" onClick={this.addColor}>{this.props.dict['model.add']}</Button>
                <Button className="color-add mk-green" onClick={this.addColor}>添加</Button>
                <EditTable actions={['edit', 'move', 'del']} data={plot.colors || []} columns={colorColumns} onChange={this.changeColor}/>
              </div>
            </TabPane> : null}
src/menu/components/chart/antv-dashboard/chartcompile/index.scss
@@ -4,32 +4,21 @@
    color: #1890ff;
  }
}
.menu-chart-edit-modal {
  .ant-modal {
    top: 50px;
    .ant-modal-body {
      min-height: 50vh;
      max-height: calc(100vh - 190px);
      padding-top: 10px;
      .ant-tabs-nav-wrap {
        text-align: center;
      }
      .color-sketch-block {
        position: relative;
        top: 5px;
        width: 240px;
      }
      .color-add {
        float: right;
        margin-bottom: 10px;
        position: relative;
        z-index: 1;
      }
      .color-col {
        .ant-form-item-control {
          height: 40px;
        }
      }
.menu-chart-edit-box {
  .color-sketch-block {
    position: relative;
    top: 5px;
    width: 240px;
  }
  .color-add {
    float: right;
    margin-bottom: 10px;
    position: relative;
    z-index: 1;
  }
  .color-col {
    .ant-form-item-control {
      height: 40px;
    }
  }
}
src/menu/components/chart/antv-dashboard/index.jsx
@@ -8,9 +8,7 @@
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle } from '@/utils/utils-custom.js'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
import './index.scss'
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
@@ -65,14 +63,14 @@
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    card: null,
    ismob: sessionStorage.getItem('appType') === 'mob',
    appType: sessionStorage.getItem('appType'),
    eventListener: null
  }
  UNSAFE_componentWillMount () {
    const { card, ismob } = this.props
    const { card } = this.props
    const { appType } = this.state
    if (card.isNew) {
      let _plot = null
@@ -105,19 +103,16 @@
        }
      }
      if (ismob) {
      if (appType === 'mob') {
        _plot.width = 24
      }
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: card.subtype === 'ratioboard' ? 'array' : 'object',   // 组件属性 - 数据格式
        pageable: false,    // 组件属性 - 是否可分页
        switchable: false,  // 组件属性 - 数据是否可切换
        dataName: card.dataName || '',
        width: _plot.width,
        name: _plot.name,
        subtype: card.subtype,
@@ -132,7 +127,6 @@
        search: [],
        action: [],
        plot: _plot,
        btnlog: [],
      }
      if (card.config) {
@@ -148,10 +142,7 @@
        _card.scripts = config.scripts
      }
      this.props.updateConfig(_card)
      this.setState({
        card: _card
      })
      this.updateComponent(_card, true)
    } else {
      this.setState({
        card: fromJS(card).toJS()
@@ -161,7 +152,6 @@
  componentDidMount () {
    MKEmitter.addListener('tabsChange', this.handleTabsChange)
    MKEmitter.addListener('submitStyle', this.getStyle)
    setTimeout(() => {
      this.viewrender()
@@ -180,14 +170,13 @@
      return
    }
    MKEmitter.removeListener('tabsChange', this.handleTabsChange)
    MKEmitter.removeListener('submitStyle', this.getStyle)
  }
  handleTabsChange = (parentId) => {
    const { card } = this.state
    if (parentId === card.parentId) {
      let _element = document.getElementById(card.uuid + 'canvas')
    if (parentId.indexOf(card.uuid) > -1 || parentId === 'all') {
      let _element = document.getElementById(card.uuid + 'dashboard')
      if (_element) {
        _element.innerHTML = ''
      }
@@ -238,7 +227,7 @@
    const chart = new Chart({
      container: card.uuid + 'dashboard',
      autoFit: true,
      height: this.wrap.offsetHeight - 30,
      height: getHeight(plot.height)
    })
    
    chart.data(data)
@@ -337,7 +326,7 @@
    const chart = new Chart({
      container: card.uuid + 'dashboard',
      autoFit: true,
      height: this.wrap.offsetHeight - 30,
      height: getHeight(plot.height),
      padding: [0, 0, 0, 0],
    })
    chart.data(data)
@@ -467,41 +456,63 @@
    chart.render()
  }
  updateComponent = (component) => {
    const card = fromJS(this.state.card).toJS()
    if (!is(fromJS(component.plot), fromJS(card.plot)) || !is(fromJS(component.style), fromJS(card.style)) || !is(fromJS(component.search), fromJS(card.search))) {
      let _element = document.getElementById(card.uuid + 'dashboard')
      if (_element) {
        _element.innerHTML = ''
  updateComponent = (card, init) => {
    if (!init) {
      if (!is(fromJS({plot: card.plot, style: card.style}), fromJS({plot: this.state.card.plot, style: this.state.card.style}))) {
        let _element = document.getElementById(this.state.card.uuid + 'dashboard')
        if (_element) {
          _element.innerHTML = ''
        }
        this.$timer && clearTimeout(this.$timer)
        this.$timer = setTimeout(() => {
          this.viewrender()
        }, 150)
      }
      this.$timer && clearTimeout(this.$timer)
      this.$timer = setTimeout(() => {
        this.viewrender()
      }, 150)
    }
    component.width = component.plot.width
    component.name = component.plot.name
    card.width = card.plot.width
    card.name = card.plot.name
    card.errors = []
    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: '未设置上级组件!'})
    }
    if (card.errors.length === 0) {
      card.$tables = getTables(card)
    }
    if (!card.plot.valueField) {
      card.errors.push({ level: 0, detail: '显示值尚未设置!'})
    } else if (!columns.includes(card.plot.valueField)) {
      card.errors.push({ level: 1, detail: '显示值在字段集中不存在'})
    }
    
    this.setState({
      card: component
      card: card
    })
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
    if (comIds[0] !== card.uuid || comIds.length > 1) return
    let _card = {...card, style}
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    this.updateComponent(_card)
  }
@@ -509,19 +520,25 @@
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.updateComponent(_card)
      })
    }
  }
  render() {
    const { card } = this.state
    let _style = resetStyle(card.style)
    _style.height = 'auto'
    return (
      <div className="menu-dashboard-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
      <div className="menu-dashboard-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
            <ChartCompileForm config={card} plotchange={this.updateComponent}/>
            <CopyComponent type="dashboard" card={card}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
@@ -533,7 +550,21 @@
          <ToolOutlined/>
        </Popover>
        <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
        <div className="canvas" id={card.uuid + 'dashboard'} ref={ref => this.wrap = ref}></div>
        <div className="canvas" id={card.uuid + 'dashboard'}></div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/chart/antv-dashboard/index.scss
@@ -5,14 +5,11 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  flex-flow: column;
  
  .canvas {
    margin: 0px;
    padding: 15px;
    letter-spacing: 0px;
    flex: 1;
  }
  >.anticon-tool {
@@ -25,22 +22,6 @@
    cursor: pointer;
    color: rgba(0, 0, 0, 0.85);
    background: rgba(255, 255, 255, 0.55);
  }
  .model-menu-action-list {
    position: absolute;
    right: 0px;
    z-index: 4;
    padding-top: 10px;
    font-size: 16px;
    .ant-row .anticon-plus {
      float: right;
    }
    .page-card {
      float: right;
    }
  }
}
.menu-dashboard-edit-box:hover {
src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
@@ -69,14 +69,13 @@
      required: true
    },
    {
      type: 'number',
      type: 'styleInput',
      key: 'height',
      label: '高度',
      label: '图表高度',
      initVal: card.height,
      min: 100,
      max: 1000,
      decimal: 0,
      required: true
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'cascader',
@@ -261,7 +260,7 @@
    {
      type: 'radio',
      key: 'label',
      label: '标签',
      label: '标注',
      initVal: card.label || 'false',
      required: false,
      options: [{
src/menu/components/chart/antv-pie/chartcompile/index.jsx
@@ -17,7 +17,6 @@
class LineChartDrawerForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,
    plot: PropTypes.object,
    config: PropTypes.object,
    plotchange: PropTypes.func
@@ -114,7 +113,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.onSubmit}/>)}
@@ -135,7 +134,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<InputNumber min={item.min} max={item.max} precision={item.decimal} onPressEnter={this.onSubmit}/>)}
@@ -156,7 +155,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
@@ -185,7 +184,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
@@ -309,6 +308,7 @@
  }
  render() {
    const { config } = this.props
    const { visible, plot, colorColumns, view, baseFormlist } = this.state
    const formItemLayout = {
      labelCol: {
@@ -325,8 +325,7 @@
      <div className="line-chart-drawer-form">
        <EditOutlined title="编辑" onClick={this.showDrawer} />
        <Modal
          wrapClassName="popview-modal menu-chart-edit-modal"
          title="饼图编辑"
          wrapClassName="mk-pop-modal"
          visible={visible}
          width={850}
          maskClosable={false}
@@ -334,9 +333,10 @@
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          {config.name ? <div className="mk-com-name">{config.name} - 编辑</div> : null}
          <Tabs activeKey={view} className="menu-chart-edit-box" onChange={this.changeTab}>
            <TabPane tab="组件设置" key="base">
              <NormalForm dict={this.props.dict} formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
              <NormalForm formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
            </TabPane>
            <TabPane tab="图表设置" key="normal">
              <Form {...formItemLayout}>
@@ -345,7 +345,7 @@
            </TabPane>
            {plot ? <TabPane tab="颜色设置" key="color">
              <div>
                <Button className="color-add mk-green" onClick={this.addColor}>{this.props.dict['model.add']}</Button>
                <Button className="color-add mk-green" onClick={this.addColor}>添加</Button>
                <EditTable actions={['edit', 'move', 'del']} data={plot.colors || []} columns={colorColumns} onChange={this.changeColor}/>
              </div>
            </TabPane> : null}
src/menu/components/chart/antv-pie/chartcompile/index.scss
@@ -4,28 +4,17 @@
    color: #1890ff;
  }
}
.menu-chart-edit-modal {
  .ant-modal {
    top: 50px;
    .ant-modal-body {
      min-height: 50vh;
      max-height: calc(100vh - 190px);
      padding-top: 10px;
      .ant-tabs-nav-wrap {
        text-align: center;
      }
      .color-sketch-block {
        position: relative;
        top: 5px;
        width: 240px;
      }
      .color-add {
        float: right;
        margin-bottom: 10px;
        position: relative;
        z-index: 1;
      }
    }
.menu-chart-edit-box {
  .color-sketch-block {
    position: relative;
    top: 5px;
    width: 240px;
  }
  .color-add {
    float: right;
    margin-bottom: 10px;
    position: relative;
    z-index: 1;
  }
}
src/menu/components/chart/antv-pie/index.jsx
@@ -9,10 +9,8 @@
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle } from '@/utils/utils-custom.js'
import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import './index.scss'
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
@@ -30,14 +28,14 @@
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    card: null,
    ismob: sessionStorage.getItem('appType') === 'mob',
    appType: sessionStorage.getItem('appType'),
    eventListener: null
  }
  UNSAFE_componentWillMount () {
    const { card, ismob } = this.props
    const { card } = this.props
    const { appType } = this.state
    if (card.isNew) {
      let _plot = {
@@ -48,7 +46,7 @@
        name: card.name
      }
      if (ismob) {
      if (appType === 'mob') {
        _plot.width = 24
      }
@@ -62,12 +60,9 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: 'array',   // 组件属性 - 数据格式
        pageable: false,   // 组件属性 - 是否可分页
        switchable: false, // 组件属性 - 数据是否可切换
        dataName: card.dataName || '',
        width: _plot.width,
        name: _plot.name,
        subtype: card.subtype,
@@ -82,7 +77,6 @@
        search: [],
        action: [],
        plot: _plot,
        btnlog: [],
      }
      if (card.config) {
@@ -97,16 +91,15 @@
        _card.columns = config.columns
        _card.scripts = config.scripts
        _card.search = config.search.map(col => {
          col.uuid = Utils.getuuid()
          return col
        })
        if (appType !== 'mob') {
          _card.search = config.search.map(col => {
            col.uuid = Utils.getuuid()
            return col
          })
        }
      }
      this.props.updateConfig(_card)
      this.setState({
        card: _card
      })
      this.updateComponent(_card, true)
    } else {
      this.setState({
        card: fromJS(card).toJS()
@@ -116,7 +109,6 @@
  componentDidMount () {
    MKEmitter.addListener('tabsChange', this.handleTabsChange)
    MKEmitter.addListener('submitStyle', this.getStyle)
    setTimeout(() => {
      this.viewrender()
@@ -135,13 +127,12 @@
      return
    }
    MKEmitter.removeListener('tabsChange', this.handleTabsChange)
    MKEmitter.removeListener('submitStyle', this.getStyle)
  }
  handleTabsChange = (parentId) => {
    const { card } = this.state
    if (parentId === card.parentId) {
    if (parentId.indexOf(card.uuid) > -1 || parentId === 'all') {
      let _element = document.getElementById(card.uuid + 'canvas')
      if (_element) {
        _element.innerHTML = ''
@@ -150,6 +141,22 @@
      this.$timer && clearTimeout(this.$timer)
      this.$timer = setTimeout(this.viewrender, 100)
    }
  }
  getHeight = (val) => {
    if (typeof(val) === 'string') {
      if (val.indexOf('px') > -1) {
        val = parseFloat(val)
      } else if (val.indexOf('vw') > -1) {
        val = parseFloat(val)
        val = document.body.clientWidth * val / 100
      } else if (val.indexOf('vh') > -1) {
        val = parseFloat(val)
        val = document.body.clientHeight * val / 100
      }
    }
    return parseInt(val || 400)
  }
  viewrender = () => {
@@ -257,7 +264,7 @@
    const chart = new Chart({
      container: card.uuid + 'canvas',
      autoFit: true,
      height: this.wrap.offsetHeight - 30,
      height: getHeight(plot.height),
      padding: 0,
    })
@@ -428,7 +435,7 @@
    const chart = new Chart({
      container: card.uuid + 'canvas',
      autoFit: true,
      height: this.wrap.offsetHeight - 30
      height: getHeight(plot.height)
    })
    if (plot.shape !== 'nightingale' && plot.show !== 'value') {
@@ -599,27 +606,57 @@
    chart.render()
  }
  updateComponent = (component) => {
    const card = fromJS(this.state.card).toJS()
    if (!is(fromJS(component.plot), fromJS(card.plot)) || !is(fromJS(component.style), fromJS(card.style)) || !is(fromJS(component.search), fromJS(card.search))) {
      let _element = document.getElementById(card.uuid + 'canvas')
      if (_element) {
        _element.innerHTML = ''
  updateComponent = (card, init) => {
    if (!init) {
      if (!is(fromJS({plot: card.plot, style: card.style, search: card.search}), fromJS({plot: this.state.card.plot, style: this.state.card.style, search: this.state.card.search}))) {
        let _element = document.getElementById(card.uuid + 'canvas')
        if (_element) {
          _element.innerHTML = ''
        }
        this.$timer && clearTimeout(this.$timer)
        this.$timer = setTimeout(() => {
          this.viewrender()
        }, 150)
      }
      this.$timer && clearTimeout(this.$timer)
      this.$timer = setTimeout(() => {
        this.viewrender()
      }, 150)
    }
    component.width = component.plot.width
    component.name = component.plot.name
    card.width = card.plot.width
    card.name = card.plot.name
    card.errors = []
    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: '未设置上级组件!'})
    }
    if (card.errors.length === 0) {
      card.$tables = getTables(card)
    }
    if (!card.plot.Xaxis) {
      card.errors.push({ level: 0, detail: '名称字段尚未设置!'})
    } else {
      if (!columns.includes(card.plot.Xaxis)) {
        card.errors.push({ level: 1, detail: '名称字段在字段集中不存在'})
      }
      if (!columns.includes(card.plot.Yaxis)) {
        card.errors.push({ level: 1, detail: '值字段在字段集中不存在'})
      }
    }
    
    this.setState({
      card: component
      card: card
    })
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  addSearch = () => {
@@ -644,15 +681,11 @@
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
    if (comIds[0] !== card.uuid || comIds.length > 1) return
    let _card = {...card, style}
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    this.updateComponent(_card)
  }
@@ -660,20 +693,26 @@
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.updateComponent(_card)
      })
    }
  }
  render() {
    const { card, ismob } = this.state
    const { card, appType } = this.state
    let _style = resetStyle(card.style)
    _style.height = 'auto'
    return (
      <div className="menu-pie-chart-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
      <div className="menu-pie-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            {!ismob ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
            <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
            <ChartCompileForm config={card} plotchange={this.updateComponent}/>
            <CopyComponent type="pie" card={card}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
@@ -685,7 +724,21 @@
          <ToolOutlined />
        </Popover>
        <NormalHeader config={card} updateComponent={this.updateComponent}/>
        <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
        <div className="canvas" id={card.uuid + 'canvas'}></div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/chart/antv-pie/index.scss
@@ -5,14 +5,11 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  flex-flow: column;
  
  .canvas {
    margin: 0px;
    padding: 15px;
    letter-spacing: 0px;
    flex: 1;
  }
  >.anticon-tool {
@@ -25,22 +22,6 @@
    cursor: pointer;
    color: rgba(0, 0, 0, 0.85);
    background: rgba(255, 255, 255, 0.55);
  }
  .model-menu-action-list {
    position: absolute;
    right: 0px;
    z-index: 4;
    padding-top: 10px;
    font-size: 16px;
    .ant-row .anticon-plus {
      float: right;
    }
    .page-card {
      float: right;
    }
  }
}
.menu-pie-chart-edit-box:hover {
src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx
@@ -43,14 +43,13 @@
      required: true
    },
    {
      type: 'number',
      type: 'styleInput',
      key: 'height',
      label: '高度',
      label: '图表高度',
      initVal: card.height,
      min: 100,
      max: 1000,
      decimal: 0,
      required: true
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'radio',
src/menu/components/chart/antv-scatter/chartcompile/index.jsx
@@ -14,7 +14,6 @@
class LineChartDrawerForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,
    plot: PropTypes.object,
    config: PropTypes.object,
    plotchange: PropTypes.func
@@ -66,7 +65,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.onSubmit}/>)}
@@ -87,7 +86,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<InputNumber min={item.min} max={item.max} precision={item.decimal} onPressEnter={this.onSubmit}/>)}
@@ -108,7 +107,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
@@ -137,7 +136,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
@@ -228,6 +227,7 @@
  }
  render() {
    const { config } = this.props
    const { view, visible, baseFormlist } = this.state
    const formItemLayout = {
      labelCol: {
@@ -244,8 +244,7 @@
      <div className="line-chart-drawer-form">
        <EditOutlined title="编辑" onClick={this.showDrawer} />
        <Modal
          wrapClassName="popview-modal menu-chart-edit-modal"
          title="散点图编辑"
          wrapClassName="mk-pop-modal"
          visible={visible}
          width={850}
          maskClosable={false}
@@ -253,9 +252,10 @@
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          {config.name ? <div className="mk-com-name">{config.name} - 编辑</div> : null}
          <Tabs activeKey={view} className="menu-chart-edit-box" onChange={this.changeTab}>
            <TabPane tab="组件设置" key="base">
              <NormalForm dict={this.props.dict} formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
              <NormalForm formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
            </TabPane>
            <TabPane tab="图表设置" key="normal">
              <Form {...formItemLayout}>
src/menu/components/chart/antv-scatter/chartcompile/index.scss
@@ -4,30 +4,16 @@
    color: #1890ff;
  }
}
.menu-chart-edit-modal {
  .ant-modal {
    top: 50px;
    .ant-modal-body {
      max-height: calc(100vh - 190px);
      min-height: 50vh;
      padding-top: 10px;
      .menu-chart-edit-box {
        .ant-tabs-nav-wrap {
          text-align: center;
        }
        .color-sketch-block {
          position: relative;
          top: 5px;
          width: 240px;
        }
        .color-add {
          float: right;
          margin-bottom: 10px;
          position: relative;
          z-index: 1;
        }
      }
    }
.menu-chart-edit-box {
  .color-sketch-block {
    position: relative;
    top: 5px;
    width: 240px;
  }
  .color-add {
    float: right;
    margin-bottom: 10px;
    position: relative;
    z-index: 1;
  }
}
src/menu/components/chart/antv-scatter/index.jsx
@@ -1,22 +1,19 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, notification } from 'antd'
import { Popover } from 'antd'
import { ToolOutlined, DeleteOutlined, FontColorsOutlined, PlusCircleOutlined, PlusSquareOutlined } from '@ant-design/icons'
import { Chart } from '@antv/g2'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle } from '@/utils/utils-custom.js'
import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import './index.scss'
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const ChartCompileForm = asyncIconComponent(() => import('./chartcompile'))
const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
@@ -32,7 +29,6 @@
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    card: null,
    appType: sessionStorage.getItem('appType'),
    eventListener: null
@@ -58,12 +54,9 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: 'array',   // 组件属性 - 数据格式
        pageable: false,   // 组件属性 - 是否可分页
        switchable: false, // 组件属性 - 数据是否可切换
        dataName: card.dataName || '',
        width: _plot.width,
        name: _plot.name,
        subtype: card.subtype,
@@ -78,7 +71,6 @@
        search: [],
        action: [],
        plot: _plot,
        btnlog: [],
      }
      if (card.config) {
@@ -102,10 +94,8 @@
          return col
        })
      }
      this.setState({
        card: _card
      })
      this.props.updateConfig(_card)
      this.updateComponent(_card, true)
    } else {
      this.setState({
        card: fromJS(card).toJS()
@@ -114,7 +104,7 @@
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('plusSearch', this.plusSearch)
    MKEmitter.addListener('tabsChange', this.handleTabsChange)
    setTimeout(() => {
      this.ponitrender()
@@ -132,14 +122,14 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('plusSearch', this.plusSearch)
    MKEmitter.removeListener('tabsChange', this.handleTabsChange)
  }
  handleTabsChange = (parentId) => {
    const { card } = this.state
    if (parentId === card.parentId) {
    if (parentId.indexOf(card.uuid) > -1 || parentId === 'all') {
      let _element = document.getElementById(card.uuid + 'canvas')
      if (_element) {
        _element.innerHTML = ''
@@ -195,7 +185,7 @@
    const chart = new Chart({
      container: card.uuid + 'canvas',
      autoFit: true,
      height: this.wrap.offsetHeight - 25
      height: getHeight(plot.height)
    })
    chart.data(data);
@@ -247,27 +237,57 @@
    chart.render()
  }
  updateComponent = (component) => {
    const card = fromJS(this.state.card).toJS()
    if (!is(fromJS(component.plot), fromJS(card.plot)) || !is(fromJS(component.style), fromJS(card.style)) || !is(fromJS(component.search), fromJS(card.search))) {
      let _element = document.getElementById(card.uuid + 'canvas')
      if (_element) {
        _element.innerHTML = ''
  updateComponent = (card, init) => {
    if (!init) {
      if (!is(fromJS({plot: card.plot, style: card.style, search: card.search}), fromJS({plot: this.state.card.plot, style: this.state.card.style, search: this.state.card.search}))) {
        let _element = document.getElementById(card.uuid + 'canvas')
        if (_element) {
          _element.innerHTML = ''
        }
        this.$timer && clearTimeout(this.$timer)
        this.$timer = setTimeout(() => {
          this.ponitrender()
        }, 150)
      }
      this.$timer && clearTimeout(this.$timer)
      this.$timer = setTimeout(() => {
        this.ponitrender()
      }, 150)
    }
    component.width = component.plot.width
    component.name = component.plot.name
    card.width = card.plot.width
    card.name = card.plot.name
    card.errors = []
    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: '未设置上级组件!'})
    }
    if (card.errors.length === 0) {
      card.$tables = getTables(card)
    }
    if (!card.plot.Xaxis) {
      card.errors.push({ level: 0, detail: '坐标轴尚未设置!'})
    } else {
      if (!columns.includes(card.plot.Xaxis)) {
        card.errors.push({ level: 1, detail: 'X轴在字段集中不存在'})
      }
      if (!columns.includes(card.plot.Yaxis)) {
        card.errors.push({ level: 1, detail: 'Y轴在字段集中不存在'})
      }
    }
    this.setState({
      card: component
      card: card
    })
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  addSearch = () => {
@@ -287,6 +307,16 @@
    // 注册事件-添加搜索
    MKEmitter.emit('addSearch', card.uuid, newcard)
  }
  plusSearch = (uuid, search, type) => {
    const { card } = this.state
    if (card.uuid !== uuid || type !== 'simple') return
    search.uuid = Utils.getuuid()
    search.focus = true
    MKEmitter.emit('addSearch', card.uuid, search)
  }
  addButton = () => {
@@ -320,67 +350,42 @@
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
    if (comIds[0] !== card.uuid || comIds.length > 1) return
    let _card = {...card, style}
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    this.updateComponent(_card)
  }
  handleLog = (type, logs, item) => {
    let card = fromJS(this.state.card).toJS()
    if (type === 'revert') {
      card.action = card.action ? [...card.action, item] : [item]
      card.btnlog = logs
      this.setState({ card })
      this.props.updateConfig(card)
      notification.success({
        top: 92,
        message: '恢复成功!',
        duration: 2
      })
    } else {
      card.btnlog = logs
      this.setState({ card })
      this.props.updateConfig(card)
      notification.success({
        top: 92,
        message: '清除成功!',
        duration: 2
      })
    }
  }
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.updateComponent(_card)
      })
    }
  }
  render() {
    const { card, appType } = this.state
    let _style = resetStyle(card.style)
    _style.height = 'auto'
    return (
      <div className="menu-scatter-chart-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
      <div className="menu-scatter-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
            {appType !== 'mob' ? <PlusSquareOutlined className="plus" title="添加按钮" onClick={this.addButton}/> : null}
            <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
            <ChartCompileForm config={card} plotchange={this.updateComponent}/>
            <CopyComponent type="line" card={card}/>
            <PasteComponent config={card} options={['action']} updateConfig={this.updateComponent}/>
            <PasteComponent config={card} options={['action', 'search']} updateConfig={this.updateComponent}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog}/>
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(card.uuid)}/>
@@ -390,8 +395,22 @@
          <ToolOutlined/>
        </Popover>
        <NormalHeader config={card} updateComponent={this.updateComponent}/>
        <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
        {appType !== 'mob' ? <ActionComponent type="chart" config={card} updateaction={this.updateComponent}/> : null}
        <div className="canvas" id={card.uuid + 'canvas'}></div>
        {appType !== 'mob' ? <ActionComponent config={card} updateaction={this.updateComponent}/> : null}
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/chart/antv-scatter/index.scss
@@ -5,14 +5,11 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  flex-flow: column;
  
  .canvas {
    margin: 0px;
    padding: 15px 10px 10px;
    padding: 15px;
    letter-spacing: 0px;
    flex: 1;
  }
  .chart-header {
src/menu/components/chart/chart-custom/chartcompile/formconfig.jsx
@@ -54,14 +54,13 @@
      required: true
    },
    {
      type: 'number',
      type: 'styleInput',
      key: 'height',
      label: '高度',
      label: '图表高度',
      initVal: card.height,
      min: 100,
      max: 1000,
      decimal: 0,
      required: true
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'radio',
src/menu/components/chart/chart-custom/chartcompile/index.jsx
@@ -1,12 +1,12 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Modal, Form, Tabs } from 'antd'
import { Modal, Tabs } from 'antd'
import { EditOutlined } from '@ant-design/icons'
import { getBaseForm } from './formconfig'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
// import './index.scss'
const { TabPane } = Tabs
const NormalForm = asyncComponent(() => import('@/menu/components/share/normalform'))
@@ -14,7 +14,6 @@
class CustomChartDrawerForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,
    plot: PropTypes.object,
    config: PropTypes.object,
    plotchange: PropTypes.func
@@ -87,14 +86,14 @@
  }
  render() {
    const { config } = this.props
    const { view, visible, baseFormlist, plot } = this.state
    return (
      <>
        <EditOutlined style={{color: '#1890ff'}} title="编辑" onClick={this.showDrawer} />
        <Modal
          wrapClassName="popview-modal custom-chart-edit-modal"
          title="自定义图表编辑"
          wrapClassName="mk-pop-modal"
          visible={visible}
          width={950}
          maskClosable={false}
@@ -102,9 +101,10 @@
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          {config.name ? <div className="mk-com-name">{config.name} - 编辑</div> : null}
          <Tabs activeKey={view} onChange={this.changeTab}>
            <TabPane tab="组件设置" key="base">
              <NormalForm dict={this.props.dict} formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
              <NormalForm formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
            </TabPane>
            {plot ? <TabPane tab="JS" key="JS">
              {plot.chartType === 'antv' ? <div>入参:Chart、 DataSet、 wrap(dom节点)、data、 config</div> : <div>入参:echarts、 DataSet、 wrap(dom节点)、 data、 config</div>}
@@ -117,4 +117,4 @@
  }
}
export default Form.create()(CustomChartDrawerForm)
export default CustomChartDrawerForm
src/menu/components/chart/chart-custom/chartcompile/index.scss
@@ -1,11 +0,0 @@
.custom-chart-edit-modal {
  .ant-modal {
    top: 50px;
    .ant-modal-body {
      max-height: calc(100vh - 190px);
      min-height: 50vh;
      padding-top: 10px;
    }
  }
}
src/menu/components/chart/chart-custom/index.jsx
@@ -10,10 +10,8 @@
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle } from '@/utils/utils-custom.js'
import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import './index.scss'
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
@@ -30,7 +28,6 @@
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    card: null,
    appType: sessionStorage.getItem('appType'),
  }
@@ -50,12 +47,9 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: 'array',   // 组件属性 - 数据格式
        pageable: false,   // 组件属性 - 是否可分页
        switchable: false, // 组件属性 - 数据是否可切换
        dataName: card.dataName || '',
        width: _plot.width,
        name: _plot.name,
        subtype: card.subtype,
@@ -70,7 +64,6 @@
        search: [],
        action: [],
        plot: _plot,
        btnlog: [],
      }
      if (card.config) {
@@ -90,10 +83,8 @@
          return col
        })
      }
      this.setState({
        card: _card
      })
      this.props.updateConfig(_card)
      this.updateComponent(_card, true)
    } else {
      this.setState({
        card: fromJS(card).toJS()
@@ -102,7 +93,6 @@
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('tabsChange', this.handleTabsChange)
    setTimeout(() => {
      this.viewrender()
@@ -120,14 +110,13 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('tabsChange', this.handleTabsChange)
  }
  handleTabsChange = (parentId) => {
    const { card } = this.state
    if (parentId === card.parentId) {
    if (parentId.indexOf(card.uuid) > -1 || parentId === 'all') {
      let _element = document.getElementById(card.uuid + 'canvas')
      if (_element) {
        _element.innerHTML = ''
@@ -176,28 +165,48 @@
    }
  }
  updateComponent = (component) => {
    const card = fromJS(this.state.card).toJS()
    if (!is(fromJS(component.plot), fromJS(card.plot)) || !is(fromJS(component.style), fromJS(card.style)) || !is(fromJS(component.search), fromJS(card.search))) {
      let _element = document.getElementById(card.uuid + 'canvas')
      if (_element) {
        _element.innerHTML = ''
        _element.removeAttribute('_echarts_instance_')
        _element.removeAttribute('style')
  updateComponent = (card, init) => {
    if (!init) {
      if (!is(fromJS({plot: card.plot, style: card.style, search: card.search}), fromJS({plot: this.state.card.plot, style: this.state.card.style, search: this.state.card.search}))) {
        let _element = document.getElementById(card.uuid + 'canvas')
        if (_element) {
          _element.innerHTML = ''
          _element.removeAttribute('_echarts_instance_')
          _element.removeAttribute('style')
        }
        this.$timer && clearTimeout(this.$timer)
        this.$timer = setTimeout(() => {
          this.viewrender()
        }, 150)
      }
      this.$timer && clearTimeout(this.$timer)
      this.$timer = setTimeout(() => {
        this.viewrender()
      }, 150)
    }
    component.width = component.plot.width
    component.name = component.plot.name
    card.width = card.plot.width
    card.name = card.plot.name
    card.errors = []
    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: '未设置上级组件!'})
    }
    if (card.errors.length === 0) {
      card.$tables = getTables(card)
    }
    
    this.setState({
      card: component
      card: card
    })
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  addSearch = () => {
@@ -222,15 +231,11 @@
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
    if (comIds[0] !== card.uuid || comIds.length > 1) return
    let _card = {...card, style}
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    this.updateComponent(_card)
  }
@@ -238,20 +243,26 @@
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.updateComponent(_card)
      })
    }
  }
  render() {
    const { card, appType } = this.state
    let _style = resetStyle(card.style)
    _style.height = 'auto'
    return (
      <div className="menu-custom-chart-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
      <div className="menu-custom-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
            <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
            <ChartCompileForm config={card} plotchange={this.updateComponent}/>
            <CopyComponent type="line" card={card}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
@@ -262,7 +273,23 @@
          <ToolOutlined />
        </Popover>
        <NormalHeader config={card} updateComponent={this.updateComponent}/>
        <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
        <div className="canvas-wrap" style={{height: card.plot.height}}>
          <div className="canvas" id={card.uuid + 'canvas'} style={{height: getHeight(card.plot.height)}} ref={ref => this.wrap = ref}></div>
        </div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/chart/chart-custom/index.scss
@@ -5,14 +5,14 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  flex-flow: column;
  .canvas-wrap {
    padding: 15px;
  }
  .canvas {
    margin: 0px;
    padding: 0px;
    letter-spacing: 0px;
    flex: 1;
  }
  .chart-header {
@@ -44,25 +44,6 @@
    cursor: pointer;
    color: rgba(0, 0, 0, 0.85);
    background: rgba(255, 255, 255, 0.55);
  }
  .model-menu-action-list {
    position: absolute;
    right: 0px;
    top: 30px;
    z-index: 4;
    font-size: 16px;
    .ant-row .anticon-plus {
      float: right;
    }
    .page-card {
      float: right;
    }
  }
  .normal-header + .canvas + .model-menu-action-list {
    top: 45px;
  }
}
.menu-custom-chart-edit-box:hover {
src/menu/components/code/sandbox/codecontent/index.jsx
@@ -4,85 +4,77 @@
import './index.scss'
class BraftContent extends Component {
class CodeContent extends Component {
  static propTpyes = {
    name: PropTypes.string,
    html: PropTypes.any,
    css: PropTypes.any,
    js: PropTypes.any,
    config: PropTypes.object,
  }
  state = {
    csselement: null
  }
  state = {}
  UNSAFE_componentWillMount () {
    const { css } = this.props
    const { config } = this.props
    if (css) {
      // let style = css.replace(/^[^}{]*{|}[^}{]*{/ig, (word) => {
      //   return word.replace(/}\n*/ig, `}\n#${mark}`).replace(/,/ig, `,#${mark} `)
      // })
      // style = `\n/* 自定义 */\n#${mark} ${style}\n`
    if (config.css) {
      let node = document.getElementById(config.uuid + 'style')
      node && node.remove()
      let ele = document.createElement('style')
      ele.innerHTML = css
      ele.id = config.uuid + 'style'
      ele.innerHTML = config.css
      document.getElementsByTagName('head')[0].appendChild(ele)
      // document.getElementsByTagName('head')[0].prepend(ele)
      this.setState({csselement: ele})
    }
  }
  componentDidMount () {
    const { js, name } = this.props
    if (js) {
    const { config } = this.props
    if (config.js && config.wrap.compileMode !== 'custom') {
      try {
        // eslint-disable-next-line no-eval
        eval(js)
        eval(config.js)
      } catch (e) {
        message.warning(name + 'JS 执行失败!')
        message.warning(config.name + 'JS 执行失败!')
        console.warn(config.name + e)
      }
    }
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (this.props.css !== nextProps.css) {
      const { csselement } = this.state
      if (csselement && csselement.remove) {
        csselement.remove()
      }
      if (nextProps.css) {
        let ele = document.createElement('style')
        ele.innerHTML = nextProps.css
        document.getElementsByTagName('head')[0].appendChild(ele)
    const { config } = this.props
        this.setState({csselement: ele})
    if (config.css !== nextProps.config.css) {
      let node = document.getElementById(config.uuid + 'style')
      node && node.remove()
      if (nextProps.config.css) {
        let ele = document.createElement('style')
        ele.id = config.uuid + 'style'
        ele.innerHTML = nextProps.config.css
        document.getElementsByTagName('head')[0].appendChild(ele)
      }
    }
    if (this.props.html !== nextProps.html || this.props.js !== nextProps.js) {
      if (nextProps.js) {
    if (config.html !== nextProps.config.html || config.js !== nextProps.config.js) {
      if (nextProps.config.js && nextProps.config.wrap.compileMode !== 'custom') {
        try {
          // eslint-disable-next-line no-eval
          eval(nextProps.js)
          eval(nextProps.config.js)
        } catch (e) {
          message.warning(nextProps.name + 'JS 执行失败!')
          message.warning(config.name + 'JS 执行失败!')
          console.warn(config.name + e)
        }
      }
    }
  }
  render() {
    const { html } = this.props
    const { config } = this.props
    if (!html) return <Empty style={{padding: '10px 0px'}} description={null}/>
    if (!config.html) return <Empty style={{padding: '10px 0px'}} description={null}/>
    return (
      <div dangerouslySetInnerHTML={{ __html: html }}></div>
      <div dangerouslySetInnerHTML={{ __html: config.html }}></div>
    )
  }
}
export default BraftContent
export default CodeContent
src/menu/components/code/sandbox/editorcode/index.jsx
@@ -4,8 +4,6 @@
import { Modal, Tabs, message } from 'antd'
import { FormOutlined } from '@ant-design/icons'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
@@ -19,7 +17,6 @@
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    visible: false,
    html: '',
    css: '',
@@ -75,7 +72,7 @@
  }
  render () {
    const { visible, dict, html, css, js } = this.state
    const { visible, html, css, js } = this.state
    return (
      <div style={{display: 'inline-block'}}>
@@ -86,7 +83,7 @@
          visible={visible}
          width={950}
          maskClosable={false}
          okText={dict['model.submit']}
          okText="提交"
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
src/menu/components/code/sandbox/index.jsx
@@ -9,8 +9,6 @@
import { resetStyle } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import getWrapForm from './options'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import './index.scss'
@@ -29,7 +27,6 @@
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    card: null,
    back: false
  }
@@ -41,17 +38,14 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        dataName: card.dataName || '',
        format: 'object',   // 组件属性 - 数据格式
        format: 'array',    // 组件属性 - 数据格式
        pageable: false,    // 组件属性 - 是否可分页
        switchable: false,  // 组件属性 - 数据是否可切换
        width: card.width || 24,
        name: card.name,
        subtype: card.subtype,
        setting: { interType: 'system' },
        wrap: { name: card.name, width: card.width || 24, encryption: 'true' },
        wrap: { name: card.name, datatype: 'dynamic', width: card.width || 24, encryption: 'true' },
        style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
        columns: [],
        scripts: [],
@@ -75,19 +69,15 @@
        _card.scripts = config.scripts
      }
      
      this.updateComponent(_card)
    } else {
      let _card = fromJS(card).toJS()
      _card.format = 'array'
      this.setState({
        card: _card
      })
      this.props.updateConfig(_card)
    } else {
      this.setState({
        card: fromJS(card).toJS()
      })
    }
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -101,51 +91,50 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
  }
  /**
   * @description 卡片行外层信息更新(数据源,样式等)
   */
  updateComponent = (component) => {
  updateComponent = (card) => {
    card.width = card.wrap.width
    card.name = card.wrap.name
    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: '未设置数据源!'})
      } 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: '未设置上级组件!'})
      }
    }
    this.setState({
      card: component
      card: card
    })
    component.width = component.wrap.width
    component.name = component.wrap.name
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
    if (comIds[0] !== card.uuid || comIds.length !== 1) return
    let _card = {...card, style}
    this.setState({
      card: _card
    })
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    
    this.props.updateConfig(_card)
  }
  /**
   * @description 更新搜索条件配置信息
   */
  updateconfig = (config) => {
    this.setState({
      card: config
    })
    this.props.updateConfig(config)
    this.updateComponent(_card)
  }
  getWrapForms = () => {
@@ -155,13 +144,19 @@
  }
  updateWrap = (res) => {
    this.updateconfig({...this.state.card, wrap: res})
    this.updateComponent({...this.state.card, wrap: res})
  }
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.setState({ card: _card })
        this.props.updateConfig(_card)
      })
    }
  }
@@ -176,7 +171,7 @@
            <NormalForm title="自定义组件设置" width={700} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="normaltable" card={card}/>
            <CopyComponent type="sandbox" card={card}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)} />
@@ -187,7 +182,21 @@
        } trigger="hover">
          <ToolOutlined />
        </Popover>
        <CodeContent name={card.name} html={card.html} css={card.css} js={card.js}/>
        <CodeContent config={card}/>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/code/sandbox/options.jsx
@@ -45,6 +45,20 @@
      options: [
        {value: 'dynamic', label: '动态'},
        {value: 'static', label: '静态'},
      ],
      controlFields: [
        {field: 'compileMode', values: ['dynamic']}
      ]
    },
    {
      type: 'radio',
      field: 'compileMode',
      label: '编译方式',
      initval: wrap.compileMode || 'replace',
      required: false,
      options: [
        {value: 'replace', label: '字段替换'},
        {value: 'custom', label: '自定义'},
      ]
    },
    {
src/menu/components/editor/braft-editor/editorcontent/index.jsx
@@ -4,8 +4,6 @@
import { Modal } from 'antd'
import { FormOutlined } from '@ant-design/icons'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
@@ -18,7 +16,6 @@
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    visible: false,
    html: null
  }
@@ -54,7 +51,7 @@
  render () {
    const { config } = this.props
    const { visible, dict, html } = this.state
    const { visible, html } = this.state
    if (!config) return null
@@ -68,7 +65,7 @@
          visible={visible}
          width={950}
          maskClosable={false}
          okText={dict['model.submit']}
          okText="提交"
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
src/menu/components/editor/braft-editor/index.jsx
@@ -6,6 +6,7 @@
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { getTables } from '@/utils/utils-custom.js'
import getWrapForm from './options'
import MKEmitter from '@/utils/events.js'
@@ -38,9 +39,6 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        dataName: card.dataName || '',
        format: 'object',   // 组件属性 - 数据格式
        pageable: false,    // 组件属性 - 是否可分页
        switchable: false,  // 组件属性 - 数据是否可切换
@@ -48,7 +46,7 @@
        name: card.name,
        subtype: card.subtype,
        setting: { interType: 'system' },
        wrap: { name: card.name, width: card.width || 24, encryption: 'true', minHeight: 100 },
        wrap: { name: card.name, datatype: 'dynamic', width: card.width || 24, encryption: 'true', minHeight: 100 },
        style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
        headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
        columns: [],
@@ -69,20 +67,13 @@
        _card.columns = config.columns
        _card.scripts = config.scripts
      }
      this.setState({
        card: _card
      })
      this.props.updateConfig(_card)
      this.updateComponent(_card)
    } else {
      this.setState({
        card: fromJS(card).toJS()
      })
    }
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -96,46 +87,54 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
  }
  /**
   * @description 卡片行外层信息更新(数据源,样式等)
   */
  updateComponent = (component) => {
  updateComponent = (card) => {
    card.width = card.wrap.width
    card.name = card.wrap.name
    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: '未设置数据源!'})
      } 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: '未设置上级组件!'})
      }
      if (card.errors.length === 0) {
        card.$tables = getTables(card)
      }
    }
    this.setState({
      card: component
      card: card
    })
    component.width = component.wrap.width
    component.name = component.wrap.name
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
    if (comIds[0] !== card.uuid) return
    let _card = {}
    if (comIds.length === 1) {
      _card = {...card, style}
    } else {
      return
    }
    this.setState({
      card: _card
    })
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    
    this.props.updateConfig(_card)
    this.updateComponent(_card)
  }
  getWrapForms = () => {
@@ -151,7 +150,13 @@
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.setState({ card: _card })
        this.props.updateConfig(_card)
      })
    }
  }
@@ -186,6 +191,20 @@
          value={card.wrap.datatype !== 'static' ? '<p class="empty-content">富文本</p>' : card.html}
          encryption="false"
        />
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
src/menu/components/form/dragtitle/card.jsx
@@ -9,8 +9,9 @@
import './index.scss'
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const Card = ({ id, card, active, moveCard, findCard, closeCard, selectCard, updateGroup }) => {
const Card = ({ id, card, sort, active, moveCard, findCard, closeCard, selectCard, updateGroup }) => {
  const originalIndex = findCard(id).index
  const [{ isDragging }, drag] = useDrag({
    item: { type: 'form', id, originalIndex },
@@ -32,7 +33,7 @@
      }
    }
  })
  const opacity = isDragging ? 0 : 1
  const opacity = isDragging ? 0.5 : 1
  const close = () => {
    closeCard(id)
@@ -42,7 +43,7 @@
    selectCard(id)
  }
  const getForms = () =>{
  const getForms = () => {
    return getForm(card)
  }
@@ -73,12 +74,13 @@
        <NormalForm title="分组编辑" width={850} update={updateSetting} getForms={getForms}>
          <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
        </NormalForm>
        <CopyComponent type="formgroup" card={card}/>
        <CloseOutlined className="close" type="close" onClick={close} />
      </div>
    } trigger="hover">
      <div className={'page-card ' + (active ? 'active' : '')} onClick={select} style={{ opacity: opacity}}>
        <div ref={node => drag(drop(node))}>
          <span className="form-sort">{card.sort}</span>
          <span className="form-sort">{sort}</span>
          {card.setting.title}
        </div>
      </div>
src/menu/components/form/dragtitle/index.jsx
@@ -40,10 +40,11 @@
  return (
    <div className={'normal-form-titles ' + (tabtype || '') } >
      {cards.map(card => (
      {cards.map((card, i) => (
        <Card
          id={card.uuid}
          key={card.uuid}
          sort={i + 1}
          active={card.uuid === selectId}
          card={card}
          moveCard={moveCard}
src/menu/components/form/dragtitle/index.scss
@@ -6,6 +6,7 @@
    position: relative;
    flex: 1;
    text-align: center;
    background: transparent;
    cursor: move;
    .form-sort {
      background: #d8d8d8;
src/menu/components/form/dragtitle/options.jsx
@@ -7,13 +7,13 @@
  if (appType === 'mob') {
    group.fields.forEach(f => {
      if (f.field && ['select', 'text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
      if (f.field && ['select', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
        fields.push(f)
      }
    })
  } else {
    group.fields.forEach(f => {
      if (f.field && ['select', 'link', 'text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
      if (f.field && ['select', 'link', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
        fields.push(f)
      }
    })
@@ -46,6 +46,18 @@
    },
    {
      type: 'radio',
      field: 'cache',
      label: '选项查询',
      initval: group.setting.cache || 'true',
      tooltip: '需要通过数据源查询的选项,是否使用缓存。',
      required: false,
      options: [
        {value: 'true', label: '缓存'},
        {value: 'false', label: '实时'},
      ]
    },
    {
      type: 'radio',
      field: 'align',
      label: '表单排列',
      initval: group.setting.align || 'left_right',
@@ -58,10 +70,24 @@
    },
    {
      type: 'radio',
      field: 'verticalSpace',
      label: '竖向间隙',
      initval: group.setting.verticalSpace || 'normal',
      tooltip: '正常间隙会预留出报错信息的位置,防止表单位置发生变化。',
      required: false,
      options: [
        {value: 'normal', label: '正常'},
        {value: 'middle', label: '中'},
        {value: 'small', label: '小'},
      ],
      forbid: appType === 'mob'
    },
    {
      type: 'radio',
      field: 'prevEnable',
      label: '上一步',
      initval: group.prevButton ? group.prevButton.enable || 'false' : 'false',
      tooltip: '第一组不显示。',
      tooltip: '第一组不显示。注:除关闭功能外。',
      required: false,
      options: [
        {value: 'true', label: '显示'},
@@ -85,7 +111,7 @@
      field: 'nextEnable',
      label: '跳过',
      initval: group.nextButton ? group.nextButton.enable || 'false' : 'false',
      tooltip: '最后一组不显示。',
      tooltip: '最后一组不显示。注:除关闭功能外。',
      required: false,
      options: [
        {value: 'true', label: '显示'},
src/menu/components/form/formaction/actionform/index.jsx
@@ -11,7 +11,6 @@
class ActionForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,      // 字典项
    formlist: PropTypes.any,     // 表单信息
    card: PropTypes.any,         // 按钮信息
    inputSubmit: PropTypes.any   // 回车提交事件
@@ -21,6 +20,8 @@
    formlist: null,  // 表单信息
    interType: null, // 接口类型:内部、外部
    procMode: null,  // 参数方式
    linkmenu: null,
    callbackType: null
  }
  
@@ -29,12 +30,15 @@
    let _intertype = card.intertype || 'system'  // 接口类型
    let _procMode = card.procMode || 'system'    // 参数请求方式
    let _callbackType = card.callbackType || 'script'
    let _options = this.getOptions(_intertype, _procMode)
    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') {
          item.required = true
@@ -46,30 +50,53 @@
    })
  }
  getOptions = (_intertype, _procMode) => {
  getOptions = (_intertype, _procMode, linkmenu, _callbackType) => {
    const { card } = this.props
    if (card.type === 'prev') {
      return ['type', 'label', 'enable']
      return ['type', 'label', 'enable', 'actionType']
    } else if (card.type === 'next') {
      return ['type', 'label', 'enable', 'actionType']
    } else if (card.type === 'close') {
      return ['type', 'label', 'enable']
    }
    let _options = ['type', 'label', 'intertype', 'syncComponent', 'linkmenu', 'open', 'enable', 'output', 'reload'] // 选项列表
    let _options = ['type', 'label', 'intertype', 'Ot', 'execSuccess', 'syncComponent', 'anchors', 'linkmenu', 'enable', 'output', 'reload'] // 选项列表
    
    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 {
      _options.push('sql', 'sqlType')
    }
    if (linkmenu && linkmenu !== 'goback') {
      _options.push('open')
    }
    return _options
@@ -82,10 +109,10 @@
   * 3、切换标签类型,重置可选标签
   */
  optionChange = (key, value) => {
    const { procMode } = this.state
    const { procMode, linkmenu, callbackType } = this.state
    if (key === 'intertype') {
      let _options = this.getOptions(value, procMode)
      let _options = this.getOptions(value, procMode, linkmenu, callbackType)
      this.setState({
        interType: value,
@@ -101,16 +128,39 @@
        })
      })
    } else if (key === 'procMode') {
      let _options = this.getOptions(this.state.interType, value)
      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, 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
        })
      })
@@ -144,6 +194,7 @@
  getFields() {
    const { getFieldDecorator } = this.props.form
    const { interType, callbackType } = this.state
    const fields = []
    this.state.formlist.forEach((item, index) => {
@@ -169,6 +220,24 @@
            max: formRule.func.max,
            message: formRule.func.maxMessage
          }]
        } else if (item.key === 'output') {
          if (interType === 'system' || ((interType === 'outer' || interType === 'custom') && callbackType === 'script')) {
            _rules = [{
              pattern: /^@[0-9a-zA-Z_]+@?$/,
              message: '变量以@符开头,可使用字母、数字以及_'
            }, {
              max: 100,
              message: '最多100个字符。'
            }]
          } else {
            _rules = [{
              pattern: /^[0-9a-zA-Z_]*$/,
              message: '字段可使用字母、数字以及_'
            }, {
              max: 100,
              message: '最多100个字符。'
            }]
          }
        } else {
          _rules = [{
            max: formRule.input.max,
@@ -188,7 +257,7 @@
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                    message: '请输入' + item.label + '!'
                  },
                  ..._rules
                ]
@@ -218,7 +287,7 @@
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<InputNumber min={0} max={10000} precision={0} onPressEnter={this.handleSubmit}/>)}
@@ -239,7 +308,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
@@ -274,7 +343,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
@@ -300,7 +369,7 @@
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<TextArea rows={2} readOnly={item.readonly}/>)}
@@ -321,7 +390,7 @@
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
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
@@ -1,21 +1,18 @@
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
/**
 * @description 获取表单按钮配置信息
 * @param {*} card           编辑按钮
 * @param {*} type           按钮类型,用于区分可选的打开方式
 */
export function getActionForm (card, functip, tableName, usefulFields, modules) {
export function getActionForm (card, functip, tableName, usefulFields, modules, anchors) {
  const appType = sessionStorage.getItem('appType')
  let _type = '提交'
  if (card.type === 'prev') {
    _type = '上一步'
  } else if (card.type === 'next') {
    _type = '下一步'
  } else if (card.type === 'close') {
    _type = '关闭'
  }
  let menulist = []
@@ -31,9 +28,7 @@
    } else {
      menulist = []
    }
    if (appType === 'mob') {
      menulist.push({value: 'goback', text: '返回(上一页)'})
    }
    menulist.push({value: 'goback', text: '返回(上一页)'})
  } else {
    menulist = sessionStorage.getItem('fstMenuList')
    if (menulist) {
@@ -64,19 +59,34 @@
    },
    {
      type: 'radio',
      key: 'actionType',
      label: '执行操作',
      initVal: card.actionType || 'default',
      tooltip: '关闭功能:管理系统中会关闭当前标签,子应用中为返回上一页。',
      required: true,
      options: [{
        value: 'default',
        text: '默认'
      }, {
        value: 'close',
        text: '关闭'
      }]
    },
    {
      type: 'radio',
      key: 'intertype',
      label: Formdict['header.form.intertype'],
      label: '接口类型',
      initVal: card.intertype || 'system',
      required: true,
      options: [{
        value: 'system',
        text: Formdict['model.interface.system']
        text: '系统'
      }, {
        value: 'inner',
        text: Formdict['model.interface.inner']
        text: '内部'
      }, {
        value: 'outer',
        text: Formdict['model.interface.outer']
        text: '外部'
      }, {
        value: 'custom',
        text: '自定义'
@@ -94,41 +104,44 @@
      }, {
        value: 'inner',
        text: '内部函数'
      }, {
        value: 'none',
        text: '无'
      }]
    },
    {
      type: 'radio',
      key: 'sqlType',
      label: Formdict['header.form.action.type'],
      initVal: card.sqlType || 'update',
      label: '操作类型',
      initVal: card.sqlType || '',
      required: true,
      options: [{
        value: 'insert',
        text: Formdict['header.form.action.insert']
        text: '添加'
      }, {
        value: 'update',
        text: Formdict['header.form.action.update']
        text: '修改'
      }, {
        value: 'audit',
        text: Formdict['header.form.action.audit']
        text: '审核'
      }]
    },
    {
      type: 'text',
      key: 'sql',
      label: Formdict['model.form.tablename'],
      label: '表名',
      initVal: card.sql || tableName || '',
      required: true
    },
    {
      type: 'text',
      key: 'innerFunc',
      label: Formdict['header.form.innerFunc'],
      label: '内部函数',
      initVal: card.innerFunc || '',
      tooltip: functip,
      fields: usefulFields,
      tooltipClass: 'middle',
      required: card.intertype === 'inner',
      required: true,
      readonly: false
    },
    {
@@ -142,28 +155,29 @@
    {
      type: 'text',
      key: 'url',
      label: Formdict['model.pageUrl'],
      label: '页面地址',
      initVal: card.url || '',
      required: true
    },
    {
      type: 'radio',
      key: 'sysInterface',
      label: Formdict['header.form.sysInterface'],
      label: '系统接口',
      initVal: card.sysInterface || 'false',
      tooltip: '单点登录系统',
      required: true,
      options: [{
        value: 'true',
        text: Formdict['model.true']
        text: '是'
      }, {
        value: 'false',
        text: Formdict['model.false']
        text: '否'
      }]
    },
    {
      type: 'text',
      key: 'outerFunc',
      label: Formdict['header.form.outerFunc'],
      label: '外部函数',
      initVal: card.outerFunc || '',
      required: false,
      readonly: false
@@ -226,6 +240,12 @@
      }, {
        value: 'default',
        text: '后台脚本'
      }, {
        value: 'func',
        text: '回调函数'
      }, {
        value: 'none',
        text: '无'
      }]
    },
    {
@@ -238,10 +258,41 @@
    {
      type: 'text',
      key: 'callbackFunc',
      label: Formdict['header.form.callbackFunc'],
      label: '回调函数',
      initVal: card.callbackFunc || '',
      required: false,
      required: true,
      readonly: false
    },
    {
      type: 'radio',
      key: 'Ot',
      label: '行设置',
      initVal: card.Ot,
      required: true,
      options: [{
        value: 'notRequired',
        text: '不选择行'
      }, {
        value: 'requiredSgl',
        text: '选择单行'
      }]
    },
    {
      type: 'select',
      key: 'execSuccess',
      label: '成功后',
      initVal: card.execSuccess || 'grid',
      required: true,
      options: [{
        value: 'never',
        text: '不刷新'
      }, {
        value: 'grid',
        text: '刷新当前组件'
      }, {
        value: 'mainline',
        text: '刷新上级组件 - 行'
      }]
    },
    {
      type: (appType === 'pc' || appType === 'mob') ? 'select' : 'cascader',
@@ -249,7 +300,7 @@
      label: '下一步操作',
      tooltip: '执行成功后需要打开的菜单。',
      initVal: card.linkmenu,
      help: '可返回上一页。',
      help: appType === 'pc' || appType === 'mob' ? '可返回上一页。' : null,
      required: false,
      allowClear: true,
      options: menulist
@@ -258,7 +309,7 @@
      type: 'text',
      key: 'output',
      label: '返回值',
      tooltip: '执行成功后的返回值。例如:@id',
      tooltip: '执行成功后的返回值。系统函数可指定返回的变量(以@符开头,返回id时可使用@id@);自定义函数可指定返回字段(如id)。',
      initVal: card.output || '',
      required: false
    },
@@ -268,25 +319,31 @@
      label: '打开方式',
      initVal: card.open || 'blank',
      required: false,
      forbid: appType !== 'pc',
      options: [{
        value: 'blank',
        text: '新窗口'
      }, {
        value: 'self',
        text: '当前窗口'
      }]
      forbid: appType !== 'pc' && appType !== 'mob',
      options: [
        {value: 'blank', text: appType !== 'mob' ? '新窗口' : '新页面'},
        {value: 'self', text: appType !== 'mob' ? '当前窗口' : '当前页面'},
      ]
    },
    {
      type: 'cascader',
      key: 'syncComponent',
      label: '同步刷新',
      initVal: card.syncComponent,
      tooltip: '执行成功后需要刷新的组件。',
      tooltip: '执行成功后需要刷新的组件。注:选择当前组件的上级组件无效,刷新上级组件请选择成功后“刷新上级组件 - 行”。',
      required: false,
      options: modules
    },
    {
      type: 'cascader',
      key: 'anchors',
      label: '跳转锚点',
      initVal: card.anchors || [],
      tooltip: '执行成功后,需要跳转的锚点。' + (appType === 'mob' ? '注:小程序中无效' : ''),
      required: false,
      options: anchors
    },
    {
      type: 'radio',
      key: 'reload',
      label: '上一页',
src/menu/components/form/formaction/index.jsx
@@ -4,8 +4,6 @@
import { Modal, Button, Popover } from 'antd'
import { FontColorsOutlined, EditOutlined, ProfileOutlined } from '@ant-design/icons'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import asyncComponent from '@/utils/asyncComponent'
import { getActionForm } from './formconfig'
import { resetStyle } from '@/utils/utils-custom.js'
@@ -24,16 +22,11 @@
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    appType: sessionStorage.getItem('appType'),
    card: null,          // 编辑中元素
    formlist: null,      // 表单信息
    visible: false,      // 模态框控制
    profVisible: false,  // 验证信息编辑
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -47,12 +40,9 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
  }
  handleStyle = (element) => {
    const { group } = this.props
    let _style = element.style ? fromJS(element.style).toJS() : {}
    let options = ['font', 'border', 'padding', 'margin', 'backgroundColor', 'width']
@@ -60,20 +50,21 @@
      card: element
    })
    MKEmitter.emit('changeStyle', [group.uuid, element.type], options, _style)
    MKEmitter.emit('changeStyle', options, _style, this.getStyle)
  }
  getStyle = (comIds, style) => {
  getStyle = (style) => {
    const { card } = this.state
    let group = fromJS(this.props.group).toJS()
    if (comIds.length !== 2 || comIds[0] !== group.uuid) return
    if (comIds[1] === 'prev') {
    if (card.type === 'prev') {
      group.prevButton.style = style
    } else if (comIds[1] === 'submit') {
    } else if (card.type === 'submit') {
      group.subButton.style = style
    } else if (comIds[1] === 'next') {
    } else if (card.type === 'next') {
      group.nextButton.style = style
    } else if (card.type === 'close') {
      group.closeButton.style = style
    }
    this.props.updateconfig(group)
@@ -97,16 +88,27 @@
    }
    let ableField = usefulFields.join(', ')
    let msg = `函数名称需以${ableField}等字符开始;`
    let functip = <div>
      <p style={{marginBottom: '5px'}}>{this.state.dict['model.tooltip.func.innerface'].replace('@ableField', ableField)}</p>
      <p style={{marginBottom: '5px'}}>{msg}</p>
    </div>
    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid) || []
    let supId = ''
    if (config.wrap.linkType === 'sup') {
      supId = config.wrap.supModule[config.wrap.supModule.length - 1]
    }
    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid, supId)
    let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, config.uuid) || []
    if (card.type === 'submit' && !card.Ot) {
      card.Ot = config.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
    }
    this.setState({
      visible: true,
      card: card,
      formlist: getActionForm(card, functip, config.setting.tableName, usefulFields, modules)
      formlist: getActionForm(card, functip, config.setting.tableName, usefulFields, modules, anchors)
    })
  }
@@ -136,11 +138,16 @@
      let group = fromJS(this.props.group).toJS()
      if (res.type === 'prev') {
        res.enable = group.prevButton.enable || 'true'
        group.prevButton = res
      } else if (res.type === 'submit') {
        group.subButton = res
      } else if (res.type === 'next') {
        res.enable = group.nextButton.enable || 'true'
        group.nextButton = res
      } else if (res.type === 'close') {
        res.enable = group.closeButton.enable || 'true'
        group.closeButton = res
      }
      this.setState({
@@ -192,11 +199,11 @@
  render() {
    const { group, config } = this.props
    const { visible, profVisible, card, dict } = this.state
    const { visible, profVisible, card } = this.state
    return (
      <div className="mk-form-action">
        {group.prevButton && group.prevButton.enable !== 'false' && group.sort !== 1 ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
        {group.prevButton && group.prevButton.enable === 'true' ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <EditOutlined className="edit" title="编辑" onClick={() => this.handleAction(group.prevButton)} />
            <FontColorsOutlined className="style" title="调整样式" onClick={() => this.handleStyle(group.prevButton)}/>
@@ -213,7 +220,15 @@
        } trigger="hover">
          <Button type="link" className="submit mk-primary" onDoubleClick={this.changeMenu} style={resetStyle(group.subButton.style)}>{group.subButton.label}</Button>
        </Popover>
        {group.nextButton && group.nextButton.enable !== 'false' && group.sort !== config.subcards.length ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
        {group.closeButton && group.closeButton.enable === 'true' ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <EditOutlined className="edit" title="编辑" onClick={() => this.handleAction(group.closeButton)} />
            <FontColorsOutlined className="style" title="调整样式" onClick={() => this.handleStyle(group.closeButton)}/>
          </div>
        } trigger="hover">
          <Button type="link" style={resetStyle(group.closeButton.style)}>{group.closeButton.label}</Button>
        </Popover> : null}
        {group.nextButton && group.nextButton.enable === 'true' ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <EditOutlined className="edit" title="编辑" onClick={() => this.handleAction(group.nextButton)} />
            <FontColorsOutlined className="style" title="调整样式" onClick={() => this.handleStyle(group.nextButton)}/>
@@ -223,19 +238,18 @@
        </Popover> : null}
        {/* 编辑按钮:复制、编辑 */}
        <Modal
          title={dict['model.edit']}
          title="编辑"
          visible={visible}
          width={800}
          width={920}
          maskClosable={false}
          onCancel={this.editModalCancel}
          footer={[
            <Button key="cancel" onClick={this.editModalCancel}>{dict['model.cancel']}</Button>,
            <Button key="confirm" type="primary" onClick={this.handleActionSubmit}>{dict['model.confirm']}</Button>
            <Button key="cancel" onClick={this.editModalCancel}>取消</Button>,
            <Button key="confirm" type="primary" onClick={this.handleActionSubmit}>确定</Button>
          ]}
          destroyOnClose
        >
          <ActionForm
            dict={dict}
            card={card}
            setting={config.setting}
            formlist={this.state.formlist}
@@ -245,12 +259,11 @@
        </Modal>
        {/* 按钮使用系统存储过程时,验证信息模态框 */}
        <Modal
          wrapClassName="model-table-action-verify-modal"
          title={'验证信息'}
          wrapClassName="mk-pop-modal"
          visible={profVisible}
          width={'90vw'}
          maskClosable={false}
          okText={dict['model.submit']}
          okText="提交"
          onOk={this.verifySubmit}
          onCancel={() => {
            if (this.verifyRef.handleCancel) {
@@ -265,7 +278,6 @@
        >
          <VerifyCard
            card={{...group.subButton, modal: {fields: group.fields}}}
            dict={dict}
            config={config}
            columns={config.columns}
            wrappedComponentRef={(inst) => this.verifyRef = inst}
src/menu/components/form/formaction/index.scss
@@ -4,6 +4,7 @@
  padding-bottom: 10px;
  .prev {
    color: rgba(0, 0, 0, 0.85);
    height: auto;
  }
  .submit {
@@ -11,7 +12,9 @@
    height: auto;
  }
  .skip {
    float: right;
    color: rgba(0, 0, 0, 0.85);
    position: absolute;
    height: auto;
    right: 0px;
  }
}
src/menu/components/form/simple-form/index.jsx
New file
@@ -0,0 +1,725 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, Modal, Button, Switch, notification } from 'antd'
import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import moment from 'moment'
import Api from '@/api'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { getModalForm } from '@/templates/zshare/formconfig'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import Utils from '@/utils/utils.js'
import getWrapForm from './options'
import './index.scss'
const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CardComponent = asyncComponent(() => import('@/templates/modalconfig/dragelement'))
const MobCardComponent = asyncComponent(() => import('@/mob/components/formdragelement'))
const FormAction = asyncComponent(() => import('../formaction'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
const { confirm } = Modal
class SimpleFormComponent extends Component {
  static propTpyes = {
    card: PropTypes.object,
    deletecomponent: PropTypes.func,
    updateConfig: PropTypes.func,
  }
  state = {
    appType: sessionStorage.getItem('appType'),
    card: null,
    back: false,
    showField: false,
    visible: false,
    editform: null,
    formlist: null,
    sqlVerifing: false,
    standardform: null
  }
  UNSAFE_componentWillMount () {
    const { card } = this.props
    if (card.isNew) {
      let _card = {
        uuid: card.uuid,
        type: card.type,
        format: 'object',   // 组件属性 - 数据格式
        pageable: false,    // 组件属性 - 是否可分页
        switchable: false,  // 组件属性 - 数据是否可切换
        width: card.width || 24,
        name: card.name,
        subtype: card.subtype,
        setting: { interType: 'system' },
        wrap: { name: card.name, width: card.width || 24, datatype: 'static' },
        style: { marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px' },
        headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
        columns: [],
        scripts: [],
        subcards: [{
          uuid: Utils.getuuid(),
          setting: {title: '空', align: 'left_right', enable: 'true'},
          style: {},
          fields: [],
          subButton: {label: '提交', type: 'submit', intertype: 'system', reload: 'false', sqlType: 'update', sql: '', Ot: 'notRequired', execSuccess: 'never', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
        }]
      }
      if (card.config) {
        let config = fromJS(card.config).toJS()
        _card.wrap = config.wrap
        _card.wrap.name = card.name
        _card.style = config.style
        _card.setting = config.setting
        _card.columns = config.columns
        _card.scripts = config.scripts
        _card.subcards = config.subcards.map(scard => {
          scard.uuid = Utils.getuuid()
          scard.fields = scard.fields.map(elem => {
            elem.uuid = Utils.getuuid()
            return elem
          })
          return scard
        })
      }
      this.updateComponent(_card)
    } else {
      let _card = fromJS(card).toJS()
      this.setState({
        card: _card
      })
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
  }
  /**
   * @description 卡片行外层信息更新(数据源,样式等)
   */
  updateComponent = (card) => {
    card.width = card.wrap.width
    card.name = card.wrap.name
    card.errors = []
    if (card.wrap.datatype !== 'static') {
      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)
      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: '未设置上级组件!'})
      }
      if (card.errors.length === 0) {
        card.$tables = getTables(card)
      }
      card.subcards.forEach(item => {
        item.fields.forEach(m => {
          if (m.type === 'linkMain' && !supModule) {
            card.errors.push({ level: 1, detail: `请检查关联主表“${m.label}”是否有效`})
          }
        })
      })
    } else {
      let supModule = card.wrap.supModule ? card.wrap.supModule[card.wrap.supModule.length - 1] : ''
      card.$tables = getTables(card)
      card.subcards.forEach(item => {
        item.fields.forEach(m => {
          if (m.type === 'linkMain' && !supModule) {
            card.errors.push({ level: 1, detail: `请检查关联主表“${m.label}”是否有效`})
          }
        })
      })
    }
    this.setState({
      card: card
    })
    this.props.updateConfig(card)
  }
  /**
   * @description 单个卡片信息更新
   */
  updateCard = (cell) => {
    let card = fromJS(this.state.card).toJS()
    card.subcards = card.subcards.map(item => {
      if (item.uuid === cell.uuid) return cell
      return item
    })
    this.updateComponent(card)
  }
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    this.updateComponent(_card)
  }
  updateGroup = (res) => {
    let card = fromJS(this.state.card).toJS()
    card.subcards[0] = res
    this.updateComponent(card)
  }
  plusFields = (items) => {
    const { card } = this.state
    let _card = fromJS(card).toJS()
    _card.subcards[0].fields.push(...items)
    this.updateComponent(_card)
  }
  changecols = (type) => {
    let card = fromJS(this.state.card).toJS()
    let _this = this
    card.subcards[0].fields = card.subcards[0].fields.map(item => {
      item.labelwidth = 33.3
      item.span = 24
      if (['textarea','split','hint','checkcard','brafteditor'].includes(item.type)) {
        if (type === 2) {
          item.labelwidth = 16.3
        } else if (type === 3) {
          item.labelwidth = 10.5
        } else if (type === 4) {
          item.labelwidth = 8.3
        }
      } else if (type === 2) {
        item.span = 12
      } else if (type === 3) {
        item.span = 8
      } else if (type === 4) {
        item.span = 6
      }
      return item
    })
    confirm({
      content: `确定切换为${type}列吗?`,
      onOk() {
        _this.updateComponent(card)
      },
      onCancel() {}
    })
  }
  handleList = (list, newcard) => {
    let card = fromJS(this.state.card).toJS()
    card.subcards[0].fields = list
    this.setState({}, () => {
      if (newcard) {
        this.handleForm(newcard)
      }
    })
    this.updateComponent(card)
  }
  closeForm = (cell) => {
    let card = fromJS(this.state.card).toJS()
    let _this = this
    card.subcards[0].fields = card.subcards[0].fields.filter(item => item.uuid !== cell.uuid)
    confirm({
      content: `确定删除<<${cell.label}>>吗?`,
      onOk() {
        _this.updateComponent(card)
      },
      onCancel() {}
    })
  }
  addForm = () => {
    const { appType } = this.state
    let card = fromJS(this.state.card).toJS()
    let lastItem = card.subcards[0].fields[card.subcards[0].fields.length - 1]
    let span = appType === 'mob' ? 24 : 12
    if (lastItem && lastItem.span) {
      span = lastItem.span
    }
    let newcard = {
      uuid: Utils.getuuid(),
      label: '',
      field: '',
      initval: '',
      type: 'text',
      resourceType: '0',
      span: span,
      labelwidth: 33.3,
      options: [],
      dataSource: '',
      decimal: 0,
      orderType: 'asc',
      readonly: 'false',
      required: 'true',
      focus: true
    }
    card.subcards[0].fields.push(newcard)
    this.setState({card}, () => {
      this.handleForm(newcard)
    })
  }
  editModalCancel = () => {
    let card = fromJS(this.state.card).toJS()
    card.subcards[0].fields = card.subcards[0].fields.filter(item => !item.focus)
    this.setState({card, visible: false, editform: null})
  }
  /**
   * @description 表单编辑
   */
  handleForm = (_item) => {
    const { card, appType } = this.state
    let _form = fromJS(_item).toJS()
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = []
    let standardform = null
    let uniq = new Map()
    let index = null
    uniq.set(_form.field, true)
    let _inputIndex = 1
    let _tabIndex = 1
    let _linkIndex = 1
    card.subcards[0].fields.forEach((item, i) => {
      if (_form.uuid === item.uuid) {
        index = i
      }
      let label = `${item.field || ''}(${item.label})`
      if (['text', 'number', 'textarea', 'color'].includes(item.type) && _item.field !== item.field) {
        _inputfields.push({
          field: item.field,
          label: _inputIndex + '、' + label
        })
        _inputIndex++
      }
      if (_form.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
        _tabfields.push({
          field: item.field,
          label: _tabIndex + '、' + label
        })
        _tabIndex++
      }
      if (item.type === 'switch') {
        _linksupFields.push({
          field: item.field,
          label: _linkIndex + '、' + label
        })
      }
      if (!['select', 'link', 'radio', 'checkcard'].includes(item.type)) return
      if (item.type === 'checkcard' && item.multiple === 'true') return // 选项卡多选
      if (item.field && !uniq.has(item.field)) {
        uniq.set(item.field, true)
        _linkableFields.push({
          value: item.field,
          text: _linkIndex + '、' + item.label + ' (表单)'
        })
        _linksupFields.push({
          value: item.field,
          text: _linkIndex + '、' + label
        })
        _linkIndex++
      }
    })
    _tabfields.unshift({field: '', label: '原表单'})
    if (index !== null) {
      if (index === 0) {
        standardform = card.subcards[0].fields[index + 1] || null
      } else {
        standardform = card.subcards[0].fields[index - 1] || null
      }
    }
    card.columns.forEach(col => {
      if (col.field && !uniq.has(col.field)) {
        uniq.set(col.field, true)
        _linkableFields.push({
          field: col.field,
          label: _linkIndex + '、' + col.label + ' (显示列)'
        })
        _linkIndex++
      }
    })
    if (_form.linkSubField && _form.linkSubField.length > 0) {
      let fields = _inputfields.map(item => item.field)
      _form.linkSubField = _form.linkSubField.filter(item => fields.includes(item))
    }
    if (appType !== 'mob' && !_form.span && standardform && standardform.span) {
      _form.span = standardform.span
      _form.labelwidth = standardform.labelwidth
    }
    this.setState({
      standardform,
      visible: true,
      editform: _form,
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields, card.columns)
    })
  }
  /**
   * @description 编辑后提交
   * 1、获取编辑后的表单信息
   * 2、去除可能存在的示例表单
   * 3、通过loading刷新
   */
  handleSubmit = () => {
    this.formRef.handleConfirm().then(res => {
      let _config = fromJS(this.state.card).toJS()
      let fieldrepet = false // 字段重复
      _config.subcards[0].fields = _config.subcards[0].fields.map(item => {
        if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
          fieldrepet = true
        }
        if (item.uuid === res.uuid) {
          if (item.style) {
            res.style = item.style
          }
          return res
        } else {
          return item
        }
      })
      if (fieldrepet) {
        notification.warning({
          top: 92,
          message: '字段已存在!',
          duration: 10
        })
        return
      }
      if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) {
        this.setState({
          sqlVerifing: true
        })
        let param = {
          func: 's_debug_sql',
          exec_type: 'y',
          LText: `declare @mk_organization nvarchar(512)
            ${res.dataSource}`
        }
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
        param.LText = param.LText.replace(/\n/g, ' ')
        param.LText = Utils.formatOptions(param.LText)
        param.secretkey = Utils.encrypt('', param.timestamp)
        if (window.GLOB.mainSystemApi && res.database === 'sso') {
          param.rduri = window.GLOB.mainSystemApi
        }
        Api.genericInterface(param).then(result => {
          if (result.status) {
            this.setState({
              sqlVerifing: false,
              editform: null,
              visible: false
            })
            this.updateComponent(_config)
          } else {
            this.setState({sqlVerifing: false})
            Modal.error({
              title: result.message
            })
          }
        })
      } else {
        this.setState({
          editform: null,
          visible: false
        })
        this.updateComponent(_config)
      }
    })
  }
  pasteForm = (res) => {
    let _config = fromJS(this.state.card).toJS()
    if (res.subButton) {
      let _this = this
      _config.subcards[0].setting.focus = res.focus
      _config.subcards[0].setting.cache = res.cache
      _config.subcards[0].setting.align = res.align
      _config.subcards[0].setting.enable = res.enable
      _config.subcards[0].setting.verticalSpace = res.verticalSpace || ''
      _config.wrap.focus = res.focus
      _config.wrap.cache = res.cache
      _config.wrap.align = res.align
      _config.wrap.enable = res.enable
      _config.wrap.verticalSpace = res.verticalSpace || ''
      _config.subcards[0].subButton = res.subButton
      _config.subcards[0].fields = res.fields.map(item => {
        item.uuid = Utils.getuuid()
        return item
      })
      confirm({
        content: `替换表单及按钮配置?`,
        onOk() {
          _this.updateComponent(_config)
        },
        onCancel() {}
      })
      return
    }
    let fieldrepet = false // 字段重复
    _config.subcards[0].fields.forEach(item => {
      if (res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
        fieldrepet = true
      }
    })
    if (fieldrepet) {
      notification.warning({
        top: 92,
        message: '字段已存在!',
        duration: 10
      })
      return
    }
    _config.subcards[0].fields.push(res)
    this.updateComponent(_config)
    this.handleForm(res)
    notification.success({
      top: 92,
      message: '粘贴成功!',
      duration: 2
    })
  }
  getWrapForms = () => {
    return getWrapForm(this.state.card)
  }
  updateWrap = (res) => {
    let _card = fromJS(this.state.card).toJS()
    _card.wrap = res
    if (res.datatype === 'static') {
      if (res.supModule && res.supModule.length > 0) {
        _card.setting.supModule = res.supModule
      } else {
        _card.setting.supModule = ''
      }
    }
    _card.subcards[0].setting.focus = _card.wrap.focus
    _card.subcards[0].setting.cache = _card.wrap.cache
    _card.subcards[0].setting.align = _card.wrap.align
    _card.subcards[0].setting.enable = _card.wrap.enable
    _card.subcards[0].setting.verticalSpace = _card.wrap.verticalSpace
    if (_card.wrap.closeEnable === 'true' && !_card.subcards[0].closeButton) {
      _card.subcards[0].closeButton = {label: '关闭', enable: 'true', type: 'close', style: {backgroundColor: '#ffffff', color: 'rgba(0,0,0,0.65)', borderColor: '#d9d9d9', borderWidth: '1px', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px', marginLeft: '10px'}}
    } else if (_card.subcards[0].closeButton) {
      _card.subcards[0].closeButton.enable = _card.wrap.closeEnable
    }
    this.updateComponent(_card)
  }
  clearGroup = () => {
    let card = fromJS(this.state.card).toJS()
    let _this = this
    card.subcards[0].fields = []
    confirm({
      content: `确定清空表单吗?`,
      onOk() {
        _this.updateComponent(card)
      },
      onCancel() {}
    })
  }
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.setState({ card: _card })
        this.props.updateConfig(_card)
      })
    }
  }
  render() {
    const { card, appType } = this.state
    return (
      <div className="menu-simple-form-edit-box" style={resetStyle(card.style)} onClick={this.clickComponent} id={card.uuid}>
        <NormalHeader config={card} updateComponent={this.updateComponent}/>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <NormalForm title="表单设置" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="simpleform" card={card}/>
            <PasteComponent config={card} options={['form', 'formgroup']} updateConfig={this.pasteForm} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)} />
            {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
            {card.wrap.datatype === 'static' ? <SettingOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/> : null}
          </div>
        } trigger="hover">
          <ToolOutlined />
        </Popover>
        <div className="form-area">
          <PlusOutlined className="plus" title="添加表单" onClick={this.addForm}/>
          <FieldsComponent config={card.subcards[0]} type="form" plusFields={this.plusFields} />
          <span style={{color: 'red', marginLeft: '30px', cursor: 'pointer'}} onClick={this.clearGroup}>清空</span>
          <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4列</Button> : null}
          <div style={{clear: 'both'}}></div>
          {appType !== 'mob' ? <CardComponent
            list={card.subcards[0].fields}
            setting={card.subcards[0].setting}
            showField={this.state.showField}
            handleList={this.handleList}
            handleForm={this.handleForm}
            closeForm={this.closeForm}
          /> : <MobCardComponent
            list={card.subcards[0].fields}
            setting={card.subcards[0].setting}
            showField={this.state.showField}
            handleList={this.handleList}
            handleForm={this.handleForm}
            closeForm={this.closeForm}
          />}
          <FormAction config={card} group={card.subcards[0]} updateconfig={this.updateGroup}/>
        </div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
        <Modal
          title="编辑"
          visible={this.state.visible}
          width={950}
          maskClosable={false}
          onCancel={this.editModalCancel}
          onOk={this.handleSubmit}
          confirmLoading={this.state.sqlVerifing}
          destroyOnClose
        >
          <ModalForm
            card={this.state.editform}
            formlist={this.state.formlist}
            inputSubmit={this.handleSubmit}
            standardform={this.state.standardform}
            wrappedComponentRef={(inst) => this.formRef = inst}
          />
        </Modal>
      </div>
    )
  }
}
export default SimpleFormComponent
src/menu/components/form/simple-form/index.scss
copy from src/menu/components/form/normal-form/index.scss copy to src/menu/components/form/simple-form/index.scss
File was copied from src/menu/components/form/normal-form/index.scss
@@ -1,4 +1,4 @@
.menu-normal-form-edit-box {
.menu-simple-form-edit-box {
  position: relative;
  box-sizing: border-box;
  background: #ffffff;
@@ -32,10 +32,10 @@
    position: relative;
    background: #ffffff;
    border-radius: 2px;
    margin-bottom: 15px;
  }
  .form-area {
    position: relative;
    padding-top: 15px;
    .page-card {
      background: transparent;
    }
@@ -68,6 +68,10 @@
      padding-top: 10px;
      padding-bottom: 30px;
    }
    .modal-fields-row:not(.mob-form) {
      padding-left: 10px;
      padding-right: 10px;
    }
    .am-list-item {
      background-color: transparent;
    }
src/menu/components/form/simple-form/options.jsx
New file
@@ -0,0 +1,205 @@
import MenuUtils from '@/utils/utils-custom.js'
/**
 * @description Wrap表单配置信息
 */
export default function (config) {
  let appType = sessionStorage.getItem('appType')
  let roleList = sessionStorage.getItem('sysRoles')
  let wrap = config.wrap
  if (roleList) {
    try {
      roleList = JSON.parse(roleList)
    } catch (e) {
      roleList = []
    }
  } else {
    roleList = []
  }
  let fields = [{field: '', label: '空'}]
  if (appType === 'mob') {
    config.subcards[0].fields.forEach(f => {
      if (f.field && ['select', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
        fields.push(f)
      }
    })
  } else {
    config.subcards[0].fields.forEach(f => {
      if (f.field && ['select', 'link', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
        fields.push(f)
      }
    })
  }
  let modules = []
  let menu = window.GLOB.customMenu
  modules = MenuUtils.getSupModules(menu.components, config.uuid, menu.interfaces)
  if (wrap.supModule && wrap.supModule.length > 0 && wrap.supModule[0] !== 'empty') {
    let has = MenuUtils.checkSupModules(modules, wrap.supModule.slice(-1)[0])
    if (!has) {
      wrap.supModule = ''
    }
  }
  const wrapForm = [
    {
      type: 'text',
      field: 'title',
      label: '标题',
      initval: wrap.title || '',
      required: false
    },
    {
      type: 'text',
      field: 'name',
      label: '组件名称',
      initval: wrap.name || '',
      tooltip: '用于组件间的区分。',
      required: true
    },
    {
      type: 'number',
      field: 'width',
      label: '宽度',
      initval: wrap.width || 24,
      tooltip: '栅格布局,每行等分为24列。',
      min: 1,
      max: 24,
      precision: 0,
      required: true
    },
    {
      type: 'radio',
      field: 'datatype',
      label: '数据来源',
      initval: wrap.datatype || 'static',
      tooltip: '初始值来源于数据源或表单默认值。',
      required: false,
      options: [
        {value: 'dynamic', label: '动态'},
        {value: 'static', label: '静态'},
      ],
      controlFields: [
        {field: 'supModule', values: ['static']},
      ]
    },
    {
      type: 'select',
      field: 'focus',
      label: '焦点',
      initval: wrap.focus || '',
      required: false,
      options: fields
    },
    {
      type: 'radio',
      field: 'cache',
      label: '选项查询',
      initval: wrap.cache || 'true',
      tooltip: '需要通过数据源查询的选项,是否使用缓存。',
      required: false,
      options: [
        {value: 'true', label: '缓存'},
        {value: 'false', label: '实时'},
      ]
    },
    {
      type: 'radio',
      field: 'align',
      label: '表单排列',
      initval: wrap.align || 'left_right',
      required: false,
      options: [
        {value: 'left_right', label: '左右'},
        {value: 'up_down', label: '上下'},
      ],
      forbid: appType === 'mob'
    },
    {
      type: 'radio',
      field: 'verticalSpace',
      label: '竖向间隙',
      initval: wrap.verticalSpace || 'normal',
      tooltip: '正常间隙会预留出报错信息的位置,防止表单位置发生变化。',
      required: false,
      options: [
        {value: 'normal', label: '正常'},
        {value: 'middle', label: '中'},
        {value: 'small', label: '小'},
      ],
      forbid: appType === 'mob'
    },
    {
      type: 'radio',
      field: 'enable',
      label: '提交',
      initval: wrap.enable || 'true',
      required: false,
      options: [
        {value: 'true', label: '显示'},
        {value: 'false', label: '隐藏'},
      ]
    },
    {
      type: 'radio',
      field: 'closeEnable',
      label: '关闭',
      initval: wrap.closeEnable || 'false',
      tooltip: '管理系统中会关闭当前标签,子应用中为返回上一页。',
      required: false,
      options: [
        {value: 'true', label: '显示'},
        {value: 'false', label: '隐藏'},
      ]
    },
    {
      type: 'radio',
      field: 'goback',
      label: '空值返回',
      initval: wrap.goback || 'false',
      tooltip: '当查询数据为空时,返回上一界面。',
      required: false,
      options: [
        {value: 'true', label: '是'},
        {value: 'false', label: '否'},
      ],
      forbid: appType !== 'mob'
    },
    {
      type: 'radio',
      field: 'permission',
      label: '权限验证',
      initval: wrap.permission || 'false',
      required: false,
      options: [
        {value: 'true', label: '启用'},
        {value: 'false', label: '禁用'},
      ],
      forbid: !appType
    },
    {
      type: 'cascader',
      field: 'supModule',
      label: '上级组件',
      initval: wrap.supModule || [],
      required: false,
      options: modules,
      allowClear: true
    },
    {
      type: 'multiselect',
      field: 'blacklist',
      label: '黑名单',
      initval: wrap.blacklist || [],
      required: false,
      options: roleList,
      forbid: !!appType
    },
  ]
  return wrapForm
}
src/menu/components/form/step-form/index.jsx
File was renamed from src/menu/components/form/normal-form/index.jsx
@@ -9,12 +9,10 @@
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { getModalForm } from '@/templates/zshare/formconfig'
import { resetStyle } from '@/utils/utils-custom.js'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import Utils from '@/utils/utils.js'
import getWrapForm from './options'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import './index.scss'
const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
@@ -31,7 +29,7 @@
const { confirm } = Modal
class PropCardEditComponent extends Component {
class StepFormComponent extends Component {
  static propTpyes = {
    card: PropTypes.object,
    deletecomponent: PropTypes.func,
@@ -39,7 +37,6 @@
  }
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    appType: sessionStorage.getItem('appType'),
    card: null,
    back: false,
@@ -59,12 +56,9 @@
      let _card = {
        uuid: card.uuid,
        type: card.type,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: 'object',   // 组件属性 - 数据格式
        pageable: false,    // 组件属性 - 是否可分页
        switchable: false,  // 组件属性 - 数据是否可切换
        dataName: card.dataName || '',
        width: card.width || 24,
        name: card.name,
        subtype: card.subtype,
@@ -80,7 +74,7 @@
          style: {},
          fields: [],
          prevButton: {label: '上一步', type: 'prev', enable: 'false', style: {marginRight: '15px', paddingTop: '5px', paddingBottom: '5px'}},
          subButton: {label: '提交', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
          subButton: {label: '提交', type: 'submit', intertype: 'system', reload: 'false', sqlType: 'update', sql: '', Ot: 'notRequired', execSuccess: 'never', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
          nextButton: {label: '跳过', type: 'next', enable: 'false', style: {paddingTop: '5px', paddingBottom: '5px'}}
        }]
      }
@@ -106,10 +100,9 @@
        })
      }
      this.setState({
        card: _card,
        group: _card.subcards[0] || null
      })
      this.props.updateConfig(_card)
      this.updateComponent(_card)
    } else {
      let _card = fromJS(card).toJS()
      this.setState({
@@ -117,11 +110,6 @@
        group: _card.subcards[0] || null
      })
    }
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -135,39 +123,65 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle)
  }
  updateComponentStyle = (parentId, keys, style) => {
    const { card } = this.state
    if (card.uuid !== parentId) return
    let subcards = card.subcards.map(item => {
      if (keys.includes(item.uuid)) {
        item.style = {...item.style, ...style}
      }
      return item
    })
    this.setState({card: {...card, subcards: []}}, () => {
      this.updateComponent({...card, subcards: subcards})
    })
  }
  /**
   * @description 卡片行外层信息更新(数据源,样式等)
   */
  updateComponent = (component) => {
  updateComponent = (card) => {
    card.width = card.wrap.width
    card.name = card.wrap.name
    card.errors = []
    if (card.wrap.datatype !== 'static') {
      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)
      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: '未设置上级组件!'})
      }
      if (card.errors.length === 0) {
        card.$tables = getTables(card)
      }
      card.subcards.forEach(item => {
        item.fields.forEach(m => {
          if (m.type === 'linkMain' && !supModule) {
            card.errors.push({ level: 1, detail: `请检查分组“${item.setting.title}”中关联主表“${m.label}”是否有效`})
          }
        })
      })
    } else {
      let supModule = card.wrap.supModule ? card.wrap.supModule[card.wrap.supModule.length - 1] : ''
      card.$tables = getTables(card)
      card.subcards.forEach(item => {
        item.fields.forEach(m => {
          if (m.type === 'linkMain' && !supModule) {
            card.errors.push({ level: 1, detail: `请检查分组“${item.setting.title}”中关联主表“${m.label}”是否有效`})
          }
        })
      })
    }
    this.setState({
      card: component
      card: card
    })
    component.width = component.wrap.width
    component.name = component.wrap.name
    this.props.updateConfig(component)
    this.props.updateConfig(card)
  }
  /**
@@ -181,43 +195,19 @@
      return item
    })
    this.setState({card})
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style)
    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (comIds, style) => {
    const { card, group } = this.state
    if (comIds[0] === 'form') {
      let Index = group.fields.findIndex(n => n.uuid === comIds[1])
      if (Index === -1) return
      let _group = fromJS(group).toJS()
      _group.fields[Index].style = style
      this.updateGroup(_group)
      return
    }
    if (comIds.length !== 1 || comIds[0] !== card.uuid) return
    let _card = {...card, style}
    this.setState({
      card: _card
    })
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    
    this.props.updateConfig(_card)
    this.updateComponent(_card)
  }
  addCard = () => {
@@ -230,17 +220,16 @@
      style: {},
      fields: [],
      prevButton: {label: '上一步', type: 'prev', enable: 'false', style: {marginRight: '15px', paddingTop: '5px', paddingBottom: '5px'}},
      subButton: {label: '提交', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
      subButton: {label: '提交', type: 'submit', intertype: 'system', reload: 'false', sqlType: 'update', sql: '', Ot: 'notRequired', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
      nextButton: {label: '跳过', type: 'next', enable: 'false', style: {paddingTop: '5px', paddingBottom: '5px'}}
    }
    card.subcards.push(newcard)
    
    this.setState({
      card,
      group: newcard
    })
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  changecards = (list) => {
@@ -250,8 +239,7 @@
      return item
    })
    this.setState({card})
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  selectGroup = (item) => {
@@ -279,8 +267,8 @@
          _group = card.subcards[0] || null
        }
        _this.setState({card, group: _group})
        _this.props.updateConfig(card)
        _this.setState({group: _group})
        _this.updateComponent(card)
      },
      onCancel() {}
    })
@@ -296,8 +284,8 @@
      return item
    })
    this.setState({card, group})
    this.props.updateConfig(card)
    this.setState({group})
    this.updateComponent(card)
  }
  plusFields = (items) => {
@@ -343,8 +331,8 @@
          }
          return item
        })
        _this.setState({group: config, card})
        _this.props.updateConfig(card)
        _this.setState({group: config})
        _this.updateComponent(card)
      },
      onCancel() {}
    })
@@ -363,12 +351,12 @@
      return item
    })
    this.setState({card, group}, () => {
    this.setState({group}, () => {
      if (newcard) {
        this.handleForm(newcard)
      }
    })
    this.props.updateConfig(card)
    this.updateComponent(card)
  }
  closeForm = (cell) => {
@@ -388,8 +376,8 @@
    confirm({
      content: `确定删除<<${cell.label}>>吗?`,
      onOk() {
        _this.setState({card, group})
        _this.props.updateConfig(card)
        _this.setState({group})
        _this.updateComponent(card)
      },
      onCancel() {}
    })
@@ -461,35 +449,28 @@
        index = i
      }
      let label = `${item.field || ''}(${item.label})`
      if (['text', 'number', 'textarea', 'color'].includes(item.type) && _item.field !== item.field) {
        _inputfields.push({
          field: item.field,
          label: _inputIndex + '、' + item.label
          label: _inputIndex + '、' + label
        })
        _inputIndex++
      }
      if (appType === 'mob') {
        if (_form.field !== item.field && item.hidden !== 'true' && ['text', 'number'].includes(item.type)) {
          _tabfields.push({
            field: item.field,
            label: _tabIndex + '、' + item.label
          })
          _tabIndex++
        }
      } else {
        if (_form.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
          _tabfields.push({
            field: item.field,
            label: _tabIndex + '、' + item.label
          })
          _tabIndex++
        }
      if (_item.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
        _tabfields.push({
          field: item.field,
          label: _tabIndex + '、' + label
        })
        _tabIndex++
      }
      if (item.type === 'switch') {
        _linksupFields.push({
          field: item.field,
          label: _linkIndex + '、' + item.label
          label: _linkIndex + '、' + label
        })
      }
      
@@ -504,7 +485,7 @@
        })
        _linksupFields.push({
          field: item.field,
          label: _linkIndex + '、' + item.label
          label: _linkIndex + '、' + label
        })
        _linkIndex++
      }
@@ -546,7 +527,7 @@
      standardform,
      visible: true,
      editform: _form,
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields)
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields, card.columns)
    })
  }
@@ -593,20 +574,22 @@
        let param = {
          func: 's_debug_sql',
          exec_type: 'y',
          LText: res.dataSource
          LText: `declare @mk_organization nvarchar(512)
            ${res.dataSource}`
        }
        param.LText = param.LText.replace(/@\$|\$@/ig, '')
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
        param.LText = param.LText.replace(/\n/g, ' ')
        
        param.LText = Utils.formatOptions(param.LText)
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.secretkey = Utils.encrypt('', param.timestamp)
        if (window.GLOB.mainSystemApi && res.database === 'sso') {
          param.rduri = window.GLOB.mainSystemApi
        }
        
        Api.getLocalConfig(param).then(result => {
        Api.genericInterface(param).then(result => {
          if (result.status) {
            this.setState({
              sqlVerifing: false,
@@ -633,6 +616,41 @@
  }
  pasteForm = (res) => {
    if (res.subtype === 'simpleform') {
      res = res.subcards[0]
    }
    if (res.subButton) {
      let card = fromJS(this.state.card).toJS()
      res.uuid = Utils.getuuid()
      res.sort = card.subcards.length + 1
      res.fields.forEach(item => {
        item.uuid = Utils.getuuid()
      })
      if (!res.prevButton) {
        res.prevButton = {label: '上一步', type: 'prev', enable: 'false', style: {marginRight: '15px', paddingTop: '5px', paddingBottom: '5px'}}
      }
      if (!res.nextButton) {
        res.nextButton = {label: '跳过', type: 'next', enable: 'false', style: {paddingTop: '5px', paddingBottom: '5px'}}
      }
      card.subcards.push(res)
      this.setState({
        group: res
      })
      this.updateComponent(card)
      notification.success({
        top: 92,
        message: '粘贴成功!',
        duration: 2
      })
      return
    }
    let _config = fromJS(this.state.group).toJS()
    let fieldrepet = false // 字段重复
@@ -668,18 +686,34 @@
  }
  updateWrap = (res) => {
    this.updateComponent({...this.state.card, wrap: res})
    let _card = {...this.state.card, wrap: res}
    if (res.datatype === 'static') {
      if (res.supModule && res.supModule.length > 0) {
        _card.setting.supModule = res.supModule
      } else {
        _card.setting.supModule = ''
      }
    }
    this.updateComponent(_card)
  }
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.card)
      MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => {
        let _card = {...this.state.card}
        _card.style = {..._card.style, ...style}
        this.setState({ card: _card })
        this.props.updateConfig(_card)
      })
    }
  }
  render() {
    const { card, dict, group, appType } = this.state
    const { card, group, appType } = this.state
    return (
      <div className="menu-normal-form-edit-box" style={resetStyle(card.style)} onClick={this.clickComponent} id={card.uuid}>
@@ -690,7 +724,7 @@
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="stepform" card={card}/>
            <PasteComponent config={card} options={['form']} updateConfig={this.pasteForm} />
            <PasteComponent config={card} options={['form', 'formgroup', 'simpleform']} updateConfig={this.pasteForm} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)} />
@@ -711,7 +745,7 @@
        {group ? <div className="form-area">
          <PlusOutlined className="plus" title="添加表单" onClick={this.addForm}/>
          <FieldsComponent config={group} type="form" plusFields={this.plusFields} />
          <Switch checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
          <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2列</Button> : null}
          {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3列</Button> : null}
@@ -721,7 +755,6 @@
            list={group.fields}
            setting={group.setting}
            showField={this.state.showField}
            placeholder={dict['header.form.modal.placeholder']}
            handleList={this.handleList}
            handleForm={this.handleForm}
            closeForm={this.closeForm}
@@ -735,8 +768,22 @@
          />}
          <FormAction config={card} group={group} updateconfig={this.updateGroup}/>
        </div> : null}
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
        <Modal
          title={this.state.dict['model.edit']}
          title="编辑"
          visible={this.state.visible}
          width={950}
          maskClosable={false}
@@ -746,7 +793,6 @@
          destroyOnClose
        >
          <ModalForm
            dict={this.state.dict}
            card={this.state.editform}
            formlist={this.state.formlist}
            inputSubmit={this.handleSubmit}
@@ -759,4 +805,4 @@
  }
}
export default PropCardEditComponent
export default StepFormComponent
Diff truncated after the above file
src/menu/components/form/step-form/index.scss src/menu/components/form/step-form/options.jsx src/menu/components/form/tab-form/index.jsx src/menu/components/form/tab-form/index.scss src/menu/components/group/groupcomponents/card.jsx src/menu/components/group/groupcomponents/index.jsx src/menu/components/group/normal-group/index.jsx src/menu/components/group/normal-group/options.jsx src/menu/components/group/paste/index.jsx src/menu/components/iframe/index.jsx src/menu/components/iframe/index.scss src/menu/components/iframe/options.jsx src/menu/components/module/voucher/index.jsx src/menu/components/module/voucher/options.jsx src/menu/components/search/main-search/dategroup/index.scss src/menu/components/search/main-search/dragsearch/card.jsx src/menu/components/search/main-search/dragsearch/index.jsx src/menu/components/search/main-search/index.jsx src/menu/components/search/main-search/index.scss src/menu/components/search/main-search/options.jsx src/menu/components/share/actioncomponent/actionform/index.jsx src/menu/components/share/actioncomponent/actionform/index.scss src/menu/components/share/actioncomponent/dragaction/card.jsx src/menu/components/share/actioncomponent/dragaction/index.jsx src/menu/components/share/actioncomponent/formconfig.jsx src/menu/components/share/actioncomponent/index.jsx src/menu/components/share/actioncomponent/index.scss src/menu/components/share/clockcomponent/index.jsx src/menu/components/share/clockcomponent/index.scss src/menu/components/share/clockcomponent/settingform/index.jsx src/menu/components/share/copycomponent/index.jsx src/menu/components/share/logcomponent/index.jsx (deleted) src/menu/components/share/logcomponent/index.scss (deleted) src/menu/components/share/markcomponent/index.jsx src/menu/components/share/markcomponent/markform/index.jsx src/menu/components/share/normalform/index.jsx src/menu/components/share/normalform/index.scss src/menu/components/share/normalheader/index.jsx src/menu/components/share/normalheader/index.scss src/menu/components/share/pastebasetable/index.jsx src/menu/components/share/pastebasetable/index.scss src/menu/components/share/pastecomponent/index.jsx src/menu/components/share/searchcomponent/dragsearch/card.jsx src/menu/components/share/searchcomponent/dragsearch/index.jsx src/menu/components/share/searchcomponent/index.jsx src/menu/components/share/sourcecomponent/index.jsx src/menu/components/share/sourcecomponent/index.scss src/menu/components/share/sourcecomponent/inputform/index.jsx src/menu/components/share/usercomponent/index.jsx src/menu/components/share/usercomponent/settingform/index.jsx src/menu/components/table/base-table/columns/editColumn/formconfig.jsx src/menu/components/table/base-table/columns/editColumn/index.jsx src/menu/components/table/base-table/columns/editColumn/index.scss src/menu/components/table/base-table/columns/index.jsx src/menu/components/table/base-table/columns/index.scss src/menu/components/table/base-table/index.jsx src/menu/components/table/base-table/index.scss src/menu/components/table/base-table/options.jsx src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx src/menu/components/table/edit-table/columns/editColumn/index.jsx src/menu/components/table/edit-table/columns/index.jsx src/menu/components/table/edit-table/columns/index.scss src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx src/menu/components/table/edit-table/columns/tableIn/index.jsx src/menu/components/table/edit-table/columns/tableIn/uniqueform/index.jsx src/menu/components/table/edit-table/index.jsx src/menu/components/table/edit-table/index.scss src/menu/components/table/edit-table/options.jsx src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx src/menu/components/table/normal-table/columns/editColumn/index.jsx src/menu/components/table/normal-table/columns/index.jsx src/menu/components/table/normal-table/columns/index.scss src/menu/components/table/normal-table/index.jsx src/menu/components/table/normal-table/index.scss src/menu/components/table/normal-table/options.jsx src/menu/components/tabs/antv-tabs/dragabletabs.jsx src/menu/components/tabs/antv-tabs/index.jsx src/menu/components/tabs/antv-tabs/index.scss src/menu/components/tabs/antv-tabs/options.jsx src/menu/components/tabs/paste/index.jsx src/menu/components/tabs/tabcomponents/card.jsx src/menu/components/tabs/tabcomponents/index.jsx src/menu/components/tabs/table-tabs/dragabletabs.jsx src/menu/components/tabs/table-tabs/index.jsx src/menu/components/tabs/table-tabs/index.scss src/menu/components/tabs/table-tabs/options.jsx src/menu/components/timeline/normal-timeline/index.jsx src/menu/components/timeline/normal-timeline/index.scss src/menu/components/timeline/normal-timeline/options.jsx src/menu/components/tree/antd-tree/index.jsx src/menu/components/tree/antd-tree/options.jsx src/menu/datasource/index.jsx src/menu/datasource/verifycard/columnform/index.jsx src/menu/datasource/verifycard/customscript/index.jsx src/menu/datasource/verifycard/index.jsx src/menu/datasource/verifycard/index.scss src/menu/datasource/verifycard/settingform/index.jsx src/menu/datasource/verifycard/utils.jsx src/menu/menushell/card.jsx src/menu/menushell/index.jsx src/menu/menushell/index.scss src/menu/modalconfig/controller.jsx src/menu/modalconfig/index.jsx src/menu/modalconfig/index.scss src/menu/modulecell/dragsource/index.jsx src/menu/modulecell/dragsource/index.scss src/menu/modulecell/index.jsx src/menu/modulecell/index.scss src/menu/modulesource/option.jsx src/menu/padcontroller/index.jsx (deleted) src/menu/padcontroller/index.scss (deleted) src/menu/pastecontroller/index.jsx src/menu/picturecontroller/editform/index.jsx src/menu/picturecontroller/index.jsx src/menu/picturecontroller/index.scss src/menu/popview/index.jsx (deleted) src/menu/replaceField/index.jsx src/menu/replaceField/settingform/index.jsx src/menu/stylecombcontrolbutton/index.jsx src/menu/stylecombcontrolbutton/index.scss src/menu/stylecombcontroller/index.jsx src/menu/stylecombcontroller/styleInput/index.jsx src/menu/stylecombcontroller/styleInput/index.scss src/menu/stylecontroller/index.jsx src/menu/stylecontroller/styleInput/index.jsx src/menu/stylecontroller/styleInput/index.scss src/menu/sysinterface/index.jsx src/menu/sysinterface/index.scss src/menu/sysinterface/settingform/baseform/index.jsx (deleted) src/menu/sysinterface/settingform/baseform/index.scss (deleted) src/menu/sysinterface/settingform/index.jsx (deleted) src/menu/sysinterface/settingform/index.scss (deleted) src/menu/sysinterface/settingform/simplescript/index.jsx (deleted) src/menu/sysinterface/settingform/simplescript/index.scss (deleted) src/menu/sysinterface/settingform/utils.jsx (deleted) src/menu/tablenodes/index.jsx src/menu/tablenodes/index.scss src/menu/tableshell/card.jsx src/menu/tableshell/index.jsx src/menu/tableshell/index.scss src/menu/transfer/index.jsx src/menu/transfer/index.scss src/menu/urlfieldcomponent/index.scss src/menu/versions/index.jsx src/menu/viewnodes/index.jsx src/menu/viewnodes/index.scss src/mob/colorsketch/index.jsx src/mob/components/formdragelement/card.jsx src/mob/components/formdragelement/index.jsx src/mob/components/formdragelement/index.scss src/mob/components/menubar/common-menubar/index.jsx src/mob/components/menubar/normal-menubar/index.jsx src/mob/components/menubar/normal-menubar/index.scss src/mob/components/menubar/normal-menubar/menucomponent/index.jsx src/mob/components/menubar/normal-menubar/menucomponent/options.jsx src/mob/components/navbar/normal-navbar/index.jsx src/mob/components/navbar/normal-navbar/index.scss src/mob/components/navbar/normal-navbar/menus/drags/card.jsx src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx src/mob/components/official/index.jsx src/mob/components/official/index.scss src/mob/components/official/options.jsx src/mob/components/search/single-search/index.jsx src/mob/components/sharecode/index.jsx src/mob/components/sharecode/index.scss src/mob/components/sharecode/options.jsx src/mob/components/tabs/antv-tabs/dragabletabs.jsx src/mob/components/tabs/antv-tabs/index.jsx src/mob/components/tabs/antv-tabs/index.scss src/mob/components/tabs/antv-tabs/options.jsx src/mob/components/tabs/tabcomponents/card.jsx src/mob/components/tabs/tabcomponents/index.jsx src/mob/components/topbar/normal-navbar/index.jsx src/mob/components/topbar/normal-navbar/index.scss src/mob/components/topbar/normal-navbar/options.jsx src/mob/mobshell/card.jsx src/mob/mobshell/index.jsx src/mob/modalconfig/controller.jsx src/mob/modalconfig/index.jsx src/mob/modalconfig/index.scss src/mob/modalconfig/source.jsx src/mob/modulesource/index.jsx src/mob/modulesource/option.jsx src/mob/searchconfig/groupdragelement/card.jsx src/mob/searchconfig/index.jsx src/mob/searchconfig/index.scss src/mob/searchconfig/searchdragelement/card.jsx src/mob/searchconfig/settingform/index.jsx src/pc/bgcontroller/index.jsx src/pc/components/login/normal-login/index.jsx src/pc/components/login/normal-login/index.scss src/pc/components/login/normal-login/loginform.jsx src/pc/components/login/normal-login/options.jsx src/pc/components/login/normal-login/signform.jsx src/pc/components/navbar/normal-navbar/index.jsx src/pc/components/navbar/normal-navbar/index.scss src/pc/components/navbar/normal-navbar/linksetting/index.jsx src/pc/components/navbar/normal-navbar/menusetting/index.jsx src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx src/pc/createview/index.jsx src/pc/createview/settingform/index.jsx src/pc/menushell/card.jsx src/pc/menushell/index.jsx src/pc/menushell/index.scss src/pc/modulesource/option.jsx src/pc/quotecomponent/index.jsx src/pc/quotecomponent/settingform/index.jsx src/router/index.js src/setupProxy.js src/store/action-type.js src/store/action.js src/store/reducer.js src/tabviews/basetable/index.jsx src/tabviews/basetable/index.scss src/tabviews/calendar/index.jsx src/tabviews/commontable/index.jsx src/tabviews/custom/components/card/balcony/index.jsx src/tabviews/custom/components/card/cardItem/index.jsx src/tabviews/custom/components/card/cardcellList/asyncButtonComponent.jsx src/tabviews/custom/components/card/cardcellList/index.jsx src/tabviews/custom/components/card/cardcellList/index.scss src/tabviews/custom/components/card/data-card/index.jsx src/tabviews/custom/components/card/data-card/index.scss src/tabviews/custom/components/card/prop-card/index.jsx src/tabviews/custom/components/card/table-card/index.jsx src/tabviews/custom/components/card/table-card/index.scss src/tabviews/custom/components/carousel/cardItem/index.jsx src/tabviews/custom/components/carousel/data-card/index.jsx src/tabviews/custom/components/carousel/data-card/index.scss src/tabviews/custom/components/carousel/prop-card/index.jsx src/tabviews/custom/components/carousel/prop-card/index.scss src/tabviews/custom/components/chart/antv-G6/index.jsx src/tabviews/custom/components/chart/antv-G6/index.scss src/tabviews/custom/components/chart/antv-bar-line/asyncButtonComponent.jsx src/tabviews/custom/components/chart/antv-bar-line/index.jsx src/tabviews/custom/components/chart/antv-bar-line/index.scss src/tabviews/custom/components/chart/antv-dashboard/index.jsx src/tabviews/custom/components/chart/antv-dashboard/index.scss src/tabviews/custom/components/chart/antv-pie/index.jsx src/tabviews/custom/components/chart/antv-pie/index.scss src/tabviews/custom/components/chart/antv-scatter/asyncButtonComponent.jsx src/tabviews/custom/components/chart/antv-scatter/index.jsx src/tabviews/custom/components/chart/antv-scatter/index.scss src/tabviews/custom/components/chart/custom-chart/index.jsx src/tabviews/custom/components/chart/custom-chart/index.scss src/tabviews/custom/components/code/sand-box/index.jsx src/tabviews/custom/components/editor/braft-editor/index.jsx src/tabviews/custom/components/form/simple-form/index.jsx src/tabviews/custom/components/form/simple-form/index.scss src/tabviews/custom/components/form/step-form/index.jsx src/tabviews/custom/components/form/step-form/index.scss src/tabviews/custom/components/form/tab-form/index.jsx src/tabviews/custom/components/form/tab-form/index.scss src/tabviews/custom/components/group/normal-group/index.jsx src/tabviews/custom/components/group/normal-group/index.scss src/tabviews/custom/components/iframe/index.jsx src/tabviews/custom/components/iframe/index.scss src/tabviews/custom/components/interfaces/index.jsx src/tabviews/custom/components/interfaces/index.scss src/tabviews/custom/components/interfaces/interItem/index.jsx src/tabviews/custom/components/interfaces/interItem/index.scss src/tabviews/custom/components/module/voucher/assistTable/index.jsx src/tabviews/custom/components/module/voucher/assistTable/index.scss src/tabviews/custom/components/module/voucher/index.jsx src/tabviews/custom/components/share/normalTable/index.jsx src/tabviews/custom/components/share/normalTable/index.scss src/tabviews/custom/components/share/normalheader/index.jsx src/tabviews/custom/components/share/normalheader/index.scss src/tabviews/custom/components/share/tabtransfer/index.jsx src/tabviews/custom/components/table/base-table/index.jsx src/tabviews/custom/components/table/base-table/index.scss src/tabviews/custom/components/table/edit-table/index.jsx src/tabviews/custom/components/table/edit-table/normalTable/index.jsx src/tabviews/custom/components/table/edit-table/normalTable/index.scss src/tabviews/custom/components/table/normal-table/index.jsx src/tabviews/custom/components/table/normal-table/index.scss src/tabviews/custom/components/tabs/antv-tabs/index.jsx src/tabviews/custom/components/timeline/normal-timeline/index.jsx src/tabviews/custom/components/timeline/normal-timeline/index.scss src/tabviews/custom/components/tree/antd-tree/index.jsx src/tabviews/custom/components/tree/antd-tree/index.scss src/tabviews/custom/index.jsx src/tabviews/custom/popview/index.jsx src/tabviews/custom/popview/index.scss src/tabviews/debugtable/index.jsx src/tabviews/debugtable/index.scss src/tabviews/formtab/actionList/index.jsx src/tabviews/formtab/formgroup/index.jsx src/tabviews/formtab/index.jsx src/tabviews/home/defaulthome/index.jsx src/tabviews/home/defaulthome/index.scss src/tabviews/home/index.jsx src/tabviews/rolemanage/index.jsx src/tabviews/rolemanage/index.scss src/tabviews/scriptmanage/actionList/index.jsx (deleted) src/tabviews/scriptmanage/actionList/index.scss (deleted) src/tabviews/scriptmanage/config.jsx (deleted) src/tabviews/scriptmanage/index.jsx (deleted) src/tabviews/scriptmanage/index.scss (deleted) src/tabviews/subtable/index.jsx src/tabviews/subtabtable/index.jsx src/tabviews/treepage/index.jsx src/tabviews/verupmanage/actionList/index.jsx (deleted) src/tabviews/verupmanage/actionList/index.scss (deleted) src/tabviews/verupmanage/config.jsx (deleted) src/tabviews/verupmanage/index.jsx (deleted) src/tabviews/verupmanage/index.scss (deleted) src/tabviews/verupmanage/subtabtable/index.jsx (deleted) src/tabviews/verupmanage/subtabtable/index.scss (deleted) src/tabviews/zshare/actionList/asyncButtonComponent.jsx src/tabviews/zshare/actionList/changeuserbutton/index.jsx src/tabviews/zshare/actionList/excelInbutton/excelin/index.jsx src/tabviews/zshare/actionList/excelInbutton/index.jsx src/tabviews/zshare/actionList/exceloutbutton/index.jsx src/tabviews/zshare/actionList/funcMegvii/index.jsx src/tabviews/zshare/actionList/funcMegvii/index.scss src/tabviews/zshare/actionList/funcMegvii/mock.js src/tabviews/zshare/actionList/funczip/index.jsx src/tabviews/zshare/actionList/funczip/index.scss src/tabviews/zshare/actionList/funczip/mock.js src/tabviews/zshare/actionList/index.jsx src/tabviews/zshare/actionList/newpagebutton/index.jsx src/tabviews/zshare/actionList/normalbutton/index.jsx src/tabviews/zshare/actionList/popupbutton/index.jsx src/tabviews/zshare/actionList/popupbutton/index.scss src/tabviews/zshare/actionList/printbutton/index.jsx src/tabviews/zshare/actionList/tabbutton/index.jsx src/tabviews/zshare/automatic/index.jsx src/tabviews/zshare/cardcomponent/asyncButtonComponent.jsx src/tabviews/zshare/cardcomponent/index.jsx src/tabviews/zshare/cardcomponent/index.scss src/tabviews/zshare/chartcomponent/asyncButtonComponent.jsx src/tabviews/zshare/chartcomponent/index.jsx src/tabviews/zshare/fileupload-pice/index.jsx src/tabviews/zshare/fileupload-pice/index.scss src/tabviews/zshare/fileupload/index.jsx src/tabviews/zshare/fileupload/index.scss src/tabviews/zshare/mutilform/index.jsx src/tabviews/zshare/mutilform/index.scss src/tabviews/zshare/mutilform/mkCascader/data.json src/tabviews/zshare/mutilform/mkCascader/index.jsx src/tabviews/zshare/mutilform/mkCascader/index.scss src/tabviews/zshare/mutilform/mkCheckCard/index.jsx src/tabviews/zshare/mutilform/mkCheckCard/index.scss src/tabviews/zshare/mutilform/mkColor/index.jsx src/tabviews/zshare/mutilform/mkDatePicker/index.jsx src/tabviews/zshare/mutilform/mkFormula/index.jsx src/tabviews/zshare/mutilform/mkFormula/index.scss src/tabviews/zshare/mutilform/mkInput/index.jsx src/tabviews/zshare/mutilform/mkNumberInput/index.jsx src/tabviews/zshare/mutilform/mkSelect/index.jsx src/tabviews/zshare/mutilform/mkTextArea/index.jsx src/tabviews/zshare/normalTable/index.jsx src/tabviews/zshare/normalTable/index.scss src/tabviews/zshare/pageMessage/index.jsx src/tabviews/zshare/settingcomponent/editTable/index.jsx src/tabviews/zshare/settingcomponent/index.jsx src/tabviews/zshare/settingcomponent/index.scss src/tabviews/zshare/tablenodes/index.jsx src/tabviews/zshare/tablenodes/index.scss src/tabviews/zshare/topSearch/advanceform/index.jsx src/tabviews/zshare/topSearch/advanceform/index.scss src/tabviews/zshare/topSearch/dategroup/index.scss src/tabviews/zshare/topSearch/index.jsx src/tabviews/zshare/topSearch/index.scss src/templates/calendarconfig/calcomponent/calendarform/index.jsx src/templates/calendarconfig/calcomponent/index.jsx src/templates/calendarconfig/index.jsx src/templates/calendarconfig/index.scss src/templates/calendarconfig/source.jsx src/templates/calendarconfig/tabcomponent/index.jsx src/templates/calendarconfig/tabcomponent/tabform/index.jsx src/templates/comtableconfig/index.jsx src/templates/comtableconfig/index.scss src/templates/comtableconfig/menuform/index.jsx src/templates/comtableconfig/source.jsx src/templates/comtableconfig/updatetable/index.jsx src/templates/comtableconfig/updatetable/index.scss src/templates/formtabconfig/actionform/index.jsx src/templates/formtabconfig/dragelement/card.jsx src/templates/formtabconfig/groupform/index.jsx src/templates/formtabconfig/index.jsx src/templates/formtabconfig/index.scss src/templates/formtabconfig/settingform/index.jsx src/templates/formtabconfig/source.jsx src/templates/menuconfig/editfirstmenu/index.jsx (deleted) src/templates/menuconfig/editfirstmenu/index.scss (deleted) src/templates/menuconfig/editsecmenu/index.jsx (deleted) src/templates/menuconfig/editsecmenu/index.scss (deleted) src/templates/menuconfig/editthdmenu/index.jsx (deleted) src/templates/menuconfig/editthdmenu/index.scss (deleted) src/templates/menuconfig/menuelement/card.jsx (deleted) src/templates/menuconfig/menuform/index.scss (deleted) src/templates/modalconfig/checkCard/index.jsx src/templates/modalconfig/checkCard/index.scss src/templates/modalconfig/dragelement/card.jsx src/templates/modalconfig/dragelement/index.jsx src/templates/modalconfig/dragelement/index.scss src/templates/modalconfig/index.jsx src/templates/modalconfig/index.scss src/templates/modalconfig/menuform/index.jsx src/templates/modalconfig/settingform/index.jsx src/templates/modalconfig/settingform/index.scss src/templates/modalconfig/source.jsx src/templates/sharecomponent/actioncomponent/actionform/index.jsx src/templates/sharecomponent/actioncomponent/actionform/index.scss src/templates/sharecomponent/actioncomponent/dragaction/card.jsx src/templates/sharecomponent/actioncomponent/dragaction/index.jsx src/templates/sharecomponent/actioncomponent/index.jsx src/templates/sharecomponent/actioncomponent/index.scss src/templates/sharecomponent/actioncomponent/verifyexcelin/columnform/index.jsx src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx src/templates/sharecomponent/actioncomponent/verifyexcelin/uniqueform/index.jsx src/templates/sharecomponent/actioncomponent/verifyexcelout/columnform/index.jsx src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.scss src/templates/sharecomponent/actioncomponent/verifyexcelout/datasource/index.jsx src/templates/sharecomponent/actioncomponent/verifyexcelout/datasource/index.scss src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx src/templates/sharecomponent/actioncomponent/verifyexcelout/index.scss src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx src/templates/sharecomponent/actioncomponent/verifymegvii/index.jsx src/templates/sharecomponent/actioncomponent/verifymegvii/index.scss src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx src/templates/sharecomponent/cardcomponent/carddetailform/index.jsx src/templates/sharecomponent/cardcomponent/dragdetail/card.jsx src/templates/sharecomponent/cardcomponent/index.jsx src/templates/sharecomponent/cardcomponent/index.scss src/templates/sharecomponent/chartcomponent/chartcompile/index.jsx src/templates/sharecomponent/chartcomponent/index.jsx src/templates/sharecomponent/chartgroupcomponent/chartform/index.jsx src/templates/sharecomponent/chartgroupcomponent/dragchartview/card.jsx src/templates/sharecomponent/chartgroupcomponent/index.jsx src/templates/sharecomponent/columncomponent/colspanform/index.jsx src/templates/sharecomponent/columncomponent/columnform/index.jsx src/templates/sharecomponent/columncomponent/dragcolumn/card.jsx src/templates/sharecomponent/columncomponent/gridbtnform/index.jsx src/templates/sharecomponent/columncomponent/index.jsx src/templates/sharecomponent/columncomponent/index.scss src/templates/sharecomponent/columncomponent/markcolumn/index.jsx src/templates/sharecomponent/columncomponent/markcolumn/markform/index.jsx src/templates/sharecomponent/fieldscomponent/editcard/index.jsx src/templates/sharecomponent/fieldscomponent/index.jsx src/templates/sharecomponent/searchcomponent/dategroup/index.scss src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx src/templates/sharecomponent/searchcomponent/index.jsx src/templates/sharecomponent/searchcomponent/index.scss src/templates/sharecomponent/searchcomponent/searchform/index.jsx src/templates/sharecomponent/searchcomponent/searchform/index.scss src/templates/sharecomponent/searchcomponent/settingform/index.jsx src/templates/sharecomponent/searchcomponent/settingform/index.scss src/templates/sharecomponent/settingcalcomponent/index.jsx src/templates/sharecomponent/settingcalcomponent/index.scss src/templates/sharecomponent/settingcalcomponent/verifycard/columnform/index.jsx src/templates/sharecomponent/settingcalcomponent/verifycard/index.jsx src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.jsx src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.scss src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx src/templates/sharecomponent/settingcomponent/index.jsx src/templates/sharecomponent/settingcomponent/index.scss src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx src/templates/sharecomponent/settingcomponent/settingform/datasource/index.scss src/templates/sharecomponent/settingcomponent/settingform/index.jsx src/templates/sharecomponent/settingcomponent/settingform/index.scss src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx src/templates/sharecomponent/settingcomponent/settingform/utils.jsx src/templates/sharecomponent/tablecomponent/index.jsx src/templates/sharecomponent/tablecomponent/index.scss src/templates/sharecomponent/tabscomponent/index.jsx src/templates/sharecomponent/tabscomponent/tabdragelement/card.jsx src/templates/sharecomponent/tabscomponent/tabdragelement/index.jsx src/templates/sharecomponent/tabscomponent/tabform/index.jsx src/templates/sharecomponent/treesettingcomponent/index.jsx src/templates/sharecomponent/treesettingcomponent/index.scss src/templates/sharecomponent/treesettingcomponent/settingform/datasource/index.jsx src/templates/sharecomponent/treesettingcomponent/settingform/datasource/index.scss src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx src/templates/subtableconfig/index.jsx src/templates/subtableconfig/index.scss src/templates/subtableconfig/menuform/index.jsx src/templates/subtableconfig/source.jsx src/templates/treepageconfig/index.jsx src/templates/treepageconfig/index.scss src/templates/treepageconfig/source.jsx src/templates/zshare/codemirror/index.jsx src/templates/zshare/codemirror/index.scss src/templates/zshare/createfunc/index.jsx src/templates/zshare/createinterface/index.jsx src/templates/zshare/createinterface/mutilform/index.jsx src/templates/zshare/customscript/index.jsx src/templates/zshare/editTable/index.jsx src/templates/zshare/editcard/index.jsx src/templates/zshare/editcomponent/index.jsx src/templates/zshare/formconfig.jsx src/templates/zshare/menuform/index.jsx src/templates/zshare/modalform/datatable/index.jsx src/templates/zshare/modalform/datatable/index.scss src/templates/zshare/modalform/fieldtable/index.jsx src/templates/zshare/modalform/index.jsx src/templates/zshare/modalform/index.scss src/templates/zshare/pasteform/index.jsx src/templates/zshare/unattended/index.jsx src/templates/zshare/unattended/settingform/index.jsx src/templates/zshare/verifycard/baseform/index.jsx src/templates/zshare/verifycard/baseform/index.scss src/templates/zshare/verifycard/billcodeform/index.jsx src/templates/zshare/verifycard/callbackcustomscript/index.jsx src/templates/zshare/verifycard/contrastform/index.jsx src/templates/zshare/verifycard/customform/index.jsx src/templates/zshare/verifycard/customscript/index.jsx src/templates/zshare/verifycard/index.jsx src/templates/zshare/verifycard/index.scss src/templates/zshare/verifycard/uniqueform/index.jsx src/templates/zshare/verifycard/voucherform/index.jsx src/utils/asyncComponent.jsx src/utils/asyncIconComponent.jsx src/utils/asyncLoadComponent.jsx src/utils/asyncSpinComponent.jsx src/utils/option.js src/utils/sqlFormatter-origin.js src/utils/sqlFormatter.js src/utils/timer-task.js src/utils/utils-custom.js src/utils/utils-datamanage.js src/utils/utils-update.js src/utils/utils.js src/views/appcheck/index.jsx src/views/appmanage/index.jsx src/views/appmanage/scriptform/index.jsx src/views/appmanage/scriptform/index.scss src/views/appmanage/submutilform/index.jsx src/views/appmanage/submutilform/index.scss src/views/basedesign/index.jsx src/views/basedesign/index.scss src/views/billprint/index.jsx src/views/billprint/index.scss src/views/design/header/editfirstmenu/dragelement/card.jsx src/views/design/header/editfirstmenu/dragelement/index.jsx src/views/design/header/editfirstmenu/dragelement/index.scss src/views/design/header/editfirstmenu/dragelement/itemtypes.js src/views/design/header/editfirstmenu/index.jsx src/views/design/header/editfirstmenu/index.scss src/views/design/header/editfirstmenu/menuform/index.jsx src/views/design/header/editfirstmenu/menuform/index.scss src/views/design/header/index.jsx src/views/design/header/index.scss src/views/design/header/versions/index.jsx src/views/design/index.jsx src/views/design/index.scss src/views/design/sidemenu/editsecmenu/index.jsx src/views/design/sidemenu/editsecmenu/index.scss src/views/design/sidemenu/editthdmenu/index.jsx src/views/design/sidemenu/editthdmenu/index.scss src/views/design/sidemenu/index.jsx src/views/design/sidemenu/index.scss src/views/design/sidemenu/menuelement/card.jsx src/views/design/sidemenu/menuelement/index.jsx src/views/design/sidemenu/menuelement/index.scss src/views/design/sidemenu/menuelement/itemtypes.js src/views/design/sidemenu/menuform/index.jsx src/views/design/sidemenu/menuform/index.scss src/views/design/sidemenu/thdmenuform/index.jsx src/views/design/sidemenu/thdmenuform/index.scss src/views/design/sidemenu/thdmenuplus/index.jsx src/views/design/sidemenu/thdmenuplus/index.scss src/views/design/sidemenu/thdmenuplus/preview/index.jsx src/views/design/sidemenu/thdmenuplus/preview/index.scss src/views/imdesign/index.jsx src/views/imdesign/index.scss src/views/imdesign/menuform/index.jsx src/views/interface/header/index.jsx src/views/interface/history/index.jsx src/views/interface/workspace/request/index.jsx src/views/login/index.jsx src/views/login/logincodeform.jsx src/views/login/loginform.jsx src/views/main/index.jsx src/views/mainparams/index.jsx src/views/mainparams/index.scss src/views/menudesign/homeform/index.jsx src/views/menudesign/index.jsx src/views/menudesign/index.scss src/views/menudesign/menuform/index.jsx src/views/menudesign/popview/index.jsx src/views/menudesign/popview/index.scss src/views/menudesign/popview/menuform/index.jsx src/views/menudesign/popview/menuform/index.scss src/views/menudesign/printmenuform/index.jsx src/views/mobdesign/index.jsx src/views/mobdesign/index.scss src/views/mobdesign/menuform/index.jsx src/views/mobdesign/menuform/index.scss src/views/pay/index.jsx src/views/pcdesign/index.jsx src/views/pcdesign/index.scss src/views/pcdesign/menuform/index.jsx src/views/printTemplate/mutilform/index.jsx src/views/printTemplate/option.js src/views/printTemplate/print.js src/views/rolemanage/index.jsx src/views/sso/index.jsx src/views/systemfunc/header/index.jsx src/views/systemfunc/header/index.scss src/views/systemfunc/index.jsx src/views/systemfunc/index.scss src/views/systemfunc/sidemenu/config.jsx src/views/systemfunc/sidemenu/index.jsx src/views/systemfunc/sidemenu/index.scss src/views/systemproc/index.jsx src/views/systemproc/index.scss src/views/systemproc/proc/index.jsx src/views/systemproc/proc/index.scss src/views/tabledesign/index.jsx src/views/tabledesign/index.scss src/views/tabledesign/menuform/index.jsx src/views/tabledesign/menuform/index.scss src/views/tabledesign/popview/index.jsx src/views/tabledesign/popview/index.scss src/views/tabledesign/source.jsx src/views/tabledesign/tablesource/index.jsx src/views/tabledesign/tablesource/index.scss