From 7b0269a4281eb11a14e222e1153c10203f3a0e67 Mon Sep 17 00:00:00 2001 From: bac-joker Date: Thu, 27 Aug 2020 17:18:57 +0800 Subject: [PATCH] clear commit --- .editorconfig | 15 + .eslintrc.js | 20 + .gitignore | 10 + LICENSE | 21 + lerna.json | 7 + package.json | 27 + packages/fes-cli/LICENSE | 21 + packages/fes-cli/bin/index.js | 70 + .../fes-cli/build/configs/postcss.config.js | 8 + .../fes-cli/build/configs/webpack.config.js | 504 + packages/fes-cli/build/helpers/browser.js | 1 + packages/fes-cli/build/helpers/config.js | 62 + .../fes-cli/build/helpers/createDevServer.js | 44 + packages/fes-cli/build/helpers/getPort.js | 25 + packages/fes-cli/build/helpers/log.js | 13 + packages/fes-cli/build/mock/cgiMock.js | 142 + packages/fes-cli/build/mock/init.js | 112 + packages/fes-cli/build/mock/task/cgiMock.js | 17 + packages/fes-cli/build/mock/test/app.js | 64 + packages/fes-cli/build/mock/test/myfile.txt | 1 + packages/fes-cli/build/mock/util.js | 62 + .../fes-cli/build/preComplie/components.js | 26 + packages/fes-cli/build/preComplie/route.js | 121 + packages/fes-cli/build/tasks/build.js | 25 + packages/fes-cli/build/tasks/components.js | 45 + packages/fes-cli/build/tasks/dev.js | 63 + packages/fes-cli/build/tasks/index.js | 15 + packages/fes-cli/build/tasks/init.js | 54 + packages/fes-cli/build/tasks/route.js | 35 + packages/fes-cli/build/tasks/update.js | 15 + packages/fes-cli/change.md | 7 + packages/fes-cli/package.json | 98 + packages/fes-cli/template/.eslintrc.js | 17 + packages/fes-cli/template/.gitignore | 8 + packages/fes-cli/template/LICENSE | 21 + packages/fes-cli/template/fes.config.js | 140 + packages/fes-cli/template/mock.js | 113 + packages/fes-cli/template/package.json | 57 + packages/fes-cli/template/src/app.js | 45 + .../fes-cli/template/src/assets/images/bg.png | Bin 0 -> 6059 bytes .../template/src/assets/images/logo.png | Bin 0 -> 2742 bytes .../template/src/assets/styles/login.scss | 131 + .../template/src/assets/styles/main.scss | 50 + .../template/src/assets/styles/variables.scss | 90 + .../template/src/components/fesHeader.vue | 14 + .../template/src/components/fesLeft.vue | 9 + .../template/src/pages/api/fes/index.vue | 74 + .../template/src/pages/api/fesApi/index.vue | 50 + .../template/src/pages/api/fesApp/index.vue | 94 + .../template/src/pages/api/fesFesx/index.vue | 26 + .../template/src/pages/api/fesMap/index.vue | 20 + .../template/src/pages/api/fesMenu/index.vue | 129 + .../src/pages/api/fesStorage/index.vue | 38 + .../template/src/pages/api/fesUtil/index.vue | 33 + .../template/src/pages/header/index.vue | 77 + .../fes-cli/template/src/pages/home/index.vue | 142 + .../fes-cli/template/src/pages/i18n/index.vue | 48 + .../fes-cli/template/src/pages/layout/a.vue | 12 + .../fes-cli/template/src/pages/layout/b.vue | 12 + .../template/src/pages/layout/layout.vue | 16 + .../template/src/pages/list/edit/index.vue | 89 + .../fes-cli/template/src/pages/list/index.vue | 84 + packages/fes-cli/template/src/pages/route.vue | 28 + .../template/src/pages/static/index.vue | 18 + packages/fes-cli/template/src/static/1.txt | 1 + packages/fes-cli/template/src/static/bell.png | Bin 0 -> 443 bytes .../fes-cli/template/src/static/favicon.ico | Bin 0 -> 5430 bytes packages/fes-core/LICENSE | 21 + packages/fes-core/package.json | 33 + packages/fes-core/src/api/index.js | 395 + packages/fes-core/src/app.js | 9 + packages/fes-core/src/config/index.js | 61 + packages/fes-core/src/directive/index.js | 22 + packages/fes-core/src/env/index.js | 3 + packages/fes-core/src/fesx/_fesx.js | 4 + packages/fes-core/src/fesx/fesx.js | 56 + packages/fes-core/src/fesx/index.js | 9 + packages/fes-core/src/filter/index.js | 154 + packages/fes-core/src/index.html | 16 + packages/fes-core/src/instance/app.js | 328 + packages/fes-core/src/instance/page.js | 122 + packages/fes-core/src/instance/permission.js | 34 + packages/fes-core/src/map/index.js | 42 + packages/fes-core/src/polyfill/index.js | 48 + packages/fes-core/src/storage/index.js | 183 + packages/fes-core/src/util/dom.js | 106 + packages/fes-core/src/util/event.js | 51 + packages/fes-core/src/util/format.js | 46 + packages/fes-core/src/util/history.js | 38 + packages/fes-core/src/util/index.js | 88 + packages/fes-core/src/util/object.js | 27 + packages/fes-core/src/util/type.js | 36 + .../fes-core/src/views/components/index.js | 29 + .../src/views/components/listPanel.vue | 11 + .../src/views/components/routeMenu.vue | 91 + .../src/views/components/searchPanel.vue | 14 + packages/fes-core/src/views/layout/left.vue | 108 + packages/fes-core/src/views/layout/root.vue | 67 + .../fes-core/src/views/styles/components.scss | 48 + packages/fes-core/src/views/styles/index.scss | 3 + .../fes-core/src/views/styles/layout.scss | 425 + .../fes-core/src/views/styles/polyfill.scss | 22 + packages/fes-doc/LICENSE | 21 + packages/fes-doc/deploy.sh | 25 + .../.vuepress/components/componetTemplate.vue | 95 + .../.vuepress/components/templateLayout.vue | 16 + packages/fes-doc/docs/.vuepress/config.js | 93 + packages/fes-doc/docs/.vuepress/enhanceApp.js | 20 + .../fes-doc/docs/.vuepress/public/logo.jpg | Bin 0 -> 379104 bytes .../fes-doc/docs/.vuepress/styles/index.styl | 79 + .../docs/.vuepress/styles/override.styl | 1 + packages/fes-doc/docs/data.json | 3390 ++ .../fes-doc/docs/guide/directory-structure.md | 364 + packages/fes-doc/docs/guide/i18n.md | 91 + packages/fes-doc/docs/guide/install.md | 10 + packages/fes-doc/docs/guide/layout.md | 25 + packages/fes-doc/docs/guide/migration.md | 75 + packages/fes-doc/docs/guide/migrationLast.md | 13 + packages/fes-doc/docs/guide/option.md | 188 + packages/fes-doc/docs/guide/permisson.md | 54 + packages/fes-doc/docs/guide/play.md | 155 + packages/fes-doc/docs/guide/plugins/sso.md | 29 + packages/fes-doc/docs/guide/plugins/wa.md | 0 packages/fes-doc/docs/guide/route.md | 73 + packages/fes-doc/docs/ui/affix.md | 64 + packages/fes-doc/docs/ui/backTop.md | 68 + packages/fes-doc/docs/ui/button.md | 88 + packages/fes-doc/docs/ui/carousel.md | 61 + packages/fes-doc/docs/ui/checkbox.md | 148 + packages/fes-doc/docs/ui/collapse.md | 83 + packages/fes-doc/docs/ui/contextmenu.md | 48 + packages/fes-doc/docs/ui/datePicker.md | 213 + packages/fes-doc/docs/ui/draggable.md | 94 + packages/fes-doc/docs/ui/dropdown.md | 163 + packages/fes-doc/docs/ui/form.md | 407 + packages/fes-doc/docs/ui/icon.md | 55 + packages/fes-doc/docs/ui/input.md | 190 + packages/fes-doc/docs/ui/layout.md | 87 + packages/fes-doc/docs/ui/loading.md | 59 + packages/fes-doc/docs/ui/menu.md | 175 + packages/fes-doc/docs/ui/message.md | 119 + packages/fes-doc/docs/ui/modal.md | 196 + packages/fes-doc/docs/ui/pagination.md | 93 + packages/fes-doc/docs/ui/panel.md | 60 + packages/fes-doc/docs/ui/process-circle.md | 139 + packages/fes-doc/docs/ui/radio.md | 170 + packages/fes-doc/docs/ui/select.md | 171 + packages/fes-doc/docs/ui/split.md | 220 + packages/fes-doc/docs/ui/step.md | 130 + packages/fes-doc/docs/ui/switch.md | 102 + packages/fes-doc/docs/ui/tab.md | 195 + packages/fes-doc/docs/ui/table.md | 539 + .../fes-doc/docs/ui/templates/backTop/1.md | 12 + .../fes-doc/docs/ui/templates/backTop/2.md | 23 + .../fes-doc/docs/ui/templates/button/1.md | 19 + .../fes-doc/docs/ui/templates/button/2.md | 19 + .../fes-doc/docs/ui/templates/button/3.md | 14 + .../fes-doc/docs/ui/templates/button/4.md | 13 + .../fes-doc/docs/ui/templates/carousel/1.md | 30 + .../fes-doc/docs/ui/templates/checkbox/1.md | 32 + .../fes-doc/docs/ui/templates/checkbox/2.md | 18 + .../fes-doc/docs/ui/templates/checkbox/3.md | 27 + .../fes-doc/docs/ui/templates/checkbox/4.md | 33 + .../fes-doc/docs/ui/templates/collapse/1.md | 38 + .../docs/ui/templates/contextmenu/1.md | 24 + .../fes-doc/docs/ui/templates/datePicker/1.md | 17 + .../fes-doc/docs/ui/templates/datePicker/2.md | 14 + .../fes-doc/docs/ui/templates/datePicker/3.md | 15 + .../fes-doc/docs/ui/templates/datePicker/4.md | 14 + .../fes-doc/docs/ui/templates/datePicker/5.md | 16 + .../fes-doc/docs/ui/templates/datePicker/6.md | 21 + .../fes-doc/docs/ui/templates/datePicker/7.md | 13 + .../fes-doc/docs/ui/templates/draggable/1.md | 47 + .../fes-doc/docs/ui/templates/dropdown/1.md | 29 + .../fes-doc/docs/ui/templates/dropdown/2.md | 55 + .../fes-doc/docs/ui/templates/dropdown/3.md | 29 + .../fes-doc/docs/ui/templates/dropdown/4.md | 34 + .../fes-doc/docs/ui/templates/dropdown/5.md | 34 + packages/fes-doc/docs/ui/templates/form/1.md | 74 + packages/fes-doc/docs/ui/templates/form/2.md | 51 + packages/fes-doc/docs/ui/templates/form/3.md | 50 + packages/fes-doc/docs/ui/templates/form/4.md | 35 + packages/fes-doc/docs/ui/templates/form/5.md | 106 + packages/fes-doc/docs/ui/templates/icon/1.md | 13 + packages/fes-doc/docs/ui/templates/input/1.md | 21 + .../fes-doc/docs/ui/templates/input/10.md | 19 + packages/fes-doc/docs/ui/templates/input/2.md | 17 + packages/fes-doc/docs/ui/templates/input/3.md | 17 + packages/fes-doc/docs/ui/templates/input/4.md | 19 + packages/fes-doc/docs/ui/templates/input/5.md | 17 + packages/fes-doc/docs/ui/templates/input/6.md | 17 + packages/fes-doc/docs/ui/templates/input/7.md | 17 + packages/fes-doc/docs/ui/templates/input/8.md | 25 + packages/fes-doc/docs/ui/templates/input/9.md | 19 + .../fes-doc/docs/ui/templates/layout/1.md | 18 + .../fes-doc/docs/ui/templates/layout/2.md | 17 + .../fes-doc/docs/ui/templates/loading/1.md | 14 + .../fes-doc/docs/ui/templates/loading/2.md | 15 + packages/fes-doc/docs/ui/templates/menu/1.md | 61 + packages/fes-doc/docs/ui/templates/menu/2.md | 44 + .../fes-doc/docs/ui/templates/message/1.md | 25 + .../fes-doc/docs/ui/templates/message/2.md | 29 + .../fes-doc/docs/ui/templates/message/3.md | 25 + packages/fes-doc/docs/ui/templates/modal/1.md | 72 + packages/fes-doc/docs/ui/templates/modal/2.md | 23 + packages/fes-doc/docs/ui/templates/modal/3.md | 33 + packages/fes-doc/docs/ui/templates/modal/4.md | 30 + .../fes-doc/docs/ui/templates/pagination/1.md | 27 + .../fes-doc/docs/ui/templates/pagination/2.md | 27 + .../fes-doc/docs/ui/templates/pagination/3.md | 28 + packages/fes-doc/docs/ui/templates/panel/1.md | 32 + .../docs/ui/templates/process-circle/1.md | 25 + .../docs/ui/templates/process-circle/2.md | 45 + .../docs/ui/templates/process-circle/3.md | 46 + packages/fes-doc/docs/ui/templates/radio/1.md | 32 + packages/fes-doc/docs/ui/templates/radio/2.md | 19 + packages/fes-doc/docs/ui/templates/radio/3.md | 33 + packages/fes-doc/docs/ui/templates/radio/4.md | 27 + packages/fes-doc/docs/ui/templates/radio/5.md | 27 + .../fes-doc/docs/ui/templates/select/1.md | 26 + .../fes-doc/docs/ui/templates/select/2.md | 26 + .../fes-doc/docs/ui/templates/select/3.md | 38 + .../fes-doc/docs/ui/templates/select/4.md | 42 + packages/fes-doc/docs/ui/templates/split/1.md | 44 + packages/fes-doc/docs/ui/templates/split/2.md | 32 + packages/fes-doc/docs/ui/templates/split/3.md | 51 + packages/fes-doc/docs/ui/templates/step/1.md | 21 + packages/fes-doc/docs/ui/templates/step/2.md | 21 + packages/fes-doc/docs/ui/templates/step/3.md | 21 + packages/fes-doc/docs/ui/templates/step/4.md | 31 + packages/fes-doc/docs/ui/templates/step/5.md | 39 + .../fes-doc/docs/ui/templates/switch/1.md | 17 + .../fes-doc/docs/ui/templates/switch/2.md | 19 + .../fes-doc/docs/ui/templates/switch/3.md | 26 + .../fes-doc/docs/ui/templates/switch/4.md | 13 + packages/fes-doc/docs/ui/templates/tab/1.md | 27 + packages/fes-doc/docs/ui/templates/tab/2.md | 22 + packages/fes-doc/docs/ui/templates/tab/3.md | 22 + packages/fes-doc/docs/ui/templates/tab/4.md | 25 + packages/fes-doc/docs/ui/templates/tab/5.md | 30 + packages/fes-doc/docs/ui/templates/tab/6.md | 39 + packages/fes-doc/docs/ui/templates/table/1.md | 48 + .../fes-doc/docs/ui/templates/table/10.md | 68 + .../fes-doc/docs/ui/templates/table/11.md | 53 + .../fes-doc/docs/ui/templates/table/12.md | 52 + .../fes-doc/docs/ui/templates/table/13.md | 80 + .../fes-doc/docs/ui/templates/table/14.md | 24 + packages/fes-doc/docs/ui/templates/table/2.md | 69 + packages/fes-doc/docs/ui/templates/table/3.md | 71 + packages/fes-doc/docs/ui/templates/table/4.md | 50 + packages/fes-doc/docs/ui/templates/table/5.md | 63 + packages/fes-doc/docs/ui/templates/table/6.md | 74 + packages/fes-doc/docs/ui/templates/table/7.md | 62 + packages/fes-doc/docs/ui/templates/table/8.md | 60 + packages/fes-doc/docs/ui/templates/table/9.md | 62 + .../fes-doc/docs/ui/templates/timePicker/1.md | 20 + .../fes-doc/docs/ui/templates/timePicker/2.md | 16 + .../fes-doc/docs/ui/templates/timePicker/3.md | 16 + .../fes-doc/docs/ui/templates/timePicker/4.md | 14 + .../fes-doc/docs/ui/templates/timePicker/5.md | 31 + .../fes-doc/docs/ui/templates/timePicker/6.md | 12 + packages/fes-doc/docs/ui/templates/toast/1.md | 17 + packages/fes-doc/docs/ui/templates/toast/2.md | 25 + packages/fes-doc/docs/ui/templates/toast/3.md | 19 + packages/fes-doc/docs/ui/templates/toast/4.md | 19 + packages/fes-doc/docs/ui/templates/toast/5.md | 21 + .../fes-doc/docs/ui/templates/tooltip/1.md | 12 + .../fes-doc/docs/ui/templates/tooltip/2.md | 21 + .../fes-doc/docs/ui/templates/tooltip/3.md | 26 + .../fes-doc/docs/ui/templates/tooltip/4.md | 113 + .../fes-doc/docs/ui/templates/tooltip/5.md | 60 + packages/fes-doc/docs/ui/templates/tree/1.md | 42 + packages/fes-doc/docs/ui/templates/tree/2.md | 37 + packages/fes-doc/docs/ui/templates/tree/3.md | 42 + packages/fes-doc/docs/ui/templates/tree/4.md | 62 + .../fes-doc/docs/ui/templates/upload/1.md | 31 + .../fes-doc/docs/ui/templates/upload/2.md | 29 + packages/fes-doc/docs/ui/templates/zoom/1.md | 16 + packages/fes-doc/docs/ui/templates/zoom/2.md | 22 + packages/fes-doc/docs/ui/timePicker.md | 151 + packages/fes-doc/docs/ui/toast.md | 122 + packages/fes-doc/docs/ui/tooltip.md | 228 + packages/fes-doc/docs/ui/tree.md | 156 + packages/fes-doc/docs/ui/upload.md | 92 + packages/fes-doc/docs/ui/zoom.md | 62 + packages/fes-doc/images/banner_ad.png | Bin 0 -> 22573 bytes packages/fes-doc/images/banner_apply.png | Bin 0 -> 20691 bytes packages/fes-doc/images/banner_tips.png | Bin 0 -> 21396 bytes packages/fes-doc/images/framework.jpg | Bin 0 -> 1498906 bytes packages/fes-doc/images/icon_notice.png | Bin 0 -> 443 bytes packages/fes-doc/images/layout.png | Bin 0 -> 62840 bytes packages/fes-doc/images/layout2.png | Bin 0 -> 43810 bytes packages/fes-doc/package.json | 27 + packages/fes-doc/test.md | 50 + packages/fes-template/.editorconfig | 15 + packages/fes-template/.eslintrc.js | 17 + packages/fes-template/LICENSE | 21 + packages/fes-template/fes.config.js | 140 + packages/fes-template/mock.js | 113 + packages/fes-template/package.json | 60 + packages/fes-template/src/app.js | 45 + .../fes-template/src/assets/images/bg.png | Bin 0 -> 6059 bytes .../fes-template/src/assets/images/logo.png | Bin 0 -> 2742 bytes .../fes-template/src/assets/styles/login.scss | 131 + .../fes-template/src/assets/styles/main.scss | 50 + .../src/assets/styles/variables.scss | 90 + .../fes-template/src/components/fesHeader.fes | 14 + .../fes-template/src/components/fesLeft.fes | 9 + .../fes-template/src/pages/api/fes/index.vue | 74 + .../src/pages/api/fesApi/index.vue | 50 + .../src/pages/api/fesApp/index.vue | 94 + .../src/pages/api/fesFesx/index.vue | 26 + .../src/pages/api/fesMap/index.vue | 20 + .../src/pages/api/fesMenu/index.vue | 129 + .../src/pages/api/fesStorage/index.vue | 38 + .../src/pages/api/fesUtil/index.vue | 33 + .../fes-template/src/pages/header/index.vue | 77 + .../fes-template/src/pages/home/index.vue | 142 + .../fes-template/src/pages/i18n/index.vue | 48 + packages/fes-template/src/pages/layout/a.vue | 12 + packages/fes-template/src/pages/layout/b.vue | 12 + .../fes-template/src/pages/layout/layout.vue | 16 + .../src/pages/list/edit/index.vue | 89 + .../fes-template/src/pages/list/index.vue | 84 + packages/fes-template/src/pages/route.vue | 28 + .../fes-template/src/pages/static/index.vue | 18 + packages/fes-template/src/static/1.txt | 1 + packages/fes-template/src/static/bell.png | Bin 0 -> 443 bytes packages/fes-template/src/static/favicon.ico | Bin 0 -> 5430 bytes packages/fes-template/webpack.config.js | 27 + packages/fes-ui/LICENSE | 21 + packages/fes-ui/build/createServer.js | 74 + packages/fes-ui/build/gulpfile.js | 95 + packages/fes-ui/build/mock.js | 62 + packages/fes-ui/build/mock/cgiMock.js | 133 + packages/fes-ui/build/mock/init.js | 127 + packages/fes-ui/build/mock/log.js | 38 + packages/fes-ui/build/mock/task/cgiMock.js | 20 + packages/fes-ui/build/mock/test/app.js | 62 + packages/fes-ui/build/mock/test/myfile.txt | 1 + packages/fes-ui/build/mock/util.js | 63 + packages/fes-ui/build/webpack.dist.config.js | 130 + .../fes-ui/build/webpack.dist.prod.config.js | 43 + .../fes-ui/build/webpack.examples.config.js | 119 + packages/fes-ui/dist/fes-ui.js | 30629 ++++++++++++++++ packages/fes-ui/dist/fes-ui.min.js | 1 + packages/fes-ui/dist/styles/fes-ui.css | 5540 +++ packages/fes-ui/dist/styles/fes-ui.min.css | 1 + .../fes-ui/dist/styles/iconfont/iconfont.eot | Bin 0 -> 67402 bytes .../fes-ui/dist/styles/iconfont/iconfont.svg | 732 + .../fes-ui/dist/styles/iconfont/iconfont.ttf | Bin 0 -> 67124 bytes .../fes-ui/dist/styles/iconfont/iconfont.woff | Bin 0 -> 36124 bytes .../fes-ui/dist/styles/iconfont/ionicons.eot | Bin 0 -> 112650 bytes .../fes-ui/dist/styles/iconfont/ionicons.svg | 2090 ++ .../fes-ui/dist/styles/iconfont/ionicons.ttf | Bin 0 -> 112472 bytes .../fes-ui/dist/styles/iconfont/ionicons.woff | Bin 0 -> 65908 bytes .../dist/styles/iconfont/ionicons.woff2 | Bin 0 -> 50556 bytes packages/fes-ui/examples/data.json | 3390 ++ packages/fes-ui/examples/images/girl.jpg | Bin 0 -> 170450 bytes .../fes-ui/examples/images/icon_notice.png | Bin 0 -> 443 bytes packages/fes-ui/examples/images/layout.png | Bin 0 -> 62840 bytes packages/fes-ui/examples/images/web32002.jpg | Bin 0 -> 62569 bytes packages/fes-ui/examples/index.html | 17 + packages/fes-ui/examples/js/app.js | 31 + packages/fes-ui/examples/js/demand.js | 130 + packages/fes-ui/examples/js/router.js | 295 + packages/fes-ui/examples/styles/main.scss | 471 + packages/fes-ui/examples/views/App.vue | 41 + .../fes-ui/examples/views/component/affix.vue | 111 + .../examples/views/component/backTop.vue | 103 + .../examples/views/component/button.vue | 110 + .../examples/views/component/carousel.vue | 47 + .../examples/views/component/checkbox.vue | 197 + .../examples/views/component/collapse.vue | 62 + .../examples/views/component/contextmenu.vue | 92 + .../examples/views/component/datePicker.vue | 727 + .../examples/views/component/draggable.vue | 110 + .../examples/views/component/dropdown.vue | 196 + .../fes-ui/examples/views/component/form.vue | 678 + .../fes-ui/examples/views/component/icon.vue | 63 + .../fes-ui/examples/views/component/index.vue | 203 + .../fes-ui/examples/views/component/input.vue | 339 + .../examples/views/component/install.vue | 24 + .../examples/views/component/layout.vue | 113 + .../examples/views/component/loading.vue | 112 + .../fes-ui/examples/views/component/log.vue | 27 + .../examples/views/component/md/affix1.md | 16 + .../examples/views/component/md/affix2.md | 27 + .../examples/views/component/md/affix3.md | 21 + .../examples/views/component/md/affix4.md | 5 + .../examples/views/component/md/affix5.md | 3 + .../examples/views/component/md/backTop1.md | 14 + .../examples/views/component/md/backTop2.md | 31 + .../examples/views/component/md/backTop3.md | 4 + .../examples/views/component/md/backTop4.md | 10 + .../examples/views/component/md/button1.md | 17 + .../examples/views/component/md/button2.md | 12 + .../examples/views/component/md/button3.md | 6 + .../examples/views/component/md/button4.md | 11 + .../examples/views/component/md/checkbox1.md | 15 + .../examples/views/component/md/checkbox2.md | 29 + .../examples/views/component/md/checkbox3.md | 29 + .../views/component/md/contextmenu.md | 24 + .../views/component/md/datepicker1.md | 26 + .../views/component/md/datepicker2.md | 23 + .../views/component/md/datepicker3.md | 18 + .../views/component/md/datepicker4.md | 18 + .../views/component/md/datepicker5.md | 30 + .../views/component/md/datepicker6.md | 24 + .../views/component/md/datepicker7.md | 24 + .../views/component/md/datepicker8.md | 14 + .../examples/views/component/md/draggable1.md | 44 + .../examples/views/component/md/draggable2.md | 4 + .../examples/views/component/md/dropdown1.md | 26 + .../examples/views/component/md/dropdown2.md | 32 + .../examples/views/component/md/dropdown3.md | 52 + .../examples/views/component/md/dropdown4.md | 57 + .../examples/views/component/md/dropdown5.md | 4 + .../examples/views/component/md/dropdown6.md | 3 + .../examples/views/component/md/dropdown7.md | 5 + .../examples/views/component/md/form1.md | 66 + .../examples/views/component/md/form2.md | 49 + .../examples/views/component/md/form3.md | 42 + .../examples/views/component/md/form4.md | 112 + .../examples/views/component/md/icon1.md | 11 + .../examples/views/component/md/icon2.md | 5 + .../examples/views/component/md/input1.md | 15 + .../examples/views/component/md/input2.md | 14 + .../examples/views/component/md/input3.md | 14 + .../examples/views/component/md/input4.md | 14 + .../examples/views/component/md/input5.md | 21 + .../examples/views/component/md/input6.md | 15 + .../examples/views/component/md/input7.md | 17 + .../examples/views/component/md/input8.md | 16 + .../examples/views/component/md/install.md | 4 + .../examples/views/component/md/layout1.md | 16 + .../examples/views/component/md/layout2.md | 15 + .../examples/views/component/md/layout3.md | 4 + .../examples/views/component/md/loading1.md | 15 + .../examples/views/component/md/loading2.md | 13 + .../examples/views/component/md/menu1.md | 17 + .../examples/views/component/md/menu2.md | 37 + .../examples/views/component/md/menu3.md | 26 + .../examples/views/component/md/message1.md | 17 + .../examples/views/component/md/message2.md | 22 + .../examples/views/component/md/message3.md | 28 + .../examples/views/component/md/modal1.md | 79 + .../examples/views/component/md/modal2.md | 37 + .../examples/views/component/md/play.md | 16 + .../views/component/md/processCircle1.md | 15 + .../views/component/md/processCircle2.md | 41 + .../views/component/md/processCircle3.md | 42 + .../views/component/md/processCircle4.md | 9 + .../examples/views/component/md/radio1.md | 29 + .../examples/views/component/md/radio2.md | 29 + .../examples/views/component/md/radio3.md | 29 + .../examples/views/component/md/select.md | 26 + .../examples/views/component/md/select2.md | 26 + .../examples/views/component/md/step1.md | 15 + .../examples/views/component/md/step2.md | 15 + .../examples/views/component/md/step3.md | 15 + .../examples/views/component/md/step4.md | 28 + .../examples/views/component/md/switch1.md | 19 + .../examples/views/component/md/switch2.md | 21 + .../examples/views/component/md/table1.md | 44 + .../examples/views/component/md/table10.md | 5 + .../examples/views/component/md/table2.md | 80 + .../examples/views/component/md/table3.md | 78 + .../examples/views/component/md/table4.md | 61 + .../examples/views/component/md/table5.md | 50 + .../examples/views/component/md/table6.md | 59 + .../examples/views/component/md/table7.md | 47 + .../examples/views/component/md/table8.md | 3 + .../examples/views/component/md/table9.md | 13 + .../examples/views/component/md/tabs1.md | 20 + .../examples/views/component/md/tabs2.md | 20 + .../examples/views/component/md/tabs3.md | 3 + .../examples/views/component/md/tabs4.md | 3 + .../examples/views/component/md/tabs5.md | 6 + .../examples/views/component/md/tabs6.md | 23 + .../examples/views/component/md/tabs7.md | 38 + .../views/component/md/timePicker1.md | 4 + .../views/component/md/timePicker2.md | 8 + .../views/component/md/timePicker3.md | 4 + .../views/component/md/timePicker4.md | 9 + .../views/component/md/timePicker5.md | 43 + .../examples/views/component/md/toast1.md | 16 + .../examples/views/component/md/toast2.md | 22 + .../examples/views/component/md/toast3.md | 16 + .../examples/views/component/md/tooltip1.md | 10 + .../examples/views/component/md/tooltip2.md | 94 + .../examples/views/component/md/tooltip3.md | 16 + .../examples/views/component/md/tooltip4.md | 23 + .../examples/views/component/md/tooltip5.md | 21 + .../examples/views/component/md/tree1.md | 39 + .../examples/views/component/md/tree2.md | 39 + .../examples/views/component/md/upload.md | 21 + .../examples/views/component/md/zoom1.md | 10 + .../examples/views/component/md/zoom2.md | 18 + .../examples/views/component/md/zoom3.md | 5 + .../fes-ui/examples/views/component/menu.vue | 168 + .../examples/views/component/message.vue | 248 + .../fes-ui/examples/views/component/modal.vue | 330 + .../examples/views/component/pagination.vue | 43 + .../fes-ui/examples/views/component/panel.vue | 50 + .../fes-ui/examples/views/component/play.vue | 28 + .../views/component/processCircle.vue | 158 + .../fes-ui/examples/views/component/radio.vue | 229 + .../examples/views/component/select.vue | 455 + .../fes-ui/examples/views/component/split.vue | 162 + .../fes-ui/examples/views/component/step.vue | 204 + .../examples/views/component/switch.vue | 127 + .../fes-ui/examples/views/component/tab.vue | 227 + .../fes-ui/examples/views/component/table.vue | 395 + .../examples/views/component/timePicker.vue | 396 + .../fes-ui/examples/views/component/toast.vue | 150 + .../examples/views/component/tooltip.vue | 405 + .../fes-ui/examples/views/component/tree.vue | 289 + .../examples/views/component/upload.vue | 143 + .../fes-ui/examples/views/component/zoom.vue | 79 + .../examples/views/guide/components.vue | 22 + .../fes-ui/examples/views/guide/config.vue | 13 + packages/fes-ui/examples/views/guide/fes.vue | 13 + .../fes-ui/examples/views/guide/fesApi.vue | 13 + .../fes-ui/examples/views/guide/fesApp.vue | 91 + .../fes-ui/examples/views/guide/fesFesx.vue | 16 + .../fes-ui/examples/views/guide/fesMap.vue | 13 + .../examples/views/guide/fesStorage.vue | 13 + .../fes-ui/examples/views/guide/fesUtil.vue | 33 + .../fes-ui/examples/views/guide/index.vue | 45 + .../fes-ui/examples/views/guide/install.vue | 14 + .../fes-ui/examples/views/guide/introduce.vue | 39 + .../fes-ui/examples/views/guide/layout.vue | 13 + packages/fes-ui/examples/views/guide/log.vue | 22 + .../examples/views/guide/md/components.md | 4 + .../fes-ui/examples/views/guide/md/config.md | 82 + .../fes-ui/examples/views/guide/md/fes.md | 138 + .../fes-ui/examples/views/guide/md/fesApi.md | 46 + .../fes-ui/examples/views/guide/md/fesFesx.md | 24 + .../fes-ui/examples/views/guide/md/fesMap.md | 7 + .../examples/views/guide/md/fesStorage.md | 14 + .../fes-ui/examples/views/guide/md/layout.md | 17 + .../fes-ui/examples/views/guide/md/log.md | 15 + .../fes-ui/examples/views/guide/md/mock.md | 119 + .../fes-ui/examples/views/guide/md/play.md | 46 + .../fes-ui/examples/views/guide/md/role.md | 37 + .../fes-ui/examples/views/guide/md/route.md | 64 + packages/fes-ui/examples/views/guide/mock.vue | 15 + packages/fes-ui/examples/views/guide/play.vue | 125 + packages/fes-ui/examples/views/guide/role.vue | 13 + .../fes-ui/examples/views/guide/route.vue | 21 + packages/fes-ui/examples/views/panel.vue | 51 + packages/fes-ui/package.json | 94 + .../fes-ui/src/components/affix/affix.vue | 132 + packages/fes-ui/src/components/affix/index.js | 3 + .../src/components/affix/style/index.scss | 2 + .../src/components/back-top/backTop.vue | 101 + .../fes-ui/src/components/back-top/index.js | 3 + .../src/components/back-top/style/index.scss | 2 + .../fes-ui/src/components/button/button.vue | 94 + .../fes-ui/src/components/button/index.js | 3 + .../src/components/button/style/index.scss | 2 + .../src/components/carousel/carousel.vue | 93 + .../fes-ui/src/components/carousel/index.js | 3 + .../src/components/carousel/style/index.scss | 2 + packages/fes-ui/src/components/cell/index.js | 3 + .../src/components/cell/style/index.scss | 2 + .../src/components/checkbox-com/checkbox.vue | 114 + .../components/checkbox-com/checkboxGroup.vue | 136 + .../src/components/checkbox-com/index.js | 7 + .../components/checkbox-com/style/index.scss | 2 + .../src/components/checkbox-group/index.js | 3 + .../checkbox-group/style/index.scss | 2 + .../fes-ui/src/components/checkbox/index.js | 3 + .../src/components/checkbox/style/index.scss | 2 + .../src/components/collapse/collapse.vue | 78 + .../src/components/collapse/collapsePanel.vue | 85 + .../fes-ui/src/components/collapse/index.js | 5 + .../src/components/collapse/openAnim.vue | 51 + .../src/components/collapse/style/index.scss | 2 + .../fes-ui/src/components/column/index.js | 3 + .../src/components/column/style/index.scss | 3 + .../src/components/contextmenu/index.js | 3 + .../src/components/contextmenu/index.vue | 68 + .../components/contextmenu/style/index.scss | 2 + .../src/components/data-table/column.vue | 124 + .../src/components/data-table/editCell.vue | 160 + .../components/data-table/headComponent.vue | 29 + .../fes-ui/src/components/data-table/index.js | 9 + .../components/data-table/style/index.scss | 3 + .../src/components/data-table/table.vue | 513 + .../src/components/data-table/tableAction.vue | 37 + .../components/data-table/tableComponent.vue | 29 + .../data-table/tableDetailComponent.vue | 39 + .../src/components/data-table/tableExpand.vue | 29 + .../src/components/data-table/tableText.vue | 38 + .../src/components/data-table/treeTable.vue | 169 + .../src/components/date-picker/calendar.vue | 756 + .../src/components/date-picker/calendars.vue | 465 + .../src/components/date-picker/datePicker.vue | 228 + .../src/components/date-picker/index.js | 5 + .../src/components/date-picker/propsMixin.js | 95 + .../components/date-picker/style/index.scss | 2 + .../components/draggable/DraggableItem.vue | 71 + .../src/components/draggable/Manager.js | 39 + .../src/components/draggable/draggable.vue | 218 + .../fes-ui/src/components/draggable/index.js | 3 + .../src/components/draggable/style/index.scss | 1 + .../fes-ui/src/components/draggable/utils.js | 74 + .../src/components/dropdown-com/dropdown.vue | 85 + .../components/dropdown-com/dropdownMenu.vue | 102 + .../src/components/dropdown-com/index.js | 7 + .../components/dropdown-com/style/index.scss | 2 + .../src/components/dropdown-menu/index.js | 3 + .../components/dropdown-menu/style/index.scss | 2 + .../fes-ui/src/components/dropdown/index.js | 3 + .../src/components/dropdown/style/index.scss | 2 + .../fes-ui/src/components/form-item/index.js | 3 + .../src/components/form-item/style/index.scss | 2 + packages/fes-ui/src/components/form/form.vue | 130 + .../fes-ui/src/components/form/formItem.vue | 156 + packages/fes-ui/src/components/form/index.js | 7 + packages/fes-ui/src/components/form/rule.js | 68 + .../src/components/form/style/index.scss | 2 + packages/fes-ui/src/components/icon/icon.vue | 48 + packages/fes-ui/src/components/icon/index.js | 3 + .../src/components/icon/style/index.scss | 1 + packages/fes-ui/src/components/input/index.js | 3 + .../fes-ui/src/components/input/input.vue | 265 + .../src/components/input/style/index.scss | 2 + .../fes-ui/src/components/layout/cell.vue | 29 + .../fes-ui/src/components/layout/index.js | 6 + packages/fes-ui/src/components/layout/row.vue | 10 + .../src/components/layout/style/index.scss | 2 + .../fes-ui/src/components/loading/index.js | 3 + .../fes-ui/src/components/loading/loading.vue | 35 + .../src/components/loading/style/index.scss | 2 + packages/fes-ui/src/components/menu/index.js | 9 + packages/fes-ui/src/components/menu/menu.vue | 114 + .../fes-ui/src/components/menu/menuGroup.vue | 21 + .../fes-ui/src/components/menu/menuItem.vue | 48 + .../fes-ui/src/components/menu/routeMenu.vue | 120 + .../src/components/menu/style/index.scss | 2 + .../fes-ui/src/components/menu/subMenu.vue | 138 + .../fes-ui/src/components/message/index.js | 126 + .../fes-ui/src/components/message/message.vue | 63 + .../src/components/message/style/index.scss | 3 + packages/fes-ui/src/components/modal/index.js | 3 + .../fes-ui/src/components/modal/modal.vue | 168 + .../src/components/modal/style/index.scss | 2 + .../src/components/option-group/index.js | 3 + .../components/option-group/style/index.scss | 2 + .../fes-ui/src/components/pagination/index.js | 3 + .../src/components/pagination/pagination.vue | 238 + .../components/pagination/style/index.scss | 2 + packages/fes-ui/src/components/panel/index.js | 3 + .../fes-ui/src/components/panel/panel.vue | 24 + .../src/components/panel/style/index.scss | 2 + .../src/components/process-circle/index.js | 3 + .../process-circle/processCircle.vue | 70 + .../process-circle/style/index.scss | 2 + .../fes-ui/src/components/radio-com/index.js | 7 + .../fes-ui/src/components/radio-com/radio.vue | 111 + .../src/components/radio-com/radioGroup.vue | 150 + .../src/components/radio-com/style/index.scss | 2 + .../src/components/radio-group/index.js | 3 + .../components/radio-group/style/index.scss | 2 + packages/fes-ui/src/components/radio/index.js | 3 + .../src/components/radio/style/index.scss | 2 + .../fes-ui/src/components/route-menu/index.js | 3 + .../components/route-menu/style/index.scss | 2 + packages/fes-ui/src/components/row/index.js | 3 + .../src/components/row/style/index.scss | 2 + .../fes-ui/src/components/select/index.js | 9 + .../fes-ui/src/components/select/option.vue | 98 + .../src/components/select/optionGroup.vue | 17 + .../fes-ui/src/components/select/select.vue | 619 + .../src/components/select/style/index.scss | 2 + .../fes-ui/src/components/split-com/index.js | 7 + .../fes-ui/src/components/split-com/split.vue | 258 + .../src/components/split-com/splitItem.vue | 150 + .../src/components/split-com/style/index.scss | 2 + .../fes-ui/src/components/split-item/index.js | 3 + .../components/split-item/style/index.scss | 2 + packages/fes-ui/src/components/split/index.js | 3 + .../src/components/split/style/index.scss | 2 + .../fes-ui/src/components/step-com/index.js | 7 + .../fes-ui/src/components/step-com/step.vue | 69 + .../fes-ui/src/components/step-com/steps.vue | 60 + .../src/components/step-com/style/index.scss | 2 + packages/fes-ui/src/components/step/index.js | 3 + .../src/components/step/style/index.scss | 2 + packages/fes-ui/src/components/steps/index.js | 3 + .../src/components/steps/style/index.scss | 2 + .../fes-ui/src/components/switch/index.js | 3 + .../src/components/switch/style/index.scss | 2 + .../fes-ui/src/components/switch/switch.vue | 80 + .../fes-ui/src/components/tab-com/index.js | 7 + .../src/components/tab-com/style/index.scss | 2 + .../fes-ui/src/components/tab-com/tab.vue | 49 + .../src/components/tab-com/tabComponent.vue | 20 + .../fes-ui/src/components/tab-com/tabs.vue | 244 + packages/fes-ui/src/components/tab/index.js | 3 + .../src/components/tab/style/index.scss | 2 + packages/fes-ui/src/components/tabs/index.js | 3 + .../src/components/tabs/style/index.scss | 2 + .../src/components/time-picker/index.js | 3 + .../components/time-picker/pickerContent.vue | 377 + .../src/components/time-picker/pickerItem.vue | 101 + .../components/time-picker/style/index.scss | 2 + .../src/components/time-picker/timePicker.vue | 151 + packages/fes-ui/src/components/toast/index.js | 147 + .../src/components/toast/style/index.scss | 2 + packages/fes-ui/src/components/toast/swap.vue | 19 + .../fes-ui/src/components/toast/toast.vue | 46 + .../fes-ui/src/components/tooltip/index.js | 6 + .../src/components/tooltip/style/index.scss | 2 + .../fes-ui/src/components/tooltip/tooltip.js | 170 + .../fes-ui/src/components/tooltip/tooltip.vue | 132 + .../components/tooltip/tooltipComponent.vue | 21 + .../fes-ui/src/components/tree-table/index.js | 3 + .../components/tree-table/style/index.scss | 3 + packages/fes-ui/src/components/tree/index.js | 3 + .../fes-ui/src/components/tree/nodeText.vue | 40 + .../src/components/tree/style/index.scss | 2 + packages/fes-ui/src/components/tree/tree.vue | 227 + .../fes-ui/src/components/tree/treeNode.vue | 122 + .../src/components/upload/iePolyfill.js | 99 + .../fes-ui/src/components/upload/index.js | 3 + .../src/components/upload/style/index.scss | 2 + .../fes-ui/src/components/upload/upload.vue | 203 + .../src/components/v-picker-popup/index.js | 3 + .../components/v-picker-popup/pickerPopup.vue | 85 + .../v-picker-popup/style/index.scss | 2 + .../src/components/v-readonly-input/index.js | 3 + .../v-readonly-input/readonlyInput.vue | 71 + .../v-readonly-input/style/index.scss | 2 + .../fes-ui/src/components/wb-button/index.js | 3 + .../src/components/wb-button/style/index.scss | 2 + .../fes-ui/src/components/wb-form/index.js | 3 + .../src/components/wb-form/style/index.scss | 2 + .../components/wb-input-date-picker/index.js | 3 + .../wb-input-date-picker/style/index.scss | 2 + .../fes-ui/src/components/wb-input/index.js | 3 + .../src/components/wb-input/style/index.scss | 2 + .../src/components/wb-menu-group/index.js | 3 + .../components/wb-menu-group/style/index.scss | 2 + .../src/components/wb-menu-item/index.js | 3 + .../components/wb-menu-item/style/index.scss | 2 + .../fes-ui/src/components/wb-menu/index.js | 3 + .../src/components/wb-menu/style/index.scss | 2 + .../fes-ui/src/components/wb-option/index.js | 3 + .../src/components/wb-option/style/index.scss | 2 + .../fes-ui/src/components/wb-select/index.js | 3 + .../src/components/wb-select/style/index.scss | 2 + .../src/components/wb-sub-menu/index.js | 3 + .../components/wb-sub-menu/style/index.scss | 2 + .../fes-ui/src/components/wb-switch/index.js | 3 + .../src/components/wb-switch/style/index.scss | 2 + .../fes-ui/src/components/wb-table/index.js | 3 + .../src/components/wb-table/style/index.scss | 3 + packages/fes-ui/src/components/zoom/index.js | 6 + .../src/components/zoom/style/index.scss | 2 + packages/fes-ui/src/components/zoom/zoom.js | 74 + packages/fes-ui/src/components/zoom/zoom.vue | 92 + packages/fes-ui/src/directives/autoRow.js | 68 + .../fes-ui/src/directives/clickoutside.js | 27 + .../fes-ui/src/directives/mouseoutside.js | 24 + packages/fes-ui/src/i18n/format.js | 45 + packages/fes-ui/src/i18n/index.js | 73 + packages/fes-ui/src/i18n/messages.js | 197 + packages/fes-ui/src/i18n/mixin.js | 21 + packages/fes-ui/src/i18n/watch.js | 28 + packages/fes-ui/src/index.js | 124 + packages/fes-ui/src/mixins/emitter.js | 34 + .../fes-ui/src/styles/animation/index.scss | 120 + packages/fes-ui/src/styles/common/base.scss | 81 + packages/fes-ui/src/styles/common/common.scss | 0 packages/fes-ui/src/styles/common/expand.scss | 21 + .../fes-ui/src/styles/common/iconfont.scss | 1947 + .../src/styles/common/iconfont/ionicons.eot | Bin 0 -> 112650 bytes .../src/styles/common/iconfont/ionicons.svg | 2090 ++ .../src/styles/common/iconfont/ionicons.ttf | Bin 0 -> 112472 bytes .../src/styles/common/iconfont/ionicons.woff | Bin 0 -> 65908 bytes .../src/styles/common/iconfont/ionicons.woff2 | Bin 0 -> 50556 bytes packages/fes-ui/src/styles/common/index.scss | 5 + .../fes-ui/src/styles/common/normalize.scss | 461 + .../fes-ui/src/styles/common/variables.scss | 91 + .../fes-ui/src/styles/components/affix.scss | 4 + .../fes-ui/src/styles/components/backTop.scss | 26 + .../fes-ui/src/styles/components/button.scss | 137 + .../src/styles/components/carousel.scss | 40 + .../src/styles/components/checkbox.scss | 128 + .../fes-ui/src/styles/components/circle.scss | 14 + .../src/styles/components/collapse.scss | 56 + .../src/styles/components/contextmenu.scss | 37 + .../src/styles/components/datePicker.scss | 224 + .../src/styles/components/dropdown.scss | 67 + .../fes-ui/src/styles/components/form.scss | 114 + .../fes-ui/src/styles/components/index.scss | 35 + .../fes-ui/src/styles/components/input.scss | 177 + .../fes-ui/src/styles/components/layout.scss | 37 + .../fes-ui/src/styles/components/loading.scss | 9 + .../fes-ui/src/styles/components/menu.scss | 344 + .../fes-ui/src/styles/components/message.scss | 62 + .../fes-ui/src/styles/components/modal.scss | 96 + .../src/styles/components/pagination.scss | 129 + .../fes-ui/src/styles/components/panel.scss | 44 + .../fes-ui/src/styles/components/radio.scss | 180 + .../fes-ui/src/styles/components/select.scss | 226 + .../fes-ui/src/styles/components/split.scss | 26 + .../fes-ui/src/styles/components/step.scss | 155 + .../fes-ui/src/styles/components/switch.scss | 46 + .../fes-ui/src/styles/components/tab.scss | 141 + .../fes-ui/src/styles/components/table.scss | 156 + .../src/styles/components/timePicker.scss | 60 + .../fes-ui/src/styles/components/toast.scss | 53 + .../fes-ui/src/styles/components/tooltip.scss | 285 + .../fes-ui/src/styles/components/tree.scss | 54 + .../src/styles/components/treeTable.scss | 16 + .../fes-ui/src/styles/components/upload.scss | 7 + .../src/styles/components/vPickerPopup.scss | 90 + .../src/styles/components/vReadonlyInput.scss | 66 + .../fes-ui/src/styles/components/zoom.scss | 37 + packages/fes-ui/src/styles/demand.scss | 4 + .../fes-ui/src/styles/iconfont/ionicons.eot | Bin 0 -> 112650 bytes .../fes-ui/src/styles/iconfont/ionicons.svg | 2090 ++ .../fes-ui/src/styles/iconfont/ionicons.ttf | Bin 0 -> 112472 bytes .../fes-ui/src/styles/iconfont/ionicons.woff | Bin 0 -> 65908 bytes .../fes-ui/src/styles/iconfont/ionicons.woff2 | Bin 0 -> 50556 bytes packages/fes-ui/src/styles/index.scss | 6 + packages/fes-ui/src/styles/mixins/index.scss | 113 + packages/fes-ui/src/utils/EventListener.js | 30 + .../fes-ui/src/utils/elementResizeEvent.js | 106 + packages/fes-ui/src/utils/keyCode.js | 601 + packages/fes-ui/src/utils/util.js | 534 + 836 files changed, 100821 insertions(+) create mode 100644 .editorconfig create mode 100644 .eslintrc.js create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 lerna.json create mode 100644 package.json create mode 100644 packages/fes-cli/LICENSE create mode 100755 packages/fes-cli/bin/index.js create mode 100644 packages/fes-cli/build/configs/postcss.config.js create mode 100644 packages/fes-cli/build/configs/webpack.config.js create mode 100644 packages/fes-cli/build/helpers/browser.js create mode 100644 packages/fes-cli/build/helpers/config.js create mode 100644 packages/fes-cli/build/helpers/createDevServer.js create mode 100644 packages/fes-cli/build/helpers/getPort.js create mode 100644 packages/fes-cli/build/helpers/log.js create mode 100644 packages/fes-cli/build/mock/cgiMock.js create mode 100644 packages/fes-cli/build/mock/init.js create mode 100644 packages/fes-cli/build/mock/task/cgiMock.js create mode 100644 packages/fes-cli/build/mock/test/app.js create mode 100644 packages/fes-cli/build/mock/test/myfile.txt create mode 100644 packages/fes-cli/build/mock/util.js create mode 100644 packages/fes-cli/build/preComplie/components.js create mode 100644 packages/fes-cli/build/preComplie/route.js create mode 100644 packages/fes-cli/build/tasks/build.js create mode 100644 packages/fes-cli/build/tasks/components.js create mode 100644 packages/fes-cli/build/tasks/dev.js create mode 100644 packages/fes-cli/build/tasks/index.js create mode 100644 packages/fes-cli/build/tasks/init.js create mode 100644 packages/fes-cli/build/tasks/route.js create mode 100644 packages/fes-cli/build/tasks/update.js create mode 100644 packages/fes-cli/change.md create mode 100644 packages/fes-cli/package.json create mode 100644 packages/fes-cli/template/.eslintrc.js create mode 100644 packages/fes-cli/template/.gitignore create mode 100644 packages/fes-cli/template/LICENSE create mode 100644 packages/fes-cli/template/fes.config.js create mode 100644 packages/fes-cli/template/mock.js create mode 100644 packages/fes-cli/template/package.json create mode 100644 packages/fes-cli/template/src/app.js create mode 100644 packages/fes-cli/template/src/assets/images/bg.png create mode 100644 packages/fes-cli/template/src/assets/images/logo.png create mode 100644 packages/fes-cli/template/src/assets/styles/login.scss create mode 100644 packages/fes-cli/template/src/assets/styles/main.scss create mode 100644 packages/fes-cli/template/src/assets/styles/variables.scss create mode 100644 packages/fes-cli/template/src/components/fesHeader.vue create mode 100644 packages/fes-cli/template/src/components/fesLeft.vue create mode 100644 packages/fes-cli/template/src/pages/api/fes/index.vue create mode 100644 packages/fes-cli/template/src/pages/api/fesApi/index.vue create mode 100644 packages/fes-cli/template/src/pages/api/fesApp/index.vue create mode 100644 packages/fes-cli/template/src/pages/api/fesFesx/index.vue create mode 100644 packages/fes-cli/template/src/pages/api/fesMap/index.vue create mode 100644 packages/fes-cli/template/src/pages/api/fesMenu/index.vue create mode 100644 packages/fes-cli/template/src/pages/api/fesStorage/index.vue create mode 100644 packages/fes-cli/template/src/pages/api/fesUtil/index.vue create mode 100644 packages/fes-cli/template/src/pages/header/index.vue create mode 100644 packages/fes-cli/template/src/pages/home/index.vue create mode 100644 packages/fes-cli/template/src/pages/i18n/index.vue create mode 100644 packages/fes-cli/template/src/pages/layout/a.vue create mode 100644 packages/fes-cli/template/src/pages/layout/b.vue create mode 100644 packages/fes-cli/template/src/pages/layout/layout.vue create mode 100644 packages/fes-cli/template/src/pages/list/edit/index.vue create mode 100644 packages/fes-cli/template/src/pages/list/index.vue create mode 100644 packages/fes-cli/template/src/pages/route.vue create mode 100644 packages/fes-cli/template/src/pages/static/index.vue create mode 100644 packages/fes-cli/template/src/static/1.txt create mode 100644 packages/fes-cli/template/src/static/bell.png create mode 100644 packages/fes-cli/template/src/static/favicon.ico create mode 100644 packages/fes-core/LICENSE create mode 100644 packages/fes-core/package.json create mode 100644 packages/fes-core/src/api/index.js create mode 100644 packages/fes-core/src/app.js create mode 100644 packages/fes-core/src/config/index.js create mode 100644 packages/fes-core/src/directive/index.js create mode 100644 packages/fes-core/src/env/index.js create mode 100644 packages/fes-core/src/fesx/_fesx.js create mode 100644 packages/fes-core/src/fesx/fesx.js create mode 100644 packages/fes-core/src/fesx/index.js create mode 100644 packages/fes-core/src/filter/index.js create mode 100644 packages/fes-core/src/index.html create mode 100644 packages/fes-core/src/instance/app.js create mode 100644 packages/fes-core/src/instance/page.js create mode 100644 packages/fes-core/src/instance/permission.js create mode 100644 packages/fes-core/src/map/index.js create mode 100644 packages/fes-core/src/polyfill/index.js create mode 100644 packages/fes-core/src/storage/index.js create mode 100644 packages/fes-core/src/util/dom.js create mode 100644 packages/fes-core/src/util/event.js create mode 100644 packages/fes-core/src/util/format.js create mode 100644 packages/fes-core/src/util/history.js create mode 100644 packages/fes-core/src/util/index.js create mode 100644 packages/fes-core/src/util/object.js create mode 100644 packages/fes-core/src/util/type.js create mode 100644 packages/fes-core/src/views/components/index.js create mode 100644 packages/fes-core/src/views/components/listPanel.vue create mode 100644 packages/fes-core/src/views/components/routeMenu.vue create mode 100644 packages/fes-core/src/views/components/searchPanel.vue create mode 100644 packages/fes-core/src/views/layout/left.vue create mode 100644 packages/fes-core/src/views/layout/root.vue create mode 100644 packages/fes-core/src/views/styles/components.scss create mode 100644 packages/fes-core/src/views/styles/index.scss create mode 100644 packages/fes-core/src/views/styles/layout.scss create mode 100644 packages/fes-core/src/views/styles/polyfill.scss create mode 100644 packages/fes-doc/LICENSE create mode 100644 packages/fes-doc/deploy.sh create mode 100644 packages/fes-doc/docs/.vuepress/components/componetTemplate.vue create mode 100644 packages/fes-doc/docs/.vuepress/components/templateLayout.vue create mode 100644 packages/fes-doc/docs/.vuepress/config.js create mode 100644 packages/fes-doc/docs/.vuepress/enhanceApp.js create mode 100644 packages/fes-doc/docs/.vuepress/public/logo.jpg create mode 100644 packages/fes-doc/docs/.vuepress/styles/index.styl create mode 100644 packages/fes-doc/docs/.vuepress/styles/override.styl create mode 100644 packages/fes-doc/docs/data.json create mode 100644 packages/fes-doc/docs/guide/directory-structure.md create mode 100644 packages/fes-doc/docs/guide/i18n.md create mode 100644 packages/fes-doc/docs/guide/install.md create mode 100644 packages/fes-doc/docs/guide/layout.md create mode 100644 packages/fes-doc/docs/guide/migration.md create mode 100644 packages/fes-doc/docs/guide/migrationLast.md create mode 100644 packages/fes-doc/docs/guide/option.md create mode 100644 packages/fes-doc/docs/guide/permisson.md create mode 100644 packages/fes-doc/docs/guide/play.md create mode 100644 packages/fes-doc/docs/guide/plugins/sso.md create mode 100644 packages/fes-doc/docs/guide/plugins/wa.md create mode 100644 packages/fes-doc/docs/guide/route.md create mode 100644 packages/fes-doc/docs/ui/affix.md create mode 100644 packages/fes-doc/docs/ui/backTop.md create mode 100644 packages/fes-doc/docs/ui/button.md create mode 100644 packages/fes-doc/docs/ui/carousel.md create mode 100644 packages/fes-doc/docs/ui/checkbox.md create mode 100644 packages/fes-doc/docs/ui/collapse.md create mode 100644 packages/fes-doc/docs/ui/contextmenu.md create mode 100644 packages/fes-doc/docs/ui/datePicker.md create mode 100644 packages/fes-doc/docs/ui/draggable.md create mode 100644 packages/fes-doc/docs/ui/dropdown.md create mode 100644 packages/fes-doc/docs/ui/form.md create mode 100644 packages/fes-doc/docs/ui/icon.md create mode 100644 packages/fes-doc/docs/ui/input.md create mode 100644 packages/fes-doc/docs/ui/layout.md create mode 100644 packages/fes-doc/docs/ui/loading.md create mode 100644 packages/fes-doc/docs/ui/menu.md create mode 100644 packages/fes-doc/docs/ui/message.md create mode 100644 packages/fes-doc/docs/ui/modal.md create mode 100644 packages/fes-doc/docs/ui/pagination.md create mode 100644 packages/fes-doc/docs/ui/panel.md create mode 100644 packages/fes-doc/docs/ui/process-circle.md create mode 100644 packages/fes-doc/docs/ui/radio.md create mode 100644 packages/fes-doc/docs/ui/select.md create mode 100644 packages/fes-doc/docs/ui/split.md create mode 100644 packages/fes-doc/docs/ui/step.md create mode 100644 packages/fes-doc/docs/ui/switch.md create mode 100644 packages/fes-doc/docs/ui/tab.md create mode 100644 packages/fes-doc/docs/ui/table.md create mode 100644 packages/fes-doc/docs/ui/templates/backTop/1.md create mode 100644 packages/fes-doc/docs/ui/templates/backTop/2.md create mode 100644 packages/fes-doc/docs/ui/templates/button/1.md create mode 100644 packages/fes-doc/docs/ui/templates/button/2.md create mode 100644 packages/fes-doc/docs/ui/templates/button/3.md create mode 100644 packages/fes-doc/docs/ui/templates/button/4.md create mode 100644 packages/fes-doc/docs/ui/templates/carousel/1.md create mode 100644 packages/fes-doc/docs/ui/templates/checkbox/1.md create mode 100644 packages/fes-doc/docs/ui/templates/checkbox/2.md create mode 100644 packages/fes-doc/docs/ui/templates/checkbox/3.md create mode 100644 packages/fes-doc/docs/ui/templates/checkbox/4.md create mode 100644 packages/fes-doc/docs/ui/templates/collapse/1.md create mode 100644 packages/fes-doc/docs/ui/templates/contextmenu/1.md create mode 100644 packages/fes-doc/docs/ui/templates/datePicker/1.md create mode 100644 packages/fes-doc/docs/ui/templates/datePicker/2.md create mode 100644 packages/fes-doc/docs/ui/templates/datePicker/3.md create mode 100644 packages/fes-doc/docs/ui/templates/datePicker/4.md create mode 100644 packages/fes-doc/docs/ui/templates/datePicker/5.md create mode 100644 packages/fes-doc/docs/ui/templates/datePicker/6.md create mode 100644 packages/fes-doc/docs/ui/templates/datePicker/7.md create mode 100644 packages/fes-doc/docs/ui/templates/draggable/1.md create mode 100644 packages/fes-doc/docs/ui/templates/dropdown/1.md create mode 100644 packages/fes-doc/docs/ui/templates/dropdown/2.md create mode 100644 packages/fes-doc/docs/ui/templates/dropdown/3.md create mode 100644 packages/fes-doc/docs/ui/templates/dropdown/4.md create mode 100644 packages/fes-doc/docs/ui/templates/dropdown/5.md create mode 100644 packages/fes-doc/docs/ui/templates/form/1.md create mode 100644 packages/fes-doc/docs/ui/templates/form/2.md create mode 100644 packages/fes-doc/docs/ui/templates/form/3.md create mode 100644 packages/fes-doc/docs/ui/templates/form/4.md create mode 100644 packages/fes-doc/docs/ui/templates/form/5.md create mode 100644 packages/fes-doc/docs/ui/templates/icon/1.md create mode 100644 packages/fes-doc/docs/ui/templates/input/1.md create mode 100644 packages/fes-doc/docs/ui/templates/input/10.md create mode 100644 packages/fes-doc/docs/ui/templates/input/2.md create mode 100644 packages/fes-doc/docs/ui/templates/input/3.md create mode 100644 packages/fes-doc/docs/ui/templates/input/4.md create mode 100644 packages/fes-doc/docs/ui/templates/input/5.md create mode 100644 packages/fes-doc/docs/ui/templates/input/6.md create mode 100644 packages/fes-doc/docs/ui/templates/input/7.md create mode 100644 packages/fes-doc/docs/ui/templates/input/8.md create mode 100644 packages/fes-doc/docs/ui/templates/input/9.md create mode 100644 packages/fes-doc/docs/ui/templates/layout/1.md create mode 100644 packages/fes-doc/docs/ui/templates/layout/2.md create mode 100644 packages/fes-doc/docs/ui/templates/loading/1.md create mode 100644 packages/fes-doc/docs/ui/templates/loading/2.md create mode 100644 packages/fes-doc/docs/ui/templates/menu/1.md create mode 100644 packages/fes-doc/docs/ui/templates/menu/2.md create mode 100644 packages/fes-doc/docs/ui/templates/message/1.md create mode 100644 packages/fes-doc/docs/ui/templates/message/2.md create mode 100644 packages/fes-doc/docs/ui/templates/message/3.md create mode 100644 packages/fes-doc/docs/ui/templates/modal/1.md create mode 100644 packages/fes-doc/docs/ui/templates/modal/2.md create mode 100644 packages/fes-doc/docs/ui/templates/modal/3.md create mode 100644 packages/fes-doc/docs/ui/templates/modal/4.md create mode 100644 packages/fes-doc/docs/ui/templates/pagination/1.md create mode 100644 packages/fes-doc/docs/ui/templates/pagination/2.md create mode 100644 packages/fes-doc/docs/ui/templates/pagination/3.md create mode 100644 packages/fes-doc/docs/ui/templates/panel/1.md create mode 100644 packages/fes-doc/docs/ui/templates/process-circle/1.md create mode 100644 packages/fes-doc/docs/ui/templates/process-circle/2.md create mode 100644 packages/fes-doc/docs/ui/templates/process-circle/3.md create mode 100644 packages/fes-doc/docs/ui/templates/radio/1.md create mode 100644 packages/fes-doc/docs/ui/templates/radio/2.md create mode 100644 packages/fes-doc/docs/ui/templates/radio/3.md create mode 100644 packages/fes-doc/docs/ui/templates/radio/4.md create mode 100644 packages/fes-doc/docs/ui/templates/radio/5.md create mode 100644 packages/fes-doc/docs/ui/templates/select/1.md create mode 100644 packages/fes-doc/docs/ui/templates/select/2.md create mode 100644 packages/fes-doc/docs/ui/templates/select/3.md create mode 100644 packages/fes-doc/docs/ui/templates/select/4.md create mode 100644 packages/fes-doc/docs/ui/templates/split/1.md create mode 100644 packages/fes-doc/docs/ui/templates/split/2.md create mode 100644 packages/fes-doc/docs/ui/templates/split/3.md create mode 100644 packages/fes-doc/docs/ui/templates/step/1.md create mode 100644 packages/fes-doc/docs/ui/templates/step/2.md create mode 100644 packages/fes-doc/docs/ui/templates/step/3.md create mode 100644 packages/fes-doc/docs/ui/templates/step/4.md create mode 100644 packages/fes-doc/docs/ui/templates/step/5.md create mode 100644 packages/fes-doc/docs/ui/templates/switch/1.md create mode 100644 packages/fes-doc/docs/ui/templates/switch/2.md create mode 100644 packages/fes-doc/docs/ui/templates/switch/3.md create mode 100644 packages/fes-doc/docs/ui/templates/switch/4.md create mode 100644 packages/fes-doc/docs/ui/templates/tab/1.md create mode 100644 packages/fes-doc/docs/ui/templates/tab/2.md create mode 100644 packages/fes-doc/docs/ui/templates/tab/3.md create mode 100644 packages/fes-doc/docs/ui/templates/tab/4.md create mode 100644 packages/fes-doc/docs/ui/templates/tab/5.md create mode 100644 packages/fes-doc/docs/ui/templates/tab/6.md create mode 100644 packages/fes-doc/docs/ui/templates/table/1.md create mode 100644 packages/fes-doc/docs/ui/templates/table/10.md create mode 100644 packages/fes-doc/docs/ui/templates/table/11.md create mode 100644 packages/fes-doc/docs/ui/templates/table/12.md create mode 100644 packages/fes-doc/docs/ui/templates/table/13.md create mode 100644 packages/fes-doc/docs/ui/templates/table/14.md create mode 100644 packages/fes-doc/docs/ui/templates/table/2.md create mode 100644 packages/fes-doc/docs/ui/templates/table/3.md create mode 100644 packages/fes-doc/docs/ui/templates/table/4.md create mode 100644 packages/fes-doc/docs/ui/templates/table/5.md create mode 100644 packages/fes-doc/docs/ui/templates/table/6.md create mode 100644 packages/fes-doc/docs/ui/templates/table/7.md create mode 100644 packages/fes-doc/docs/ui/templates/table/8.md create mode 100644 packages/fes-doc/docs/ui/templates/table/9.md create mode 100644 packages/fes-doc/docs/ui/templates/timePicker/1.md create mode 100644 packages/fes-doc/docs/ui/templates/timePicker/2.md create mode 100644 packages/fes-doc/docs/ui/templates/timePicker/3.md create mode 100644 packages/fes-doc/docs/ui/templates/timePicker/4.md create mode 100644 packages/fes-doc/docs/ui/templates/timePicker/5.md create mode 100644 packages/fes-doc/docs/ui/templates/timePicker/6.md create mode 100644 packages/fes-doc/docs/ui/templates/toast/1.md create mode 100644 packages/fes-doc/docs/ui/templates/toast/2.md create mode 100644 packages/fes-doc/docs/ui/templates/toast/3.md create mode 100644 packages/fes-doc/docs/ui/templates/toast/4.md create mode 100644 packages/fes-doc/docs/ui/templates/toast/5.md create mode 100644 packages/fes-doc/docs/ui/templates/tooltip/1.md create mode 100644 packages/fes-doc/docs/ui/templates/tooltip/2.md create mode 100644 packages/fes-doc/docs/ui/templates/tooltip/3.md create mode 100644 packages/fes-doc/docs/ui/templates/tooltip/4.md create mode 100644 packages/fes-doc/docs/ui/templates/tooltip/5.md create mode 100644 packages/fes-doc/docs/ui/templates/tree/1.md create mode 100644 packages/fes-doc/docs/ui/templates/tree/2.md create mode 100644 packages/fes-doc/docs/ui/templates/tree/3.md create mode 100644 packages/fes-doc/docs/ui/templates/tree/4.md create mode 100644 packages/fes-doc/docs/ui/templates/upload/1.md create mode 100644 packages/fes-doc/docs/ui/templates/upload/2.md create mode 100644 packages/fes-doc/docs/ui/templates/zoom/1.md create mode 100644 packages/fes-doc/docs/ui/templates/zoom/2.md create mode 100644 packages/fes-doc/docs/ui/timePicker.md create mode 100644 packages/fes-doc/docs/ui/toast.md create mode 100644 packages/fes-doc/docs/ui/tooltip.md create mode 100644 packages/fes-doc/docs/ui/tree.md create mode 100644 packages/fes-doc/docs/ui/upload.md create mode 100644 packages/fes-doc/docs/ui/zoom.md create mode 100644 packages/fes-doc/images/banner_ad.png create mode 100644 packages/fes-doc/images/banner_apply.png create mode 100644 packages/fes-doc/images/banner_tips.png create mode 100644 packages/fes-doc/images/framework.jpg create mode 100644 packages/fes-doc/images/icon_notice.png create mode 100644 packages/fes-doc/images/layout.png create mode 100644 packages/fes-doc/images/layout2.png create mode 100644 packages/fes-doc/package.json create mode 100644 packages/fes-doc/test.md create mode 100644 packages/fes-template/.editorconfig create mode 100644 packages/fes-template/.eslintrc.js create mode 100644 packages/fes-template/LICENSE create mode 100644 packages/fes-template/fes.config.js create mode 100644 packages/fes-template/mock.js create mode 100644 packages/fes-template/package.json create mode 100644 packages/fes-template/src/app.js create mode 100644 packages/fes-template/src/assets/images/bg.png create mode 100644 packages/fes-template/src/assets/images/logo.png create mode 100644 packages/fes-template/src/assets/styles/login.scss create mode 100644 packages/fes-template/src/assets/styles/main.scss create mode 100644 packages/fes-template/src/assets/styles/variables.scss create mode 100644 packages/fes-template/src/components/fesHeader.fes create mode 100644 packages/fes-template/src/components/fesLeft.fes create mode 100644 packages/fes-template/src/pages/api/fes/index.vue create mode 100644 packages/fes-template/src/pages/api/fesApi/index.vue create mode 100644 packages/fes-template/src/pages/api/fesApp/index.vue create mode 100644 packages/fes-template/src/pages/api/fesFesx/index.vue create mode 100644 packages/fes-template/src/pages/api/fesMap/index.vue create mode 100644 packages/fes-template/src/pages/api/fesMenu/index.vue create mode 100644 packages/fes-template/src/pages/api/fesStorage/index.vue create mode 100644 packages/fes-template/src/pages/api/fesUtil/index.vue create mode 100644 packages/fes-template/src/pages/header/index.vue create mode 100644 packages/fes-template/src/pages/home/index.vue create mode 100644 packages/fes-template/src/pages/i18n/index.vue create mode 100644 packages/fes-template/src/pages/layout/a.vue create mode 100644 packages/fes-template/src/pages/layout/b.vue create mode 100644 packages/fes-template/src/pages/layout/layout.vue create mode 100644 packages/fes-template/src/pages/list/edit/index.vue create mode 100644 packages/fes-template/src/pages/list/index.vue create mode 100644 packages/fes-template/src/pages/route.vue create mode 100644 packages/fes-template/src/pages/static/index.vue create mode 100644 packages/fes-template/src/static/1.txt create mode 100644 packages/fes-template/src/static/bell.png create mode 100644 packages/fes-template/src/static/favicon.ico create mode 100644 packages/fes-template/webpack.config.js create mode 100644 packages/fes-ui/LICENSE create mode 100644 packages/fes-ui/build/createServer.js create mode 100644 packages/fes-ui/build/gulpfile.js create mode 100644 packages/fes-ui/build/mock.js create mode 100644 packages/fes-ui/build/mock/cgiMock.js create mode 100644 packages/fes-ui/build/mock/init.js create mode 100644 packages/fes-ui/build/mock/log.js create mode 100644 packages/fes-ui/build/mock/task/cgiMock.js create mode 100644 packages/fes-ui/build/mock/test/app.js create mode 100644 packages/fes-ui/build/mock/test/myfile.txt create mode 100644 packages/fes-ui/build/mock/util.js create mode 100644 packages/fes-ui/build/webpack.dist.config.js create mode 100644 packages/fes-ui/build/webpack.dist.prod.config.js create mode 100644 packages/fes-ui/build/webpack.examples.config.js create mode 100644 packages/fes-ui/dist/fes-ui.js create mode 100644 packages/fes-ui/dist/fes-ui.min.js create mode 100644 packages/fes-ui/dist/styles/fes-ui.css create mode 100644 packages/fes-ui/dist/styles/fes-ui.min.css create mode 100644 packages/fes-ui/dist/styles/iconfont/iconfont.eot create mode 100644 packages/fes-ui/dist/styles/iconfont/iconfont.svg create mode 100644 packages/fes-ui/dist/styles/iconfont/iconfont.ttf create mode 100644 packages/fes-ui/dist/styles/iconfont/iconfont.woff create mode 100644 packages/fes-ui/dist/styles/iconfont/ionicons.eot create mode 100644 packages/fes-ui/dist/styles/iconfont/ionicons.svg create mode 100644 packages/fes-ui/dist/styles/iconfont/ionicons.ttf create mode 100644 packages/fes-ui/dist/styles/iconfont/ionicons.woff create mode 100644 packages/fes-ui/dist/styles/iconfont/ionicons.woff2 create mode 100644 packages/fes-ui/examples/data.json create mode 100644 packages/fes-ui/examples/images/girl.jpg create mode 100644 packages/fes-ui/examples/images/icon_notice.png create mode 100644 packages/fes-ui/examples/images/layout.png create mode 100644 packages/fes-ui/examples/images/web32002.jpg create mode 100644 packages/fes-ui/examples/index.html create mode 100644 packages/fes-ui/examples/js/app.js create mode 100644 packages/fes-ui/examples/js/demand.js create mode 100644 packages/fes-ui/examples/js/router.js create mode 100644 packages/fes-ui/examples/styles/main.scss create mode 100644 packages/fes-ui/examples/views/App.vue create mode 100644 packages/fes-ui/examples/views/component/affix.vue create mode 100644 packages/fes-ui/examples/views/component/backTop.vue create mode 100644 packages/fes-ui/examples/views/component/button.vue create mode 100644 packages/fes-ui/examples/views/component/carousel.vue create mode 100644 packages/fes-ui/examples/views/component/checkbox.vue create mode 100644 packages/fes-ui/examples/views/component/collapse.vue create mode 100644 packages/fes-ui/examples/views/component/contextmenu.vue create mode 100644 packages/fes-ui/examples/views/component/datePicker.vue create mode 100644 packages/fes-ui/examples/views/component/draggable.vue create mode 100644 packages/fes-ui/examples/views/component/dropdown.vue create mode 100644 packages/fes-ui/examples/views/component/form.vue create mode 100644 packages/fes-ui/examples/views/component/icon.vue create mode 100644 packages/fes-ui/examples/views/component/index.vue create mode 100644 packages/fes-ui/examples/views/component/input.vue create mode 100644 packages/fes-ui/examples/views/component/install.vue create mode 100644 packages/fes-ui/examples/views/component/layout.vue create mode 100644 packages/fes-ui/examples/views/component/loading.vue create mode 100644 packages/fes-ui/examples/views/component/log.vue create mode 100644 packages/fes-ui/examples/views/component/md/affix1.md create mode 100644 packages/fes-ui/examples/views/component/md/affix2.md create mode 100644 packages/fes-ui/examples/views/component/md/affix3.md create mode 100644 packages/fes-ui/examples/views/component/md/affix4.md create mode 100644 packages/fes-ui/examples/views/component/md/affix5.md create mode 100644 packages/fes-ui/examples/views/component/md/backTop1.md create mode 100644 packages/fes-ui/examples/views/component/md/backTop2.md create mode 100644 packages/fes-ui/examples/views/component/md/backTop3.md create mode 100644 packages/fes-ui/examples/views/component/md/backTop4.md create mode 100644 packages/fes-ui/examples/views/component/md/button1.md create mode 100644 packages/fes-ui/examples/views/component/md/button2.md create mode 100644 packages/fes-ui/examples/views/component/md/button3.md create mode 100644 packages/fes-ui/examples/views/component/md/button4.md create mode 100644 packages/fes-ui/examples/views/component/md/checkbox1.md create mode 100644 packages/fes-ui/examples/views/component/md/checkbox2.md create mode 100644 packages/fes-ui/examples/views/component/md/checkbox3.md create mode 100644 packages/fes-ui/examples/views/component/md/contextmenu.md create mode 100644 packages/fes-ui/examples/views/component/md/datepicker1.md create mode 100644 packages/fes-ui/examples/views/component/md/datepicker2.md create mode 100644 packages/fes-ui/examples/views/component/md/datepicker3.md create mode 100644 packages/fes-ui/examples/views/component/md/datepicker4.md create mode 100644 packages/fes-ui/examples/views/component/md/datepicker5.md create mode 100644 packages/fes-ui/examples/views/component/md/datepicker6.md create mode 100644 packages/fes-ui/examples/views/component/md/datepicker7.md create mode 100644 packages/fes-ui/examples/views/component/md/datepicker8.md create mode 100644 packages/fes-ui/examples/views/component/md/draggable1.md create mode 100644 packages/fes-ui/examples/views/component/md/draggable2.md create mode 100644 packages/fes-ui/examples/views/component/md/dropdown1.md create mode 100644 packages/fes-ui/examples/views/component/md/dropdown2.md create mode 100644 packages/fes-ui/examples/views/component/md/dropdown3.md create mode 100644 packages/fes-ui/examples/views/component/md/dropdown4.md create mode 100644 packages/fes-ui/examples/views/component/md/dropdown5.md create mode 100644 packages/fes-ui/examples/views/component/md/dropdown6.md create mode 100644 packages/fes-ui/examples/views/component/md/dropdown7.md create mode 100644 packages/fes-ui/examples/views/component/md/form1.md create mode 100644 packages/fes-ui/examples/views/component/md/form2.md create mode 100644 packages/fes-ui/examples/views/component/md/form3.md create mode 100644 packages/fes-ui/examples/views/component/md/form4.md create mode 100644 packages/fes-ui/examples/views/component/md/icon1.md create mode 100644 packages/fes-ui/examples/views/component/md/icon2.md create mode 100644 packages/fes-ui/examples/views/component/md/input1.md create mode 100644 packages/fes-ui/examples/views/component/md/input2.md create mode 100644 packages/fes-ui/examples/views/component/md/input3.md create mode 100644 packages/fes-ui/examples/views/component/md/input4.md create mode 100644 packages/fes-ui/examples/views/component/md/input5.md create mode 100644 packages/fes-ui/examples/views/component/md/input6.md create mode 100644 packages/fes-ui/examples/views/component/md/input7.md create mode 100644 packages/fes-ui/examples/views/component/md/input8.md create mode 100644 packages/fes-ui/examples/views/component/md/install.md create mode 100644 packages/fes-ui/examples/views/component/md/layout1.md create mode 100644 packages/fes-ui/examples/views/component/md/layout2.md create mode 100644 packages/fes-ui/examples/views/component/md/layout3.md create mode 100644 packages/fes-ui/examples/views/component/md/loading1.md create mode 100644 packages/fes-ui/examples/views/component/md/loading2.md create mode 100644 packages/fes-ui/examples/views/component/md/menu1.md create mode 100644 packages/fes-ui/examples/views/component/md/menu2.md create mode 100644 packages/fes-ui/examples/views/component/md/menu3.md create mode 100644 packages/fes-ui/examples/views/component/md/message1.md create mode 100644 packages/fes-ui/examples/views/component/md/message2.md create mode 100644 packages/fes-ui/examples/views/component/md/message3.md create mode 100644 packages/fes-ui/examples/views/component/md/modal1.md create mode 100644 packages/fes-ui/examples/views/component/md/modal2.md create mode 100644 packages/fes-ui/examples/views/component/md/play.md create mode 100644 packages/fes-ui/examples/views/component/md/processCircle1.md create mode 100644 packages/fes-ui/examples/views/component/md/processCircle2.md create mode 100644 packages/fes-ui/examples/views/component/md/processCircle3.md create mode 100644 packages/fes-ui/examples/views/component/md/processCircle4.md create mode 100644 packages/fes-ui/examples/views/component/md/radio1.md create mode 100644 packages/fes-ui/examples/views/component/md/radio2.md create mode 100644 packages/fes-ui/examples/views/component/md/radio3.md create mode 100644 packages/fes-ui/examples/views/component/md/select.md create mode 100644 packages/fes-ui/examples/views/component/md/select2.md create mode 100644 packages/fes-ui/examples/views/component/md/step1.md create mode 100644 packages/fes-ui/examples/views/component/md/step2.md create mode 100644 packages/fes-ui/examples/views/component/md/step3.md create mode 100644 packages/fes-ui/examples/views/component/md/step4.md create mode 100644 packages/fes-ui/examples/views/component/md/switch1.md create mode 100644 packages/fes-ui/examples/views/component/md/switch2.md create mode 100644 packages/fes-ui/examples/views/component/md/table1.md create mode 100644 packages/fes-ui/examples/views/component/md/table10.md create mode 100644 packages/fes-ui/examples/views/component/md/table2.md create mode 100644 packages/fes-ui/examples/views/component/md/table3.md create mode 100644 packages/fes-ui/examples/views/component/md/table4.md create mode 100644 packages/fes-ui/examples/views/component/md/table5.md create mode 100644 packages/fes-ui/examples/views/component/md/table6.md create mode 100644 packages/fes-ui/examples/views/component/md/table7.md create mode 100644 packages/fes-ui/examples/views/component/md/table8.md create mode 100644 packages/fes-ui/examples/views/component/md/table9.md create mode 100644 packages/fes-ui/examples/views/component/md/tabs1.md create mode 100644 packages/fes-ui/examples/views/component/md/tabs2.md create mode 100644 packages/fes-ui/examples/views/component/md/tabs3.md create mode 100644 packages/fes-ui/examples/views/component/md/tabs4.md create mode 100644 packages/fes-ui/examples/views/component/md/tabs5.md create mode 100644 packages/fes-ui/examples/views/component/md/tabs6.md create mode 100644 packages/fes-ui/examples/views/component/md/tabs7.md create mode 100644 packages/fes-ui/examples/views/component/md/timePicker1.md create mode 100644 packages/fes-ui/examples/views/component/md/timePicker2.md create mode 100644 packages/fes-ui/examples/views/component/md/timePicker3.md create mode 100644 packages/fes-ui/examples/views/component/md/timePicker4.md create mode 100644 packages/fes-ui/examples/views/component/md/timePicker5.md create mode 100644 packages/fes-ui/examples/views/component/md/toast1.md create mode 100644 packages/fes-ui/examples/views/component/md/toast2.md create mode 100644 packages/fes-ui/examples/views/component/md/toast3.md create mode 100644 packages/fes-ui/examples/views/component/md/tooltip1.md create mode 100644 packages/fes-ui/examples/views/component/md/tooltip2.md create mode 100644 packages/fes-ui/examples/views/component/md/tooltip3.md create mode 100644 packages/fes-ui/examples/views/component/md/tooltip4.md create mode 100644 packages/fes-ui/examples/views/component/md/tooltip5.md create mode 100644 packages/fes-ui/examples/views/component/md/tree1.md create mode 100644 packages/fes-ui/examples/views/component/md/tree2.md create mode 100644 packages/fes-ui/examples/views/component/md/upload.md create mode 100644 packages/fes-ui/examples/views/component/md/zoom1.md create mode 100644 packages/fes-ui/examples/views/component/md/zoom2.md create mode 100644 packages/fes-ui/examples/views/component/md/zoom3.md create mode 100644 packages/fes-ui/examples/views/component/menu.vue create mode 100644 packages/fes-ui/examples/views/component/message.vue create mode 100644 packages/fes-ui/examples/views/component/modal.vue create mode 100644 packages/fes-ui/examples/views/component/pagination.vue create mode 100644 packages/fes-ui/examples/views/component/panel.vue create mode 100644 packages/fes-ui/examples/views/component/play.vue create mode 100644 packages/fes-ui/examples/views/component/processCircle.vue create mode 100644 packages/fes-ui/examples/views/component/radio.vue create mode 100644 packages/fes-ui/examples/views/component/select.vue create mode 100644 packages/fes-ui/examples/views/component/split.vue create mode 100644 packages/fes-ui/examples/views/component/step.vue create mode 100644 packages/fes-ui/examples/views/component/switch.vue create mode 100644 packages/fes-ui/examples/views/component/tab.vue create mode 100644 packages/fes-ui/examples/views/component/table.vue create mode 100644 packages/fes-ui/examples/views/component/timePicker.vue create mode 100644 packages/fes-ui/examples/views/component/toast.vue create mode 100644 packages/fes-ui/examples/views/component/tooltip.vue create mode 100644 packages/fes-ui/examples/views/component/tree.vue create mode 100644 packages/fes-ui/examples/views/component/upload.vue create mode 100644 packages/fes-ui/examples/views/component/zoom.vue create mode 100644 packages/fes-ui/examples/views/guide/components.vue create mode 100644 packages/fes-ui/examples/views/guide/config.vue create mode 100644 packages/fes-ui/examples/views/guide/fes.vue create mode 100644 packages/fes-ui/examples/views/guide/fesApi.vue create mode 100644 packages/fes-ui/examples/views/guide/fesApp.vue create mode 100644 packages/fes-ui/examples/views/guide/fesFesx.vue create mode 100644 packages/fes-ui/examples/views/guide/fesMap.vue create mode 100644 packages/fes-ui/examples/views/guide/fesStorage.vue create mode 100644 packages/fes-ui/examples/views/guide/fesUtil.vue create mode 100644 packages/fes-ui/examples/views/guide/index.vue create mode 100644 packages/fes-ui/examples/views/guide/install.vue create mode 100644 packages/fes-ui/examples/views/guide/introduce.vue create mode 100644 packages/fes-ui/examples/views/guide/layout.vue create mode 100644 packages/fes-ui/examples/views/guide/log.vue create mode 100644 packages/fes-ui/examples/views/guide/md/components.md create mode 100644 packages/fes-ui/examples/views/guide/md/config.md create mode 100644 packages/fes-ui/examples/views/guide/md/fes.md create mode 100644 packages/fes-ui/examples/views/guide/md/fesApi.md create mode 100644 packages/fes-ui/examples/views/guide/md/fesFesx.md create mode 100644 packages/fes-ui/examples/views/guide/md/fesMap.md create mode 100644 packages/fes-ui/examples/views/guide/md/fesStorage.md create mode 100644 packages/fes-ui/examples/views/guide/md/layout.md create mode 100644 packages/fes-ui/examples/views/guide/md/log.md create mode 100644 packages/fes-ui/examples/views/guide/md/mock.md create mode 100644 packages/fes-ui/examples/views/guide/md/play.md create mode 100644 packages/fes-ui/examples/views/guide/md/role.md create mode 100644 packages/fes-ui/examples/views/guide/md/route.md create mode 100644 packages/fes-ui/examples/views/guide/mock.vue create mode 100644 packages/fes-ui/examples/views/guide/play.vue create mode 100644 packages/fes-ui/examples/views/guide/role.vue create mode 100644 packages/fes-ui/examples/views/guide/route.vue create mode 100644 packages/fes-ui/examples/views/panel.vue create mode 100644 packages/fes-ui/package.json create mode 100644 packages/fes-ui/src/components/affix/affix.vue create mode 100644 packages/fes-ui/src/components/affix/index.js create mode 100644 packages/fes-ui/src/components/affix/style/index.scss create mode 100644 packages/fes-ui/src/components/back-top/backTop.vue create mode 100644 packages/fes-ui/src/components/back-top/index.js create mode 100644 packages/fes-ui/src/components/back-top/style/index.scss create mode 100644 packages/fes-ui/src/components/button/button.vue create mode 100644 packages/fes-ui/src/components/button/index.js create mode 100644 packages/fes-ui/src/components/button/style/index.scss create mode 100644 packages/fes-ui/src/components/carousel/carousel.vue create mode 100644 packages/fes-ui/src/components/carousel/index.js create mode 100644 packages/fes-ui/src/components/carousel/style/index.scss create mode 100644 packages/fes-ui/src/components/cell/index.js create mode 100644 packages/fes-ui/src/components/cell/style/index.scss create mode 100644 packages/fes-ui/src/components/checkbox-com/checkbox.vue create mode 100644 packages/fes-ui/src/components/checkbox-com/checkboxGroup.vue create mode 100644 packages/fes-ui/src/components/checkbox-com/index.js create mode 100644 packages/fes-ui/src/components/checkbox-com/style/index.scss create mode 100644 packages/fes-ui/src/components/checkbox-group/index.js create mode 100644 packages/fes-ui/src/components/checkbox-group/style/index.scss create mode 100644 packages/fes-ui/src/components/checkbox/index.js create mode 100644 packages/fes-ui/src/components/checkbox/style/index.scss create mode 100644 packages/fes-ui/src/components/collapse/collapse.vue create mode 100644 packages/fes-ui/src/components/collapse/collapsePanel.vue create mode 100644 packages/fes-ui/src/components/collapse/index.js create mode 100644 packages/fes-ui/src/components/collapse/openAnim.vue create mode 100644 packages/fes-ui/src/components/collapse/style/index.scss create mode 100644 packages/fes-ui/src/components/column/index.js create mode 100644 packages/fes-ui/src/components/column/style/index.scss create mode 100644 packages/fes-ui/src/components/contextmenu/index.js create mode 100644 packages/fes-ui/src/components/contextmenu/index.vue create mode 100644 packages/fes-ui/src/components/contextmenu/style/index.scss create mode 100644 packages/fes-ui/src/components/data-table/column.vue create mode 100644 packages/fes-ui/src/components/data-table/editCell.vue create mode 100644 packages/fes-ui/src/components/data-table/headComponent.vue create mode 100644 packages/fes-ui/src/components/data-table/index.js create mode 100644 packages/fes-ui/src/components/data-table/style/index.scss create mode 100644 packages/fes-ui/src/components/data-table/table.vue create mode 100644 packages/fes-ui/src/components/data-table/tableAction.vue create mode 100644 packages/fes-ui/src/components/data-table/tableComponent.vue create mode 100644 packages/fes-ui/src/components/data-table/tableDetailComponent.vue create mode 100644 packages/fes-ui/src/components/data-table/tableExpand.vue create mode 100644 packages/fes-ui/src/components/data-table/tableText.vue create mode 100644 packages/fes-ui/src/components/data-table/treeTable.vue create mode 100644 packages/fes-ui/src/components/date-picker/calendar.vue create mode 100644 packages/fes-ui/src/components/date-picker/calendars.vue create mode 100644 packages/fes-ui/src/components/date-picker/datePicker.vue create mode 100644 packages/fes-ui/src/components/date-picker/index.js create mode 100644 packages/fes-ui/src/components/date-picker/propsMixin.js create mode 100644 packages/fes-ui/src/components/date-picker/style/index.scss create mode 100644 packages/fes-ui/src/components/draggable/DraggableItem.vue create mode 100644 packages/fes-ui/src/components/draggable/Manager.js create mode 100644 packages/fes-ui/src/components/draggable/draggable.vue create mode 100644 packages/fes-ui/src/components/draggable/index.js create mode 100644 packages/fes-ui/src/components/draggable/style/index.scss create mode 100644 packages/fes-ui/src/components/draggable/utils.js create mode 100644 packages/fes-ui/src/components/dropdown-com/dropdown.vue create mode 100644 packages/fes-ui/src/components/dropdown-com/dropdownMenu.vue create mode 100644 packages/fes-ui/src/components/dropdown-com/index.js create mode 100644 packages/fes-ui/src/components/dropdown-com/style/index.scss create mode 100644 packages/fes-ui/src/components/dropdown-menu/index.js create mode 100644 packages/fes-ui/src/components/dropdown-menu/style/index.scss create mode 100644 packages/fes-ui/src/components/dropdown/index.js create mode 100644 packages/fes-ui/src/components/dropdown/style/index.scss create mode 100644 packages/fes-ui/src/components/form-item/index.js create mode 100644 packages/fes-ui/src/components/form-item/style/index.scss create mode 100644 packages/fes-ui/src/components/form/form.vue create mode 100644 packages/fes-ui/src/components/form/formItem.vue create mode 100644 packages/fes-ui/src/components/form/index.js create mode 100644 packages/fes-ui/src/components/form/rule.js create mode 100644 packages/fes-ui/src/components/form/style/index.scss create mode 100644 packages/fes-ui/src/components/icon/icon.vue create mode 100644 packages/fes-ui/src/components/icon/index.js create mode 100644 packages/fes-ui/src/components/icon/style/index.scss create mode 100644 packages/fes-ui/src/components/input/index.js create mode 100644 packages/fes-ui/src/components/input/input.vue create mode 100644 packages/fes-ui/src/components/input/style/index.scss create mode 100644 packages/fes-ui/src/components/layout/cell.vue create mode 100644 packages/fes-ui/src/components/layout/index.js create mode 100644 packages/fes-ui/src/components/layout/row.vue create mode 100644 packages/fes-ui/src/components/layout/style/index.scss create mode 100644 packages/fes-ui/src/components/loading/index.js create mode 100644 packages/fes-ui/src/components/loading/loading.vue create mode 100644 packages/fes-ui/src/components/loading/style/index.scss create mode 100644 packages/fes-ui/src/components/menu/index.js create mode 100644 packages/fes-ui/src/components/menu/menu.vue create mode 100644 packages/fes-ui/src/components/menu/menuGroup.vue create mode 100644 packages/fes-ui/src/components/menu/menuItem.vue create mode 100644 packages/fes-ui/src/components/menu/routeMenu.vue create mode 100644 packages/fes-ui/src/components/menu/style/index.scss create mode 100644 packages/fes-ui/src/components/menu/subMenu.vue create mode 100644 packages/fes-ui/src/components/message/index.js create mode 100644 packages/fes-ui/src/components/message/message.vue create mode 100644 packages/fes-ui/src/components/message/style/index.scss create mode 100644 packages/fes-ui/src/components/modal/index.js create mode 100644 packages/fes-ui/src/components/modal/modal.vue create mode 100644 packages/fes-ui/src/components/modal/style/index.scss create mode 100644 packages/fes-ui/src/components/option-group/index.js create mode 100644 packages/fes-ui/src/components/option-group/style/index.scss create mode 100644 packages/fes-ui/src/components/pagination/index.js create mode 100644 packages/fes-ui/src/components/pagination/pagination.vue create mode 100644 packages/fes-ui/src/components/pagination/style/index.scss create mode 100644 packages/fes-ui/src/components/panel/index.js create mode 100644 packages/fes-ui/src/components/panel/panel.vue create mode 100644 packages/fes-ui/src/components/panel/style/index.scss create mode 100644 packages/fes-ui/src/components/process-circle/index.js create mode 100644 packages/fes-ui/src/components/process-circle/processCircle.vue create mode 100644 packages/fes-ui/src/components/process-circle/style/index.scss create mode 100644 packages/fes-ui/src/components/radio-com/index.js create mode 100644 packages/fes-ui/src/components/radio-com/radio.vue create mode 100644 packages/fes-ui/src/components/radio-com/radioGroup.vue create mode 100644 packages/fes-ui/src/components/radio-com/style/index.scss create mode 100644 packages/fes-ui/src/components/radio-group/index.js create mode 100644 packages/fes-ui/src/components/radio-group/style/index.scss create mode 100644 packages/fes-ui/src/components/radio/index.js create mode 100644 packages/fes-ui/src/components/radio/style/index.scss create mode 100644 packages/fes-ui/src/components/route-menu/index.js create mode 100644 packages/fes-ui/src/components/route-menu/style/index.scss create mode 100644 packages/fes-ui/src/components/row/index.js create mode 100644 packages/fes-ui/src/components/row/style/index.scss create mode 100644 packages/fes-ui/src/components/select/index.js create mode 100644 packages/fes-ui/src/components/select/option.vue create mode 100644 packages/fes-ui/src/components/select/optionGroup.vue create mode 100644 packages/fes-ui/src/components/select/select.vue create mode 100644 packages/fes-ui/src/components/select/style/index.scss create mode 100644 packages/fes-ui/src/components/split-com/index.js create mode 100644 packages/fes-ui/src/components/split-com/split.vue create mode 100644 packages/fes-ui/src/components/split-com/splitItem.vue create mode 100644 packages/fes-ui/src/components/split-com/style/index.scss create mode 100644 packages/fes-ui/src/components/split-item/index.js create mode 100644 packages/fes-ui/src/components/split-item/style/index.scss create mode 100644 packages/fes-ui/src/components/split/index.js create mode 100644 packages/fes-ui/src/components/split/style/index.scss create mode 100644 packages/fes-ui/src/components/step-com/index.js create mode 100644 packages/fes-ui/src/components/step-com/step.vue create mode 100644 packages/fes-ui/src/components/step-com/steps.vue create mode 100644 packages/fes-ui/src/components/step-com/style/index.scss create mode 100644 packages/fes-ui/src/components/step/index.js create mode 100644 packages/fes-ui/src/components/step/style/index.scss create mode 100644 packages/fes-ui/src/components/steps/index.js create mode 100644 packages/fes-ui/src/components/steps/style/index.scss create mode 100644 packages/fes-ui/src/components/switch/index.js create mode 100644 packages/fes-ui/src/components/switch/style/index.scss create mode 100644 packages/fes-ui/src/components/switch/switch.vue create mode 100644 packages/fes-ui/src/components/tab-com/index.js create mode 100644 packages/fes-ui/src/components/tab-com/style/index.scss create mode 100644 packages/fes-ui/src/components/tab-com/tab.vue create mode 100644 packages/fes-ui/src/components/tab-com/tabComponent.vue create mode 100644 packages/fes-ui/src/components/tab-com/tabs.vue create mode 100644 packages/fes-ui/src/components/tab/index.js create mode 100644 packages/fes-ui/src/components/tab/style/index.scss create mode 100644 packages/fes-ui/src/components/tabs/index.js create mode 100644 packages/fes-ui/src/components/tabs/style/index.scss create mode 100644 packages/fes-ui/src/components/time-picker/index.js create mode 100644 packages/fes-ui/src/components/time-picker/pickerContent.vue create mode 100644 packages/fes-ui/src/components/time-picker/pickerItem.vue create mode 100644 packages/fes-ui/src/components/time-picker/style/index.scss create mode 100644 packages/fes-ui/src/components/time-picker/timePicker.vue create mode 100644 packages/fes-ui/src/components/toast/index.js create mode 100644 packages/fes-ui/src/components/toast/style/index.scss create mode 100644 packages/fes-ui/src/components/toast/swap.vue create mode 100644 packages/fes-ui/src/components/toast/toast.vue create mode 100644 packages/fes-ui/src/components/tooltip/index.js create mode 100644 packages/fes-ui/src/components/tooltip/style/index.scss create mode 100644 packages/fes-ui/src/components/tooltip/tooltip.js create mode 100644 packages/fes-ui/src/components/tooltip/tooltip.vue create mode 100644 packages/fes-ui/src/components/tooltip/tooltipComponent.vue create mode 100644 packages/fes-ui/src/components/tree-table/index.js create mode 100644 packages/fes-ui/src/components/tree-table/style/index.scss create mode 100644 packages/fes-ui/src/components/tree/index.js create mode 100644 packages/fes-ui/src/components/tree/nodeText.vue create mode 100644 packages/fes-ui/src/components/tree/style/index.scss create mode 100644 packages/fes-ui/src/components/tree/tree.vue create mode 100644 packages/fes-ui/src/components/tree/treeNode.vue create mode 100644 packages/fes-ui/src/components/upload/iePolyfill.js create mode 100644 packages/fes-ui/src/components/upload/index.js create mode 100644 packages/fes-ui/src/components/upload/style/index.scss create mode 100644 packages/fes-ui/src/components/upload/upload.vue create mode 100644 packages/fes-ui/src/components/v-picker-popup/index.js create mode 100644 packages/fes-ui/src/components/v-picker-popup/pickerPopup.vue create mode 100644 packages/fes-ui/src/components/v-picker-popup/style/index.scss create mode 100644 packages/fes-ui/src/components/v-readonly-input/index.js create mode 100644 packages/fes-ui/src/components/v-readonly-input/readonlyInput.vue create mode 100644 packages/fes-ui/src/components/v-readonly-input/style/index.scss create mode 100644 packages/fes-ui/src/components/wb-button/index.js create mode 100644 packages/fes-ui/src/components/wb-button/style/index.scss create mode 100644 packages/fes-ui/src/components/wb-form/index.js create mode 100644 packages/fes-ui/src/components/wb-form/style/index.scss create mode 100644 packages/fes-ui/src/components/wb-input-date-picker/index.js create mode 100644 packages/fes-ui/src/components/wb-input-date-picker/style/index.scss create mode 100644 packages/fes-ui/src/components/wb-input/index.js create mode 100644 packages/fes-ui/src/components/wb-input/style/index.scss create mode 100644 packages/fes-ui/src/components/wb-menu-group/index.js create mode 100644 packages/fes-ui/src/components/wb-menu-group/style/index.scss create mode 100644 packages/fes-ui/src/components/wb-menu-item/index.js create mode 100644 packages/fes-ui/src/components/wb-menu-item/style/index.scss create mode 100644 packages/fes-ui/src/components/wb-menu/index.js create mode 100644 packages/fes-ui/src/components/wb-menu/style/index.scss create mode 100644 packages/fes-ui/src/components/wb-option/index.js create mode 100644 packages/fes-ui/src/components/wb-option/style/index.scss create mode 100644 packages/fes-ui/src/components/wb-select/index.js create mode 100644 packages/fes-ui/src/components/wb-select/style/index.scss create mode 100644 packages/fes-ui/src/components/wb-sub-menu/index.js create mode 100644 packages/fes-ui/src/components/wb-sub-menu/style/index.scss create mode 100644 packages/fes-ui/src/components/wb-switch/index.js create mode 100644 packages/fes-ui/src/components/wb-switch/style/index.scss create mode 100644 packages/fes-ui/src/components/wb-table/index.js create mode 100644 packages/fes-ui/src/components/wb-table/style/index.scss create mode 100644 packages/fes-ui/src/components/zoom/index.js create mode 100644 packages/fes-ui/src/components/zoom/style/index.scss create mode 100644 packages/fes-ui/src/components/zoom/zoom.js create mode 100644 packages/fes-ui/src/components/zoom/zoom.vue create mode 100644 packages/fes-ui/src/directives/autoRow.js create mode 100644 packages/fes-ui/src/directives/clickoutside.js create mode 100644 packages/fes-ui/src/directives/mouseoutside.js create mode 100644 packages/fes-ui/src/i18n/format.js create mode 100644 packages/fes-ui/src/i18n/index.js create mode 100644 packages/fes-ui/src/i18n/messages.js create mode 100644 packages/fes-ui/src/i18n/mixin.js create mode 100644 packages/fes-ui/src/i18n/watch.js create mode 100644 packages/fes-ui/src/index.js create mode 100644 packages/fes-ui/src/mixins/emitter.js create mode 100644 packages/fes-ui/src/styles/animation/index.scss create mode 100644 packages/fes-ui/src/styles/common/base.scss create mode 100644 packages/fes-ui/src/styles/common/common.scss create mode 100644 packages/fes-ui/src/styles/common/expand.scss create mode 100644 packages/fes-ui/src/styles/common/iconfont.scss create mode 100644 packages/fes-ui/src/styles/common/iconfont/ionicons.eot create mode 100644 packages/fes-ui/src/styles/common/iconfont/ionicons.svg create mode 100644 packages/fes-ui/src/styles/common/iconfont/ionicons.ttf create mode 100644 packages/fes-ui/src/styles/common/iconfont/ionicons.woff create mode 100644 packages/fes-ui/src/styles/common/iconfont/ionicons.woff2 create mode 100644 packages/fes-ui/src/styles/common/index.scss create mode 100644 packages/fes-ui/src/styles/common/normalize.scss create mode 100644 packages/fes-ui/src/styles/common/variables.scss create mode 100644 packages/fes-ui/src/styles/components/affix.scss create mode 100644 packages/fes-ui/src/styles/components/backTop.scss create mode 100644 packages/fes-ui/src/styles/components/button.scss create mode 100644 packages/fes-ui/src/styles/components/carousel.scss create mode 100644 packages/fes-ui/src/styles/components/checkbox.scss create mode 100644 packages/fes-ui/src/styles/components/circle.scss create mode 100644 packages/fes-ui/src/styles/components/collapse.scss create mode 100644 packages/fes-ui/src/styles/components/contextmenu.scss create mode 100644 packages/fes-ui/src/styles/components/datePicker.scss create mode 100644 packages/fes-ui/src/styles/components/dropdown.scss create mode 100644 packages/fes-ui/src/styles/components/form.scss create mode 100644 packages/fes-ui/src/styles/components/index.scss create mode 100644 packages/fes-ui/src/styles/components/input.scss create mode 100644 packages/fes-ui/src/styles/components/layout.scss create mode 100644 packages/fes-ui/src/styles/components/loading.scss create mode 100644 packages/fes-ui/src/styles/components/menu.scss create mode 100644 packages/fes-ui/src/styles/components/message.scss create mode 100644 packages/fes-ui/src/styles/components/modal.scss create mode 100644 packages/fes-ui/src/styles/components/pagination.scss create mode 100644 packages/fes-ui/src/styles/components/panel.scss create mode 100644 packages/fes-ui/src/styles/components/radio.scss create mode 100644 packages/fes-ui/src/styles/components/select.scss create mode 100644 packages/fes-ui/src/styles/components/split.scss create mode 100644 packages/fes-ui/src/styles/components/step.scss create mode 100644 packages/fes-ui/src/styles/components/switch.scss create mode 100644 packages/fes-ui/src/styles/components/tab.scss create mode 100644 packages/fes-ui/src/styles/components/table.scss create mode 100644 packages/fes-ui/src/styles/components/timePicker.scss create mode 100644 packages/fes-ui/src/styles/components/toast.scss create mode 100644 packages/fes-ui/src/styles/components/tooltip.scss create mode 100644 packages/fes-ui/src/styles/components/tree.scss create mode 100644 packages/fes-ui/src/styles/components/treeTable.scss create mode 100644 packages/fes-ui/src/styles/components/upload.scss create mode 100644 packages/fes-ui/src/styles/components/vPickerPopup.scss create mode 100644 packages/fes-ui/src/styles/components/vReadonlyInput.scss create mode 100644 packages/fes-ui/src/styles/components/zoom.scss create mode 100644 packages/fes-ui/src/styles/demand.scss create mode 100644 packages/fes-ui/src/styles/iconfont/ionicons.eot create mode 100644 packages/fes-ui/src/styles/iconfont/ionicons.svg create mode 100644 packages/fes-ui/src/styles/iconfont/ionicons.ttf create mode 100644 packages/fes-ui/src/styles/iconfont/ionicons.woff create mode 100644 packages/fes-ui/src/styles/iconfont/ionicons.woff2 create mode 100644 packages/fes-ui/src/styles/index.scss create mode 100644 packages/fes-ui/src/styles/mixins/index.scss create mode 100644 packages/fes-ui/src/utils/EventListener.js create mode 100644 packages/fes-ui/src/utils/elementResizeEvent.js create mode 100644 packages/fes-ui/src/utils/keyCode.js create mode 100644 packages/fes-ui/src/utils/util.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..8786e6e2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..5850016e --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,20 @@ + +module.exports = { + extends: [ + '@webank/eslint-config-webank/vue', + ], + globals: { + // 这里填入你的项目需要的全局变量 + // 这里值为 false 表示这个全局变量不允许被重新赋值,比如: + // + // Vue: false + }, + rules: { + 'no-plusplus': 'off', + 'no-bitwise': 'off', + 'vue/comment-directive': 'off', + 'no-param-reassign': 'off', + 'func-names': 'off', + 'class-methods-use-this': 'off' + } +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..44f8c500 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +.DS_Store +.idea +.git +.vscode +.history +.cache +node_modules +npm-debug.log +/packages/fes-template/dist +/packages/fes-doc/docs/.vuepress/dist diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..23c3e60f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-present harrywan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/lerna.json b/lerna.json new file mode 100644 index 00000000..4a0606c6 --- /dev/null +++ b/lerna.json @@ -0,0 +1,7 @@ +{ + "packages": [ + "packages/*" + ], + "version": "independent", + "npmClient": "npm" +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..ba26e9af --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "fes", + "description": "一个好用的前端管理台快速开发框架", + "preferGlobal": true, + "scripts": { + "bootstrap": "lerna bootstrap" + }, + "author": "harrywan qlin", + "license": "MIT", + "keywords": [ + "管理端", + "fes", + "fast", + "easy", + "strong" + ], + "repository": { + "type": "git", + "url": "https://github.com/WeBankFinTech/fes.git" + }, + "dependencies": { + "lerna": "^3.18.4" + }, + "devDependencies": { + "@webank/eslint-config-webank": "^0.1.6" + } +} diff --git a/packages/fes-cli/LICENSE b/packages/fes-cli/LICENSE new file mode 100644 index 00000000..23c3e60f --- /dev/null +++ b/packages/fes-cli/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-present harrywan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/packages/fes-cli/bin/index.js b/packages/fes-cli/bin/index.js new file mode 100755 index 00000000..55fc4a0e --- /dev/null +++ b/packages/fes-cli/bin/index.js @@ -0,0 +1,70 @@ +#!/usr/bin/env node + +const commander = require('commander'); + +const pkg = require('../package.json'); +const generateConfig = require('../build/helpers/config'); +const log = require('../build/helpers/log'); + +commander.usage(' [options]') + .version(pkg.version) + .option('-e, --env ', '配置环境 local(本地) | sit(测试) | prod(生产)') + .description(pkg.description); + +commander.command('init [name]') + .description('创建项目') + .action(async (name) => { + const projectInit = require('../build/tasks/init'); + const config = generateConfig('init'); + await projectInit(config, name); + }); + +commander.command('update') + .description('将 fes2 项目升级到 fes3') + .action(() => { + const update = require('../build/tasks/update'); + const config = generateConfig('update'); + update(config); + }); + +commander.command('route') + .description('根据当前项目结构自动生成 route') + .action(() => { + const route = require('../build/tasks/route'); + const config = generateConfig('route'); + route(config); + }); + +commander.command('components') + .description('预编译 src/components 里面的组件') + .action(() => { + const components = require('../build/tasks/components'); + const config = generateConfig('components'); + components(config); + }); + +commander.command('dev') + .description('开发调试, 默认 local') + .action(() => { + const dev = require('../build/tasks/dev'); + const config = generateConfig('dev', commander.env || 'local'); + dev(config); + }); + +commander.command('build') + .description('打包压缩,默认 prod') + .action(() => { + const build = require('../build/tasks/build'); + const config = generateConfig('build', commander.env || 'prod'); + build(config); + }); + +commander.parse(process.argv); + + +if (!process.argv.slice(2).length) { + commander.outputHelp((text) => { + log.message(text); + return ''; + }); +} diff --git a/packages/fes-cli/build/configs/postcss.config.js b/packages/fes-cli/build/configs/postcss.config.js new file mode 100644 index 00000000..1fd92570 --- /dev/null +++ b/packages/fes-cli/build/configs/postcss.config.js @@ -0,0 +1,8 @@ +const autoprefixer = require('autoprefixer'); +const browsers = require('../helpers/browser'); + +module.exports = { + plugins: [ + autoprefixer({ browsers }) + ] +}; diff --git a/packages/fes-cli/build/configs/webpack.config.js b/packages/fes-cli/build/configs/webpack.config.js new file mode 100644 index 00000000..ee026653 --- /dev/null +++ b/packages/fes-cli/build/configs/webpack.config.js @@ -0,0 +1,504 @@ +const path = require('path'); +const fs = require('fs'); +const merge = require('webpack-merge'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); +const CopyPlugin = require('copy-webpack-plugin'); +const OptimizeCssnanoPlugin = require('@intervolga/optimize-cssnano-plugin'); +const TerserPlugin = require('terser-webpack-plugin'); +const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const HtmlPlugin = require('html-webpack-plugin'); +const browsers = require('../helpers/browser'); + +module.exports = function webpackConfig(configs, webpack, mode) { + let template = path.resolve( + configs.folders.PROJECT_DIR, + './src/index.html' + ); + if (!fs.existsSync(template)) { + template = path.resolve(configs.folders.FES_DIR, './src/index.html'); + } + + const isDev = mode === 'dev'; + const isBuild = mode === 'build'; + + const projectNodeModulesDir = path.resolve( + configs.folders.PROJECT_DIR, + './node_modules' + ); + const cliNodeModulesDir = path.resolve( + configs.folders.CLI_DIR, + './node_modules' + ); + const nodeModulesDir = ['node_modules', projectNodeModulesDir, cliNodeModulesDir]; + const presets = [ + [ + path.resolve(cliNodeModulesDir, '@babel/preset-env'), + { + modules: false, + useBuiltIns: 'entry', + corejs: 3, + targets: { + browsers + } + } + ] + ]; + const plugins = [ + path.resolve(cliNodeModulesDir, '@babel/plugin-proposal-object-rest-spread'), + path.resolve(cliNodeModulesDir, '@babel/plugin-syntax-dynamic-import') + ]; + const cssloaders = [ + isDev + ? { + loader: 'vue-style-loader', + options: { + sourceMap: false, + shadowMode: false + } + } + : { + loader: MiniCssExtractPlugin.loader, + options: { + publicPath: '../' + } + }, + { + loader: 'css-loader', + options: { + sourceMap: false, + importLoaders: 2 + } + }, + { + loader: 'postcss-loader', + options: { + config: { + path: path.resolve(configs.folders.CLI_DIR, 'build/configs/postcss.config.js') + }, + sourceMap: false + } + } + ]; + + + const baseConfig = { + + mode: isDev ? 'development' : 'production', + + context: path.resolve(configs.folders.PROJECT_DIR), + + entry: { + app: [ + path.resolve(configs.folders.CLI_DIR, './node_modules/babel-polyfill'), + // path.resolve(configs.folders.CLI_DIR, './build/utils/create-nonce'), + path.resolve(configs.folders.FES_DIR, './src/app.js') + ] + }, + + resolve: { + extensions: ['.js', '.fes', '.vue', '.json'], + modules: nodeModulesDir, + alias: { + projectRoot: configs.folders.PROJECT_DIR, + '@': path.resolve(configs.folders.PROJECT_DIR, 'src'), + '@@': path.resolve(configs.folders.FES_DIR, 'src'), + assets: path.resolve( + configs.folders.PROJECT_DIR, + './src/assets/' + ), + vue$: 'vue/dist/vue.esm.js' + } + }, + + resolveLoader: { + modules: nodeModulesDir + }, + + output: { + globalObject: 'this', + filename: isDev ? 'js/[name].js' : 'js/[name].[contenthash:8].js', + chunkFilename: isDev ? 'js/[name].chunk.js' : 'js/[name].[contenthash:8].js', + path: configs.folders.PROJECT_DIST_DIR, + publicPath: isDev ? '/' : './' + }, + + module: { + noParse: /^(vue|vue-router|vuex|vuex-router-sync|axios|@webank\/fes-ui)$/, + rules: [ + + /* config.module.rule('vue') */ + { + test: /\.vue|fes$/, + use: [ + { + loader: 'cache-loader', + options: { + cacheDirectory: path.resolve(configs.folders.PROJECT_DIR, 'node_modules/.cache/vue-loader') + } + }, + { + loader: 'vue-loader', + options: { + compilerOptions: { + preserveWhitespace: false + }, + cacheDirectory: path.resolve(configs.folders.PROJECT_DIR, 'node_modules/.cache/vue-loader') + } + } + ] + }, + + /* config.module.rule('images') */ + { + test: /\.(png|jpe?g|gif|webp)(\?.*)?$/, + use: [ + { + loader: 'url-loader', + options: { + limit: 4096, + fallback: { + loader: 'file-loader', + options: { + name: isDev ? 'img/[name].[ext]' : 'img/[name].[hash:8].[ext]' + } + } + } + } + ] + }, + + /* config.module.rule('svg') */ + { + test: /\.(svg)(\?.*)?$/, + use: [ + { + loader: 'file-loader', + options: { + name: isDev ? 'img/[name].[ext]' : 'img/[name].[hash:8].[ext]' + } + } + ] + }, + + /* config.module.rule('media') */ + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + use: [ + { + loader: 'url-loader', + options: { + limit: 4096, + fallback: { + loader: 'file-loader', + options: { + name: isDev ? 'media/[name].[ext]' : 'media/[name].[hash:8].[ext]' + } + } + } + } + ] + }, + + /* config.module.rule('fonts') */ + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i, + use: [ + { + loader: 'url-loader', + options: { + limit: 4096, + fallback: { + loader: 'file-loader', + options: { + name: isDev ? 'fonts/[name].[ext]' : 'fonts/[name].[hash:8].[ext]' + } + } + } + } + ] + }, + + /* config.module.rule('css') */ + { + test: /\.css$/, + use: cssloaders + }, + + /* config.module.rule('postcss') */ + { + test: /\.p(ost)?css$/, + use: cssloaders + }, + + /* config.module.rule('scss') */ + { + test: /\.scss$/, + use: cssloaders.concat([ + { + loader: 'sass-loader', + options: { + sourceMap: false + } + } + ]) + }, + + /* config.module.rule('sass') */ + { + test: /\.sass$/, + use: cssloaders.concat([ + { + loader: 'sass-loader', + options: { + sourceMap: false, + indentedSyntax: true + } + } + ]) + }, + + /* config.module.rule('less') */ + { + test: /\.less$/, + use: cssloaders.concat([ + { + loader: 'less-loader', + options: { + sourceMap: false, + javascriptEnabled: true + } + } + ]) + }, + + /* config.module.rule('stylus') */ + { + test: /\.styl(us)?$/, + use: cssloaders.concat([ + { + loader: 'stylus-loader', + options: { + sourceMap: false, + preferPathResolver: 'webpack' + } + } + ]) + }, + + /* config.module.rule('js') */ + { + test: /\.m?jsx?$/, + use: [ + { + loader: 'cache-loader', + options: { + cacheDirectory: path.resolve(configs.folders.PROJECT_DIR, 'node_modules/.cache/babel-loader') + } + }, + { + loader: 'thread-loader' + }, + { + loader: 'babel-loader', + options: { + presets, + plugins + } + } + ] + } + + ] + }, + + devtool: isDev && 'cheap-module-eval-source-map', + + plugins: [ + + /* config.plugin('progress') */ + new webpack.ProgressPlugin(), + + /* config.plugin('vue-loader') */ + new VueLoaderPlugin(), + + /* config.plugin('define') */ + new webpack.DefinePlugin({ + 'process.privateFesEnv': { + env: `"${configs.env}"` + }, + 'process.env': { + env: JSON.stringify(configs.env), + command: JSON.stringify(configs.command) + } + }), + + /* config.plugin('clean dist') */ + isBuild && new CleanWebpackPlugin(), + + /* config.plugin('extract-css') */ + isBuild + && new MiniCssExtractPlugin({ + filename: 'css/[name].[contenthash:8].css', + chunkFilename: 'css/[name].[contenthash:8].css' + }), + + /* config.plugin('Copy static') */ + isBuild + && new CopyPlugin([ + { + from: configs.folders.PROJECT_STATIC_DIR, + to: path.resolve( + configs.folders.PROJECT_DIST_DIR, + 'static' + ) + } + ]), + + /* config.plugin('optimize-css') */ + isBuild + && new OptimizeCssnanoPlugin({ + sourceMap: false, + cssnanoOptions: { + preset: [ + 'default', + { + mergeLonghand: false, + cssDeclarationSorter: false + } + ] + } + }), + + /* config.plugin('hash-module-ids') */ + isBuild + && new webpack.HashedModuleIdsPlugin({ + hashDigest: 'hex' + }), + + /* config.plugin('固定一下 chunk id') */ + isBuild + && new webpack.NamedChunksPlugin((chunk) => { + if (chunk.name) { + return chunk.name; + } + // eslint-disable-next-line + const hash = require('hash-sum'); + const joinedHash = hash( + Array.from(chunk.modulesIterable, m => m.id).join('_') + ); + return `chunk-${joinedHash}`; + }), + + /* config.plugin('Copyright') */ + isBuild + && new webpack.BannerPlugin( + 'Created By MumbleFe. Copyright © 2015 - 2018 WeBank.' + ), + + /* config.plugin('case-sensitive-paths') */ + new CaseSensitivePathsPlugin(), + + /* config.plugin('friendly-errors') */ + new FriendlyErrorsPlugin(), + + /* config.plugin('index.html') */ + new HtmlPlugin({ + template, + minify: isBuild && { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true, + collapseBooleanAttributes: true, + removeScriptTypeAttributes: true + } + }) + + ] + }; + + if (isBuild) { + baseConfig.optimization = { + minimizer: [ + new TerserPlugin({ + test: /\.m?js(\?.*)?$/i, + chunkFilter: () => true, + warningsFilter: () => true, + extractComments: false, + sourceMap: true, + cache: true, + cacheKeys: defaultCacheKeys => defaultCacheKeys, + parallel: true, + include: undefined, + exclude: undefined, + minify: undefined, + terserOptions: { + output: { + comments: /^\**!|@preserve|@license|@cc_on/i + }, + compress: { + arrows: false, + collapse_vars: false, + comparisons: false, + computed_props: false, + hoist_funs: false, + hoist_props: false, + hoist_vars: false, + inline: false, + loops: false, + negate_iife: false, + properties: false, + reduce_funcs: false, + reduce_vars: false, + switches: false, + toplevel: false, + typeofs: false, + booleans: true, + if_return: true, + sequences: true, + unused: true, + conditionals: true, + dead_code: true, + evaluate: true + }, + mangle: { + safari10: true + } + } + }) + ], + splitChunks: { + cacheGroups: { + vendors: { + name: 'chunk-vendors', + test: /[\\/]node_modules[\\/]/, + priority: -10, + chunks: 'initial' + }, + common: { + name: 'chunk-common', + minChunks: 2, + priority: -20, + chunks: 'initial', + reuseExistingChunk: true + } + } + }, + runtimeChunk: true + }; + } + + baseConfig.plugins = baseConfig.plugins.filter(plu => plu !== false); + + let advancedConfig = {}; + const projectWebpackConfigFile = path.resolve(configs.folders.PROJECT_DIR, 'webpack.config.js'); + if (fs.existsSync(projectWebpackConfigFile)) { + console.log('[init] 加载项目个性webpack配置文件'); + // eslint-disable-next-line + advancedConfig = require(projectWebpackConfigFile)(mode, configs, webpack); + } + + return merge(baseConfig, advancedConfig); +}; diff --git a/packages/fes-cli/build/helpers/browser.js b/packages/fes-cli/build/helpers/browser.js new file mode 100644 index 00000000..5504a544 --- /dev/null +++ b/packages/fes-cli/build/helpers/browser.js @@ -0,0 +1 @@ +module.exports = ['>1%', 'last 2 versions', 'safari >= 7', 'ie >= 9']; diff --git a/packages/fes-cli/build/helpers/config.js b/packages/fes-cli/build/helpers/config.js new file mode 100644 index 00000000..9eb00788 --- /dev/null +++ b/packages/fes-cli/build/helpers/config.js @@ -0,0 +1,62 @@ +const path = require('path'); +const fs = require('fs'); +const log = require('./log'); + +function generateConfig(command, env) { + // cli目录 + const CLI_DIR = path.dirname(path.dirname(fs.realpathSync(process.argv[1]))); + // 解决git-bash目录问题 + const PROJECT_DIR = process.env.PWD || process.cwd(); + const FES_DIR = path.resolve(PROJECT_DIR, './node_modules/@webank/fes-core'); + + const PROJECT_DIST_DIR = path.resolve(PROJECT_DIR, 'dist'); + const PROJECT_CACHE_DIR = path.resolve(PROJECT_DIR, './.cache'); + const PROJECT_PAGE_DIR = path.resolve(PROJECT_DIR, './src/pages'); + const PROJECT_CPN_DIR = path.resolve(PROJECT_DIR, './src/components'); + const PROJECT_STATIC_DIR = path.join(PROJECT_DIR, './src/static'); + const projectName = path.basename(PROJECT_DIR); + + const fesConfigFile = path.join(PROJECT_DIR, 'fes.config.js'); + + const config = { + command, + env, + ports: { + server: 5000, + liveReload: 35729 + }, + projectName, + folders: { + CLI_DIR, + FES_DIR, + PROJECT_DIR, + PROJECT_STATIC_DIR, + PROJECT_DIST_DIR, + PROJECT_CACHE_DIR, + PROJECT_PAGE_DIR, + PROJECT_CPN_DIR + } + }; + + if (fs.existsSync(fesConfigFile)) { + try { + // eslint-disable-next-line + const fesCofig = require(path.join(config.folders.PROJECT_DIR, 'fes.config.js')); + config.CDN = fesCofig.env[config.env].cdn; + config.needCDN = !!config.CDN; + } catch (e) { + config.needCDN = false; + } + } + + if (!config.needCDN) { + if (config.command === 'dev' || config.command === 'build') { + log.warn('项目没有配置cdn,打包之后将不会请求cdn的地址,请开发者注意!!'); + } + } + + return config; +} + + +module.exports = generateConfig; diff --git a/packages/fes-cli/build/helpers/createDevServer.js b/packages/fes-cli/build/helpers/createDevServer.js new file mode 100644 index 00000000..4bf01f8f --- /dev/null +++ b/packages/fes-cli/build/helpers/createDevServer.js @@ -0,0 +1,44 @@ +const + http = require('http'); +const webpack = require('webpack'); +const express = require('express'); +const opn = require('opn'); +const webpackHotMiddleware = require('webpack-hot-middleware'); +const webpackDevMiddleware = require('webpack-dev-middleware'); +const initMock = require('../mock/init.js'); + + +module.exports = function createDevServer(port, defaultConfig) { + defaultConfig.entry.app.unshift('webpack-hot-middleware/client?reload=true'); + defaultConfig.plugins.push(new webpack.HotModuleReplacementPlugin()); + defaultConfig.plugins.push(new webpack.NamedModulesPlugin()); + + const app = express(); + const compiler = webpack(defaultConfig); + + // devServer 自带支持,添加自定义插件。 + app.use(webpackDevMiddleware(compiler, { + lazy: false, + watchOptions: { + aggregateTimeout: 300, + poll: 1000 + }, + stats: { + colors: true, + chunks: false, + timings: true + }, + publicPath: defaultConfig.output.publicPath + })); + + app.use(webpackHotMiddleware(compiler)); + app.use('/static', express.static('src/static')); + + + // 初始化Mock数据 + initMock(app); + + opn(`http://localhost:${port}`); + + http.createServer(app).listen(port); +}; diff --git a/packages/fes-cli/build/helpers/getPort.js b/packages/fes-cli/build/helpers/getPort.js new file mode 100644 index 00000000..9cd57cd8 --- /dev/null +++ b/packages/fes-cli/build/helpers/getPort.js @@ -0,0 +1,25 @@ +const net = require('net'); + +function checkout(port) { + return new Promise((resolve) => { + const server = net.createServer(); + server.once('error', (err) => { + if (err.code === 'EADDRINUSE') { + resolve(checkout(port + 1)); + } + }); + + server.once('listening', () => { + server.close(() => { + resolve(port); + }); + }); + + server.listen(port); + }); +} + +module.exports = function getPort(basePort) { + basePort = basePort || 5000; + return checkout(basePort); +}; diff --git a/packages/fes-cli/build/helpers/log.js b/packages/fes-cli/build/helpers/log.js new file mode 100644 index 00000000..a4582378 --- /dev/null +++ b/packages/fes-cli/build/helpers/log.js @@ -0,0 +1,13 @@ +const chalk = require('chalk'); + +module.exports = { + error(msg) { + return console.log(chalk.red(msg)); + }, + warn(msg) { + return console.log(chalk.yellow(msg)); + }, + message(msg) { + return console.log(chalk.cyan(msg)); + } +}; diff --git a/packages/fes-cli/build/mock/cgiMock.js b/packages/fes-cli/build/mock/cgiMock.js new file mode 100644 index 00000000..a64ebf8d --- /dev/null +++ b/packages/fes-cli/build/mock/cgiMock.js @@ -0,0 +1,142 @@ +const express = require('express'); +const fs = require('fs'); +const path = require('path'); +const httpProxy = require('http-proxy'); +const url = require('url'); + +const util = require('./util'); + +const proxy = httpProxy.createProxyServer(); +global.router = express.Router(); + +/** + * 数据模拟函数 + */ +function cgiMock() { + // eslint-disable-next-line + const option = getOption(arguments); + + if (!option.url || !option.result) { + return; + } + + // option.method is one of ['get','post','delete','put'...] + const method = option.method || 'use'; + + global.router[method.toLowerCase()](option.url, (req, res) => { + setTimeout(() => { + // set header + res.set(option.headers); + + // set Content-Type + option.type && res.type(option.type); + + // set status code + res.status(option.statusCode); + + // set cookie + util.each(option.cookies, (item) => { + const name = item.name; + const value = item.value; + delete item.name; + delete item.value; + res.cookie(name, value, item); + }); + + // do result + if (util.isFunction(option.result)) { + option.result(req, res); + } else if (util.isArray(option.result) || util.isObject(option.result)) { + !option.type && res.type('json'); + res.json(option.result); + } else { + !option.type && res.type('text'); + res.send(option.result.toString()); + } + }, option.timeout); + }); +} + +// 根据参数个数获取配置 +function getOption(arg) { + const len = arg.length; + // 默认配置 + const option = { + headers: { + 'Cache-Control': 'no-cache' + }, + statusCode: 200, + cookies: [], + timeout: 0 + }; + if (len === 0) { + return cgiMock; + } if (len === 1) { + const newOption = arg[0]; + if (util.isObject(newOption)) { + util.each(newOption, (value, key) => { + if (key === 'headers') { + util.each(newOption.headers, (headervalue, headerkey) => { + option.headers[headerkey] = newOption.headers[headerkey]; + }); + } else { + option[key] = newOption[key]; + } + }); + } + } else { + option.url = arg[0]; + option.result = arg[1]; + } + return option; +} + +// 把基于 cgiMockfile 的相对绝对转成绝对路径 +function parsePath(value) { + return path.join(global.cgiMockFilePath, value); +} + + +// log proxy data +proxy.on('open', (proxySocket) => { + proxySocket.on('data', (chunk) => { + console.log(chunk.toString()); + }); +}); +proxy.on('proxyRes', (proxyRes) => { + console.log('RAW Response from the target', JSON.stringify(proxyRes.headers, true, 2)); + const cookie = proxyRes.headers['set-cookie']; + if (cookie && cookie.length > 0) { + for (let i = 0; i < cookie.length; i++) { + cookie[i] = cookie[i].replace('Secure', ''); + } + } +}); + +proxy.on('error', (e) => { + console.log(e); +}); + +// 规则之外的请求转发 +cgiMock.proxy = function (host) { + process.nextTick(() => { + global.router.use((req, res) => { + proxy.web(req, res, { + target: host, + secure: false + }); + }); + }); + proxy.on('proxyReq', (proxyReq) => { + proxyReq.setHeader('Host', url.parse(host).host); + }); +}; + +// 读取文件内容 +cgiMock.file = function (file) { + return fs.readFileSync(parsePath(file)); +}; + +cgiMock.prefix = '/'; + +module.exports = cgiMock; diff --git a/packages/fes-cli/build/mock/init.js b/packages/fes-cli/build/mock/init.js new file mode 100644 index 00000000..1b9b3747 --- /dev/null +++ b/packages/fes-cli/build/mock/init.js @@ -0,0 +1,112 @@ +const Mock = require('mockjs'); +const faker = require('faker'); +const path = require('path'); +const fs = require('fs'); + +const logger = require('morgan'); +const cookieParser = require('cookie-parser'); +const bodyParser = require('body-parser'); +const onFinished = require('on-finished'); + +const util = require('./util'); +const cgiMock = require('./cgiMock'); +const log = require('../helpers/log'); + +const main = { + init(app, argv, cwd) { + this.app = app; + this.argv = argv; + this.cwd = cwd; + + app.use(logger('dev')); + app.use( + bodyParser.urlencoded({ + extended: false + }) + ); + app.use(cookieParser()); + + this.customRoute(); + this.defaultRoute(); + }, + + customRoute() { + const argv = this.argv; + const defaultCgiMockFile = path.join(process.cwd(), 'mock.js'); + const home = process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME']; + + let cgiMockFile; + if (argv) { + if (argv.f) { + if (process.platform === 'win32') { + cgiMockFile = path.resolve(this.cwd, this.argv.f); + } else if (argv.f[0] === '~') { + cgiMockFile = path.resolve( + home, + argv.f.replace(/^~\//, '') + ); + } else { + cgiMockFile = path.resolve(this.cwd, this.argv.f); + } + } else { + cgiMockFile = defaultCgiMockFile; + } + } else { + cgiMockFile = defaultCgiMockFile; + } + global.cgiMockFilePath = path.resolve(cgiMockFile, '..'); + + const loadRouteConfig = function () { + util.cleanCache(cgiMockFile); + try { + if (!fs.existsSync(cgiMockFile)) { + log.error('[WARN] 不存在mock.js文件'); + } else { + // eslint-disable-next-line + const projectMock = require(cgiMockFile); + if (util.isFunction(projectMock)) { + global.router.stack = []; + projectMock(cgiMock, Mock, faker); + log.message('[SUCCESS] mock.js 加载成功'); + } else { + log.error( + `[ERROR] mock.js cannot be ${typeof projectMock}` + ); + } + } + } catch (e) { + log.error('[ERROR] mock.js 有误,请检查'); + log.error(JSON.stringify(e)); + } + }; + + loadRouteConfig(); + this.app.use(cgiMock.prefix, (req, res, next) => { + onFinished(res, () => { + loadRouteConfig(); + }); + global.router(req, res, next); + }); + + util.watchFile(cgiMockFile, () => { + log.message('[INFO] mock.js 发生变化'); + loadRouteConfig(); + }); + }, + + defaultRoute() { + const app = this.app; + + setTimeout(() => { + app.use((err, req, res) => { + res.json({ + status: err.status || 500, + message: err.message, + err + }); + }); + }); + } +}; + +module.exports = main.init.bind(main); diff --git a/packages/fes-cli/build/mock/task/cgiMock.js b/packages/fes-cli/build/mock/task/cgiMock.js new file mode 100644 index 00000000..7b4a12ed --- /dev/null +++ b/packages/fes-cli/build/mock/task/cgiMock.js @@ -0,0 +1,17 @@ + + +const express = require('express'); +const argv = require('yargs').argv; + +const port = argv.p || 8888; +const cwd = process.cwd(); + +const app = express(); +const init = require('../init'); + +init(app, argv, cwd); + +app.set('port', port); +app.listen(port, () => { + console.log(`cgiMock server listening on ${port}`); +}); diff --git a/packages/fes-cli/build/mock/test/app.js b/packages/fes-cli/build/mock/test/app.js new file mode 100644 index 00000000..30ce9580 --- /dev/null +++ b/packages/fes-cli/build/mock/test/app.js @@ -0,0 +1,64 @@ +module.exports = function mock(cgiMock, Mock) { + const Random = Mock.Random; + + // 前缀,全局(可选) + cgiMock.prefix = '/prefix'; + + // 返回一个数字 + cgiMock('/number', 123); + + // 返回一个json + cgiMock({ + url: '/json', + result: { + code: '400101', msg: "不合法的请求:Missing cookie 'wb_app_id' for method parameter of type String", transactionTime: '20170309171146', success: false + } + }); + + // 利用mock.js 产生随机文本 + cgiMock('/text', Random.cparagraph()); + + // 返回一个字符串 利用mock.js 产生随机字符 + cgiMock('/string', Mock.mock({ + 'string|1-10': '★' + })); + + + // 正则匹配url, 返回一个字符串 + cgiMock(/\/abc|\/xyz/, 'regexp test!'); + + // option.result 参数如果是一个函数, 可以实现自定义返回内容, 接收的参数是是经过 express 封装的 req 和 res 对象. + cgiMock(/\/function$/, (req, res) => { + res.send('function test'); + }); + + // 返回文本 fs.readFileSync + cgiMock('/file', cgiMock.file('./test.json')); + + // 更复杂的规则配置 + cgiMock({ + url: /\/who/, + method: 'GET', + result(req, res) { + if (req.query.name === 'kwan') { + res.json({ kwan: '孤独患者' }); + } else { + res.send('Nooooooooooo'); + } + }, + headers: { + 'Content-Type': 'text/plain', + 'Content-Length': '123', + ETag: '12345' + }, + cookies: [ + { + name: 'myname', value: 'kwan', maxAge: 900000, httpOnly: true + } + ], + // 接口随机延迟 + timeout: Mock.mock({ + 'number|1000-5000': 1000 + }).number + }); +}; diff --git a/packages/fes-cli/build/mock/test/myfile.txt b/packages/fes-cli/build/mock/test/myfile.txt new file mode 100644 index 00000000..3ebaf0c4 --- /dev/null +++ b/packages/fes-cli/build/mock/test/myfile.txt @@ -0,0 +1 @@ +file test \ No newline at end of file diff --git a/packages/fes-cli/build/mock/util.js b/packages/fes-cli/build/mock/util.js new file mode 100644 index 00000000..4b10b7ab --- /dev/null +++ b/packages/fes-cli/build/mock/util.js @@ -0,0 +1,62 @@ +const fs = require('fs'); + +const toString = Object.prototype.toString; +module.exports = { + + isArray(value) { + return toString.call(value) === '[object Array]'; + }, + + isObject(value) { + return toString.call(value) === '[object Object]'; + }, + + isFunction(value) { + return toString.call(value) === '[object Function]'; + }, + + each(val, callback) { + if (this.isArray(val)) { + val.forEach(callback); + } + if (this.isObject(val)) { + Object.keys(val).forEach((key) => { + callback(val[key], key); + }); + } + }, + + watchFile(filename, callback) { + const isWin = (process.platform === 'win32'); + if (isWin) { + return fs.watch(filename, (event) => { + if (event === 'change') { + return callback(filename); + } + return null; + }); + } + return fs.watchFile(filename, { + interval: 200 + }, (curr, prev) => { + if (curr.mtime > prev.mtime) { + return callback(filename); + } + return null; + }); + }, + + unwatchFile(watcher, filename) { + if (watcher) { + watcher.close && watcher.close(); + } else { + fs.unwatchFile(filename); + } + }, + + cleanCache(modulePath) { + if (require.cache[modulePath]) { + delete require.cache[modulePath]; + } + } +}; diff --git a/packages/fes-cli/build/preComplie/components.js b/packages/fes-cli/build/preComplie/components.js new file mode 100644 index 00000000..cafa05d9 --- /dev/null +++ b/packages/fes-cli/build/preComplie/components.js @@ -0,0 +1,26 @@ +// 全局注册common目录下的组件 +const fs = require('fs'); +const Path = require('path'); +const stringUtil = require('node-plus-string'); + +function addComp(path, outputCommonDir, components) { + const dirList = fs.readdirSync(path); + dirList.forEach((item) => { + if (fs.statSync(`${path}/${item}`).isFile() + && item[0] !== '.' + && ['.fes', '.vue'].indexOf(Path.extname(item)) !== -1) { + const fileName = Path.basename(item, Path.extname(item)); + const tagName = stringUtil.capitalize(fileName); + components.push({ + tagName, + path: Path.resolve(outputCommonDir, item).replace(/\\/g, '\\\\') + }); + } + }); +} + +module.exports = function genComponents(commonDir, outputCommonDir) { + const components = []; + addComp(commonDir, outputCommonDir, components); + return components; +}; diff --git a/packages/fes-cli/build/preComplie/route.js b/packages/fes-cli/build/preComplie/route.js new file mode 100644 index 00000000..15fed007 --- /dev/null +++ b/packages/fes-cli/build/preComplie/route.js @@ -0,0 +1,121 @@ +// pages +// ├── index.fes # 根路由页面 路径 index.html#/ +// ├── a.fes # 路径 /a +// ├── b +// │ ├── index.fes # 路径 /b +// │ ├── @id.fes # 动态路由 /b/:id +// │ └── c.fes # 路径 /b/c +// └── layout.fes # 根路由下所有page共用的外层 + +const fs = require('fs'); +const Path = require('path'); + +let pagesDir; +let outputPageDir; +let components = []; + +function checkHasLayout(path) { + const dirList = fs.readdirSync(path); + let hasLayout = false; + dirList.forEach((item) => { + if (fs.statSync(`${path}/${item}`).isFile() + && item[0] !== '.' && ['.fes', '.vue'].indexOf(Path.extname(item)) !== -1 + && Path.basename(item, Path.extname(item)) === 'layout') { + hasLayout = true; + } + }); + return hasLayout; +} + +function routeUrlFormmter(str) { + return str.replace(/@/g, ':'); +} + +function genRoute(path, prePathUrl, preRoutes) { + const hasLayout = checkHasLayout(path); + const dirList = fs.readdirSync(path); + let childRoutes = {}; + const parentRoutes = {}; + const preRouteUrl = routeUrlFormmter(prePathUrl); + if (hasLayout) { + parentRoutes[preRouteUrl] = { + subRoutes: childRoutes + }; + } else { + childRoutes = parentRoutes; + } + dirList.forEach((item) => { + if (fs.statSync(`${path}/${item}`).isFile() + && item[0] !== '.' && ['.fes', '.vue'].indexOf(Path.extname(item)) !== -1) { + const fileName = Path.basename(item, Path.extname(item)); + const preRouteName = path.slice(pagesDir.length + 1); + let routePath = Path.posix.join(preRouteUrl, (fileName === 'index' ? '' : fileName.replace(/@/g, ':'))); + const filePath = Path.resolve(path.replace(pagesDir, outputPageDir), item); + let routeName = preRouteName ? `${preRouteName}_${fileName}` : fileName; + routeName = routeName.replace(/\//g, '_').replace(/@/g, ''); + routePath = routePath.replace(/@/g, ':'); + + if (hasLayout && fileName === 'index') { + routePath = '/'; + } else if (hasLayout && fileName !== 'index') { + routePath = routePath.split(preRouteUrl)[1]; + } + components.push({ + name: routeName, + path: filePath.replace(/\\/g, '\\\\') + }); + if (fileName === 'layout') { + parentRoutes[preRouteUrl].component = routeName; + return; + } + childRoutes[routePath] = { + name: routeName || 'index', + component: routeName + }; + } + }); + preRoutes = Object.assign(preRoutes, parentRoutes); + const toNextRoutes = hasLayout ? childRoutes : preRoutes; + + dirList.forEach((item) => { + if (fs.statSync(`${path}/${item}`).isDirectory()) { + let toNextPreRouteUrl = Path.posix.join(prePathUrl, item); + if (hasLayout) { + toNextPreRouteUrl = Path.posix.join('/', item); + } + genRoute(`${path}/${item}`, toNextPreRouteUrl, toNextRoutes, outputPageDir, components); + } + }); +} + +function fixRouter2(routes, newRoutes, f) { + Object.keys(routes).forEach((p) => { + const item = { + path: f ? p.slice(1) : p, + component: routes[p].component + }; + if (routes[p].name) { + item.name = routes[p].name; + } + if (routes[p].subRoutes) { + item.children = []; + fixRouter2(routes[p].subRoutes, item.children, true); + } + newRoutes.push(item); + }); +} + +module.exports = function (_pagesDir, _outputPageDir) { + const routes = {}; + const newRoutes = []; + components = []; + pagesDir = _pagesDir; + outputPageDir = _outputPageDir; + genRoute(pagesDir, '/', routes); + fixRouter2(routes, newRoutes); + return { + routes, + newRoutes, + components + }; +}; diff --git a/packages/fes-cli/build/tasks/build.js b/packages/fes-cli/build/tasks/build.js new file mode 100644 index 00000000..8c55c893 --- /dev/null +++ b/packages/fes-cli/build/tasks/build.js @@ -0,0 +1,25 @@ +const webpack = require('webpack'); +const log = require('../helpers/log'); +const createProdConfig = require('../configs/webpack.config'); + +const generateRoute = require('./route'); +const generateComponent = require('./components'); + +function startBuild(config) { + try { + generateRoute(config); + generateComponent(config); + const webpackConfig = createProdConfig(config, webpack, 'build'); + webpack(webpackConfig, (err) => { + if (err) { + log.error(err); + return; + } + console.log('[build] success'); + }); + } catch (e) { + log.error(e); + } +} + +module.exports = startBuild; diff --git a/packages/fes-cli/build/tasks/components.js b/packages/fes-cli/build/tasks/components.js new file mode 100644 index 00000000..b9e6189a --- /dev/null +++ b/packages/fes-cli/build/tasks/components.js @@ -0,0 +1,45 @@ +const render = require('json-templater/string'); +const path = require('path'); +const endOfLine = require('os').EOL; +const fs = require('fs-extra'); +const getCommonComponent = require('../preComplie/components'); + +function generateComponent(config) { + const OUTPUT_PATH = path.resolve(config.folders.PROJECT_CACHE_DIR, 'commonComp.js'); + const IMPORT_TEMPLATE = 'import {{name}} from \'{{path}}\';'; + const LIST_TEMPLATE = ' {{name}}'; + + const MAIN_TEMPLATE = ` +/** +* 全局组件配置输出 +*/ +{{include}} + +export default { +{{list}} +}; +`; + + const components = getCommonComponent(config.folders.PROJECT_CPN_DIR, config.folders.PROJECT_CPN_DIR); + + const componentsTemplate = []; + const listTemplate = []; + components.forEach((item) => { + componentsTemplate.push(render(IMPORT_TEMPLATE, { + name: item.tagName, + path: item.path + })); + listTemplate.push(render(LIST_TEMPLATE, { + name: item.tagName + })); + }); + + const template = render(MAIN_TEMPLATE, { + include: componentsTemplate.join(endOfLine), + list: listTemplate.join(`,${endOfLine}`) + }); + + fs.outputFileSync(OUTPUT_PATH, template); +} + +module.exports = generateComponent; diff --git a/packages/fes-cli/build/tasks/dev.js b/packages/fes-cli/build/tasks/dev.js new file mode 100644 index 00000000..d389a598 --- /dev/null +++ b/packages/fes-cli/build/tasks/dev.js @@ -0,0 +1,63 @@ +const path = require('path'); +const chokidar = require('chokidar'); +const webpack = require('webpack'); +const createDevServer = require('../helpers/createDevServer'); +const getPort = require('../helpers/getPort'); +const log = require('../helpers/log'); +const createDevConfig = require('../configs/webpack.config'); + +const generateRoute = require('./route'); +const generateComponent = require('./components'); + + +function routeHandle(config) { + generateRoute(config); + // 监听pages变化重新生成路由 + const pagesWatcher = chokidar.watch(path.resolve(config.folders.PROJECT_DIR, './src/pages')); + pagesWatcher.on('ready', () => { + pagesWatcher.on('add', (filePath) => { + if (path.extname(filePath) === '.fes' || path.extname(filePath) === '.vue') { + generateRoute(config); + } + }).on('unlink', (filePath) => { + if (path.extname(filePath) === '.fes' || path.extname(filePath) === '.vue') { + generateRoute(config); + } + }); + }); +} + +function globalComponentHandle(config) { + generateComponent(config); + // 监听components变化重新生成组件注入文件 + const compWatcher = chokidar.watch(path.resolve(config.folders.PROJECT_DIR, './src/components')); + compWatcher.on('ready', () => { + compWatcher.on('add', (filePath) => { + if (path.extname(filePath) === '.fes' || path.extname(filePath) === '.vue') { + generateComponent(config); + } + }).on('unlink', (filePath) => { + if (path.extname(filePath) === '.fes' || path.extname(filePath) === '.vue') { + generateComponent(config); + } + }); + }); +} + +function startDev(config) { + routeHandle(config); + globalComponentHandle(config); + const webpackConfig = createDevConfig(config, webpack, 'dev'); + if (!webpackConfig) return; + + getPort(config.ports.server) + .then((port) => { + log.message(`------------ find port success. port: ${port}`); + createDevServer(port, webpackConfig); + }).catch((err) => { + log.message('------------ build error.'); + log.error(err); + }); +} + +module.exports = startDev; diff --git a/packages/fes-cli/build/tasks/index.js b/packages/fes-cli/build/tasks/index.js new file mode 100644 index 00000000..9f1fa8d5 --- /dev/null +++ b/packages/fes-cli/build/tasks/index.js @@ -0,0 +1,15 @@ +const init = require('./init.js'); +const route = require('./route.js'); +const components = require('./components.js'); +const build = require('./build.js'); +const dev = require('./dev.js'); +const update = require('./update.js'); + +module.exports = { + init, + route, + components, + build, + dev, + update +}; diff --git a/packages/fes-cli/build/tasks/init.js b/packages/fes-cli/build/tasks/init.js new file mode 100644 index 00000000..6d77a58d --- /dev/null +++ b/packages/fes-cli/build/tasks/init.js @@ -0,0 +1,54 @@ +const path = require('path'); +const fs = require('fs-extra'); +const prompts = require('prompts'); +const { exec } = require('child_process'); +const log = require('../helpers/log'); + + +function createProject(config, projectName) { + log.message('正在初始化项目...'); + const projectDir = path.resolve(config.folders.PROJECT_DIR, projectName); + if (fs.pathExistsSync(projectDir)) { + log.error('该项目已存在,请重新输入!'); + return Promise.reject(); + } + return new Promise((resolve, reject) => { + fs.copy(`${config.folders.CLI_DIR}/template`, `${config.folders.PROJECT_DIR}/${projectName}`).then(() => { + exec(`cd ${config.folders.PROJECT_DIR}/${projectName} && git init && npm i @webank/fes-core @webank/fes-ui && npm i`, (err) => { + if (err) { + log.error(err); + reject(err); + return; + } + log.message(`项目 ${projectName} 创建完成,请执行下面的命令进行使用:`); + log.message(`$ cd ${projectName}`); + log.message('$ npm run dev'); + resolve(); + }); + }).catch((err) => { + log.error(err); + reject(err); + }); + }); +} + +async function initProject(config, projectName) { + if (projectName) { + await createProject(config, projectName); + } else { + const response = await prompts([ + { + type: 'text', + name: 'name', + message: '请输入项目名称: ' + } + ]); + if (!response.name) { + await initProject(config, projectName); + } else { + await createProject(config, response.name); + } + } +} + +module.exports = initProject; diff --git a/packages/fes-cli/build/tasks/route.js b/packages/fes-cli/build/tasks/route.js new file mode 100644 index 00000000..bb77c71c --- /dev/null +++ b/packages/fes-cli/build/tasks/route.js @@ -0,0 +1,35 @@ +const render = require('json-templater/string'); +const path = require('path'); +const endOfLine = require('os').EOL; +const fs = require('fs-extra'); +const getRoute = require('../preComplie/route'); + +function generateRoute(config) { + const OUTPUT_PATH = path.resolve(config.folders.PROJECT_CACHE_DIR, 'routeConfig.js'); + const IMPORT_TEMPLATE = 'import {{name}} from \'{{path}}\';'; + + const MAIN_TEMPLATE = ` +{{include}} + +export default {{routes}}; +`; + + const routes = getRoute(config.folders.PROJECT_PAGE_DIR, config.folders.PROJECT_PAGE_DIR); + + const componentsTemplate = []; + routes.components.forEach((item) => { + componentsTemplate.push(render(IMPORT_TEMPLATE, { + name: item.name, + path: item.path + })); + }); + + const template = render(MAIN_TEMPLATE, { + include: componentsTemplate.join(endOfLine), + routes: JSON.stringify(routes.newRoutes).replace(/"component":"(.+?)"/g, '"component": $1') + }); + + fs.outputFileSync(OUTPUT_PATH, template); +} + +module.exports = generateRoute; diff --git a/packages/fes-cli/build/tasks/update.js b/packages/fes-cli/build/tasks/update.js new file mode 100644 index 00000000..38f11487 --- /dev/null +++ b/packages/fes-cli/build/tasks/update.js @@ -0,0 +1,15 @@ +const { exec } = require('child_process'); +const log = require('../helpers/log'); + +function update(config) { + log.message('安装@webank/fes-core @webank/fes-ui...'); + exec(`cd ${config.folders.PROJECT_DIR} && npm i @webank/fes-core @webank/fes-ui --save && npm i`, (err) => { + if (err) { + console.error(err); + return; + } + log.message('升级完毕'); + }); +} + +module.exports = update; diff --git a/packages/fes-cli/change.md b/packages/fes-cli/change.md new file mode 100644 index 00000000..333bc476 --- /dev/null +++ b/packages/fes-cli/change.md @@ -0,0 +1,7 @@ +# 变更 + +* 改用 commander 描述命令行参数 +* 删除命令选项 https,(实际上代码中没有用到) +* 更改 configs >> config +* init 模版使用 cli 自带模版,fes-core/fes-ui 创建项目时安装,新项目都采用最新的版本 +* 该更 route | components 生成方式(使其不依赖 gulp 的编译) diff --git a/packages/fes-cli/package.json b/packages/fes-cli/package.json new file mode 100644 index 00000000..8df30e7f --- /dev/null +++ b/packages/fes-cli/package.json @@ -0,0 +1,98 @@ +{ + "name": "@webank/fes-cli", + "version": "0.1.1", + "description": "一个好用的前端管理台快速开发框架", + "preferGlobal": true, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "bin": { + "fes": "./bin/index.js" + }, + "author": "harrywan,qlin", + "repository": { + "type": "git", + "url": "https://github.com/WeBankFinTech/fes.js.git" + }, + "license": "MIT", + "keywords": [ + "管理端", + "fes", + "fast", + "easy", + "strong" + ], + "dependencies": { + "@babel/core": "^7.6.4", + "@babel/helper-module-imports": "^7.7.0", + "@babel/plugin-proposal-class-properties": "^7.7.0", + "@babel/plugin-proposal-decorators": "^7.7.0", + "@babel/plugin-proposal-object-rest-spread": "^7.6.2", + "@babel/plugin-syntax-dynamic-import": "^7.2.0", + "@babel/plugin-transform-runtime": "^7.6.2", + "@babel/preset-env": "^7.6.3", + "@babel/runtime": "^7.7.2", + "@intervolga/optimize-cssnano-plugin": "^1.0.6", + "autoprefixer": "^8.1.0", + "babel-loader": "^8.0.6", + "babel-polyfill": "^6.26.0", + "body-parser": "^1.5.2", + "cache-loader": "^4.1.0", + "case-sensitive-paths-webpack-plugin": "^2.2.0", + "chalk": "^1.1.1", + "chokidar": "^1.7.0", + "clean-webpack-plugin": "^3.0.0", + "commander": "^4.1.0", + "cookie-parser": "^1.4.3", + "copy-webpack-plugin": "^5.0.4", + "cross-spawn": "^2.1.0", + "css-loader": "^3.1.0", + "execa": "^0.8.0", + "express": "^4.14.0", + "express-http-proxy": "^0.10.0", + "express-session": "^1.7.2", + "faker": "^4.1.0", + "file-loader": "^4.2.0", + "friendly-errors-webpack-plugin": "^1.7.0", + "fs": "0.0.2", + "fs-extra": "^8.1.0", + "hash-sum": "^2.0.0", + "html-webpack-plugin": "^3.2.0", + "http-proxy": "^1.12.0", + "is-ci": "^1.0.10", + "json-templater": "^1.2.0", + "lodash": "^4.17.4", + "mini-css-extract-plugin": "^0.8.0", + "mockjs": "^1.1.0", + "morgan": "^1.2.2", + "node-plus-string": "^1.0.1", + "node-sass": "^4.13.0", + "normalize-path": "^1.0.0", + "on-finished": "^2.3.0", + "opn": "^4.0.2", + "path": "^0.12.7", + "postcss-loader": "^3.0.0", + "prompts": "^2.3.0", + "request": "^2.81.0", + "require-dir": "^0.3.0", + "sass-loader": "^8.0.0", + "shelljs": "^0.5.3", + "string-replace-loader": "^2.2.0", + "strip-indent": "^2.0.0", + "style-loader": "^1.0.0", + "tar-fs": "^1.16.0", + "terser-webpack-plugin": "^2.2.1", + "thread-loader": "^2.1.3", + "url-loader": "^2.2.0", + "vue-loader": "^15.7.2", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "^2.6.10", + "webpack": "^4.41.2", + "webpack-cli": "^3.3.9", + "webpack-dev-middleware": "^3.7.2", + "webpack-dev-server": "^3.9.0", + "webpack-hot-middleware": "^2.25.0", + "webpack-merge": "^4.2.2", + "yargs": "^3.31.0" + } +} diff --git a/packages/fes-cli/template/.eslintrc.js b/packages/fes-cli/template/.eslintrc.js new file mode 100644 index 00000000..a27eba89 --- /dev/null +++ b/packages/fes-cli/template/.eslintrc.js @@ -0,0 +1,17 @@ + +module.exports = { + extends: [ + '@webank/eslint-config-webank/vue', + ], + globals: { + // 这里填入你的项目需要的全局变量 + // 这里值为 false 表示这个全局变量不允许被重新赋值,比如: + // + // Vue: false + }, + rules: { + 'no-plusplus': 'off', + 'no-bitwise': 'off', + 'vue/comment-directive': 'off' + } +}; diff --git a/packages/fes-cli/template/.gitignore b/packages/fes-cli/template/.gitignore new file mode 100644 index 00000000..d6cee42e --- /dev/null +++ b/packages/fes-cli/template/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +.idea +.git +.vscode +.cache +/dist +.history +/node_modules \ No newline at end of file diff --git a/packages/fes-cli/template/LICENSE b/packages/fes-cli/template/LICENSE new file mode 100644 index 00000000..23c3e60f --- /dev/null +++ b/packages/fes-cli/template/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-present harrywan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/packages/fes-cli/template/fes.config.js b/packages/fes-cli/template/fes.config.js new file mode 100644 index 00000000..e2fe8d4c --- /dev/null +++ b/packages/fes-cli/template/fes.config.js @@ -0,0 +1,140 @@ +module.exports = { + mode: 'vertical', // 可选有vertical、horizontal,默认vertical + theme: 'blue', // 可选有blue、dark,默认blue + fesName: 'xx 运营平台', // 项目名称 + favicon: 'static/favicon.ico', // 图标 + // 环境变量配置, 默认使用local环境 + env: { + // 本地开发环境 + local: { + api: '' + }, + // 测试环境 --env=sit 触发使用 + develop: { + api: '' + }, + // 生产环境 --env=prod 触发使用 + prod: { + api: '' + } + }, + // 配置角色-路由访问权限,使用FesApp.setRole('unLogin')来修改当前用户的角色,控制路由访问权限 + roles: { + unLogin: ['/home'], + service: ['/list', '/home'], + admin: ['/list', '/api/fes'] + }, + // map + map: { + status: [['1', '成功'], ['2', '失败']] + }, + // 左侧菜单配置 + menu: [ + { + title: '$i18n.menu.interface', + path: '/api', + subMenu: [ + { + title: 'Fes', + path: '/api/fes' + }, + { + title: 'FesApp', + path: '/api/fesApp' + }, + { + title: 'FesApi', + path: '/api/fesApi' + }, + { + title: 'FesMenu', + path: '/api/fesMenu' + }, + { + title: 'FesMap', + path: '/api/fesMap' + }, + { + title: 'FesFesx', + path: '/api/fesFesx' + }, + { + title: 'FesStorage', + path: '/api/fesStorage' + }, + { + title: 'FesUtil', + path: '/api/fesUtil' + } + ] + }, + { + title: '路由', + path: '/route' + }, + { + icon: 'static/bell.png', + title: '列表页', + path: '/list' + }, + { + title: '内容很多的编辑', + path: '/list/edit' + }, + { + title: '显示头部', + path: '/header' + }, + { + title: '静态资源', + path: '/static' + }, + { + title: '子路由', + path: '/layout', + subMenu: [ + { + title: '子路由A', + path: '/layout/a' + }, + { + title: '子路由B', + path: '/layout/b' + } + ] + }, + { + title: '国际化', + path: '/i18n' + } + ], + i18n: { + locale: 'en', // default zh-cn + messages: { + 'zh-cn': { + menu: { + interface: '接口' + }, + overview: '概述', + i18n: { + internationalization: '国际化,基于', + achieve: '实现。', + ui: 'UI组件' + }, + title: '标题' + }, + en: { + menu: { + interface: 'interface' + }, + overview: 'Overview', + i18n: { + internationalization: 'internationalization,base on', + achieve: 'to achieve.', + ui: 'UI components' + }, + title: 'title' + } + } + } +}; diff --git a/packages/fes-cli/template/mock.js b/packages/fes-cli/template/mock.js new file mode 100644 index 00000000..f9fcf1a8 --- /dev/null +++ b/packages/fes-cli/template/mock.js @@ -0,0 +1,113 @@ +module.exports = (cgiMock, Mock) => { + const { Random } = Mock; + + // 前缀,全局(可选) + // cgiMock.prefix = ''; + + // 返回一个数字 + cgiMock('/number', 123); + + // 返回一个json + cgiMock({ + url: '/json', + result: { + code: '400101', msg: "不合法的请求:Missing cookie 'wb_app_id' for method parameter of type String", transactionTime: '20170309171146', success: false + } + }); + + // 利用mock.js 产生随机文本 + cgiMock('/text', Random.cparagraph()); + + // 返回一个字符串 利用mock.js 产生随机字符 + cgiMock('/string', Mock.mock({ + 'string|1-10': '★' + })); + + + // 正则匹配url, 返回一个字符串 + // cgiMock(/\/abc|\/xyz/, 'regexp test!'); + + // option.result 参数如果是一个函数, 可以实现自定义返回内容, 接收的参数是是经过 express 封装的 req 和 res 对象. + // cgiMock(/\/function$/, function (req, res) { + // res.send('function test'); + // }); + + // 返回文本 fs.readFileSync + // cgiMock('/file', cgiMock.file('./test.json')); + + // 更复杂的规则配置 + cgiMock({ + url: /\/who/, + method: 'GET', + result(req, res) { + if (req.query.name === 'kwan') { + res.json({ kwan: '孤独患者' }); + } else { + res.send('Nooooooooooo'); + } + }, + headers: { + 'Content-Type': 'text/plain', + 'Content-Length': '123', + ETag: '12345' + }, + cookies: [ + { + name: 'myname', value: 'kwan', maxAge: 900000, httpOnly: true + } + ], + // 接口随机延迟 + timeout: Mock.mock({ + 'number|1000-5000': 1000 + }).number + }); + // 登录 + cgiMock('/login', (req, res) => { + res.send(JSON.stringify({ + code: '0', + msg: '', + result: { + username: '万纯(harrywan)', + roleName: '管理员' + } + })); + }); + + cgiMock('/getTestList', (req, res) => { + const list = []; + for (let i = 0; i < req.body.pageSize; i++) { + list.push({ + a: i + }); + } + res.send(JSON.stringify({ + code: '0', + msg: 'this is message', + result: { + list, + page: { + pageSize: req.body.pageSize, + currentPage: req.body.currentPage, + totalPage: 1000 + } + } + + })); + }); + + cgiMock('/getNumber', (req, res) => { + res.send(JSON.stringify({ + code: '0', + msg: 'this is message', + result: 4 + })); + }); + + cgiMock('/getRoleName', (req, res) => { + res.send(JSON.stringify({ + code: '0', + msg: 'this is message', + result: 'admin' + })); + }); +}; diff --git a/packages/fes-cli/template/package.json b/packages/fes-cli/template/package.json new file mode 100644 index 00000000..4822c03e --- /dev/null +++ b/packages/fes-cli/template/package.json @@ -0,0 +1,57 @@ +{ + "name": "@webank/fes-template", + "version": "0.1.0", + "description": "fes项目模版", + "main": "index.js", + "scripts": { + "build": "fes build", + "dev": "fes dev" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.js": [ + "eslint", + "git add" + ], + "*.fes": [ + "eslint", + "git add" + ], + "*.vue": [ + "eslint", + "git add" + ] + }, + "keywords": [ + "管理端", + "fes", + "fast", + "easy", + "strong" + ], + "files": [ + ".eslintrc.js", + ".gitignore", + "fes.config.js", + "mock.js", + "package.json", + "README.md", + "/src" + ], + "repository": { + "type": "git" + }, + "author": "harrywan qlin", + "license": "MIT", + "devDependencies": { + "@webank/eslint-config-webank": "^0.1.4", + "husky": "^3.0.9", + "lint-staged": "^9.4.2" + }, + "dependencies": {}, + "peerDependencies": {} +} diff --git a/packages/fes-cli/template/src/app.js b/packages/fes-cli/template/src/app.js new file mode 100644 index 00000000..56067030 --- /dev/null +++ b/packages/fes-cli/template/src/app.js @@ -0,0 +1,45 @@ +import './assets/styles/main.scss'; + +export default function () { + this.FesApp.set('FesName', '$i18n.title'); + + setTimeout(() => { + this.FesApp.setRole('admin', false); + }, 1000); + + // 设置退出逻辑 + this.on('fes_logout', () => { + this.FesApp.setRole('unLogin'); + this.FesStorage.set('userLogin', false); + }); + + // 设置logo点击事件 + this.on('fes_logo_click', () => { + window.Toast('你点击了LOGO'); + }); + + // 设置路由钩子 + this.FesApp.setBeforeRouter((from, to, next) => { + next(); + }); + this.FesApp.setAfterRouter((route) => { + console.log(`您浏览到了${route.path}`); + }); + + // // 设置当前角色 + // if (!this.FesStorage.get('userLogin') === true) { + // this.setRole('unLogin') + // } + + // 设置AJAX配置 + this.FesApi.option({ + }); + + // 设置响应结构 + this.FesApi.setResponse({ + successCode: '0', + codePath: 'code', + messagePath: 'msg', + resultPath: 'result' + }); +} diff --git a/packages/fes-cli/template/src/assets/images/bg.png b/packages/fes-cli/template/src/assets/images/bg.png new file mode 100644 index 0000000000000000000000000000000000000000..28a4e820b4af428f4dacb597f9d7c26c91c56663 GIT binary patch literal 6059 zcmaiYXEa=I^zIo(&FD2s^dQ=Z8l5l*ksx}Q(TOf1gBZPps8NFvMEs)HNYoj<28k{* zN<=qAH^`m;y&vv}`{BOp?6dcN&e_kq%Q|bF^}c>=q)S81K@9)^jlQ0?2>?)p6YU*J zQsTXM*T9CT@*f*M(IM*9?aSiYk&^oHqUwPUjgzIHXFq=VS=O@jU+e0p_O-PUy{zT<(OJUFH;Xg?+wfssgP&E|MM0CDLuw!K)~KRhhCPhFOE2c|MY4# zb6#Z3e?ESD<+Bx6$3*O#IqzcXyqiyg8jUR!0G5Jwy-L~*JPCe|9+n?+Cn>&}t>;&` zj-owxumE6l+ZMm8WfvB$Lp%Cnir?G2?j(*B@U&&OCOquGztJ*9mhGq|(2@evjKMxU zjBks{6Ah!9gR5IUb^(Cxv8o(W7BBDfYYW0c4r~avCSG{Iq!@nn^O7W)IKf*iCXHij z1ccqgk8=cTZFXQkw4~X?P5Jr4$wJ7=Rv!S=Ww1~{2={0N0bn}2iZ8dmBnyq|HmUxP z4^Q8*X~K$6O?o%zK>@_)#FNGJ3=Hj87lH{2T|nd=|@G@yQp(n3Lpdaq>Vu6eB`KKaCN47&P$ApG&;Cc<#=$jQ}~qt z2k^J-@MJ26M?LJHf6Q_X0tlOJZC%rj;HAcVyP{P#GqJf__aK!gjhbQY3g_iz7+|H4 zhX_A1ER67LjLpyf zG3HK%GI#_u=RPTbd`;MMeW!XFP0--TKmdqQ>sG$)8{C&V6dv__)5T8|>j=3+`1T*q zdEdamq=3wH$8B$4pSe(5iOqGi0oRR`6?5spM0f^bqzDuqXRx=0;Ij6ncTK4I&(8Ke zxX_-K2EdJ&?2|JUaj~*==Vyo27<7tYMX_&)UH~lL+nJC3X+a zU>?Cr9#RJ&GLBxP`881<681F{a5YM59`0PB*FZRhMfYh^;?0r0GlpI~WmkI^xuY8( z>Y1+KWy7kImUehrFTU_`kV#A?RJod_WNz`=@IX2J?H5MR{NNJ+f!vdK&g!!{R$ovY zO$gLuUTB)=@D+*r%KfkOjC+hONN5(z00CaXzO!zc(`f2HZ9LZvYCI4LEf_+$^oNO} z`kAYZ3?v{Y4j`nkRD-3ecb*Hrua+&!RY6A4{>7z2xy9-NcO#VjKIxgDl!;t|qS$jW zfzX24x4n15N|f?pLe=0y)E2PRkbc)}wV3%N@bAtO^5-qrcY>*e1!};K5Spcq+Y9CH zA9N)7LX~4Tw^NO;O)iaem#VmkoL{Q4J51aBQl>PALMEV3X|IwdGjPzuC9qtafN&S%rbp4T5D$W^^S2i39fZqo3uPqs_T^iJnT9M`oyw2Q zu3q)wxSfJU|6&dLm;#Sk|GIj%Wb+8#_zdHo)39cif0PMe%IM7>SGK>&v_@TD7NQvx z->QyB<}0}a*{%d^eu9=o15@JoHv#gg((&MQdJq7FVRsBwKIgSHvl`DBB znho4l|JgpZN2*T#?zsG*CB+hJTgXw!&*qP3Y(tikn zIKVfxIV0_2?1Pnh{kU`{&heWWv0~@WN3)kYVt&c-!t3|3(PV}tgr^8Tl%Cm!zNXvK z!?)@JsoVEpnl;~%+(;j})eueQxTj$}RU|J!MxCxu?pK`CX)Lv(I2fn=AWt0WyPY9p z0g~#nOTCSKPrJ_Z;ctEeRku2-Zt?Nd<^5g?pJ<4Du`@%R<9GTM(NLfS@%`Ljqlk{NA%iG?_M;T|H5`G-=5<0zkZ`&AKFpuCS$5Z?Ky7M(SvOJ`JvcfCX(-&UZtvWd_ZnfRIy+0B7RitDMK zJJd@hmiIh9IJS#2bBv8=zg8>g5I+vVDmf_5?xu%G5}B#sW_~}7Tqg$|Ei!%M9rRg# z#_YW;9n9mH>V|*3X!i%Z!TyO|jN9^<)v!VFizTO?Zgf$Hvr{3KkVqYD0ac0Q$r`HY z)cMdNc}5B$Te2wm78mLBKS{`$2j)x&Hv6cmkYm&1y?f6TGEKa7ItT6QrhRC&_;x-g zs%GDOj5&OCgEOIEV^O~09i|6UjJR_mbcN?w8pWOeii|+=J)Md3_HD;MCb64kRii4s zd!`=Z+VE2Z0=8F-q_gqM9CmISbU?j%mr% zjLwNLWmCI6bRuI47?JSr%x3qDwqdF~D{sjMR-=!2Td-m)l*eYV{UTYsT?YE36Eam4 z#R86>2b_Mh&8>{d20IHX+_v0H;Lr!fUhN7Eix$3Hv6QIR6kt!p)~Cj!Yp5O~Ywa1& zn>xOjpA!l*Bf!~gJ%ei0x5Y5Eoup5+JAWozR(3o_45yExMi$S^c=^=Q$j;Y}hN?(a^FJeb^GH@k7J2@QMa7YM z_`BJU2|jO>zV5_UwviT!pq-*&_($1(~*_Bw1SVVoIvwOjG>sA#u;v4B8d#E{I zg^rn!)Nks%Rpa)ZwWV$U}aU$la#4aC6{LfXb9Yg!bDZUVtwuisN?@ZC79KCNj#9H+F z{r7vwCQA*}r#p{yS`WIQqSgAGLt0I}(;_`8m+fQuP1Q7S(8L0MbPVIKSkG8qYjqmT zl*cX-C#0-2r-$?GI{D0Ff4Jo52{yHTo*TY|2snB5aPn%|DfvPRwRTosIeZ+TBFAF! zX>@%!cZmUvJlrBBo9{0E)b?UcodlhPxMkeP@X|ZKhy{lK*d`p(x*x&VMVqo4m)&a> z97^-Sq}vA6C!HHpd7&ur$fQNgD5B-BRs@B#YtIQ|Bg#2xKRWDl08h)0x|o`YkLAzp z{R2W!UV~K?BQv@#p})OBs6%Wh(n^Td5as#%Ed9^=pXL{~X1R~R)k%m7xi5{S#|xSn z`LKVjWTo|I{O0*Q%l=zW&+=hOh35C)5uPv?@BFFS`!)LB^(*lkf{*L=eP;0dL~b*E zQE)%{$NgfFj#@eGf$~^ux4&df`-*1M5BA#7r7VbiCMa;oesNIo(RKV{ia+7hed*`@ zRJ3d(+vixhD6|edyxFPPc$~sv!&}kA*WGKoIS+d81IJLS7@a=X*E{bkNj|Y#6UQ!< z8oN9-?o=Iu$+U2!kMXNl&)D>4J1XCkl%OLB(%O2BUy@y+b!@^F&Wu*6PhtDQ#wPEA zb#;9m+)%AOU--QBI^sFIp#D5q^6EZVu-HdZ!VPA79OX5?yq}2J+T^($^%FCj&B~l$ zlD41|kn1?5yxf~VT&hg2+oT?w)j70A)EW?p+Fz9TlPvrt2gIdj=g-_O#u#sk3|EaW z@{xb|IuSaV4HYT>{A1IK%bBnZS_+bqJk!^+h@LnV8oiNFeieXZ)jjwR2~g7C=j89g zipE};kfUQMu4~Y}#x`ny0S$=i5g5qDRx)E{{67Ep$rE|q+n}iT0C3pg6tC^tytUmi zIj0g5PSaT$OZ$y_oLu?{bKG5;K+SpdlK9Fie<8|LCS)0nev!NLLj=zVk-~Lh_Qs+g=QA^1n$5sufGr(4BuqL_ek^)d zY&_P;i_H>Z;b%)13<+acjS=;PN5}`T-iN^HME#Miom}bzzY?J1HWD)`j6?9pVAm$X znTl=S{P!4KMjU+qo^V!%IHSL%3}#F|nIE~_j_fyuGy1Uo-dmohz$gE%O817Cdmiq0 zFr!)9yt*Z)^Ndw~8ZVR`9Q(8Hed1Q>*$wQ(@z7>(9|v3t26~hgU|SY(**`!#G|<=l z>~0&v{PFS%Z$X~-sv`K=CsC|WInRTZ$`XwtZZrr@hoF!Zwb4VX3A z<2@yLAJMi=h}3aY7eFWLLoxeo5me&Dy7<4qrpwFmUwzt6%b(q(%!oScWha;d6(Etw z8%|ZUxeK|#eReTT6`pRmQ&HC!l34yPbAxS$Z}dUn$g4;Gc&D zB^+qjCBLw}UBv8}W964QkCja>K9!hdsd@$@&-fIzfS|dMbrn9Yn-#K_+DNBVKxaRs zvgO-{`;;k;r_}e_!L>dSddOZW$95Sn^4P!tt?4EVbI|o!Gg+~;xMLH^;Zf0gQ^CW$LO&;8Pqc+-B&7t?hn~CU?8oaTcql`%{-z**>f>vEA%5h$ zV=^w(AR@MNz-YEZ%i&V0-={JE^o1@tQ|G_~s9G=ToilT#eMzpe5{Km=+OXebuF@PBOxr6;@al?^>`kn-gX zAd?uw$rU=Iuq5yn{*f0m;xK3+sXST`rE>S&nS*3Rd)nG`mm4R_=`*fy^4 z^C%Q2iDSuxOA2E~*7Mu3D}+AUw;QU}*%P^dOqn~U=guV>YBBgbyBh5cEjj1N_m}8T zqKhujUiXiZ2j>K3y2J9mW*zpeYZ(=3UbkL{pv4~j~*6lx3D==F+X;EPXThV(hY)ki&`vuxz6Qbr^vyf zl+X%ggVB4Tj!lGg+eI&*-qEEeKI5+erXH&Yp$)u7V}IetRuexN%nf|~@$t!Eb~pE; zL(A%`@7VyUmqa>(qHyzJc*OJ{bw;o4Y!LCW&mMT;!a21J4(yIzWNxSv4@JFtc7Y~vB^3Ioo?t157Ov#S zV6ESU?bumq+r+#?EW(N*&>AkLRp+RIMkPqYkT)A!Et;_2@2#-(+CJa;0u)^Sf z84w|1LZB_8t;0(mh2^fm^lB?Xa(OB02g5(>Pbf&x1l z;UI(|Q7A|tzzvmO;io5C@5upn%E;8PnatWwySpGJ;FU0u5)1*zNXWwX_2HiW3SgnMzt`JL6 z#FkXbC}KV9*lg%v*r<82v6Z{_8Ey4Ee>^?E*X#HD9z?? zJIR|6s8~gcR}Z*F@kKiU<`j#8kVq82saAtW{}mKn&TF_IH|n63bT zvNQ8~-xqK!B4M*G1k+vv^qca?ZMmsv%T0?A+D0>7Fg+STapqw%G_824*^6`Nw zqVX9qm_UNp$5@IJ78WNI@-PTQQc@B;$qvrt$0AV9&dvy=EyC8;MuD&qBy)r`u?-~azZ z+3e3~fiRHypM3wPupl^@$3z4&1zZuIt{7a5=|(6X2G3{Ggj{|wmz(gZiK!RpNevbR>7X*dor~^Cv|gGtV6PJqY0WIqD87+av5s;{uD3f&nHXqLndW^_@>7G zS|2-|@LH>Kuy)CP*f-@kGAB3vm8H~M`q%mNp0TAliL3C!d9(I21K4!ZZK62SUk;|} z(heHK*R}c(J<=e5C%hAGgh&mb`a4DRr=^%ab|KcCyQ8Gtlj))k;cgnuz+$x;WFYj*V4u=8BYhF=AAETx&md;nvd*CfR$Y9 zi!_{JNdp_|Rb_(ZZL8BoaWGkkjCT;aZTGG3??fmswyOGto5oBnX{l#?6Y7VX19ohA zx!|H|HA)Isr-6a3p6(!~frKQ=`v2mOFAb6d1H{M=RVQ z;Twmko-W$2gDOHh85|ejG+gipHO5$|8e^{(v$N>)7eR?7G}x zDkmk+tZ=C9~1^MOB0ZcB`)$y&6N z1Kr@RGn(52p6j3Khel2u=#iV41*^Hb0NLWbT##RK{eDq+{5k3_Xz4+V6f^1kBOtF78u&?5U^QEw^slJe4$MjBhV*HS9mTx}aC*O_=b|)ZGn*0AE|s+uXlSY4PQx4-+OH?SF4LV~@zYywr@hUt zS{SU7=8#QGj>QMP2IKX8UIgefMl*H~zQR@-`Po^vbVyK?jVf#ctE}`fEnni+Nf7I$dGA z=0*6YDixP~_N<+mmoPYaHW!zWw=Tt|wN+7W)P>*3T3Za0R(A9Sy=ECrdh{d7x@(-; zG>-*Fr9<=+y5BoDUHZ|-+vH1-$(Yiiw5zt+)^8ep(hiwwr0L@ggZ91xJ--=Mz6G=p zWrClbxjCgQX?u1|&G`QKrIuT@8IsQEhFSi|gReFnO}#g!J&)Z|{H@1G4zl4p=))oQ z>!n87%TrCvt0AHcmAl-%a-Hzq6PT_r|P~#ifa39ikUAM=Ids6DzB- zelOn#g_{tIIu)A_JbFOODeg$U-tp|EfMq$qvoSf?<%W!G<-XKakL-%ufG^wc5>RyG{d(%D|GUNn|X zUB2MP!Uxwh`dE5(i2%hAIWZE0<-g&g$ zEdR=|%CF^HBEly5oNh-WmFSeajnx#>bmxnSWt#Gu$;L>thmg+tJS8qwKI04;)+QHk zjZH8IYnKn@;*EFAAtQW+-tn%Rdk&iPuA~6WqcaAk!GHB;kyX|G=ot}ho29N zfBeunwEb)5?a4#>GwS0`BbMcbP|n<`vuFJ7U8z<&%%pNer=j^IyX8$qxD?UN`O@8S zwMA{K1rBxKfP{imMsI)aI8s7zE4*~;$nx-Ut6_+_Rr83kUf`={foiClx#^>|nV%dx zA$^;bwo(Q)fFx}HoUn1>bnap>Mn6c>y+RYqZ{{ANerFwkIadJDWxcBM)FDn=oOS-z z=UA#lv)uto;XkXqtO|!_cscDX8m$Qlq%viI7<@zjjxhxx{-KaMtbI)9w lx!hW95m%gZd*QuS6kxat@y4p`7nhAcNfMDvxQvTB@o&h0hqV9z literal 0 HcmV?d00001 diff --git a/packages/fes-cli/template/src/assets/styles/login.scss b/packages/fes-cli/template/src/assets/styles/login.scss new file mode 100644 index 00000000..3c5a095d --- /dev/null +++ b/packages/fes-cli/template/src/assets/styles/login.scss @@ -0,0 +1,131 @@ +.login-panel { + position: absolute; + left: 0; + top: 0; + margin: 0; + right: 0; + width: 100%; + height: 100%; + background-color: $body-background; + background-image: url("../images/bg.png"); + background-position: left bottom; + background-repeat: no-repeat; + background-size: 100% auto; + font-size: 18px; + color: $black-text-color; + } + + .login-panel .login-panel-swap { + position: relative; + width: 945px; + height: 324px; + margin: 10% auto; + border-radius: $border-radius-small; + } + + .login-panel .logo { + display: inline-block; + vertical-align: middle; + width: 400px; + height: 100%; + text-align: center; + .logo-text { + display: inline-block; + vertical-align: middle; + margin-top: 130px; + font-size: 28px; + font-weight: bold; + } + } + + .login-panel .split { + display: inline-block; + background: $border-color-base; + width: 1px; + height: 180px; + vertical-align: middle; + } + + .login-panel .error { + margin-top: 10px; + width: 350px; + color: $error-color; + font-size: 14px; + .ui-icon-exclamation-circle{ + margin-right: 6px; + } + } + + .login-panel .login-form { + position: relative; + display: inline-block; + vertical-align: middle; + padding: 0 75px 0; + height: 270px; + input::-webkit-input-placeholder{ + color: $black-text-color; + } + input::-moz-placeholder { + color: $black-text-color; + } + /* ie */ + input:-ms-input-placeholder { + color: $black-text-color; + } + /* firefox 19+ */ + input:-moz-placeholder { + color: $black-text-color; + } + + input:-webkit-autofill { + -webkit-box-shadow: 0 0 0px 1000px white inset !important; + -webkit-text-fill-color: $black-text-color !important; + } + .line{ + padding-top: 30px; + border-bottom: 1px solid $border-color-split; + } + input[type="text"], + input[type="password"]{ + margin: 0; + width: 350px; + height: 40px; + line-height: 40px; + padding: 0 15px; + vertical-align: middle; + background: 0 0; + outline: 0; + border: none; + font-size: 16px; + color: $black-text-color; + } + button { + margin-top: 10px; + width: 350px; + height: 48px; + border-radius: 4px; + line-height: 46px; + border: none; + outline: 0; + background-color: $primary-color; + color: #ffffff; + cursor: pointer; + text-align: center; + font-size: 18px; + &:hover { + background-color: $selected-color; + } + } + } + +.ie-palceholder::after{ + content: '用户名'; + position: absolute; + left: 88px; + top: 38px; + font-size: 16px; +} +.ie-palceholder-password::after{ + content: '密码'; + top: 110px; +} \ No newline at end of file diff --git a/packages/fes-cli/template/src/assets/styles/main.scss b/packages/fes-cli/template/src/assets/styles/main.scss new file mode 100644 index 00000000..76e41f96 --- /dev/null +++ b/packages/fes-cli/template/src/assets/styles/main.scss @@ -0,0 +1,50 @@ +@import "variables"; +@import "login"; + +.article { + padding: 20px; + h1 { + font-size: 26px; + font-weight: 400; + margin: 12px 0; + } + + h2 { + margin: 25px 0 12px; + font-size: 20px; + font-weight: 400; + } + + h3 { + font-size: 16px; + font-weight: 400; + } + + p { + font-size: 14px; + margin: 5px; + } + + ul { + padding-left: 40px; + } + + li { + list-style-type: disc; + margin-bottom: 5px; + font-size: 14px; + } + table{ + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + border: 1px solid #e9e9e9; + width: 500px; + margin-bottom: 24px; + } + th,td { + border: 1px solid #e9e9e9; + padding: 8px 16px; + text-align: left; + } +} \ No newline at end of file diff --git a/packages/fes-cli/template/src/assets/styles/variables.scss b/packages/fes-cli/template/src/assets/styles/variables.scss new file mode 100644 index 00000000..bb87d50f --- /dev/null +++ b/packages/fes-cli/template/src/assets/styles/variables.scss @@ -0,0 +1,90 @@ +// Color +$primary-color : #3399ff; +$info-color : #2db7f5; +$success-color : #00cc66; +$warning-color : #ff9900; +$error-color : #ff5500; +$link-color : #3399ff; +$link-hover-color : #5cadff; +$link-focus-color : rgba(51,153,255, .2); +$link-active-color : #3091f2; +$selected-color : rgba($primary-color, .9); +$tooltip-color : #fff; +//辅助/图标 +$subsidiary-color : #9ea7b4; +$disabled-color : #f3f3f3; + +// Base +$body-background : #fff; +$component-background : #fff; +$font-family : "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; +$code-family : Consolas,Menlo,Courier,monospace; +$title-color : #464c5b; +$text-color : #657180; +$black-text-color : #333333; +$sub-text-color : #999; +$dark-color : #333; + +//失效 Disabled +$tip-color : #c3cbd6; +$font-size-lg : 16px; +$font-size-base : 14px; +$font-size-small : 12px; +$line-height-base : 1.5; +$line-height-computed : floor(($font-size-base * $line-height-base)); +$border-radius-base : 6px; +$border-radius-small : 4px; +$cursor-disabled : not-allowed; + +// Border color +$border-color-base : #d7dde4; // outside +$border-color-split : #e3e8ee; // inside + + +// Background color +$background-color-base : #f7f7f7; // base +$background-color-select-hover: #f3f3f3; +$tooltip-bg : rgba(70, 76, 91, .9); +$head-bg : #f9fafc; +$table-thead-bg : #f5f7f9; +$table-td-stripe-bg : #f5f7f9; +$table-td-hover-bg : #ebf7ff; +$table-td-highlight-bg : #ebf7ff; + +// Z-index +$zindex-spin : 8; +$zindex-affix : 10; +$zindex-back-top : 10; +$zindex-select : 900; +$zindex-modal : 1000; +$zindex-message : 1010; +$zindex-notification : 1010; +$zindex-tooltip : 1060; +$zindex-loading-bar : 2000; + +// Animation +$animation-time : .3s; +$transition-time : .2s; +$ease-out : cubic-bezier(0.215, 0.61, 0.355, 1); +$ease-in : cubic-bezier(0.55, 0.055, 0.675, 0.19); +$ease-in-out : cubic-bezier(0.645, 0.045, 0.355, 1); +$ease-out-back : cubic-bezier(0.12, 0.4, 0.29, 1.46); +$ease-in-back : cubic-bezier(0.71, -0.46, 0.88, 0.6); +$ease-in-out-back : cubic-bezier(0.71, -0.46, 0.29, 1.46); +$ease-out-circ : cubic-bezier(0.08, 0.82, 0.17, 1); +$ease-in-circ : cubic-bezier(0.6, 0.04, 0.98, 0.34); +$ease-in-out-circ : cubic-bezier(0.78, 0.14, 0.15, 0.86); +$ease-out-quint : cubic-bezier(0.23, 1, 0.32, 1); +$ease-in-quint : cubic-bezier(0.755, 0.05, 0.855, 0.06); +$ease-in-out-quint : cubic-bezier(0.86, 0, 0.07, 1); + +// Shadow +$shadow-color : rgba(0, 0, 0, .2); +$shadow-1-up : 0 -1px 6px $shadow-color; +$shadow-1-down : 0 1px 6px $shadow-color; +$shadow-1-left : -1px 0 6px $shadow-color; +$shadow-1-right : 1px 0 6px $shadow-color; +$shadow-2 : 0 2px 8px $shadow-color; +$box-shadow-base : $shadow-1-down; + +$mask-color: rgba(55, 55, 55, .6); diff --git a/packages/fes-cli/template/src/components/fesHeader.vue b/packages/fes-cli/template/src/components/fesHeader.vue new file mode 100644 index 00000000..22564d9c --- /dev/null +++ b/packages/fes-cli/template/src/components/fesHeader.vue @@ -0,0 +1,14 @@ + + diff --git a/packages/fes-cli/template/src/components/fesLeft.vue b/packages/fes-cli/template/src/components/fesLeft.vue new file mode 100644 index 00000000..e64ebed8 --- /dev/null +++ b/packages/fes-cli/template/src/components/fesLeft.vue @@ -0,0 +1,9 @@ + + diff --git a/packages/fes-cli/template/src/pages/api/fes/index.vue b/packages/fes-cli/template/src/pages/api/fes/index.vue new file mode 100644 index 00000000..f67abf2c --- /dev/null +++ b/packages/fes-cli/template/src/pages/api/fes/index.vue @@ -0,0 +1,74 @@ + + diff --git a/packages/fes-cli/template/src/pages/api/fesApi/index.vue b/packages/fes-cli/template/src/pages/api/fesApi/index.vue new file mode 100644 index 00000000..250925bd --- /dev/null +++ b/packages/fes-cli/template/src/pages/api/fesApi/index.vue @@ -0,0 +1,50 @@ + + diff --git a/packages/fes-cli/template/src/pages/api/fesApp/index.vue b/packages/fes-cli/template/src/pages/api/fesApp/index.vue new file mode 100644 index 00000000..f3c5ef9d --- /dev/null +++ b/packages/fes-cli/template/src/pages/api/fesApp/index.vue @@ -0,0 +1,94 @@ + + diff --git a/packages/fes-cli/template/src/pages/api/fesFesx/index.vue b/packages/fes-cli/template/src/pages/api/fesFesx/index.vue new file mode 100644 index 00000000..c1dc2d4a --- /dev/null +++ b/packages/fes-cli/template/src/pages/api/fesFesx/index.vue @@ -0,0 +1,26 @@ + + diff --git a/packages/fes-cli/template/src/pages/api/fesMap/index.vue b/packages/fes-cli/template/src/pages/api/fesMap/index.vue new file mode 100644 index 00000000..bf0f8cca --- /dev/null +++ b/packages/fes-cli/template/src/pages/api/fesMap/index.vue @@ -0,0 +1,20 @@ + + diff --git a/packages/fes-cli/template/src/pages/api/fesMenu/index.vue b/packages/fes-cli/template/src/pages/api/fesMenu/index.vue new file mode 100644 index 00000000..aaffb93e --- /dev/null +++ b/packages/fes-cli/template/src/pages/api/fesMenu/index.vue @@ -0,0 +1,129 @@ + + diff --git a/packages/fes-cli/template/src/pages/api/fesStorage/index.vue b/packages/fes-cli/template/src/pages/api/fesStorage/index.vue new file mode 100644 index 00000000..a5e469dd --- /dev/null +++ b/packages/fes-cli/template/src/pages/api/fesStorage/index.vue @@ -0,0 +1,38 @@ + + diff --git a/packages/fes-cli/template/src/pages/api/fesUtil/index.vue b/packages/fes-cli/template/src/pages/api/fesUtil/index.vue new file mode 100644 index 00000000..be19be80 --- /dev/null +++ b/packages/fes-cli/template/src/pages/api/fesUtil/index.vue @@ -0,0 +1,33 @@ + + diff --git a/packages/fes-cli/template/src/pages/header/index.vue b/packages/fes-cli/template/src/pages/header/index.vue new file mode 100644 index 00000000..98e5cdfe --- /dev/null +++ b/packages/fes-cli/template/src/pages/header/index.vue @@ -0,0 +1,77 @@ + + diff --git a/packages/fes-cli/template/src/pages/home/index.vue b/packages/fes-cli/template/src/pages/home/index.vue new file mode 100644 index 00000000..ab58795f --- /dev/null +++ b/packages/fes-cli/template/src/pages/home/index.vue @@ -0,0 +1,142 @@ + + diff --git a/packages/fes-cli/template/src/pages/i18n/index.vue b/packages/fes-cli/template/src/pages/i18n/index.vue new file mode 100644 index 00000000..b0ef9c45 --- /dev/null +++ b/packages/fes-cli/template/src/pages/i18n/index.vue @@ -0,0 +1,48 @@ + + + diff --git a/packages/fes-cli/template/src/pages/layout/a.vue b/packages/fes-cli/template/src/pages/layout/a.vue new file mode 100644 index 00000000..76f339b3 --- /dev/null +++ b/packages/fes-cli/template/src/pages/layout/a.vue @@ -0,0 +1,12 @@ + + diff --git a/packages/fes-cli/template/src/pages/layout/b.vue b/packages/fes-cli/template/src/pages/layout/b.vue new file mode 100644 index 00000000..8a6a578c --- /dev/null +++ b/packages/fes-cli/template/src/pages/layout/b.vue @@ -0,0 +1,12 @@ + + diff --git a/packages/fes-cli/template/src/pages/layout/layout.vue b/packages/fes-cli/template/src/pages/layout/layout.vue new file mode 100644 index 00000000..32df58ad --- /dev/null +++ b/packages/fes-cli/template/src/pages/layout/layout.vue @@ -0,0 +1,16 @@ + + diff --git a/packages/fes-cli/template/src/pages/list/edit/index.vue b/packages/fes-cli/template/src/pages/list/edit/index.vue new file mode 100644 index 00000000..64e8c23b --- /dev/null +++ b/packages/fes-cli/template/src/pages/list/edit/index.vue @@ -0,0 +1,89 @@ + + diff --git a/packages/fes-cli/template/src/pages/list/index.vue b/packages/fes-cli/template/src/pages/list/index.vue new file mode 100644 index 00000000..328f3c6a --- /dev/null +++ b/packages/fes-cli/template/src/pages/list/index.vue @@ -0,0 +1,84 @@ + + diff --git a/packages/fes-cli/template/src/pages/route.vue b/packages/fes-cli/template/src/pages/route.vue new file mode 100644 index 00000000..d5286533 --- /dev/null +++ b/packages/fes-cli/template/src/pages/route.vue @@ -0,0 +1,28 @@ + + diff --git a/packages/fes-cli/template/src/pages/static/index.vue b/packages/fes-cli/template/src/pages/static/index.vue new file mode 100644 index 00000000..1bdce2ad --- /dev/null +++ b/packages/fes-cli/template/src/pages/static/index.vue @@ -0,0 +1,18 @@ + + diff --git a/packages/fes-cli/template/src/static/1.txt b/packages/fes-cli/template/src/static/1.txt new file mode 100644 index 00000000..9d07aa0d --- /dev/null +++ b/packages/fes-cli/template/src/static/1.txt @@ -0,0 +1 @@ +111 \ No newline at end of file diff --git a/packages/fes-cli/template/src/static/bell.png b/packages/fes-cli/template/src/static/bell.png new file mode 100644 index 0000000000000000000000000000000000000000..8ae7067864eafd7e8807934bbae042a2cdb3cbd4 GIT binary patch literal 443 zcmV;s0Yv_ZP)Px$bxA})R5%gcR6k3@P!PX+wxDU%Mf3|4zk^Gsf`gMdxQQ-`4o;;75eXtfTOAzZ z=peYeiHn~j_z7GpNh=NHychEF&%C77%?HWdyWgL83ArE?EHce`7>)Jo`YKoj1gj;P&k zaqT4umgYjVu-|``yktkmrNS)1_fJ$QX|$n=GsH*}8zHXEV4$e0Dv6DV;#{HSaZXWw zBUai}{KrN}mQ@AYzThc8Pd)Us8^kMUG%hQDGLeVL25g(ZY@&l{4=>>DS9prop;kli zJfnb^4^1Y-+A$9>MMIlq@-O9(e<@a~F2oTJ>3ymeZuH*~;u9dgMlR lm-!v;23j`3UT>)Jfp4#5Wv8{jegpsj002ovPDHLkV1nPp!Xy9y literal 0 HcmV?d00001 diff --git a/packages/fes-cli/template/src/static/favicon.ico b/packages/fes-cli/template/src/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..82339b3b1dbbcf4550b737faf99c7774196fb8cb GIT binary patch literal 5430 zcmcgwX>3$g6n=;X+3|<}Oe_lM4}(N0C5Rv{W&J^*wo?RyAcBe}5&;u}0*OVy7L=Ay zXf2DCb|BCKWlMolQL5~P(pm(H?9=IVT4p+(_4u9l<_-5P?F_|ulQZ|;bI*6abC-9Q zk)%%2V^W_!67o1{&f}6aK$4`mIHg_yeFk(dLWd$O6g@IYf<9UzqCvr6a2=!u;tfkR z^2|^uG_Wl^+PcCf8~An;Y_eeRr06G%J;p#^&`W#&+C~cwO(V;@`5-Yh&vvE5}7=D}8hx zzSiZsXwv%)bp1v^?_?0K0r<(~hP$>PS!Oz9AM8gja~C)xcwp8umJ^iSP?sl_;1=C2bSk~ zIqV~QVl4FGK3B%d6U`1WoP*7Cv2eqV&l#JUPn+vD?W*2P%gW}`tm3iqo|;^kKr@RH zY4PD%lwX-eR~DX!e8cgN$vb75Ey(67=P7uRfkXkImj>G|>W zXT}Kf9?R3aA>af^1Lr9{g9Fh;$_Uj zO$l^k#i+>nrk<;6AmH+WGxBYsuGwFCoxNu==CgNCpi{TXRX2vbuCbO1if2-j?re3h zNurQfd;WoQ1CIgX=!LSTaoLI0hQ7}~IF*{c56&3_xvB{G$g^!>r0?n(@2eryDTfPDUI#V#9aW zg7STZ?<{>w_Rz$F;Z%C1NHmG5>^o7Q;pZ4a&N~_`xcMwODJn;w2}JlghJocb$*)|6 zM6;;npzW%G-(M|XWg}Q{^O>a?*k{U>`xbMvSSk&7lL(#*;uuFO`zov&EV%jH)Lg2% zgzt+g|Kh(*E?9z>Xq;lZelGwwpWpu*zwftvA#(Y?#rzGTQa}Ew7yi5P_g5Visdyjc z@z<=s#M9dK*LSCv{F%%UeQ!jK5^1Z6D)T6KJ>Z&m?k z4s&xt950}*S?DE)JO+L>j?`HWTD#FjJNJ5MSBZx*QRcUd+Rk}eMzi`HHqe9156*rH zyYdU2@^}@jH*Irke2V^KDKA~wEO>iR1lLNDo6Cr&JM>i#tdtUu!-(<5xroL;azZ^F zI@+pt$MaqZF3lTHjRpDvXs_3UZruscS4*2{$lJ!Zr#=q0S@2C0F-D)@+om6Pm0Qix z&hJD+4D5^7IInszx) { + if (util.isString(obj[p])) { + obj[p] = obj[p].trim(); + } else if (util.isPlainObject(obj[p])) { + trim(obj[p]); + } else if (util.isArray(obj[p])) { + trim(obj[p]); + } + }); +}; + +const requsetLog = { + data: storage.get('FES_AJAX_LOG') || [], + importantApi: {}, + creatLog(url, data, status) { + let _data; + if (data) { + _data = JSON.stringify(data); + } + if (_data && _data.length > 1000) { + data = _data.slice(0, 1000); // 大约1K + } + const now = new Date().getTime(); + const obj = { + url, + data, + timestamp: now, + status: status || 'send' + }; + if (this.data.length >= 500) { + this.data.shift(); + } + this.data.push(obj); + try { + storage.set('FES_AJAX_LOG', this.data); + } catch (e) { + storage.remove('FES_AJAX_LOG'); + this.data = [obj]; + storage.set('FES_AJAX_LOG', this.data); + } + return obj; + }, + changeLogStatus(log, newStatus) { + const logs = this.data.filter(obj => obj.timestamp === log.timestamp); + if (logs.length > 0) { + logs[0].status = newStatus; + storage.set('FES_AJAX_LOG', this.data); + } + }, + getLogByURL(url, data) { + return this.data.filter(obj => obj.url === url && JSON.stringify(data) === JSON.stringify(obj.data)); + } +}; + +const instance = axios.create({ + method: 'post', + baseURL: env.api, + timeout: 10000, + withCredentials: true +}); + +const api = { + instance, + error: {}, + constructionOfResponse: { + codePath: 'code', + successCode: '0', + messagePath: 'msg', + resultPath: 'result' + } +}; + +const getData = function (data, resultFormat) { + const _arr = ['codePath', 'messagePath', 'resultPath']; + const arr = []; const + rst = {}; + for (let i = 0; i < _arr.length; i++) { + const pathArray = resultFormat[_arr[i]].split('.'); + const pathLength = pathArray.length; + let result; + if (pathLength === 1 && pathArray[0] === '*') { + result = data; + } else { + result = data[pathArray[0]]; + } + for (let j = 1; j < pathLength; j++) { + result = result[pathArray[j]]; + if (!result) { + if (j < pathLength - 1) { + console.error(`【FEX】ConstructionOfResponse配置错误:${_arr[i]}拿到的值是undefined,请检查配置`); + } + break; + } + } + arr.push(result); + } + rst.code = arr[0]; + rst.message = arr[1]; + rst.result = arr[2]; + return rst; +}; + +const success = function (response) { + // 响应结构 + const resultFormat = (response.config && response.config.resultFormat) || api.constructionOfResponse; + // 哪些code不处理错误 + const ignoreCode = (response.config && response.config.ignoreCode) || []; + if (util.isNull(resultFormat.codePath) || util.isNull(resultFormat.successCode) + || util.isNull(resultFormat.messagePath) || util.isNull(resultFormat.resultPath)) { + console.error('【FEX】Api配置错误: 请调用setConstructionOfResponse来设置API的响应结构'); + return null; + } + + let data; + if (util.isString(response.data)) { + data = JSON.parse(response.data); + } else if (util.isObject(response.data)) { + data = response.data; + } else { + throw new Error(util.format('fesMessages.defaultError')); + } + + const { code, message, result } = getData(data, resultFormat); + + if (code !== resultFormat.successCode) { + let _message = ''; + if (api.error[code]) { + api.error[code].forEach(fn => fn(response)); + } else if (!ignoreCode.includes(code) && ignoreCode !== '*') { + _message = message || util.format('fesMessages.defaultError'); + } + const error = new Error(_message); + error.response = response; + throw error; + } + return result || {}; +}; + +const fail = function (error) { + let _message = ''; + const response = error.response; + if (response && api.error[response.status]) { + api.error[response.status].forEach(fn => fn(response)); + } else { + _message = util.format('fesMessages.defaultError'); + try { + if (response && response.data) { + let data; + if (util.isString(response.data)) { + data = JSON.parse(response.data); + } else if (util.isObject(response.data)) { + data = response.data; + } + if (data) { + const { message } = getData(data, (response.config && response.config.resultFormat) || api.constructionOfResponse); + _message = message; + } + } + } catch (e) { + // 可以啥都不做 + } + } + error.message = _message; + throw error; +}; + +const param = function (url, data, option) { + const method = instance.defaults.method || 'post'; + if (util.isNull(url)) { + return console.error('请传入URL'); + } if (!util.isNull(url) && util.isNull(data) && util.isNull(option)) { + option = { + method + }; + } else if (!util.isNull(url) && !util.isNull(data) && util.isNull(option)) { + option = { + method + }; + if (util.isString(data)) { + option.method = data; + } else if (util.isObject(data)) { + option.data = data; + } + } else if (!util.isNull(url) && !util.isNull(data) && !util.isNull(option)) { + if (!util.isObject(data)) { + data = {}; + } + if (util.isString(option)) { + option = { + method: option + }; + } else if (util.isObject(option)) { + option.method = option.method || method; + } else { + option = { + method + }; + } + if (option.method === 'get' || option.method === 'delete' || option.method === 'head' || option.method === 'options') { + option.params = data; + } + if (option.method === 'post' || option.method === 'put' || option.method === 'patch') { + option.data = data; + } + } + // 过滤参数中的空格 + const _data = option.params || option.data; + if (_data && util.isObject(_data) && option.trim !== false) { + trim(_data); + } + + option.url = url; + + // 如果传了button + if (option.button) { + option.button.currentDisabled = true; + } + + return instance.request(option); +}; + +const action = function (url, data, option) { + // 记录日志 + const log = requsetLog.creatLog(url, data); + + return param(url, data, option) + .then(success, fail) + .then((response) => { + requsetLog.changeLogStatus(log, 'success'); + if (option && option.button) { + option.button.currentDisabled = false; + } + return response; + }) + .catch((error) => { + requsetLog.changeLogStatus(log, 'fail'); + if (option && option.button) { + option.button.currentDisabled = false; + } + error.message && window.Toast.error(error.message); + throw error; + }); +}; + +api.fetch = function (url, data, option) { + if (requsetLog.importantApi[url]) { + const logs = requsetLog.getLogByURL(url, data); + if (logs.length > 0) { + const compareLog = logs[logs.length - 1]; + if (compareLog.status === 'compare') { + requsetLog.creatLog(url, data, 'notAllowed'); + return { + then: () => {} + }; + } + const importantApiOption = requsetLog.importantApi[url]; + const control = importantApiOption.control || 10000; + const message = importantApiOption.message || util.format('fesMessages.importInterfaceTip', { s: control / 1000 }); + if (new Date().getTime() - compareLog.timestamp < control) { + const oldStatus = compareLog.status; + requsetLog.changeLogStatus(compareLog, 'compare'); + return new Promise(((resolve, reject) => { + window.Message.confirm(util.format('fesMessages.tip'), message).then((index) => { + if (compareLog.status === 'compare') { + requsetLog.changeLogStatus(compareLog, oldStatus); + } + if (index === 0) { + resolve(action(url, data, option)); + } else { + reject(new Error('不允许相同操作间隔过小')); + } + }); + })); + } + return action(url, data, option); + } + return action(url, data, option); + } + return action(url, data, option); +}; + +/** + * 设置 request Header + * @param headers Object + */ +api.setHeader = function (headers = {}) { + Object.keys(headers).forEach((p) => { + if (['delete', 'get', 'head', 'post', 'put', 'patch', 'common'].includes(p)) { + instance.defaults.headers[p] = Object.assign({}, instance.defaults.headers[p], headers[p]); + } else { + instance.defaults.headers.common[p] = headers[p]; + } + }); +}; + +/** + * 配置ajax请求参数 + * @param option + */ +api.option = function (option = {}) { + const { + root, + baseURL, + timeout, + headers, + config, + ...others + } = option; + if (root || baseURL) { + instance.defaults.baseURL = root || baseURL; + } + if (timeout && util.isNumber(timeout)) { + instance.defaults.timeout = timeout; + } + if (headers) { + api.setHeader(headers); + } + const otherPropertys = Object.assign({}, others, config); + Object.keys(otherPropertys).forEach((p) => { + instance.defaults[p] = otherPropertys[p]; + }); +}; + +/** + * 请求拦截器 + * @param before function 请求之前的拦截器 + */ +api.setReqInterceptor = function (before, error) { + if (Array.isArray(before)) { + return instance.interceptors.request.use(...before); + } + return instance.interceptors.request.use(before, error); +}; +api.ejectReqInterceptor = function (interceptor) { + return instance.interceptors.request.eject(interceptor); +}; + +/** + * 响应拦截器 + * @param after function 响应之后的拦截器 + */ +api.setResInterceptor = function (after, error) { + if (Array.isArray(after)) { + return instance.interceptors.response.use(...after); + } + return instance.interceptors.response.use(after, error); +}; +api.ejectResInterceptor = function (interceptor) { + return instance.interceptors.response.eject(interceptor); +}; + +/** + * 配置错误响应 + * @param option + */ +api.setError = function (option) { + if (option && util.isObject(option)) { + Object.keys(option).forEach((key) => { + if (!util.isArray(api.error[key])) { + api.error[key] = []; + } + api.error[key].push(option[key]); + }); + } +}; + +/** + * 设置响应结构 + * @param constructionOfResponse + */ +api.setResponse = function (constructionOfResponse) { + this.constructionOfResponse = constructionOfResponse; +}; + +/** + * 配置重要请求 + */ +api.setImportant = function (option) { + if (option && util.isObject(option)) { + requsetLog.importantApi = option; + } else { + console.error('【FEX】ImportantApi配置错误: 参数必须是对象{"/get": { message:"xxx", control: 10000 } }'); + } +}; + +export default api; diff --git a/packages/fes-core/src/app.js b/packages/fes-core/src/app.js new file mode 100644 index 00000000..84a20634 --- /dev/null +++ b/packages/fes-core/src/app.js @@ -0,0 +1,9 @@ +import './polyfill'; +// eslint-disable-next-line +import '@webank/fes-ui/dist/styles/fes-ui.css'; +import './views/styles/index.scss'; +// eslint-disable-next-line +import init from 'projectRoot/src/app.js'; +import App from './instance/app'; + +App.init(init); diff --git a/packages/fes-core/src/config/index.js b/packages/fes-core/src/config/index.js new file mode 100644 index 00000000..f885e93d --- /dev/null +++ b/packages/fes-core/src/config/index.js @@ -0,0 +1,61 @@ +// eslint-disable-next-line +import fesConfig from 'projectRoot/fes.config.js'; + +// 设置默认 +if (!fesConfig.mode) { + fesConfig.mode = 'vertical'; +} + +if (!fesConfig.theme) { + fesConfig.theme = 'blue'; +} + +if (!fesConfig.env) { + fesConfig.env = {}; +} + +if (!fesConfig.roles) { + fesConfig.roles = {}; +} + +if (!fesConfig.menu) { + fesConfig.menu = []; +} + +if (!fesConfig.i18n) { + fesConfig.i18n = { + locale: 'zh-cn', + messages: { + } + }; +} +if (!fesConfig.i18n.locale) { + fesConfig.i18n.locale = 'zh-cn'; +} +if (!fesConfig.i18n.messages) { + fesConfig.i18n.messages = {}; +} +if (!fesConfig.i18n.messages['zh-cn']) { + fesConfig.i18n.messages['zh-cn'] = {}; +} +if (!fesConfig.i18n.messages.en) { + fesConfig.i18n.messages.en = {}; +} +Object.assign(fesConfig.i18n.messages['zh-cn'], { + fesMessages: { + defaultError: '后台接口异常,请联系开发处理!', + importInterfaceTip: '两个相同请求间隔小于 {s} 秒,是否继续?', + tip: '提示', + noPermission: '您没有访问当前路径的权限' + } +}); +Object.assign(fesConfig.i18n.messages.en, { + fesMessages: { + defaultError: 'Server-end API error, please contact the admin.', + importInterfaceTip: 'Repetitive request in {s} seconds, continue anyway?', + tip: 'Tips', + noPermission: 'You don’t have the authority to access.' + } +}); + +export default fesConfig; diff --git a/packages/fes-core/src/directive/index.js b/packages/fes-core/src/directive/index.js new file mode 100644 index 00000000..e30be449 --- /dev/null +++ b/packages/fes-core/src/directive/index.js @@ -0,0 +1,22 @@ +// TODO runtime 实例和具体功能解耦 +/*eslint-disable */ +import app from '../instance/app'; + +/** + * 常用的指令 + */ +export const permission = { + bind(el, binding) { + const dispaly = el.style.display; + const setDispaly = () => { + const urls = app.getAllowPage() || []; + if (urls.indexOf(binding.value) === -1) { + el.style.display = 'none'; + } else { + el.style.display = dispaly; + } + }; + setDispaly(); + app.FesUtil.event.on('fes_allowPage_change', setDispaly); + } +}; diff --git a/packages/fes-core/src/env/index.js b/packages/fes-core/src/env/index.js new file mode 100644 index 00000000..bd46bbdb --- /dev/null +++ b/packages/fes-core/src/env/index.js @@ -0,0 +1,3 @@ +import fesConfig from '../config'; + +export default fesConfig.env[process.privateFesEnv.env] || {}; diff --git a/packages/fes-core/src/fesx/_fesx.js b/packages/fes-core/src/fesx/_fesx.js new file mode 100644 index 00000000..1672d8a4 --- /dev/null +++ b/packages/fes-core/src/fesx/_fesx.js @@ -0,0 +1,4 @@ +import FesxClass from './fesx'; + +const insideName = `inside_${window.location.pathname.replace(/\//g, '_')}`; +export default new FesxClass(insideName); diff --git a/packages/fes-core/src/fesx/fesx.js b/packages/fes-core/src/fesx/fesx.js new file mode 100644 index 00000000..ff4e4c3c --- /dev/null +++ b/packages/fes-core/src/fesx/fesx.js @@ -0,0 +1,56 @@ +/** + * 全局状态管理 + */ +import Vue from 'vue'; +import storage from '../storage'; +import util from '../util'; + +class Fesx { + constructor(name) { + Object.defineProperty(this, 'name', { + value: name, + enumerable: false + }); + Object.defineProperty(this, 'pre', { + value: `FesFesx_${this.name}_`, + enumerable: false + }); + const keys = Object.keys(sessionStorage); + const len = keys.length; + for (let i = 0; i < len; i++) { + const key = keys[i]; + if (key.indexOf(this.pre) === 0) { + Vue.set(this, key.slice(this.pre.length), storage.get(key)); + } + } + } + + get(prop) { + if (!this[prop]) { + this.set(prop, storage.get(this.pre + prop)); + } + return this[prop]; + } + + set(prop, value) { + Vue.set(this, prop, value); + if (!util.isFunction(value)) { + storage.set(this.pre + prop, value); + } + return this; + } + + clear() { + const keys = Object.keys(sessionStorage); + const len = keys.length; + for (let i = 0; i < len; i++) { + const key = keys[i]; + if (key.indexOf(this.pre) === 0) { + storage.remove(key); + Vue.set(this, key.slice(this.pre.length), undefined); + } + } + } +} + +export default Fesx; diff --git a/packages/fes-core/src/fesx/index.js b/packages/fes-core/src/fesx/index.js new file mode 100644 index 00000000..f5b9f781 --- /dev/null +++ b/packages/fes-core/src/fesx/index.js @@ -0,0 +1,9 @@ +/** + * 全局状态管理 + */ + +import Fesx from './fesx'; + +const collection = new Fesx('outside'); + +export default collection; diff --git a/packages/fes-core/src/filter/index.js b/packages/fes-core/src/filter/index.js new file mode 100644 index 00000000..439ff2dc --- /dev/null +++ b/packages/fes-core/src/filter/index.js @@ -0,0 +1,154 @@ +/** + * 常用的过滤器 + */ +import util from '../util'; + +/** + * 日期格式化 + * @param _date + * @param format + * @returns {*} + */ +export function date(timestap, format) { + if (!timestap) return ''; + format = format || 'yyyy-MM-dd hh:mm:ss'; + timestap = Number(timestap); + const time = new Date(timestap); + const obj = { + 'y+': time.getFullYear(), + 'M+': time.getMonth() + 1, + 'd+': time.getDate(), + 'h+': time.getHours(), + 'm+': time.getMinutes(), + 's+': time.getSeconds() + }; + + if (new RegExp('(y+)').test(format)) { + format = format.replace(RegExp.$1, obj['y+']); + } + Object.keys(obj).forEach((j) => { + if (new RegExp(`(${j})`).test(format)) { + format = format.replace(RegExp.$1, (RegExp.$1.length === 1) ? (obj[j]) : ((`00${obj[j]}`).substr((`${obj[j]}`).length))); + } + }); + return format; +} + +/** + * 资金格式化插件 + * @param value + * @returns {string|*} + */ +export function money(value) { + const m = []; + value = Number(value).toFixed(2); + // 获取小数部分 + const decimals = value.match(/\.[0-9]*/g); + // 获取整数部分 + const integer = parseInt(value, 10).toString(); + const temp = integer.split(''); + const length = temp.length; + + // 添加","分隔符 + function formart() { + let count = 0; + for (let n = length; n > 0; n--, count++) { + if (count && count % 3 === 0) { + m.unshift(','); + count = 0; + } + m.unshift(temp.pop()); + } + const result = m.join(''); + return decimals ? result.concat(decimals) : result; + } + + return length > 3 ? formart() : value; +} + +/** + * 银行卡,四位加一空格 + * @param value + * @returns {*} + */ +export function card(value) { + value = `${value}`; + const reg = /([0-9]{4})/g; + if (value) { + value = value.replace(reg, '$1 '); + } + return value; +} + +/** + * 给字符串中间加*** + * @param value + * @param frontLen + * @param backLen + * @returns {*} + */ +export function safety(value, frontLen, backLen) { + if (value) { + const len = value.length; + let front = ''; + let back = ''; + if (frontLen && len > frontLen) { + front = value.slice(0, frontLen); + } + if (backLen && len > (frontLen + backLen)) { + back = value.slice(len - backLen); + } + return `${front}***${back}`; + } + return ''; +} + +/** + * 把数据字典中的值转换成text + * @param value + * @param arr + * @returns {string} + */ +export function map(value, arr) { + let name = ''; + if (arr && util.isArray(arr)) { + arr.forEach((item) => { + if (item.value === value) { + name = item.text; + } + }); + } + return name; +} + +/** + * 过滤掉数据中的值 + * @param value + * @param arr + * @returns {string} + */ +export function allow(value, arr) { + const _arr = []; + if (util.isArray(value)) { + value.forEach((obj) => { + if (util.isArray(arr)) { + if (arr.indexOf(obj.value) !== -1) { + _arr.push(obj); + } + } + }); + } + return _arr; +} + +export function capitalize(text) { + return text[0].toUpperCase() + text.slice(1); +} + +export function uppercase(text) { + return text.toUpperCase(); +} + +export function lowercase(text) { + return text.toLowerCase(); +} diff --git a/packages/fes-core/src/index.html b/packages/fes-core/src/index.html new file mode 100644 index 00000000..a207c0c7 --- /dev/null +++ b/packages/fes-core/src/index.html @@ -0,0 +1,16 @@ + + + + Fes + + + + + + + + + +
+ + diff --git a/packages/fes-core/src/instance/app.js b/packages/fes-core/src/instance/app.js new file mode 100644 index 00000000..1b95949a --- /dev/null +++ b/packages/fes-core/src/instance/app.js @@ -0,0 +1,328 @@ +import Vue from 'vue'; +import VueRouter from 'vue-router'; +import VueI18n from 'vue-i18n'; +// eslint-disable-next-line +import UiWebank from '@webank/fes-ui'; +// eslint-disable-next-line +import routerConfig from 'projectRoot/.cache/routeConfig.js'; +// eslint-disable-next-line +import commonCompConfig from 'projectRoot/.cache/commonComp.js'; +import Page from './page'; +import fesComponents from '../views/components'; +import root from '../views/layout/root.vue'; + +import * as filters from '../filter'; +// eslint-disable-next-line +import * as directives from '../directive'; + + +import util from '../util'; +import _fesx from '../fesx/_fesx'; +import storage from '../storage'; +import api from '../api'; +import map from '../map'; +import fesx from '../fesx'; +import fesConfig from '../config'; +import env from '../env'; +import permission from './permission'; + + +if (process.privateFesEnv.env !== 'prod') { + Vue.config.debug = true; + Vue.config.devtools = true; +} + +const rolesConfig = fesConfig.roles; + +class App { + constructor() { + this.FesApp = this; + this.FesApi = api; + this.FesStorage = storage; + this.FesMap = map; + this.FesFesx = fesx; + this.FesUtil = util; + this.FesEnv = env; + + // 允许的路由 + // 默认可以访问所有路由,第一次addAllowPage的时候需要删除'*' + this._roleId = _fesx.get('FesRoleId'); + if (this._roleId) { + permission.set(rolesConfig[this._roleId] || ['*']); + } else { + permission.set(_fesx.get('FesAllowPageList') || ['*']); + } + + this.router = null; + this.beforeRouter = null; + this.afterRouter = null; + + this.i18n = null; + } + + init(func) { + window.Vue = Vue; + + // ======================安装插件==================== + Vue.use(VueRouter); + Vue.use(UiWebank); + Vue.use(VueI18n); + Vue.use(fesComponents); + Vue.use(Page, this); + + // =====================注册全局过滤器================ + Object.keys(filters).forEach((p) => { + Vue.filter(p, filters[p]); + }); + + // =====================注册全局组件================== + Object.keys(commonCompConfig).forEach((p) => { + Vue.component(p, commonCompConfig[p]); + }); + + // =====================注册全局指令================== + Object.keys(directives).forEach((p) => { + Vue.directive(p, directives[p]); + }); + + // 设置系统名称 + if (fesConfig.fesName) { + this.set('FesName', fesConfig.fesName); + } + + // 设置系统名称 + if (fesConfig.favicon) { + this.setFavicon(fesConfig.favicon); + } + + if (util.isFunction(func)) { + func.call(this); + } + + this.run(); + } + + run() { + this.creatRouter(); + this.creatI18n(); + // eslint-disable-next-line + new Vue({ + el: '#app', + extends: root, + router: this.router, + i18n: this.i18n + }); + } + + creatI18n() { + this.i18n = new VueI18n(fesConfig.i18n); + this.setLocale(fesConfig.i18n.locale); + } + + creatRouter() { + this.router = new VueRouter({ + routes: routerConfig, + scrollBehavior(to, from, savedPosition) { + if (savedPosition) { + return savedPosition; + } + return { + x: 0, + y: 0 + }; + } + }); + this.handleRouter(); + } + + handleRouter() { + this.router.beforeEach(async (to, from, next) => { + util.history.record(to.path); + let path; + if (to.matched.length === 1) { + path = to.matched[0].path; + } else { + path = to.path; + } + // 只有允许的路由才能进 + const canRoute = await permission.match(path); + if (canRoute) { + if (this.beforeRouter && util.isFunction(this.beforeRouter)) { + this.beforeRouter(to, from, next); + } else { + next(); + } + } else { + window.Toast.error(util.format('fesMessages.noPermission')); + if (from.path) { + next(false); + } else { + next('/'); + } + } + }); + this.router.afterEach((route) => { + // 更新页面的title + let title; + fesConfig.menu.forEach((parent) => { + if (parent.path === route.path) { + title = parent.title; + } else if (parent.subMenu && parent.subMenu.length > 0) { + parent.subMenu.forEach((son) => { + if (son.path === route.path) { + title = son.title; + } + }); + } + }); + // 设置切换路由时页面的标题 + let fesName = this.get('FesName'); + if (fesName.slice(0, 6) === '$i18n.') { + fesName = util.format(fesName.slice(6)); + } + document.title = title ? `${fesName} | ${title}` : fesName; + + if (this.afterRouter && util.isFunction(this.afterRouter)) { + this.afterRouter(route); + } + }); + this.setDefaultPage(); + } + + async getDefaultPage(update) { + // 如果router已初始化,通过当前链接来找路由,返回当前链接对应的路由 + if (this.router && !update) { + const currentPath = this.router.history.getCurrentLocation(); + const isMatchCurrentPath = await permission.match(currentPath); + if (isMatchCurrentPath) { + return currentPath; + } + } + // 返回权限列表第一个 > 路由表第一个 + const allAllowedRoute = await permission.get(); + return allAllowedRoute.length > 0 ? allAllowedRoute[0] : routerConfig[0]; + } + + async setDefaultPage() { + const defaultPage = await this.getDefaultPage(true); + this.router.addRoutes([{ + path: '/', + redirect: () => defaultPage + }]); + } + + async setRole(roleId, redirect = true, update = true) { + if (_fesx.get('FesRoleId') !== roleId) { + if (rolesConfig[roleId] instanceof Array) { + permission.set(rolesConfig[roleId]); + this.set('FesRoleId', roleId); + if (this.router && redirect) { + const defaultPage = await this.getDefaultPage(update); + this.router.push(defaultPage); + } + util.event.trigger('fes_allowPage_change'); + } else { + console.error(`rolesConfig配置错误,不存在角色${roleId}`); + } + } + return this; + } + + async setAllowPage(pageList, redirect = true, update = true) { + if (pageList instanceof Array) { + permission.set(pageList); + this.set('FesRoleId', ''); // 通过角色控制权限和通过路由控制权限互斥,只能使用一种 + this.set('FesAllowPageList', pageList); + if (this.router && redirect) { + const defaultPage = await this.getDefaultPage(update); + this.router.push(defaultPage); + } + util.event.trigger('fes_allowPage_change'); + } + return this; + } + + // 废弃 API + getAllowPage() { + // 异步的这里会造成 break; + return permission.getSync(); + } + + getAllowPageAsync() { + return permission.get(); + } + + get(prop) { + return _fesx.get(prop); + } + + set(prop, value) { + _fesx.set(prop, value); + return this; + } + + // 添加过滤器 + addFilter(name, func) { + Vue.filter(name, func); + return this; + } + + // 添加指令 + addDirective(name, option) { + Vue.directive(name, option); + return this; + } + + // 添加组件 + addComponent(name, c) { + Vue.component(name, c); + return this; + } + + // 第三方插件 + addThrid(name, option) { + Vue.use(name, option); + return this; + } + + setBeforeRouter(beforeRouter) { + this.beforeRouter = beforeRouter; + return this; + } + + setAfterRouter(afterRouter) { + this.afterRouter = afterRouter; + return this; + } + + // 添加favicon + setFavicon(url) { + let favicon = document.querySelector('#favicon'); + if (!favicon) { + favicon = document.createElement('link'); + favicon.id = 'favicon'; + favicon.rel = 'shortcut icon'; + favicon.type = 'image/png'; + favicon.href = url; + document.head.appendChild(favicon); + } else { + favicon.href = url; + } + return this; + } + + setLocale(lang) { + // 修改vue-i18n的语言 + this.i18n.locale = lang; + // 修改组件库的语言 + UiWebank.i18n.setLocale(lang); + return this; + } +} + +util.merge(App.prototype, util.event); +// 暂时去掉package.json引入,安全检测不通过 +// App.prototype.version = packageConfig.version; +App.prototype.engine = 'Vue'; + +export default new App(); diff --git a/packages/fes-core/src/instance/page.js b/packages/fes-core/src/instance/page.js new file mode 100644 index 00000000..b0b72a30 --- /dev/null +++ b/packages/fes-core/src/instance/page.js @@ -0,0 +1,122 @@ +import util from '../util'; +import storage from '../storage'; +import api from '../api'; +import map from '../map'; +import fesx from '../fesx'; +import env from '../env'; +import fesConfig from '../config'; + +const fesDataCache = {}; + +const Page = { + install(Vue, App) { + Vue.mixin({ + data() { + const data = { + FesMap: map, + FesFesx: fesx + }; + + // 如果存在页面缓存 + const cacheName = this.$options.FesDataCache; + if (cacheName && fesDataCache[cacheName] && util.history.current.type !== 'forward') { + return fesDataCache[cacheName]; + } + if (this.$options.FesSyncData) { + Object.keys(this.$options.FesSyncData).forEach((p) => { + data[p] = null; + }); + } + let fesData; + if (util.isFunction(this.$options.FesData)) { + this.FesFesx = fesx; + this.FesMap = map; + fesData = this.$options.FesData.call(this); + } else { + // 直接等于,是对象的引用,会导致下次进入页面,FesData的值没变 + fesData = this.$options.FesData; + } + if (fesData) { + Object.keys(fesData).forEach((p) => { + data[p] = fesData[p]; + }); + } + return data; + }, + created() { + // route切换时,重新设置为初始值 + const comp = (this.$route && this.$route.matched) || []; + if (comp.length > 0) { + const matchPage = comp[comp.length - 1].components.default; + if (this.$options.__file === matchPage.__file) { + const defaultHeader = fesConfig.FesHeader === undefined ? false : fesConfig.FesHeader; + const defaultLeft = fesConfig.FesLeft === undefined ? true : fesConfig.FesLeft; + if (typeof matchPage.FesHeader === 'boolean') { + this.$root.header = matchPage.FesHeader; + } else { + this.$root.header = defaultHeader; + } + if (typeof matchPage.FesLeft === 'boolean') { + this.$root.left = matchPage.FesLeft; + } else { + this.$root.left = defaultLeft; + } + } + } + + const syncData = this.$options.FesSyncData; + if (syncData) { + const arr = []; + Object.keys(syncData).forEach((p) => { + if (util.isArray(syncData[p])) { + arr.push([p, syncData[p][0], syncData[p][1]]); + } else { + console.error(`【FEX】异步参数【${p}】配置错误:值不是数组`, syncData[p]); + } + }); + const requests = []; + for (let i = 0; i < arr.length; i++) { + requests.push(api.fetch(arr[i][1], util.merge({}, this.$route.params, this.$route.query, arr[i][2]))); + } + Promise.all(requests).then((values) => { + values.forEach((value, index) => { + this[arr[index][0]] = value; + }); + }); + } + + if (this.$options.FesCreated && util.isFunction(this.$options.FesCreated)) { + this.$options.FesCreated.call(this); + } + }, + mounted() { + if (this.$options.FesReady && util.isFunction(this.$options.FesReady)) { + this.$options.FesReady.call(this); + } + }, + beforeDestroy() { + const cacheName = this.$options.FesDataCache; + if (cacheName) { + fesDataCache[cacheName] = this.$data; + } + if (this.$options.FesBeforeDestroy && util.isFunction(this.$options.FesBeforeDestroy)) { + this.$options.FesBeforeDestroy.call(this); + } + }, + destroyed() { + if (this.$options.FesDestroy && util.isFunction(this.$options.FesDestroy)) { + this.$options.FesDestroy.call(this); + } + } + }); + + // 注入自己的对象 + Vue.prototype.FesApp = App; + Vue.prototype.FesUtil = util; + Vue.prototype.FesStorage = storage; + Vue.prototype.FesApi = api; + Vue.prototype.FesEnv = env; + } +}; + +export default Page; diff --git a/packages/fes-core/src/instance/permission.js b/packages/fes-core/src/instance/permission.js new file mode 100644 index 00000000..4182f106 --- /dev/null +++ b/packages/fes-core/src/instance/permission.js @@ -0,0 +1,34 @@ +/** + * 用户路由控制 + */ +import util from '../util'; + +const permission = { + allowRoutesSync: [], // 兼容老的 API 请勿使用 + allowRoutes: [], + format(allowRoutes) { + if (Array.isArray(allowRoutes)) { + return allowRoutes.map(allow => Promise.resolve(allow)); + } + return [Promise.resolve(allowRoutes)]; + }, + set(data) { + this.allowRoutesSync = data; + this.allowRoutes = this.format(data); + }, + getSync() { + return this.allowRoutesSync; + }, + get() { + return Promise.all(this.allowRoutes).then(data => data.reduce((merge, cur) => merge.concat(cur), [])); + }, + merge(data) { + this.allowRoutes = this.allowRoutes.concat(this.format(data)); + }, + async match(path) { + const mergedAllowRoutes = await this.get(); + return util.canRoute(path, mergedAllowRoutes); + } +}; + +export default permission; diff --git a/packages/fes-core/src/map/index.js b/packages/fes-core/src/map/index.js new file mode 100644 index 00000000..3c5e946e --- /dev/null +++ b/packages/fes-core/src/map/index.js @@ -0,0 +1,42 @@ +/** + * 数据字典管理 + */ +import util from '../util'; +import fesConfig from '../config'; + +const data = fesConfig.map; + +const $Map = Object.create({ + getValueByName(name, text) { + // TODO 不确定这里是否需要 === + // eslint-disable-next-line + const arr = this[name].filter(item => item.text == text); + return arr[0] ? arr[0].value : ''; + }, + getNameByValue(name, value) { + // TODO 不确定这里是否需要 === + // eslint-disable-next-line + const arr = this[name].filter(item => item.value == value); + return arr[0] ? arr[0].text : ''; + } +}); + +Object.keys(data).forEach((name) => { + $Map[name] = []; + if (util.isArray(data[name])) { + data[name].forEach((item) => { + if (item.length >= 2) { + $Map[name].push({ + value: item[0], + text: item[1] + }); + } else { + console.error(`【FEX】Map配置错误:Name${name}的值必输是数组,类似['1', '成功']`, item); + } + }); + } else { + console.error('【FEX】Map配置错误:后面的值必须是数组', data[name]); + } +}); + +export default $Map; diff --git a/packages/fes-core/src/polyfill/index.js b/packages/fes-core/src/polyfill/index.js new file mode 100644 index 00000000..ec8d06b5 --- /dev/null +++ b/packages/fes-core/src/polyfill/index.js @@ -0,0 +1,48 @@ +/* eslint-disable */ +class File { + toString() { + console.log('compatible File'); + return 'function File() { [native code] }'; + } +} + +if (window.File === undefined) { + window.File = File; +} + +// el remove +(function (arr) { + arr.forEach((item) => { + if (item.hasOwnProperty('remove')) { + return; + } + Object.defineProperty(item, 'remove', { + configurable: true, + enumerable: true, + writable: true, + value: function remove() { + if (this.parentNode !== null) this.parentNode.removeChild(this); + } + }); + }); +}([Element.prototype, CharacterData.prototype, DocumentType.prototype])); + + +// Function.bind +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== 'function') { + throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + const aArgs = Array.prototype.slice.call(arguments, 1); + const fToBind = this; + const fNOP = function () {}; + const fBound = function () { + return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, + aArgs.concat(Array.prototype.slice.call(arguments))); + }; + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + return fBound; + }; +} diff --git a/packages/fes-core/src/storage/index.js b/packages/fes-core/src/storage/index.js new file mode 100644 index 00000000..3f8eb81e --- /dev/null +++ b/packages/fes-core/src/storage/index.js @@ -0,0 +1,183 @@ +/* \ +|*| +|*| :: cookies.js :: +|*| +|*| A complete cookies reader/writer framework with full unicode support. +|*| +|*| https://developer.mozilla.org/en-US/docs/DOM/document.cookie +|*| +|*| This framework is released under the GNU Public License, version 3 or later. +|*| http://www.gnu.org/licenses/gpl-3.0-standalone.html +|*| +|*| Syntaxes: +|*| +|*| * docCookies.setItem(name, value[, end[, path[, domain[, secure]]]]) +|*| * docCookies.getItem(name) +|*| * docCookies.removeItem(name[, path], domain) +|*| * docCookies.hasItem(name) +|*| * docCookies.keys() +|*| +\ */ + +const docCookies = { + getItem(sKey) { + return decodeURIComponent(document.cookie.replace(new RegExp(`(?:(?:^|.*;)\\s*${encodeURIComponent(sKey).replace(/[-.+*]/g, '\\$&')}\\s*\\=\\s*([^;]*).*$)|^.*$`), '$1')) || null; + }, + setItem(sKey, sValue, vEnd, sPath, sDomain, bSecure) { + if (!sKey || /^(?:expires|max-age|path|domain|secure)$/i.test(sKey)) { + return false; + } + let sExpires = ''; + if (vEnd) { + switch (vEnd.constructor) { + case Number: + sExpires = vEnd === Infinity ? '; expires=Fri, 31 Dec 9999 23:59:59 GMT' : `; max-age=${vEnd}`; + break; + case String: + sExpires = `; expires=${vEnd}`; + break; + case Date: + sExpires = `; expires=${vEnd.toUTCString()}`; + break; + default: break; + } + } + document.cookie = `${encodeURIComponent(sKey)}=${encodeURIComponent(sValue)}${sExpires}${sDomain ? `; domain=${sDomain}` : ''}${sPath ? `; path=${sPath}` : ''}${bSecure ? '; secure' : ''}`; + return true; + }, + removeItem(sKey, sPath, sDomain) { + if (!sKey || !this.hasItem(sKey)) { + return false; + } + document.cookie = `${encodeURIComponent(sKey)}=; expires=Thu, 01 Jan 1970 00:00:00 GMT${sDomain ? `; domain=${sDomain}` : ''}${sPath ? `; path=${sPath}` : ''}`; + return true; + }, + hasItem(sKey) { + return (new RegExp(`(?:^|;\\s*)${encodeURIComponent(sKey).replace(/[-.+*]/g, '\\$&')}\\s*\\=`)).test(document.cookie); + }, + // eslint-disable-next-line + keys: /* optional method: you can safely remove it! */ function () { + const aKeys = document.cookie.replace(/((?:^|\s*;)[^=]+)(?=;|$)|^\s*|\s*(?:=[^;]*)?(?:\1|$)/g, '').split(/\s*(?:=[^;]*)?;\s*/); + for (let nIdx = 0; nIdx < aKeys.length; nIdx++) { + aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); + } + return aKeys; + } +}; + + +const isProd = process.env.NODE_ENV === 'production'; + +export const storageManager = { + set(key, value, storage) { + try { + window[storage].setItem(key, JSON.stringify(value)); + } catch (e) { + !isProd && console.error(e); + } + }, + get(key, storage) { + try { + if (window[storage].getItem(key)) { + return JSON.parse(window[storage].getItem(key)); + } + return window[storage].getItem(key); + } catch (e) { + !isProd && console.error(e, key); + return null; + } + }, + clear(storage) { + window[storage].clear(); + }, + remove(key, storage) { + window[storage].removeItem(key); + } +}; + +export const cookieManager = { + set(key, value, expired) { + if (expired) docCookies.setItem(key, value, expired); + else docCookies.setItem(key, value); + }, + get(key) { + return docCookies.getItem(key); + }, + clear() { + docCookies.keys().forEach((key) => { + docCookies.removeItem(key); + }); + }, + remove(key) { + docCookies.removeItem(key); + } +}; + + +/** + * 操作cookie、sessionStorage、localStorage、缓存 + */ + +const + SESSION = 'session'; +const LOCAL = 'local'; +const COOKIE = 'cookie'; + +export default { + set(key, value, category = SESSION, expired) { + const { storage, isWebStorage = true } = this._map(category); + + if (isWebStorage) { + storageManager.set(key, value, storage); + } else { + cookieManager.set(key, value, expired); + } + }, + get(key, category = SESSION) { + const { storage, isWebStorage = true } = this._map(category); + + if (isWebStorage) { + return storageManager.get(key, storage); + } + return cookieManager.get(key); + }, + clear(category = SESSION) { + const { storage, isWebStorage = true } = this._map(category); + + if (isWebStorage) { + storageManager.clear(storage); + } else { + cookieManager.clear(); + } + }, + remove(key, category = SESSION) { + const { storage, isWebStorage = true } = this._map(category); + + if (isWebStorage) { + storageManager.remove(key, storage); + } else { + cookieManager.remove(key); + } + }, + _map(category) { + let isWebStorage = true; let + storage; + + switch (true) { + case category === SESSION: + storage = 'sessionStorage'; + break; + case category === LOCAL: + storage = 'localStorage'; + break; + case category === COOKIE: + storage = 'cookie'; + isWebStorage = false; + break; + default: + storage = 'sessionStorage'; + } + + return { isWebStorage, storage }; + } +}; diff --git a/packages/fes-core/src/util/dom.js b/packages/fes-core/src/util/dom.js new file mode 100644 index 00000000..f885bdd3 --- /dev/null +++ b/packages/fes-core/src/util/dom.js @@ -0,0 +1,106 @@ +const inBrowser = typeof window !== 'undefined' + && Object.prototype.toString.call(window) !== '[object Object]'; +export const UA = inBrowser && window.navigator.userAgent.toLowerCase(); +export const isIE = UA && UA.indexOf('trident') > 0; +export const isIE9 = UA && UA.indexOf('msie 9.0') > 0; + +/** + * For IE9 compat: when both class and :class are present + * getAttribute('class') returns wrong value... + * + * @param {Element} el + * @return {String} + */ +export function getClass(el) { + let classname = el.className; + if (typeof classname === 'object') { + classname = classname.baseVal || ''; + } + return classname; +} + +/** + * 判断dom节点是否有某样式 + * + * @param {Element} el + * @return {String} + * @returns {boolean} + */ +export function hasClass(el, name) { + if (!el) return null; + const className = getClass(el); + const classes = className.split(' '); + return classes.indexOf(name) !== -1; +} + +/** + * In IE9, setAttribute('class') will result in empty class + * if the element also has the :class attribute; However in + * PhantomJS, setting `className` does not work on SVG elements... + * So we have to do a conditional check here. + * + * @param {Element} el + * @param {String} cls + */ +export function setClass(el, cls) { + /* istanbul ignore if */ + if (isIE9 && !/svg$/.test(el.namespaceURI)) { + el.className = cls; + } else { + el.setAttribute('class', cls); + } +} + +/** + * Add class with compatibility for IE & SVG + * + * @param {Element} el + * @param {String} cls + */ + +export function addClass(el, cls) { + if (el.classList) { + el.classList.add(cls); + } else { + const cur = ` ${getClass(el)} `; + if (cur.indexOf(` ${cls} `) < 0) { + setClass(el, (cur + cls).trim()); + } + } +} + +/** + * Remove class with compatibility for IE & SVG + * + * @param {Element} el + * @param {String} cls + */ + +export function removeClass(el, cls) { + if (el.classList) { + el.classList.remove(cls); + } else { + let cur = ` ${getClass(el)} `; + const tar = ` ${cls} `; + while (cur.indexOf(tar) >= 0) { + cur = cur.replace(tar, ' '); + } + setClass(el, cur.trim()); + } + if (!el.className) { + el.removeAttribute('class'); + } +} + +/** + * 从jquery扣过来的,递归去算 + * + * @param {Element} a + * @param {Element} b + * @returns {boolean} + */ +export function contains(a, b) { + const adown = a.nodeType === 9 ? a.documentElement : a; + const bup = b && b.parentNode; + return a === bup || !!(bup && bup.nodeType === 1 && adown.contains(bup)); +} diff --git a/packages/fes-core/src/util/event.js b/packages/fes-core/src/util/event.js new file mode 100644 index 00000000..b50beb4d --- /dev/null +++ b/packages/fes-core/src/util/event.js @@ -0,0 +1,51 @@ + +const eventProxy = { + onObj: {}, + oneObj: {}, + on(key, fn) { + if (fn && typeof (fn) === 'function') { + if (this.onObj[key] === undefined) { + this.onObj[key] = []; + } + this.onObj[key].push(fn); + } else { + throw new Error('请传入正确的回调函数'); + } + }, + one(key, fn) { + if (this.oneObj[key] === undefined) { + this.oneObj[key] = []; + } + + this.oneObj[key].push(fn); + }, + off(key) { + this.onObj[key] = []; + this.oneObj[key] = []; + }, + trigger(...args) { + if (args.length === 0) { + return false; + } + const key = args[0]; + args = [].concat(Array.prototype.slice.call(args, 1)); + + if (this.onObj[key] !== undefined + && this.onObj[key].length > 0) { + Object.keys(this.onObj[key]).forEach((i) => { + this.onObj[key][i].apply(null, args); + }); + } + if (this.oneObj[key] !== undefined + && this.oneObj[key].length > 0) { + Object.keys(this.oneObj[key]).forEach((i) => { + this.oneObj[key][i].apply(null, args); + this.oneObj[key][i] = undefined; + }); + this.oneObj[key] = []; + } + return null; + } +}; + +export default eventProxy; diff --git a/packages/fes-core/src/util/format.js b/packages/fes-core/src/util/format.js new file mode 100644 index 00000000..de974cf5 --- /dev/null +++ b/packages/fes-core/src/util/format.js @@ -0,0 +1,46 @@ +import fesConfig from '../config'; + +const hasOwnProperty = Object.prototype.hasOwnProperty; +const hasOwn = function (obj, key) { + return hasOwnProperty.call(obj, key); +}; +const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g; + +const template = function (string, ...args) { + if (args.length === 1 && typeof args[0] === 'object') { + args = args[0]; + } + + if (!args || !args.hasOwnProperty) { + args = {}; + } + + return string.replace(RE_NARGS, (match, prefix, i, index) => { + if (string[index - 1] === '{' && string[index + match.length] === '}') { + return i; + } + const result = hasOwn(args, i) ? args[i] : null; + if (result === null || result === undefined) { + return ''; + } + + return result; + }); +}; + +export default function (path, options) { + const array = path.split('.'); + let current = fesConfig.i18n.messages[fesConfig.i18n.locale]; + if (!current) { + current = fesConfig.i18n.messages['zh-cn']; + } + let value; + for (let i = 0, j = array.length; i < j; i++) { + const property = array[i]; + value = current[property]; + if (i === j - 1) return template(value, options); + if (!value) return ''; + current = value; + } + return ''; +} diff --git a/packages/fes-core/src/util/history.js b/packages/fes-core/src/util/history.js new file mode 100644 index 00000000..9f4a6750 --- /dev/null +++ b/packages/fes-core/src/util/history.js @@ -0,0 +1,38 @@ +import storage from '../storage'; + +const history = { + data: storage.get('Fes_History') || [], + current: null +}; + +history.record = function (href) { + const length = history.data.length; + const obj = { + href, + type: '' + }; + if (length === 0) { + obj.type = 'forward'; + } else if (length > 0 && length <= 1) { + if (history.data[length - 1].href === href) { + obj.type = 'refresh'; + } else { + obj.type = 'forward'; + } + } else if (length > 1) { + const first = history.data[length - 1]; + const second = history.data[length - 2]; + if (first.href === href) { + obj.type = 'refresh'; + } else if (second.href === href) { + obj.type = 'back'; + } else { + obj.type = 'forward'; + } + } + history.data.push(obj); + history.current = obj; + storage.set('Fes_History', history.data); +}; + +export default history; diff --git a/packages/fes-core/src/util/index.js b/packages/fes-core/src/util/index.js new file mode 100644 index 00000000..a6269904 --- /dev/null +++ b/packages/fes-core/src/util/index.js @@ -0,0 +1,88 @@ +import _ from 'lodash'; +import * as domUtil from './dom'; +import * as objectUtil from './object'; +import * as typeUtil from './type'; +import format from './format'; +import event from './event'; +import history from './history'; + +const util = { + // 验证一个path是否可以访问, 空的allowPage可以访问任何路由 + canRoute(path, allowPage) { + path = path.split('?')[0]; + if (Array.isArray(allowPage) && allowPage.length > 0) { + if (path === '' && allowPage.includes('/')) return true; + if (path) { + for (let i = 0; i < allowPage.length; i++) { + if (path === allowPage[i]) { + return true; + } + // 支持*匹配 + const reg = new RegExp(`^${allowPage[i].replace('*', '.+')}$`); + if (reg.test(path)) { + return true; + } + } + } + } + + return false; + }, + getUrlParam(name) { + const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`); + let r = window.location.search.substr(1).match(reg); + const hashQuery = window.location.hash.split('?')[1]; + if (r != null) { + return decodeURIComponent(r[2]); + } if (hashQuery) { + r = hashQuery.match(reg); + return r && decodeURIComponent(r[2]); + } + return null; + }, + removeParam(name, content) { + if (typeof name !== 'string') return false; + const prefix = encodeURIComponent(`${name}=`); + const pars = content.split(/[&;]/g); + let i = 0; const + len = pars.length; + let value = ''; + for (; i < len; i++) { + if (encodeURIComponent(pars[i]).lastIndexOf(prefix, 0) !== -1) { + pars.splice(i, 1); + } + } + value = (pars.length > 0 ? `?${pars.join('&')}` : ''); + return value; + }, + proxyFn(proxy, prop, apiArr) { + proxy[prop] = {}; + const cache = {}; + if (window.Proxy) { + proxy[prop] = new Proxy(proxy[prop], { + get(target, name) { + cache[name] = cache[name] ? cache[name] : []; + if (!target[name]) { + target[name] = function (...args) { + cache[name].push(args); + }; + } + return target[name]; + } + }); + } else { + apiArr.forEach((api) => { + if (!proxy[prop][api]) { + proxy[prop][api] = function (...args) { + cache[api] = cache[api] ? cache[api] : []; + cache[api].push(args); + }; + } + }); + } + return cache; + }, + _ +}; +objectUtil.merge(util, domUtil, objectUtil, typeUtil, { format }, { event }, { history }); +export default util; diff --git a/packages/fes-core/src/util/object.js b/packages/fes-core/src/util/object.js new file mode 100644 index 00000000..11cd5513 --- /dev/null +++ b/packages/fes-core/src/util/object.js @@ -0,0 +1,27 @@ +export function merge(...args) { + const base = args[0]; + if (!base) return null; + [].forEach.call(args, (item, index) => { + if (index > 0) { + Object.keys(item).forEach((attrname) => { + base[attrname] = item[attrname]; + }); + } + }); + return base; +} + +export function extend(...args) { + const base = args[0]; + if (!base) return null; + [].forEach.call(args, (item, index) => { + if (index > 0) { + Object.keys(item).forEach((attrname) => { + if (base[attrname] !== undefined) { + base[attrname] = item[attrname]; + } + }); + } + }); + return base; +} diff --git a/packages/fes-core/src/util/type.js b/packages/fes-core/src/util/type.js new file mode 100644 index 00000000..9d8ed912 --- /dev/null +++ b/packages/fes-core/src/util/type.js @@ -0,0 +1,36 @@ +const objectToString = Object.prototype.toString; +const OBJECT_STRING = '[object Object]'; + +export function isPlainObject(obj) { + return objectToString.call(obj) === OBJECT_STRING; +} + +export function isNumber(value) { return typeof value === 'number'; } + +export function isDate(value) { + return objectToString.call(value) === '[object Date]'; +} + +export function isFunction(value) { return typeof value === 'function'; } + +export function isObject(value) { + const type = typeof value; + return !!value && (type === 'object' || type === 'function'); +} + +export function isArray(value) { + return Array.isArray(value); +} + +export function isObjectLike(value) { + return !!value && typeof value === 'object'; +} + +export function isString(value) { + return typeof value === 'string' + || (!isArray(value) && isObjectLike(value) && objectToString.call(value) === '[object String]'); +} + +export function isNull(value) { + return value === undefined || value === null || value === ''; +} diff --git a/packages/fes-core/src/views/components/index.js b/packages/fes-core/src/views/components/index.js new file mode 100644 index 00000000..f546d986 --- /dev/null +++ b/packages/fes-core/src/views/components/index.js @@ -0,0 +1,29 @@ +/* ! + * fes-components v1.0.0 + * (c) 2017 fanniehuang + * Released under the MIT License. + */ +import FesRouteMenu from './routeMenu.vue'; +import FesSearchPanel from './searchPanel.vue'; +import FesListPanel from './listPanel.vue'; + +const fesComp = { + FesRouteMenu, + FesSearchPanel, + FesListPanel +}; + +const install = function (Vue) { + Object.keys(fesComp).forEach((key) => { + Vue.component(key, fesComp[key]); + }); +}; + +if (typeof window !== 'undefined' && window.Vue) { + install(window.Vue); +} + +export default { + install, + version: '2.0.0' +}; // eslint-disable-line no-undef diff --git a/packages/fes-core/src/views/components/listPanel.vue b/packages/fes-core/src/views/components/listPanel.vue new file mode 100644 index 00000000..2d1b56c0 --- /dev/null +++ b/packages/fes-core/src/views/components/listPanel.vue @@ -0,0 +1,11 @@ + + diff --git a/packages/fes-core/src/views/components/routeMenu.vue b/packages/fes-core/src/views/components/routeMenu.vue new file mode 100644 index 00000000..c23d6249 --- /dev/null +++ b/packages/fes-core/src/views/components/routeMenu.vue @@ -0,0 +1,91 @@ + + diff --git a/packages/fes-core/src/views/components/searchPanel.vue b/packages/fes-core/src/views/components/searchPanel.vue new file mode 100644 index 00000000..ce412f19 --- /dev/null +++ b/packages/fes-core/src/views/components/searchPanel.vue @@ -0,0 +1,14 @@ + + diff --git a/packages/fes-core/src/views/layout/left.vue b/packages/fes-core/src/views/layout/left.vue new file mode 100644 index 00000000..2467670a --- /dev/null +++ b/packages/fes-core/src/views/layout/left.vue @@ -0,0 +1,108 @@ + + diff --git a/packages/fes-core/src/views/layout/root.vue b/packages/fes-core/src/views/layout/root.vue new file mode 100644 index 00000000..9a7a635f --- /dev/null +++ b/packages/fes-core/src/views/layout/root.vue @@ -0,0 +1,67 @@ + + diff --git a/packages/fes-core/src/views/styles/components.scss b/packages/fes-core/src/views/styles/components.scss new file mode 100644 index 00000000..22ac291e --- /dev/null +++ b/packages/fes-core/src/views/styles/components.scss @@ -0,0 +1,48 @@ +.query-page { + .query-page-search { + position: relative; + background-color: #f7f7f7; + .query-page-search-buttons { + position: absolute; + margin-bottom: 16px; + margin-left: 50px; + height: 32px; + line-height: 32px; + bottom: 0; + right: 40px; + .ui-button+.ui-button { + margin-left: 8px; + } + } + .ui-form { + width: 75%; + } + .ui-form-item { + display: inline-block; + width: 33.33%; + } + } + .query-page-table { + .ui-page { + margin: 20px; + text-align: center; + } + } + .ui-modal-dialog { + overflow: auto; + } + .ui-modal-body { + width: 500px; + padding-right: 30px; + } + .link { + color: #3399ff; + cursor: pointer; + } + .link:hover { + color: #5cadff; + } + .link:active { + color: #3091f2; + } +} \ No newline at end of file diff --git a/packages/fes-core/src/views/styles/index.scss b/packages/fes-core/src/views/styles/index.scss new file mode 100644 index 00000000..4dca93c8 --- /dev/null +++ b/packages/fes-core/src/views/styles/index.scss @@ -0,0 +1,3 @@ +@import "layout.scss"; +@import "components.scss"; +@import "polyfill.scss"; \ No newline at end of file diff --git a/packages/fes-core/src/views/styles/layout.scss b/packages/fes-core/src/views/styles/layout.scss new file mode 100644 index 00000000..8c3f1d6d --- /dev/null +++ b/packages/fes-core/src/views/styles/layout.scss @@ -0,0 +1,425 @@ +$white-bg: #ffffff; +$white-border: #d7dde4; +$white-selected: #f3f3f3; + +$blue-bg: #128bd6; +$blue-selected: #077cc5; +$blue-color: #ffffff; + +$dark-bg: rgb(0, 21, 41); +$dark-bg-light: rgb(0, 33, 64); +$dark-bg-dark: rgb(0, 12, 23); +$dark-color: rgba(255, 255, 255, 0.65); +$dark-selected-bg: rgb(24, 144, 255); +$dark-selected-color: #ffffff; + +.layout { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + background-color: $white-bg; + + &.layout-left-hide { + left: -200px; + } + + &.layout-animate{ + transition: left 0.3s; + } + + &.layout-left-hidden{ + left: -200px; + .layout-left-fold-menu { + border-left: none; + border-radius: 0px 4px 4px 0px; + right: -16px; + display: block; + } + } + + &.layout-header-hide { + .layout-right-body { + top: 0; + } + } + + &.layout-theme-blue { + .layout-left { + color: $blue-color; + } + .layout-left-body { + background: $blue-bg; + } + .layout-left-fold-menu { + border-color: $blue-selected; + background-color: $blue-selected; + } + .layout-left-logo { + background: $blue-bg; + &.hasLogoEvent:hover { + background-color: $blue-selected; + cursor: pointer; + } + } + .layout-left-user-logout { + background-color: $blue-selected; + } + } + + &.layout-theme-dark { + .layout-left { + color: $dark-color; + } + .layout-left-body { + background: $dark-bg; + } + .layout-left-fold-menu { + color: $dark-selected-color; + border-color: $blue-selected; + background-color: $blue-selected; + } + .layout-left-logo { + background: $dark-bg; + color: $dark-selected-color; + &.hasLogoEvent:hover { + background: $dark-bg; + cursor: pointer; + } + } + .layout-left-user-logout { + background: $dark-bg-dark; + } + .ui-menu.ui-menu-type-dark { + background: $dark-bg; + .ui-menu-arrow { + color: $dark-color; + } + .ui-menu-submenu-title, + .ui-menu-item { + color: $dark-color; + &:hover { + color: $dark-selected-color; + background: $dark-bg; + .ui-menu-arrow { + color: $dark-selected-color; + } + } + &.ui-menu-item-actived { + color: $dark-selected-color; + background: $dark-selected-bg; + &:hover { + background: $dark-selected-bg; + } + } + } + .ui-menu-submenu-ul { + background: $dark-bg-dark; + .ui-menu-item { + color: $dark-color; + &:hover { + color: $dark-selected-color; + background: $dark-bg-dark; + } + &.ui-menu-item-actived { + color: $dark-selected-color; + background: $dark-selected-bg; + &:hover { + background: $dark-selected-bg; + } + } + } + } + .ui-menu-submenu { + &.ui-menu-submenu-actived, + &.ui-menu-submenu-choosed { + .ui-menu-submenu-title { + color: $dark-selected-color; + } + .ui-menu-arrow { + color: $dark-selected-color; + } + } + } + } + } + + &.layout-mode-vertical { + &.layout-theme-blue { + .layout-left { + box-shadow: rgba(0, 21, 41, 0.35) 2px 0px 6px; + } + // 修改蓝色的 + .ui-menu-mode-vertical.ui-menu-type-dark { + .ui-menu-submenu { + &:hover { + background: $blue-selected; + } + .ui-menu-item { + color: #8dcff8; + &:hover { + color: $blue-color; + } + &.ui-menu-item-actived { + color: $blue-color; + background: transparent; + } + } + &.ui-menu-submenu-choosed{ + background: $blue-selected; + } + &.ui-menu-submenu-actived{ + background: $blue-selected; + } + } + } + } + &.layout-theme-dark { + .layout-left { + box-shadow: rgba(0, 21, 41, 0.35) 2px 0px 6px; + } + } + } + + &.layout-mode-horizontal { + .layout-left { + left: 0; + top: 0; + width: 100%; + min-width: 1280px; + height: 60px; + } + .layout-right { + top: 60px; + bottom: 0; + left: 0; + right: 0; + } + .layout-left-body { + flex-direction: row; + } + .layout-left-menu { + margin-bottom: 0; + margin-left: 40px; + margin-right: 40px; + } + .layout-left-logo { + width: 200px; + height: 100%; + padding: 6px 0; + img { + height: 24px; + width: auto; + } + } + .layout-left-menu { + overflow: inherit; + } + .layout-left-user { + display: flex; + flex-direction: row; + width: 240px; + .layout-left-user-name { + flex: 2; + } + .layout-left-user-logout { + flex: 1; + height: 60px; + line-height: 60px; + background: $blue-bg; + border-left: 1px solid $blue-selected; + } + } + + &.layout-theme-blue { + .layout-left { + box-shadow: rgba(0, 21, 41, 0.35) 0 2px 6px; + } + .ui-menu.ui-menu-type-dark { + .ui-menu-submenu { + &.ui-menu-submenu-actived { + .ui-menu-submenu-title { + background: $blue-selected; + } + } + } + } + } + + &.layout-theme-dark { + .layout-left { + box-shadow: rgba(0, 21, 41, 0.35) 0 2px 6px; + } + .layout-left-user { + .layout-left-user-logout { + background: $dark-bg; + border-left-color: rgba(255, 255, 255, 0.3); + } + } + .ui-menu.ui-menu-type-dark { + .ui-menu-submenu { + &.ui-menu-submenu-actived { + .ui-menu-submenu-title { + color: $dark-selected-color; + background: $dark-bg; + } + } + &.ui-menu-submenu-choosed { + .ui-menu-submenu-title { + background: $dark-selected-bg; + } + } + } + .ui-menu-submenu-ul { + background: $dark-selected-color; + .ui-menu-item { + color: #657180; + &:hover { + color: $dark-selected-color; + background: $dark-selected-bg; + } + &.ui-menu-item-actived { + color: $dark-selected-color; + &:hover { + color: $dark-selected-color; + background: $dark-selected-bg; + } + } + } + .ui-menu-group-title { + color: #999; + } + } + } + } + } +} + +.layout-left { + position: absolute; + top: 0; + left: 0; + width: 200px; + height: 100%; + font-size: 14px; + &:hover { + .layout-left-fold-menu { + display: block; + } + } + + /* 设置滚动条的样式 */ + ::-webkit-scrollbar { + width: 10px; + height: 10px; + } + + /* 滚动槽 */ + ::-webkit-scrollbar-track { + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); + border-radius: 10px; + } + + /* 滚动条滑块 */ + ::-webkit-scrollbar-thumb { + border-radius: 10px; + background: rgba(0, 0, 0, 0.1); + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5); + } + + ::-webkit-scrollbar-thumb:window-inactive { + background: rgba(0, 0, 0, 0.1); + } +} + +.layout-left-fold-menu { + display: none; + position: absolute; + top: 80px; + right: 0; + overflow: hidden; + width: 16px; + height: 36px; + line-height: 36px; + border: 1px solid; + border-radius: 4px 0 0 4px; + z-index: 2; + font-size: 14px; + text-align: center; + cursor: pointer; +} + +.layout-left-body { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; +} + +.layout-left-menu { + display: flex; + flex: 1; + overflow: auto; + margin-bottom: 24px; +} + +.layout-left-logo { + padding: 50px 20px 40px; + text-align: center; + img { + width: auto; + max-height: 30px; + } + p { + font-size: 16px; + } + &.hasLogoEvent:hover { + cursor: pointer; + } +} + +.layout-left-user-name { + // flex: 1; + padding: 0 20px; + p { + margin: 10px 0; + line-height: 15px; + } +} + +.layout-left-user-logout { + // flex: 1; + height: 70px; + line-height: 70px; + text-align: center; + .ui-icon-logout { + cursor: pointer; + } +} + +.layout-right { + position: absolute; + left: 200px; + right: 0; + top: 0; + bottom: 0; + min-width: 1280px; +} + +.layout-right-header { + width: 100%; + min-width: 1280px; + height: 60px; + line-height: 60px; + position: relative; +} + +.layout-right-body { + position: absolute; + left: 0; + right: 0; + top: 60px; + bottom: 0; + overflow-y: auto; +} diff --git a/packages/fes-core/src/views/styles/polyfill.scss b/packages/fes-core/src/views/styles/polyfill.scss new file mode 100644 index 00000000..06bb089d --- /dev/null +++ b/packages/fes-core/src/views/styles/polyfill.scss @@ -0,0 +1,22 @@ +@media all and (min-width: 0\0) and (min-resolution: 0.001dpcm) { + .layout-left-menu { + padding-bottom: 24px; + margin-bottom: 0px; + position: absolute; + width: 200px; + top: 143px; + bottom: 130px; + } + .layout-left-user { + position: fixed; + width: 200px; + bottom: 0px; + left: 0px; + } +} +input[type=text]::-ms-clear { + display: none; +} +.layout-left-user-logout i { + vertical-align: bottom; +} diff --git a/packages/fes-doc/LICENSE b/packages/fes-doc/LICENSE new file mode 100644 index 00000000..23c3e60f --- /dev/null +++ b/packages/fes-doc/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-present harrywan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/packages/fes-doc/deploy.sh b/packages/fes-doc/deploy.sh new file mode 100644 index 00000000..597f0581 --- /dev/null +++ b/packages/fes-doc/deploy.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env sh + +# 确保脚本抛出遇到的错误 +set -e + +# 生成静态文件 +npm run build + +# 进入生成的文件夹 +cd docs/.vuepress/dist + +# 如果是发布到自定义域名 +# echo 'www.example.com' > CNAME + +git init +git add -A +git commit -m 'deploy' + +# 如果发布到 https://.github.io +# git push -f git@github.com:/.github.io.git master + +# 如果发布到 https://.github.io/ +git push -f https://github.com/WeBankFinTech/fes.js.git master:gh-pages + +cd - \ No newline at end of file diff --git a/packages/fes-doc/docs/.vuepress/components/componetTemplate.vue b/packages/fes-doc/docs/.vuepress/components/componetTemplate.vue new file mode 100644 index 00000000..82be7427 --- /dev/null +++ b/packages/fes-doc/docs/.vuepress/components/componetTemplate.vue @@ -0,0 +1,95 @@ +