From e3f0901364ad2a360bb58a87db29dce8d851e732 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Tue, 15 Dec 2020 11:47:40 +0800 Subject: [PATCH] init vue-element-admin --- .editorconfig | 14 + .env.development | 14 + .env.production | 6 + .env.staging | 8 + .eslintignore | 4 + .eslintrc.js | 198 +++ .gitignore | 23 + .postcssrc.js | 8 + .travis.yml | 5 + LICENSE | 21 + README.md | 214 +++ README.zh-CN.md | 232 +++ babel.config.js | 5 + build/index.js | 35 + jest.config.js | 27 + mock/article.js | 116 ++ mock/index.js | 57 + mock/mocks.js | 12 + mock/remoteSearch.js | 51 + mock/role/index.js | 98 ++ mock/role/routes.js | 525 ++++++ mock/user.js | 84 + package.json | 112 ++ plop-templates/component/index.hbs | 26 + plop-templates/component/prompt.js | 55 + plop-templates/utils.js | 9 + plop-templates/view/index.hbs | 26 + plop-templates/view/prompt.js | 55 + plopfile.js | 7 + public/favicon.ico | Bin 0 -> 67646 bytes public/index.html | 16 + public/static/tinymce4.7.5/langs/zh_CN.js | 230 +++ .../plugins/codesample/css/prism.css | 138 ++ .../plugins/emoticons/img/smiley-cool.gif | Bin 0 -> 354 bytes .../plugins/emoticons/img/smiley-cry.gif | Bin 0 -> 329 bytes .../emoticons/img/smiley-embarassed.gif | Bin 0 -> 331 bytes .../emoticons/img/smiley-foot-in-mouth.gif | Bin 0 -> 342 bytes .../plugins/emoticons/img/smiley-frown.gif | Bin 0 -> 340 bytes .../plugins/emoticons/img/smiley-innocent.gif | Bin 0 -> 336 bytes .../plugins/emoticons/img/smiley-kiss.gif | Bin 0 -> 338 bytes .../plugins/emoticons/img/smiley-laughing.gif | Bin 0 -> 343 bytes .../emoticons/img/smiley-money-mouth.gif | Bin 0 -> 321 bytes .../plugins/emoticons/img/smiley-sealed.gif | Bin 0 -> 323 bytes .../plugins/emoticons/img/smiley-smile.gif | Bin 0 -> 344 bytes .../emoticons/img/smiley-surprised.gif | Bin 0 -> 338 bytes .../emoticons/img/smiley-tongue-out.gif | Bin 0 -> 328 bytes .../emoticons/img/smiley-undecided.gif | Bin 0 -> 337 bytes .../plugins/emoticons/img/smiley-wink.gif | Bin 0 -> 350 bytes .../plugins/emoticons/img/smiley-yell.gif | Bin 0 -> 336 bytes .../plugins/visualblocks/css/visualblocks.css | 154 ++ .../skins/lightgray/content.inline.min.css | 1 + .../skins/lightgray/content.min.css | 1 + .../skins/lightgray/fonts/tinymce-mobile.woff | Bin 0 -> 4624 bytes .../skins/lightgray/fonts/tinymce-small.eot | Bin 0 -> 9492 bytes .../skins/lightgray/fonts/tinymce-small.svg | 63 + .../skins/lightgray/fonts/tinymce-small.ttf | Bin 0 -> 9304 bytes .../skins/lightgray/fonts/tinymce-small.woff | Bin 0 -> 9380 bytes .../skins/lightgray/fonts/tinymce.eot | Bin 0 -> 18808 bytes .../skins/lightgray/fonts/tinymce.svg | 131 ++ .../skins/lightgray/fonts/tinymce.ttf | Bin 0 -> 18644 bytes .../skins/lightgray/fonts/tinymce.woff | Bin 0 -> 18720 bytes .../skins/lightgray/img/anchor.gif | Bin 0 -> 53 bytes .../skins/lightgray/img/loader.gif | Bin 0 -> 2608 bytes .../skins/lightgray/img/object.gif | Bin 0 -> 152 bytes .../skins/lightgray/img/trans.gif | Bin 0 -> 43 bytes .../tinymce4.7.5/skins/lightgray/skin.min.css | 1 + .../skins/lightgray/skin.min.css.map | 1 + public/static/tinymce4.7.5/tinymce.min.js | 2 + src/App.vue | 11 + src/api/article.js | 41 + src/api/qiniu.js | 8 + src/api/remoteSearch.js | 17 + src/api/role.js | 38 + src/api/user.js | 25 + src/assets/401_images/401.gif | Bin 0 -> 164227 bytes src/assets/404_images/404.png | Bin 0 -> 98071 bytes src/assets/404_images/404_cloud.png | Bin 0 -> 4766 bytes .../custom-theme/fonts/element-icons.ttf | Bin 0 -> 11028 bytes .../custom-theme/fonts/element-icons.woff | Bin 0 -> 6124 bytes src/assets/custom-theme/index.css | 1 + src/components/BackToTop/index.vue | 116 ++ src/components/Breadcrumb/index.vue | 73 + src/components/Charts/keyboard.vue | 156 ++ src/components/Charts/lineMarker.vue | 227 +++ src/components/Charts/mixChart.vue | 271 ++++ src/components/Charts/mixins/resize.js | 32 + src/components/DndList/index.vue | 161 ++ src/components/DragSelect/index.vue | 61 + src/components/Dropzone/index.vue | 297 ++++ src/components/ErrorLog/index.vue | 68 + src/components/GithubCorner/index.vue | 54 + src/components/Hamburger/index.vue | 44 + src/components/HeaderSearch/index.vue | 190 +++ src/components/ImageCropper/index.vue | 1421 +++++++++++++++++ .../ImageCropper/utils/data2blob.js | 19 + .../ImageCropper/utils/effectRipple.js | 39 + src/components/ImageCropper/utils/language.js | 232 +++ src/components/ImageCropper/utils/mimes.js | 7 + src/components/JsonEditor/index.vue | 72 + src/components/Kanban/index.vue | 90 ++ src/components/LangSelect/index.vue | 38 + src/components/MDinput/index.vue | 360 +++++ .../MarkdownEditor/defaultOptions.js | 31 + src/components/MarkdownEditor/index.vue | 118 ++ src/components/Pagination/index.vue | 101 ++ src/components/PanThumb/index.vue | 140 ++ src/components/RightPanel/index.vue | 152 ++ src/components/Screenfull/index.vue | 60 + src/components/Share/dropdownMenu.vue | 100 ++ src/components/SizeSelect/index.vue | 57 + src/components/Sticky/index.vue | 91 ++ src/components/SvgIcon/index.vue | 43 + src/components/TextHoverEffect/Mallki.vue | 113 ++ src/components/ThemePicker/index.vue | 166 ++ .../Tinymce/components/editorImage.vue | 111 ++ src/components/Tinymce/index.vue | 210 +++ src/components/Tinymce/plugins.js | 7 + src/components/Tinymce/toolbar.js | 6 + src/components/Upload/singleImage.vue | 135 ++ src/components/Upload/singleImage2.vue | 130 ++ src/components/Upload/singleImage3.vue | 157 ++ src/components/UploadExcel/index.vue | 138 ++ src/directive/clipboard/clipboard.js | 49 + src/directive/clipboard/index.js | 13 + src/directive/el-dragDialog/drag.js | 77 + src/directive/el-dragDialog/index.js | 13 + src/directive/el-table/adaptive.js | 42 + src/directive/el-table/index.js | 14 + src/directive/permission/index.js | 13 + src/directive/permission/permission.js | 23 + src/directive/sticky.js | 91 ++ src/directive/waves/index.js | 13 + src/directive/waves/waves.css | 26 + src/directive/waves/waves.js | 72 + src/filters/index.js | 42 + src/icons/index.js | 9 + src/icons/svg/404.svg | 1 + src/icons/svg/bug.svg | 1 + src/icons/svg/chart.svg | 1 + src/icons/svg/clipboard.svg | 1 + src/icons/svg/component.svg | 1 + src/icons/svg/dashboard.svg | 1 + src/icons/svg/documentation.svg | 1 + src/icons/svg/drag.svg | 1 + src/icons/svg/edit.svg | 1 + src/icons/svg/email.svg | 1 + src/icons/svg/example.svg | 1 + src/icons/svg/excel.svg | 1 + src/icons/svg/exit-fullscreen.svg | 1 + src/icons/svg/eye-open.svg | 1 + src/icons/svg/eye.svg | 1 + src/icons/svg/form.svg | 1 + src/icons/svg/fullscreen.svg | 1 + src/icons/svg/guide 2.svg | 1 + src/icons/svg/guide.svg | 1 + src/icons/svg/icon.svg | 1 + src/icons/svg/international.svg | 1 + src/icons/svg/language.svg | 1 + src/icons/svg/link.svg | 1 + src/icons/svg/list.svg | 1 + src/icons/svg/lock.svg | 1 + src/icons/svg/message.svg | 1 + src/icons/svg/money.svg | 1 + src/icons/svg/nested.svg | 1 + src/icons/svg/password.svg | 1 + src/icons/svg/pdf.svg | 1 + src/icons/svg/people.svg | 1 + src/icons/svg/peoples.svg | 1 + src/icons/svg/qq.svg | 1 + src/icons/svg/search.svg | 1 + src/icons/svg/shopping.svg | 1 + src/icons/svg/size.svg | 1 + src/icons/svg/star.svg | 1 + src/icons/svg/tab.svg | 1 + src/icons/svg/table.svg | 1 + src/icons/svg/theme.svg | 1 + src/icons/svg/tree-table.svg | 1 + src/icons/svg/tree.svg | 1 + src/icons/svg/user.svg | 1 + src/icons/svg/wechat.svg | 1 + src/icons/svg/zip.svg | 1 + src/icons/svgo.yml | 22 + src/lang/en.js | 172 ++ src/lang/es.js | 172 ++ src/lang/index.js | 36 + src/lang/zh.js | 172 ++ src/layout/components/AppMain.vue | 49 + src/layout/components/Navbar.vue | 170 ++ src/layout/components/Settings/index.vue | 108 ++ src/layout/components/Sidebar/FixiOSBug.js | 26 + src/layout/components/Sidebar/Item.vue | 29 + src/layout/components/Sidebar/Link.vue | 36 + src/layout/components/Sidebar/Logo.vue | 82 + src/layout/components/Sidebar/SidebarItem.vue | 95 ++ src/layout/components/Sidebar/index.vue | 44 + src/layout/components/TagsView/ScrollPane.vue | 85 + src/layout/components/TagsView/index.vue | 291 ++++ src/layout/components/index.js | 5 + src/layout/index.vue | 102 ++ src/layout/mixin/ResizeHandler.js | 43 + src/main.js | 46 + src/permission.js | 70 + src/router/index.js | 403 +++++ src/router/modules/charts.js | 36 + src/router/modules/components.js | 102 ++ src/router/modules/nested.js | 66 + src/router/modules/table.js | 41 + src/settings.js | 37 + src/store/getters.js | 17 + src/store/index.js | 25 + src/store/modules/app.js | 64 + src/store/modules/errorLog.js | 23 + src/store/modules/permission.js | 69 + src/store/modules/settings.js | 32 + src/store/modules/tagsView.js | 166 ++ src/store/modules/user.js | 128 ++ src/styles/btn.scss | 99 ++ src/styles/element-ui.scss | 85 + src/styles/element-variables.scss | 31 + src/styles/index.scss | 201 +++ src/styles/mixin.scss | 66 + src/styles/sidebar.scss | 218 +++ src/styles/transition.scss | 48 + src/styles/variables.scss | 35 + src/utils/auth.js | 15 + src/utils/clipboard.js | 36 + src/utils/errorLog.js | 35 + src/utils/i18n.js | 12 + src/utils/index.js | 315 ++++ src/utils/openWindow.js | 26 + src/utils/permission.js | 25 + src/utils/request.js | 80 + src/utils/scrollTo.js | 50 + src/utils/validate.js | 51 + src/vendor/Export2Excel.js | 220 +++ src/vendor/Export2Zip.js | 24 + src/views/charts/keyboard.vue | 23 + src/views/charts/line.vue | 23 + src/views/charts/mixChart.vue | 23 + src/views/clipboard/index.vue | 49 + src/views/components-demo/avatarUpload.vue | 61 + src/views/components-demo/backToTop.vue | 150 ++ src/views/components-demo/countTo.vue | 218 +++ src/views/components-demo/dndList.vue | 39 + src/views/components-demo/dragDialog.vue | 61 + src/views/components-demo/dragKanban.vue | 66 + src/views/components-demo/dragSelect.vue | 43 + src/views/components-demo/dropzone.vue | 31 + src/views/components-demo/jsonEditor.vue | 36 + src/views/components-demo/markdown.vue | 101 ++ src/views/components-demo/mixin.vue | 168 ++ src/views/components-demo/splitpane.vue | 67 + src/views/components-demo/sticky.vue | 133 ++ src/views/components-demo/tinymce.vue | 36 + .../dashboard/admin/components/BarChart.vue | 106 ++ .../dashboard/admin/components/BoxCard.vue | 118 ++ .../dashboard/admin/components/LineChart.vue | 156 ++ .../dashboard/admin/components/PanelGroup.vue | 146 ++ .../dashboard/admin/components/PieChart.vue | 84 + .../admin/components/RaddarChart.vue | 120 ++ .../admin/components/TodoList/Todo.vue | 81 + .../admin/components/TodoList/index.scss | 320 ++++ .../admin/components/TodoList/index.vue | 127 ++ .../admin/components/TransactionTable.vue | 55 + src/views/dashboard/admin/index.vue | 109 ++ src/views/dashboard/editor/index.vue | 74 + src/views/dashboard/index.vue | 31 + src/views/documentation/index.vue | 49 + src/views/errorLog/errorTestA.vue | 13 + src/views/errorLog/errorTestB.vue | 11 + src/views/errorLog/index.vue | 33 + src/views/errorPage/401.vue | 99 ++ src/views/errorPage/404.vue | 237 +++ .../example/components/ArticleDetail.vue | 259 +++ .../example/components/Dropdown/Comment.vue | 41 + .../example/components/Dropdown/Platform.vue | 46 + .../example/components/Dropdown/SourceUrl.vue | 38 + .../example/components/Dropdown/index.js | 3 + src/views/example/components/Warning.vue | 11 + src/views/example/create.vue | 13 + src/views/example/edit.vue | 13 + src/views/example/list.vue | 112 ++ .../excel/components/AutoWidthOption.vue | 34 + src/views/excel/components/BookTypeOption.vue | 39 + src/views/excel/components/FilenameOption.vue | 28 + src/views/excel/exportExcel.vue | 115 ++ src/views/excel/mergeHeader.vue | 101 ++ src/views/excel/selectExcel.vue | 108 ++ src/views/excel/uploadExcel.vue | 42 + src/views/guide/defineSteps.js | 53 + src/views/guide/index.vue | 36 + src/views/i18n-demo/index.vue | 164 ++ src/views/i18n-demo/local.js | 63 + src/views/login/authredirect.vue | 15 + src/views/login/index.vue | 317 ++++ src/views/login/socialsignin.vue | 70 + src/views/nested/menu1/index.vue | 7 + src/views/nested/menu1/menu1-1/index.vue | 7 + src/views/nested/menu1/menu1-2/index.vue | 7 + .../nested/menu1/menu1-2/menu1-2-1/index.vue | 5 + .../nested/menu1/menu1-2/menu1-2-2/index.vue | 5 + src/views/nested/menu1/menu1-3/index.vue | 5 + src/views/nested/menu2/index.vue | 5 + src/views/pdf/content.js | 58 + src/views/pdf/download.vue | 201 +++ src/views/pdf/index.vue | 11 + .../permission/components/SwitchRoles.vue | 32 + src/views/permission/directive.vue | 111 ++ src/views/permission/page.vue | 19 + src/views/permission/role.vue | 283 ++++ src/views/qiniu/upload.vue | 41 + src/views/redirect/index.vue | 12 + src/views/svg-icons/index.vue | 71 + src/views/svg-icons/requireIcons.js | 11 + src/views/tab/components/tabPane.vue | 103 ++ src/views/tab/index.vue | 45 + src/views/table/complexTable.vue | 381 +++++ src/views/table/dragTable.vue | 154 ++ src/views/table/dynamicTable/fixedThead.vue | 62 + src/views/table/dynamicTable/index.vue | 24 + src/views/table/dynamicTable/unfixedThead.vue | 50 + src/views/table/inlineEditTable.vue | 131 ++ src/views/theme/index.vue | 118 ++ src/views/zip/index.vue | 78 + tests/unit/.eslintrc.js | 5 + tests/unit/components/Hamburger.spec.js | 18 + tests/unit/components/SvgIcon.spec.js | 22 + tests/unit/utils/formatTime.spec.js | 29 + tests/unit/utils/parseTime.spec.js | 27 + tests/unit/utils/validate.spec.js | 28 + vue.config.js | 147 ++ 331 files changed, 21629 insertions(+) create mode 100644 .editorconfig create mode 100644 .env.development create mode 100644 .env.production create mode 100644 .env.staging create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .gitignore create mode 100644 .postcssrc.js create mode 100644 .travis.yml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 README.zh-CN.md create mode 100644 babel.config.js create mode 100644 build/index.js create mode 100644 jest.config.js create mode 100644 mock/article.js create mode 100644 mock/index.js create mode 100644 mock/mocks.js create mode 100644 mock/remoteSearch.js create mode 100644 mock/role/index.js create mode 100644 mock/role/routes.js create mode 100644 mock/user.js create mode 100644 package.json create mode 100644 plop-templates/component/index.hbs create mode 100644 plop-templates/component/prompt.js create mode 100644 plop-templates/utils.js create mode 100644 plop-templates/view/index.hbs create mode 100644 plop-templates/view/prompt.js create mode 100644 plopfile.js create mode 100644 public/favicon.ico create mode 100644 public/index.html create mode 100644 public/static/tinymce4.7.5/langs/zh_CN.js create mode 100644 public/static/tinymce4.7.5/plugins/codesample/css/prism.css create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-cool.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-cry.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-embarassed.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-foot-in-mouth.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-frown.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-innocent.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-kiss.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-laughing.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-money-mouth.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-sealed.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-smile.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-surprised.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-tongue-out.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-undecided.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-wink.gif create mode 100644 public/static/tinymce4.7.5/plugins/emoticons/img/smiley-yell.gif create mode 100644 public/static/tinymce4.7.5/plugins/visualblocks/css/visualblocks.css create mode 100644 public/static/tinymce4.7.5/skins/lightgray/content.inline.min.css create mode 100644 public/static/tinymce4.7.5/skins/lightgray/content.min.css create mode 100644 public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-mobile.woff create mode 100644 public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.eot create mode 100644 public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.svg create mode 100644 public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.ttf create mode 100644 public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.woff create mode 100644 public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.eot create mode 100644 public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.svg create mode 100644 public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.ttf create mode 100644 public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.woff create mode 100644 public/static/tinymce4.7.5/skins/lightgray/img/anchor.gif create mode 100644 public/static/tinymce4.7.5/skins/lightgray/img/loader.gif create mode 100644 public/static/tinymce4.7.5/skins/lightgray/img/object.gif create mode 100644 public/static/tinymce4.7.5/skins/lightgray/img/trans.gif create mode 100644 public/static/tinymce4.7.5/skins/lightgray/skin.min.css create mode 100644 public/static/tinymce4.7.5/skins/lightgray/skin.min.css.map create mode 100644 public/static/tinymce4.7.5/tinymce.min.js create mode 100644 src/App.vue create mode 100644 src/api/article.js create mode 100644 src/api/qiniu.js create mode 100644 src/api/remoteSearch.js create mode 100644 src/api/role.js create mode 100644 src/api/user.js create mode 100644 src/assets/401_images/401.gif create mode 100644 src/assets/404_images/404.png create mode 100644 src/assets/404_images/404_cloud.png create mode 100644 src/assets/custom-theme/fonts/element-icons.ttf create mode 100644 src/assets/custom-theme/fonts/element-icons.woff create mode 100644 src/assets/custom-theme/index.css create mode 100644 src/components/BackToTop/index.vue create mode 100644 src/components/Breadcrumb/index.vue create mode 100644 src/components/Charts/keyboard.vue create mode 100644 src/components/Charts/lineMarker.vue create mode 100644 src/components/Charts/mixChart.vue create mode 100644 src/components/Charts/mixins/resize.js create mode 100644 src/components/DndList/index.vue create mode 100644 src/components/DragSelect/index.vue create mode 100644 src/components/Dropzone/index.vue create mode 100644 src/components/ErrorLog/index.vue create mode 100644 src/components/GithubCorner/index.vue create mode 100644 src/components/Hamburger/index.vue create mode 100644 src/components/HeaderSearch/index.vue create mode 100644 src/components/ImageCropper/index.vue create mode 100644 src/components/ImageCropper/utils/data2blob.js create mode 100644 src/components/ImageCropper/utils/effectRipple.js create mode 100644 src/components/ImageCropper/utils/language.js create mode 100644 src/components/ImageCropper/utils/mimes.js create mode 100644 src/components/JsonEditor/index.vue create mode 100644 src/components/Kanban/index.vue create mode 100644 src/components/LangSelect/index.vue create mode 100644 src/components/MDinput/index.vue create mode 100644 src/components/MarkdownEditor/defaultOptions.js create mode 100644 src/components/MarkdownEditor/index.vue create mode 100644 src/components/Pagination/index.vue create mode 100644 src/components/PanThumb/index.vue create mode 100644 src/components/RightPanel/index.vue create mode 100644 src/components/Screenfull/index.vue create mode 100644 src/components/Share/dropdownMenu.vue create mode 100644 src/components/SizeSelect/index.vue create mode 100644 src/components/Sticky/index.vue create mode 100644 src/components/SvgIcon/index.vue create mode 100644 src/components/TextHoverEffect/Mallki.vue create mode 100644 src/components/ThemePicker/index.vue create mode 100644 src/components/Tinymce/components/editorImage.vue create mode 100644 src/components/Tinymce/index.vue create mode 100644 src/components/Tinymce/plugins.js create mode 100644 src/components/Tinymce/toolbar.js create mode 100644 src/components/Upload/singleImage.vue create mode 100644 src/components/Upload/singleImage2.vue create mode 100644 src/components/Upload/singleImage3.vue create mode 100644 src/components/UploadExcel/index.vue create mode 100644 src/directive/clipboard/clipboard.js create mode 100644 src/directive/clipboard/index.js create mode 100644 src/directive/el-dragDialog/drag.js create mode 100644 src/directive/el-dragDialog/index.js create mode 100644 src/directive/el-table/adaptive.js create mode 100644 src/directive/el-table/index.js create mode 100644 src/directive/permission/index.js create mode 100644 src/directive/permission/permission.js create mode 100644 src/directive/sticky.js create mode 100644 src/directive/waves/index.js create mode 100644 src/directive/waves/waves.css create mode 100644 src/directive/waves/waves.js create mode 100644 src/filters/index.js create mode 100644 src/icons/index.js create mode 100644 src/icons/svg/404.svg create mode 100644 src/icons/svg/bug.svg create mode 100644 src/icons/svg/chart.svg create mode 100644 src/icons/svg/clipboard.svg create mode 100644 src/icons/svg/component.svg create mode 100644 src/icons/svg/dashboard.svg create mode 100644 src/icons/svg/documentation.svg create mode 100644 src/icons/svg/drag.svg create mode 100644 src/icons/svg/edit.svg create mode 100644 src/icons/svg/email.svg create mode 100644 src/icons/svg/example.svg create mode 100644 src/icons/svg/excel.svg create mode 100644 src/icons/svg/exit-fullscreen.svg create mode 100644 src/icons/svg/eye-open.svg create mode 100644 src/icons/svg/eye.svg create mode 100644 src/icons/svg/form.svg create mode 100644 src/icons/svg/fullscreen.svg create mode 100644 src/icons/svg/guide 2.svg create mode 100644 src/icons/svg/guide.svg create mode 100644 src/icons/svg/icon.svg create mode 100644 src/icons/svg/international.svg create mode 100644 src/icons/svg/language.svg create mode 100644 src/icons/svg/link.svg create mode 100644 src/icons/svg/list.svg create mode 100644 src/icons/svg/lock.svg create mode 100644 src/icons/svg/message.svg create mode 100644 src/icons/svg/money.svg create mode 100644 src/icons/svg/nested.svg create mode 100644 src/icons/svg/password.svg create mode 100644 src/icons/svg/pdf.svg create mode 100644 src/icons/svg/people.svg create mode 100644 src/icons/svg/peoples.svg create mode 100644 src/icons/svg/qq.svg create mode 100644 src/icons/svg/search.svg create mode 100644 src/icons/svg/shopping.svg create mode 100644 src/icons/svg/size.svg create mode 100644 src/icons/svg/star.svg create mode 100644 src/icons/svg/tab.svg create mode 100644 src/icons/svg/table.svg create mode 100644 src/icons/svg/theme.svg create mode 100644 src/icons/svg/tree-table.svg create mode 100644 src/icons/svg/tree.svg create mode 100644 src/icons/svg/user.svg create mode 100644 src/icons/svg/wechat.svg create mode 100644 src/icons/svg/zip.svg create mode 100644 src/icons/svgo.yml create mode 100644 src/lang/en.js create mode 100644 src/lang/es.js create mode 100644 src/lang/index.js create mode 100644 src/lang/zh.js create mode 100644 src/layout/components/AppMain.vue create mode 100644 src/layout/components/Navbar.vue create mode 100644 src/layout/components/Settings/index.vue create mode 100644 src/layout/components/Sidebar/FixiOSBug.js create mode 100644 src/layout/components/Sidebar/Item.vue create mode 100644 src/layout/components/Sidebar/Link.vue create mode 100644 src/layout/components/Sidebar/Logo.vue create mode 100644 src/layout/components/Sidebar/SidebarItem.vue create mode 100644 src/layout/components/Sidebar/index.vue create mode 100644 src/layout/components/TagsView/ScrollPane.vue create mode 100644 src/layout/components/TagsView/index.vue create mode 100644 src/layout/components/index.js create mode 100644 src/layout/index.vue create mode 100644 src/layout/mixin/ResizeHandler.js create mode 100644 src/main.js create mode 100644 src/permission.js create mode 100644 src/router/index.js create mode 100644 src/router/modules/charts.js create mode 100644 src/router/modules/components.js create mode 100644 src/router/modules/nested.js create mode 100644 src/router/modules/table.js create mode 100644 src/settings.js create mode 100644 src/store/getters.js create mode 100644 src/store/index.js create mode 100644 src/store/modules/app.js create mode 100644 src/store/modules/errorLog.js create mode 100644 src/store/modules/permission.js create mode 100644 src/store/modules/settings.js create mode 100644 src/store/modules/tagsView.js create mode 100644 src/store/modules/user.js create mode 100644 src/styles/btn.scss create mode 100644 src/styles/element-ui.scss create mode 100644 src/styles/element-variables.scss create mode 100644 src/styles/index.scss create mode 100644 src/styles/mixin.scss create mode 100644 src/styles/sidebar.scss create mode 100644 src/styles/transition.scss create mode 100644 src/styles/variables.scss create mode 100644 src/utils/auth.js create mode 100644 src/utils/clipboard.js create mode 100644 src/utils/errorLog.js create mode 100644 src/utils/i18n.js create mode 100644 src/utils/index.js create mode 100644 src/utils/openWindow.js create mode 100644 src/utils/permission.js create mode 100644 src/utils/request.js create mode 100644 src/utils/scrollTo.js create mode 100644 src/utils/validate.js create mode 100644 src/vendor/Export2Excel.js create mode 100644 src/vendor/Export2Zip.js create mode 100644 src/views/charts/keyboard.vue create mode 100644 src/views/charts/line.vue create mode 100644 src/views/charts/mixChart.vue create mode 100644 src/views/clipboard/index.vue create mode 100644 src/views/components-demo/avatarUpload.vue create mode 100644 src/views/components-demo/backToTop.vue create mode 100644 src/views/components-demo/countTo.vue create mode 100644 src/views/components-demo/dndList.vue create mode 100644 src/views/components-demo/dragDialog.vue create mode 100644 src/views/components-demo/dragKanban.vue create mode 100644 src/views/components-demo/dragSelect.vue create mode 100644 src/views/components-demo/dropzone.vue create mode 100644 src/views/components-demo/jsonEditor.vue create mode 100644 src/views/components-demo/markdown.vue create mode 100644 src/views/components-demo/mixin.vue create mode 100644 src/views/components-demo/splitpane.vue create mode 100644 src/views/components-demo/sticky.vue create mode 100644 src/views/components-demo/tinymce.vue create mode 100644 src/views/dashboard/admin/components/BarChart.vue create mode 100644 src/views/dashboard/admin/components/BoxCard.vue create mode 100644 src/views/dashboard/admin/components/LineChart.vue create mode 100644 src/views/dashboard/admin/components/PanelGroup.vue create mode 100644 src/views/dashboard/admin/components/PieChart.vue create mode 100644 src/views/dashboard/admin/components/RaddarChart.vue create mode 100644 src/views/dashboard/admin/components/TodoList/Todo.vue create mode 100644 src/views/dashboard/admin/components/TodoList/index.scss create mode 100644 src/views/dashboard/admin/components/TodoList/index.vue create mode 100644 src/views/dashboard/admin/components/TransactionTable.vue create mode 100644 src/views/dashboard/admin/index.vue create mode 100644 src/views/dashboard/editor/index.vue create mode 100644 src/views/dashboard/index.vue create mode 100644 src/views/documentation/index.vue create mode 100644 src/views/errorLog/errorTestA.vue create mode 100644 src/views/errorLog/errorTestB.vue create mode 100644 src/views/errorLog/index.vue create mode 100644 src/views/errorPage/401.vue create mode 100644 src/views/errorPage/404.vue create mode 100644 src/views/example/components/ArticleDetail.vue create mode 100644 src/views/example/components/Dropdown/Comment.vue create mode 100644 src/views/example/components/Dropdown/Platform.vue create mode 100644 src/views/example/components/Dropdown/SourceUrl.vue create mode 100644 src/views/example/components/Dropdown/index.js create mode 100644 src/views/example/components/Warning.vue create mode 100644 src/views/example/create.vue create mode 100644 src/views/example/edit.vue create mode 100644 src/views/example/list.vue create mode 100644 src/views/excel/components/AutoWidthOption.vue create mode 100644 src/views/excel/components/BookTypeOption.vue create mode 100644 src/views/excel/components/FilenameOption.vue create mode 100644 src/views/excel/exportExcel.vue create mode 100644 src/views/excel/mergeHeader.vue create mode 100644 src/views/excel/selectExcel.vue create mode 100644 src/views/excel/uploadExcel.vue create mode 100644 src/views/guide/defineSteps.js create mode 100644 src/views/guide/index.vue create mode 100644 src/views/i18n-demo/index.vue create mode 100644 src/views/i18n-demo/local.js create mode 100644 src/views/login/authredirect.vue create mode 100644 src/views/login/index.vue create mode 100644 src/views/login/socialsignin.vue create mode 100644 src/views/nested/menu1/index.vue create mode 100644 src/views/nested/menu1/menu1-1/index.vue create mode 100644 src/views/nested/menu1/menu1-2/index.vue create mode 100644 src/views/nested/menu1/menu1-2/menu1-2-1/index.vue create mode 100644 src/views/nested/menu1/menu1-2/menu1-2-2/index.vue create mode 100644 src/views/nested/menu1/menu1-3/index.vue create mode 100644 src/views/nested/menu2/index.vue create mode 100644 src/views/pdf/content.js create mode 100644 src/views/pdf/download.vue create mode 100644 src/views/pdf/index.vue create mode 100644 src/views/permission/components/SwitchRoles.vue create mode 100644 src/views/permission/directive.vue create mode 100644 src/views/permission/page.vue create mode 100644 src/views/permission/role.vue create mode 100644 src/views/qiniu/upload.vue create mode 100644 src/views/redirect/index.vue create mode 100644 src/views/svg-icons/index.vue create mode 100644 src/views/svg-icons/requireIcons.js create mode 100644 src/views/tab/components/tabPane.vue create mode 100644 src/views/tab/index.vue create mode 100644 src/views/table/complexTable.vue create mode 100644 src/views/table/dragTable.vue create mode 100644 src/views/table/dynamicTable/fixedThead.vue create mode 100644 src/views/table/dynamicTable/index.vue create mode 100644 src/views/table/dynamicTable/unfixedThead.vue create mode 100644 src/views/table/inlineEditTable.vue create mode 100644 src/views/theme/index.vue create mode 100644 src/views/zip/index.vue create mode 100644 tests/unit/.eslintrc.js create mode 100644 tests/unit/components/Hamburger.spec.js create mode 100644 tests/unit/components/SvgIcon.spec.js create mode 100644 tests/unit/utils/formatTime.spec.js create mode 100644 tests/unit/utils/parseTime.spec.js create mode 100644 tests/unit/utils/validate.spec.js create mode 100644 vue.config.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ea6e20f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..8f5856d --- /dev/null +++ b/.env.development @@ -0,0 +1,14 @@ +# just a flag +ENV = 'development' + +# base api +VUE_APP_BASE_API = '/dev-api' + +# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable, +# to control whether the babel-plugin-dynamic-import-node plugin is enabled. +# It only does one thing by converting all import() to require(). +# This configuration can significantly increase the speed of hot updates, +# when you have a large number of pages. +# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js + +VUE_CLI_BABEL_TRANSPILE_MODULES = true diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..80c8103 --- /dev/null +++ b/.env.production @@ -0,0 +1,6 @@ +# just a flag +ENV = 'production' + +# base api +VUE_APP_BASE_API = '/prod-api' + diff --git a/.env.staging b/.env.staging new file mode 100644 index 0000000..a8793a0 --- /dev/null +++ b/.env.staging @@ -0,0 +1,8 @@ +NODE_ENV = production + +# just a flag +ENV = 'staging' + +# base api +VUE_APP_BASE_API = '/stage-api' + diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..e6529fc --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +build/*.js +src/assets +public +dist diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..c977505 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,198 @@ +module.exports = { + root: true, + parserOptions: { + parser: 'babel-eslint', + sourceType: 'module' + }, + env: { + browser: true, + node: true, + es6: true, + }, + extends: ['plugin:vue/recommended', 'eslint:recommended'], + + // add your custom rules here + //it is base on https://github.com/vuejs/eslint-config-vue + rules: { + "vue/max-attributes-per-line": [2, { + "singleline": 10, + "multiline": { + "max": 1, + "allowFirstLine": false + } + }], + "vue/singleline-html-element-content-newline": "off", + "vue/multiline-html-element-content-newline":"off", + "vue/name-property-casing": ["error", "PascalCase"], + "vue/no-v-html": "off", + 'accessor-pairs': 2, + 'arrow-spacing': [2, { + 'before': true, + 'after': true + }], + 'block-spacing': [2, 'always'], + 'brace-style': [2, '1tbs', { + 'allowSingleLine': true + }], + 'camelcase': [0, { + 'properties': 'always' + }], + 'comma-dangle': [2, 'never'], + 'comma-spacing': [2, { + 'before': false, + 'after': true + }], + 'comma-style': [2, 'last'], + 'constructor-super': 2, + 'curly': [2, 'multi-line'], + 'dot-location': [2, 'property'], + 'eol-last': 2, + 'eqeqeq': ["error", "always", {"null": "ignore"}], + 'generator-star-spacing': [2, { + 'before': true, + 'after': true + }], + 'handle-callback-err': [2, '^(err|error)$'], + 'indent': [2, 2, { + 'SwitchCase': 1 + }], + 'jsx-quotes': [2, 'prefer-single'], + 'key-spacing': [2, { + 'beforeColon': false, + 'afterColon': true + }], + 'keyword-spacing': [2, { + 'before': true, + 'after': true + }], + 'new-cap': [2, { + 'newIsCap': true, + 'capIsNew': false + }], + 'new-parens': 2, + 'no-array-constructor': 2, + 'no-caller': 2, + 'no-console': 'off', + 'no-class-assign': 2, + 'no-cond-assign': 2, + 'no-const-assign': 2, + 'no-control-regex': 0, + 'no-delete-var': 2, + 'no-dupe-args': 2, + 'no-dupe-class-members': 2, + 'no-dupe-keys': 2, + 'no-duplicate-case': 2, + 'no-empty-character-class': 2, + 'no-empty-pattern': 2, + 'no-eval': 2, + 'no-ex-assign': 2, + 'no-extend-native': 2, + 'no-extra-bind': 2, + 'no-extra-boolean-cast': 2, + 'no-extra-parens': [2, 'functions'], + 'no-fallthrough': 2, + 'no-floating-decimal': 2, + 'no-func-assign': 2, + 'no-implied-eval': 2, + 'no-inner-declarations': [2, 'functions'], + 'no-invalid-regexp': 2, + 'no-irregular-whitespace': 2, + 'no-iterator': 2, + 'no-label-var': 2, + 'no-labels': [2, { + 'allowLoop': false, + 'allowSwitch': false + }], + 'no-lone-blocks': 2, + 'no-mixed-spaces-and-tabs': 2, + 'no-multi-spaces': 2, + 'no-multi-str': 2, + 'no-multiple-empty-lines': [2, { + 'max': 1 + }], + 'no-native-reassign': 2, + 'no-negated-in-lhs': 2, + 'no-new-object': 2, + 'no-new-require': 2, + 'no-new-symbol': 2, + 'no-new-wrappers': 2, + 'no-obj-calls': 2, + 'no-octal': 2, + 'no-octal-escape': 2, + 'no-path-concat': 2, + 'no-proto': 2, + 'no-redeclare': 2, + 'no-regex-spaces': 2, + 'no-return-assign': [2, 'except-parens'], + 'no-self-assign': 2, + 'no-self-compare': 2, + 'no-sequences': 2, + 'no-shadow-restricted-names': 2, + 'no-spaced-func': 2, + 'no-sparse-arrays': 2, + 'no-this-before-super': 2, + 'no-throw-literal': 2, + 'no-trailing-spaces': 2, + 'no-undef': 2, + 'no-undef-init': 2, + 'no-unexpected-multiline': 2, + 'no-unmodified-loop-condition': 2, + 'no-unneeded-ternary': [2, { + 'defaultAssignment': false + }], + 'no-unreachable': 2, + 'no-unsafe-finally': 2, + 'no-unused-vars': [2, { + 'vars': 'all', + 'args': 'none' + }], + 'no-useless-call': 2, + 'no-useless-computed-key': 2, + 'no-useless-constructor': 2, + 'no-useless-escape': 0, + 'no-whitespace-before-property': 2, + 'no-with': 2, + 'one-var': [2, { + 'initialized': 'never' + }], + 'operator-linebreak': [2, 'after', { + 'overrides': { + '?': 'before', + ':': 'before' + } + }], + 'padded-blocks': [2, 'never'], + 'quotes': [2, 'single', { + 'avoidEscape': true, + 'allowTemplateLiterals': true + }], + 'semi': [2, 'never'], + 'semi-spacing': [2, { + 'before': false, + 'after': true + }], + 'space-before-blocks': [2, 'always'], + 'space-before-function-paren': [2, 'never'], + 'space-in-parens': [2, 'never'], + 'space-infix-ops': 2, + 'space-unary-ops': [2, { + 'words': true, + 'nonwords': false + }], + 'spaced-comment': [2, 'always', { + 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] + }], + 'template-curly-spacing': [2, 'never'], + 'use-isnan': 2, + 'valid-typeof': 2, + 'wrap-iife': [2, 'any'], + 'yield-star-spacing': [2, 'both'], + 'yoda': [2, 'never'], + 'prefer-const': 2, + 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, + 'object-curly-spacing': [2, 'always', { + objectsInObjects: false + }], + 'array-bracket-spacing': [2, 'never'] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..78a752d --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +node_modules/ +dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +**/*.log + +tests/**/coverage/ +tests/e2e/reports +selenium-debug.log + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.local + +package-lock.json +yarn.lock diff --git a/.postcssrc.js b/.postcssrc.js new file mode 100644 index 0000000..09948d6 --- /dev/null +++ b/.postcssrc.js @@ -0,0 +1,8 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {} + } +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..16574d9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: stable +script: npm run test +notifications: + email: false diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6151575 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017-present PanJiaChen + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..48599a7 --- /dev/null +++ b/README.md @@ -0,0 +1,214 @@ +

+ +

+ +

+ + vue + + + element-ui + + + Build Status + + + license + + + GitHub release + + + gitter + + + donate + +

+ +English | [简体中文](./README.zh-CN.md) + +## Introduction + +[vue-element-admin](http://panjiachen.github.io/vue-element-admin) is a production-ready front-end solution for admin interfaces. It based on [vue](https://github.com/vuejs/vue) and use the UI Toolkit [element-ui](https://github.com/ElemeFE/element). + +It is a magical vue admin based on the newest development stack of vue, built-in i18n solution, typical templates for enterprise applications, lots of awesome features. It helps you build a large complex Single-Page Applications. I believe whatever your needs are, this project will help you. + +- [Preview](http://panjiachen.github.io/vue-element-admin) + +- [Documentation](https://panjiachen.github.io/vue-element-admin-site/) + +- [Gitter](https://gitter.im/vue-element-admin/discuss) + +- [Donate](https://panjiachen.github.io/vue-element-admin-site/donate/) + +- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki) + +- [Gitee](https://panjiachen.gitee.io/vue-element-admin/) 国内用户可访问该地址在线预览 + +- Base template recommends using: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template) +- Desktop: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) +- Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour)) + +**The current version is `4.0-beta`. If you find a problem, please put [issue](https://github.com/PanJiaChen/vue-element-admin/issues/new). If you want to use the old version - stable version, you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0)** + +**This project does not support low version browsers (e.g. IE). Please add polyfill by yourself.** + +## Preparation + +You need to install [node](http://nodejs.org/) and [git](https://git-scm.com/) locally. The project is based on [ES2015+](http://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), all request data is simulated using [Mock.js](https://github.com/nuysoft/Mock). +Understanding and learning this knowledge in advance will greatly help the use of this project. + +

+ +

+ +## Sponsors + +Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen) + +

Admin Dashboard Templates made with Vue, React and Angular.

+ +## Features + +``` +- Login / Logout + +- Permission Authentication + - Page permission + - Directive permission + - Permission configuration page + - Two-step login + +- Multi-environment build + - dev sit stage prod + +- Global Features + - I18n + - Multiple dynamic themes + - Dynamic sidebar (supports multi-level routing) + - Dynamic breadcrumb + - Tags-view (Tab page Support right-click operation) + - Svg Sprite + - Mock data + - Screenfull + - Responsive Sidebar + +- Editor + - Rich Text Editor + - Markdown Editor + - JSON Editor + +- Excel + - Export Excel + - Upload Excel + - Visualization Excel + - Export zip + +- Table + - Dynamic Table + - Drag And Drop Table + - Inline Edit Table + +- Error Page + - 401 + - 404 + +- Components + - Avatar Upload + - Back To Top + - Drag Dialog + - Drag Select + - Drag Kanban + - Drag List + - SplitPane + - Dropzone + - Sticky + - CountTo + +- Advanced Example +- Error Log +- Dashboard +- Guide Page +- ECharts +- Clipboard +- Markdown to html +``` + +## Getting started + +```bash +# clone the project +git clone https://github.com/PanJiaChen/vue-element-admin.git + +# enter the project directory +cd vue-element-admin + +# install dependency +npm install + +# develop +npm run dev +``` + +This will automatically open http://localhost:9527 + +## Build + +```bash +# build for test environment +npm run build:stage + +# build for production environment +npm run build:prod +``` + +## Advanced + +```bash +# preview the release environment effect +npm run preview + +# preview the release environment effect + static resource analysis +npm run preview -- --report + +# code format check +npm run lint + +# code format check and auto fix +npm run lint -- --fix +``` + +Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information + +## Changelog + +Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases). + +## Online Demo + +[Preview](http://panjiachen.github.io/vue-element-admin) + +## Donate + +If you find this project useful, you can buy author a glass of juice :tropical_drink: + +![donate](https://wpimg.wallstcn.com/bd273f0d-83a0-4ef2-92e1-9ac8ed3746b9.png) + +[Paypal Me](https://www.paypal.me/panfree23) + +[Buy me a coffee](https://www.buymeacoffee.com/Pan) + +## Browsers support + +Modern browsers and Internet Explorer 10+. + +| [IE / Edge](http://godban.github.io/browsers-support-badges/)
IE / Edge | [Firefox](http://godban.github.io/browsers-support-badges/)
Firefox | [Chrome](http://godban.github.io/browsers-support-badges/)
Chrome | [Safari](http://godban.github.io/browsers-support-badges/)
Safari | +| --------- | --------- | --------- | --------- | +| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions + +## License + +[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE) + +Copyright (c) 2017-present PanJiaChen diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 0000000..e0ec09b --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,232 @@ +

+ +

+ +

+ + vue + + + element-ui + + + Build Status + + + license + + + GitHub release + + + gitter + + + donate + +

+ +简体中文 | [English](./README.md) + +## 简介 + +[vue-element-admin](http://panjiachen.github.io/vue-element-admin) 是一个后台前端解决方案,它基于 [vue](https://github.com/vuejs/vue) 和 [element-ui](https://github.com/ElemeFE/element)实现。它使用了最新的前端技术栈,内置了 i18n 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件,它可以帮助你快速搭建企业级中后台产品原型。相信不管你的需求是什么,本项目都能帮助到你。 + +- [在线预览](http://panjiachen.github.io/vue-element-admin) + +- [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/) + +- [Gitter 讨论组](https://gitter.im/vue-element-admin/discuss) + +- [Donate](https://panjiachen.gitee.io/vue-element-admin-site/zh/donate) + +- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki) + +- [Gitee](https://panjiachen.gitee.io/vue-element-admin/) 在线预览(国内用户可访问该地址) + +- [国内访问文档](https://panjiachen.gitee.io/vue-element-admin-site/zh/) 文档(方便没翻墙的用户查看) + +- 基础模板建议使用: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template) +- 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) +- Typescript 版: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (鸣谢: [@Armour](https://github.com/Armour)) + +**目前版本为 `4.0-beta`,若发现问题,欢迎提[issue](https://github.com/PanJiaChen/vue-element-admin/issues/new)。若你想使用旧版本-稳定版,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0)** + +**该项目不支持低版本浏览器(如 ie),有需求请自行添加 polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)** + +群主 **[圈子](https://jianshiapp.com/circles/1209)** 群主会经常分享一些技术相关的东西,或者加入 [qq 群](https://github.com/PanJiaChen/vue-element-admin/issues/602) 或者关注 [微博](https://weibo.com/u/3423485724?is_all=1) + +## 前序准备 + +你需要在本地安装 [node](http://nodejs.org/) 和 [git](https://git-scm.com/)。本项目技术栈基于 [ES2015+](http://es6.ruanyifeng.com/)、[vue](https://cn.vuejs.org/index.html)、[vuex](https://vuex.vuejs.org/zh-cn/)、[vue-router](https://router.vuejs.org/zh-cn/) 、[vue-cli](https://github.com/vuejs/vue-cli) 、[axios](https://github.com/axios/axios) 和 [element-ui](https://github.com/ElemeFE/element),所有的请求数据都使用[Mock.js](https://github.com/nuysoft/Mock)进行模拟,提前了解和学习这些知识会对使用本项目有很大的帮助。 + +同时配套了系列教程文章,如何从零构建后一个完整的后台项目,建议大家先看完这些文章再来实践本项目 + +- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2) +- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac) +- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35) +- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板)](https://juejin.im/post/595b4d776fb9a06bbe7dba56) +- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836) +- [手摸手,带你优雅的使用 icon](https://juejin.im/post/59bb864b5188257e7a427c09) +- [手摸手,带你用合理的姿势使用 webpack4(上)](https://juejin.im/post/5b56909a518825195f499806) +- [手摸手,带你用合理的姿势使用 webpack4(下)](https://juejin.im/post/5b5d6d6f6fb9a04fea58aabc) + +**如有问题请先看上述使用文档和文章,若不能满足,欢迎 issue 和 pr** + +

+ +

+ +## Sponsors + +Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen) + +

Admin Dashboard Templates made with Vue, React and Angular.

+ +## 功能 + +``` +- 登录 / 注销 + +- 权限验证 + - 页面权限 + - 指令权限 + - 权限配置 + - 二步登录 + +- 多环境发布 + - dev sit stage prod + +- 全局功能 + - 国际化多语言 + - 多种动态换肤 + - 动态侧边栏(支持多级路由嵌套) + - 动态面包屑 + - 快捷导航(标签页) + - Svg Sprite 图标 + - 本地/后端 mock 数据 + - Screenfull全屏 + - 自适应收缩侧边栏 + +- 编辑器 + - 富文本 + - Markdown + - JSON 等多格式 + +- Excel + - 导出excel + - 导入excel + - 前端可视化excel + - 导出zip + +- 表格 + - 动态表格 + - 拖拽表格 + - 内联编辑 + +- 错误页面 + - 401 + - 404 + +- 組件 + - 头像上传 + - 返回顶部 + - 拖拽Dialog + - 拖拽Select + - 拖拽看板 + - 列表拖拽 + - SplitPane + - Dropzone + - Sticky + - CountTo + +- 综合实例 +- 错误日志 +- Dashboard +- 引导页 +- ECharts 图表 +- Clipboard(剪贴复制) +- Markdown2html +``` + +## 开发 + +```bash +# 克隆项目 +git clone https://github.com/PanJiaChen/vue-element-admin.git + +# 进入项目目录 +cd vue-element-admin + +# 安装依赖 +npm install + +# 建议不要用 cnpm 安装 会有各种诡异的bug 可以通过如下操作解决 npm 下载速度慢的问题 +npm install --registry=https://registry.npm.taobao.org + +# 启动服务 +npm run dev +``` + +浏览器访问 http://localhost:9527 + +## 发布 + +```bash +# 构建测试环境 +npm run build:stage + +# 构建生产环境 +npm run build:prod +``` + +## 其它 + +```bash +# 预览发布环境效果 +npm run preview + +# 预览发布环境效果 + 静态资源分析 +npm run preview -- --report + +# 代码格式检查 +npm run lint + +# 代码格式检查并自动修复 +npm run lint -- --fix +``` + +更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/) + +## Changelog + +Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases). + +## Online Demo + +[在线 Demo](http://panjiachen.github.io/vue-element-admin) + +## Donate + +如果你觉得这个项目帮助到了你,你可以帮作者买一杯果汁表示鼓励 :tropical_drink: +![donate](https://panjiachen.github.io/donate/donation.png) + +[更多捐赠方式](https://panjiachen.gitee.io/vue-element-admin-site/zh/donate) + +[Paypal Me](https://www.paypal.me/panfree23) + +[Buy me a coffee](https://www.buymeacoffee.com/Pan) + +## Browsers support + +Modern browsers and Internet Explorer 10+. + +| [IE / Edge](http://godban.github.io/browsers-support-badges/)
IE / Edge | [Firefox](http://godban.github.io/browsers-support-badges/)
Firefox | [Chrome](http://godban.github.io/browsers-support-badges/)
Chrome | [Safari](http://godban.github.io/browsers-support-badges/)
Safari | +| --------- | --------- | --------- | --------- | +| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions + +## License + +[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE) + +Copyright (c) 2017-present PanJiaChen diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..ba17966 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,5 @@ +module.exports = { + presets: [ + '@vue/app' + ] +} diff --git a/build/index.js b/build/index.js new file mode 100644 index 0000000..baf3807 --- /dev/null +++ b/build/index.js @@ -0,0 +1,35 @@ +const { run } = require('runjs') +const chalk = require('chalk') +const config = require('../vue.config.js') +const rawArgv = process.argv.slice(2) +const args = rawArgv.join(' ') + +if (process.env.npm_config_preview || rawArgv.includes('--preview')) { + const report = rawArgv.includes('--report') + + run(`vue-cli-service build ${args}`) + + const port = 9526 + const publicPath = config.publicPath + + var connect = require('connect') + var serveStatic = require('serve-static') + const app = connect() + + app.use( + publicPath, + serveStatic('./dist', { + index: ['index.html', '/'] + }) + ) + + app.listen(port, function () { + console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) + if (report) { + console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}/report.html`)) + } + + }) +} else { + run(`vue-cli-service build ${args}`) +} diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..1ce813e --- /dev/null +++ b/jest.config.js @@ -0,0 +1,27 @@ +module.exports = { + verbose: true, + moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], + transformIgnorePatterns: [ + 'node_modules/(?!(babel-jest|jest-vue-preprocessor)/)' + ], + transform: { + '^.+\\.vue$': 'vue-jest', + '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', + '^.+\\.jsx?$': 'babel-jest' + }, + moduleNameMapper: { + '^@/(.*)$': '/src/$1' + }, + snapshotSerializers: ['jest-serializer-vue'], + testMatch: [ + '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' + ], + collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'], + coverageDirectory: '/tests/unit/coverage', + // 'collectCoverage': true, + 'coverageReporters': [ + 'lcov', + 'text-summary' + ], + testURL: 'http://localhost/' +} diff --git a/mock/article.js b/mock/article.js new file mode 100644 index 0000000..45b7529 --- /dev/null +++ b/mock/article.js @@ -0,0 +1,116 @@ +import Mock from 'mockjs' + +const List = [] +const count = 100 + +const baseContent = '

我是测试数据我是测试数据

' +const image_uri = 'https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3' + +for (let i = 0; i < count; i++) { + List.push(Mock.mock({ + id: '@increment', + timestamp: +Mock.Random.date('T'), + author: '@first', + reviewer: '@first', + title: '@title(5, 10)', + content_short: 'mock data', + content: baseContent, + forecast: '@float(0, 100, 2, 2)', + importance: '@integer(1, 3)', + 'type|1': ['CN', 'US', 'JP', 'EU'], + 'status|1': ['published', 'draft', 'deleted'], + display_time: '@datetime', + comment_disabled: true, + pageviews: '@integer(300, 5000)', + image_uri, + platforms: ['a-platform'] + })) +} + +export default [ + { + url: '/article/list', + type: 'get', + response: config => { + const { importance, type, title, page = 1, limit = 20, sort } = config.query + + let mockList = List.filter(item => { + if (importance && item.importance !== +importance) return false + if (type && item.type !== type) return false + if (title && item.title.indexOf(title) < 0) return false + return true + }) + + if (sort === '-id') { + mockList = mockList.reverse() + } + + const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1)) + + return { + code: 20000, + data: { + total: mockList.length, + items: pageList + } + } + } + }, + + { + url: '/article/detail', + type: 'get', + response: config => { + const { id } = config.query + for (const article of List) { + if (article.id === +id) { + return { + code: 20000, + data: article + } + } + } + } + }, + + { + url: '/article/pv', + type: 'get', + response: _ => { + return { + code: 20000, + data: { + pvData: [ + { key: 'PC', pv: 1024 }, + { key: 'mobile', pv: 1024 }, + { key: 'ios', pv: 1024 }, + { key: 'android', pv: 1024 } + ] + } + } + } + }, + + { + url: '/article/create', + type: 'post', + response: _ => { + return { + code: 20000, + data: 'success' + } + } + }, + + { + url: '/article/update', + type: 'post', + response: _ => { + return { + code: 20000, + data: 'success' + } + } + } +] + diff --git a/mock/index.js b/mock/index.js new file mode 100644 index 0000000..7d9609a --- /dev/null +++ b/mock/index.js @@ -0,0 +1,57 @@ +import Mock from 'mockjs' +import mocks from './mocks' +import { param2Obj } from '../src/utils' + +const MOCK_API_BASE = '/mock' + +export function mockXHR() { + // 修复在使用 MockJS 情况下,设置 withCredentials = true,且未被拦截的跨域请求丢失 Cookies 的问题 + // https://github.com/nuysoft/Mock/issues/300 + Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send + Mock.XHR.prototype.send = function() { + if (this.custom.xhr) { + this.custom.xhr.withCredentials = this.withCredentials || false + + if (this.responseType) { + this.custom.xhr.responseType = this.responseType + } + } + this.proxy_send(...arguments) + } + + function XHR2ExpressReqWrap(respond) { + return function(options) { + let result = null + if (respond instanceof Function) { + const { body, type, url } = options + // https://expressjs.com/en/4x/api.html#req + result = respond({ + method: type, + body: JSON.parse(body), + query: param2Obj(url) + }) + } else { + result = respond + } + return Mock.mock(result) + } + } + + for (const i of mocks) { + Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response)) + } +} + +const responseFake = (url, type, respond) => { + return { + url: new RegExp(`${MOCK_API_BASE}${url}`), + type: type || 'get', + response(req, res) { + res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond)) + } + } +} + +export default mocks.map(route => { + return responseFake(route.url, route.type, route.response) +}) diff --git a/mock/mocks.js b/mock/mocks.js new file mode 100644 index 0000000..84a25dd --- /dev/null +++ b/mock/mocks.js @@ -0,0 +1,12 @@ +import user from './user' +import role from './role' +import article from './article' +import search from './remoteSearch' + +export default [ + ...user, + ...role, + ...article, + ...search +] + diff --git a/mock/remoteSearch.js b/mock/remoteSearch.js new file mode 100644 index 0000000..bb33c2f --- /dev/null +++ b/mock/remoteSearch.js @@ -0,0 +1,51 @@ +import Mock from 'mockjs' + +const NameList = [] +const count = 100 + +for (let i = 0; i < count; i++) { + NameList.push(Mock.mock({ + name: '@first' + })) +} +NameList.push({ name: 'mock-Pan' }) + +export default [ + // username search + { + url: '/search/user', + type: 'get', + response: config => { + const { name } = config.query + const mockNameList = NameList.filter(item => { + const lowerCaseName = item.name.toLowerCase() + return !(name && lowerCaseName.indexOf(name.toLowerCase()) < 0) + }) + return { + code: 20000, + data: { items: mockNameList } + } + } + }, + + // transaction list + { + url: '/transaction/list', + type: 'get', + response: _ => { + return { + code: 20000, + data: { + total: 20, + 'items|20': [{ + order_no: '@guid()', + timestamp: +Mock.Random.date('T'), + username: '@name()', + price: '@float(1000, 15000, 0, 2)', + 'status|1': ['success', 'pending'] + }] + } + } + } + } +] diff --git a/mock/role/index.js b/mock/role/index.js new file mode 100644 index 0000000..3914807 --- /dev/null +++ b/mock/role/index.js @@ -0,0 +1,98 @@ +import Mock from 'mockjs' +import { deepClone } from '../../src/utils/index.js' +import { asyncRoutes, constantRoutes } from './routes.js' + +const routes = deepClone([...constantRoutes, ...asyncRoutes]) + +const roles = [ + { + key: 'admin', + name: 'admin', + description: 'Super Administrator. Have access to view all pages.', + routes: routes + }, + { + key: 'editor', + name: 'editor', + description: 'Normal Editor. Can see all pages except permission page', + routes: routes.filter(i => i.path !== '/permission')// just a mock + }, + { + key: 'visitor', + name: 'visitor', + description: 'Just a visitor. Can only see the home page and the document page', + routes: [{ + path: '', + redirect: 'dashboard', + children: [ + { + path: 'dashboard', + name: 'Dashboard', + meta: { title: 'dashboard', icon: 'dashboard' } + } + ] + }] + } +] + +export default [ + // mock get all routes form server + { + url: '/routes', + type: 'get', + response: _ => { + return { + code: 20000, + data: routes + } + } + }, + + // mock get all roles form server + { + url: '/roles', + type: 'get', + response: _ => { + return { + code: 20000, + data: roles + } + } + }, + + // add role + { + url: '/role', + type: 'post', + response: { + code: 20000, + data: { + key: Mock.mock('@integer(300, 5000)') + } + } + }, + + // update role + { + url: '/role/[A-Za-z0-9]', + type: 'put', + response: { + code: 20000, + data: { + status: 'success' + } + } + }, + + // delete role + { + url: '/role/[A-Za-z0-9]', + type: 'delete', + response: { + code: 20000, + data: { + status: 'success' + } + } + } +] diff --git a/mock/role/routes.js b/mock/role/routes.js new file mode 100644 index 0000000..d8eaf42 --- /dev/null +++ b/mock/role/routes.js @@ -0,0 +1,525 @@ +// Just a mock data + +export const constantRoutes = [ + { + path: '/redirect', + component: 'layout/Layout', + hidden: true, + children: [ + { + path: '/redirect/:path*', + component: 'views/redirect/index' + } + ] + }, + { + path: '/login', + component: 'views/login/index', + hidden: true + }, + { + path: '/auth-redirect', + component: 'views/login/authredirect', + hidden: true + }, + { + path: '/404', + component: 'views/errorPage/404', + hidden: true + }, + { + path: '/401', + component: 'views/errorPage/401', + hidden: true + }, + { + path: '', + component: 'layout/Layout', + redirect: 'dashboard', + children: [ + { + path: 'dashboard', + component: 'views/dashboard/index', + name: 'Dashboard', + meta: { title: 'dashboard', icon: 'dashboard', noCache: true, affix: true } + } + ] + }, + { + path: '/documentation', + component: 'layout/Layout', + children: [ + { + path: 'index', + component: 'views/documentation/index', + name: 'Documentation', + meta: { title: 'documentation', icon: 'documentation', affix: true } + } + ] + }, + { + path: '/guide', + component: 'layout/Layout', + redirect: '/guide/index', + children: [ + { + path: 'index', + component: 'views/guide/index', + name: 'Guide', + meta: { title: 'guide', icon: 'guide', noCache: true } + } + ] + } +] + +export const asyncRoutes = [ + { + path: '/permission', + component: 'layout/Layout', + redirect: '/permission/index', + alwaysShow: true, + meta: { + title: 'permission', + icon: 'lock', + roles: ['admin', 'editor'] + }, + children: [ + { + path: 'page', + component: 'views/permission/page', + name: 'PagePermission', + meta: { + title: 'pagePermission', + roles: ['admin'] + } + }, + { + path: 'directive', + component: 'views/permission/directive', + name: 'DirectivePermission', + meta: { + title: 'directivePermission' + } + }, + { + path: 'role', + component: 'views/permission/role', + name: 'RolePermission', + meta: { + title: 'rolePermission', + roles: ['admin'] + } + } + ] + }, + + { + path: '/icon', + component: 'layout/Layout', + children: [ + { + path: 'index', + component: 'views/svg-icons/index', + name: 'Icons', + meta: { title: 'icons', icon: 'icon', noCache: true } + } + ] + }, + + { + path: '/components', + component: 'layout/Layout', + redirect: 'noredirect', + name: 'ComponentDemo', + meta: { + title: 'components', + icon: 'component' + }, + children: [ + { + path: 'tinymce', + component: 'views/components-demo/tinymce', + name: 'TinymceDemo', + meta: { title: 'tinymce' } + }, + { + path: 'markdown', + component: 'views/components-demo/markdown', + name: 'MarkdownDemo', + meta: { title: 'markdown' } + }, + { + path: 'json-editor', + component: 'views/components-demo/jsonEditor', + name: 'JsonEditorDemo', + meta: { title: 'jsonEditor' } + }, + { + path: 'splitpane', + component: 'views/components-demo/splitpane', + name: 'SplitpaneDemo', + meta: { title: 'splitPane' } + }, + { + path: 'avatar-upload', + component: 'views/components-demo/avatarUpload', + name: 'AvatarUploadDemo', + meta: { title: 'avatarUpload' } + }, + { + path: 'dropzone', + component: 'views/components-demo/dropzone', + name: 'DropzoneDemo', + meta: { title: 'dropzone' } + }, + { + path: 'sticky', + component: 'views/components-demo/sticky', + name: 'StickyDemo', + meta: { title: 'sticky' } + }, + { + path: 'count-to', + component: 'views/components-demo/countTo', + name: 'CountToDemo', + meta: { title: 'countTo' } + }, + { + path: 'mixin', + component: 'views/components-demo/mixin', + name: 'ComponentMixinDemo', + meta: { title: 'componentMixin' } + }, + { + path: 'back-to-top', + component: 'views/components-demo/backToTop', + name: 'BackToTopDemo', + meta: { title: 'backToTop' } + }, + { + path: 'drag-dialog', + component: 'views/components-demo/dragDialog', + name: 'DragDialogDemo', + meta: { title: 'dragDialog' } + }, + { + path: 'drag-select', + component: 'views/components-demo/dragSelect', + name: 'DragSelectDemo', + meta: { title: 'dragSelect' } + }, + { + path: 'dnd-list', + component: 'views/components-demo/dndList', + name: 'DndListDemo', + meta: { title: 'dndList' } + }, + { + path: 'drag-kanban', + component: 'views/components-demo/dragKanban', + name: 'DragKanbanDemo', + meta: { title: 'dragKanban' } + } + ] + }, + { + path: '/charts', + component: 'layout/Layout', + redirect: 'noredirect', + name: 'Charts', + meta: { + title: 'charts', + icon: 'chart' + }, + children: [ + { + path: 'keyboard', + component: 'views/charts/keyboard', + name: 'KeyboardChart', + meta: { title: 'keyboardChart', noCache: true } + }, + { + path: 'line', + component: 'views/charts/line', + name: 'LineChart', + meta: { title: 'lineChart', noCache: true } + }, + { + path: 'mixchart', + component: 'views/charts/mixChart', + name: 'MixChart', + meta: { title: 'mixChart', noCache: true } + } + ] + }, + { + path: '/nested', + component: 'layout/Layout', + redirect: '/nested/menu1/menu1-1', + name: 'Nested', + meta: { + title: 'nested', + icon: 'nested' + }, + children: [ + { + path: 'menu1', + component: 'views/nested/menu1/index', + name: 'Menu1', + meta: { title: 'menu1' }, + redirect: '/nested/menu1/menu1-1', + children: [ + { + path: 'menu1-1', + component: 'views/nested/menu1/menu1-1', + name: 'Menu1-1', + meta: { title: 'menu1-1' } + }, + { + path: 'menu1-2', + component: 'views/nested/menu1/menu1-2', + name: 'Menu1-2', + redirect: '/nested/menu1/menu1-2/menu1-2-1', + meta: { title: 'menu1-2' }, + children: [ + { + path: 'menu1-2-1', + component: 'views/nested/menu1/menu1-2/menu1-2-1', + name: 'Menu1-2-1', + meta: { title: 'menu1-2-1' } + }, + { + path: 'menu1-2-2', + component: 'views/nested/menu1/menu1-2/menu1-2-2', + name: 'Menu1-2-2', + meta: { title: 'menu1-2-2' } + } + ] + }, + { + path: 'menu1-3', + component: 'views/nested/menu1/menu1-3', + name: 'Menu1-3', + meta: { title: 'menu1-3' } + } + ] + }, + { + path: 'menu2', + name: 'Menu2', + component: 'views/nested/menu2/index', + meta: { title: 'menu2' } + } + ] + }, + + { + path: '/example', + component: 'layout/Layout', + redirect: '/example/list', + name: 'Example', + meta: { + title: 'example', + icon: 'example' + }, + children: [ + { + path: 'create', + component: 'views/example/create', + name: 'CreateArticle', + meta: { title: 'createArticle', icon: 'edit' } + }, + { + path: 'edit/:id(\\d+)', + component: 'views/example/edit', + name: 'EditArticle', + meta: { title: 'editArticle', noCache: true }, + hidden: true + }, + { + path: 'list', + component: 'views/example/list', + name: 'ArticleList', + meta: { title: 'articleList', icon: 'list' } + } + ] + }, + + { + path: '/tab', + component: 'layout/Layout', + children: [ + { + path: 'index', + component: 'views/tab/index', + name: 'Tab', + meta: { title: 'tab', icon: 'tab' } + } + ] + }, + + { + path: '/error', + component: 'layout/Layout', + redirect: 'noredirect', + name: 'ErrorPages', + meta: { + title: 'errorPages', + icon: '404' + }, + children: [ + { + path: '401', + component: 'views/errorPage/401', + name: 'Page401', + meta: { title: 'page401', noCache: true } + }, + { + path: '404', + component: 'views/errorPage/404', + name: 'Page404', + meta: { title: 'page404', noCache: true } + } + ] + }, + + { + path: '/error-log', + component: 'layout/Layout', + redirect: 'noredirect', + children: [ + { + path: 'log', + component: 'views/errorLog/index', + name: 'ErrorLog', + meta: { title: 'errorLog', icon: 'bug' } + } + ] + }, + + { + path: '/excel', + component: 'layout/Layout', + redirect: '/excel/export-excel', + name: 'Excel', + meta: { + title: 'excel', + icon: 'excel' + }, + children: [ + { + path: 'export-excel', + component: 'views/excel/exportExcel', + name: 'ExportExcel', + meta: { title: 'exportExcel' } + }, + { + path: 'export-selected-excel', + component: 'views/excel/selectExcel', + name: 'SelectExcel', + meta: { title: 'selectExcel' } + }, + { + path: 'export-merge-header', + component: 'views/excel/mergeHeader', + name: 'MergeHeader', + meta: { title: 'mergeHeader' } + }, + { + path: 'upload-excel', + component: 'views/excel/uploadExcel', + name: 'UploadExcel', + meta: { title: 'uploadExcel' } + } + ] + }, + + { + path: '/zip', + component: 'layout/Layout', + redirect: '/zip/download', + alwaysShow: true, + meta: { title: 'zip', icon: 'zip' }, + children: [ + { + path: 'download', + component: 'views/zip/index', + name: 'ExportZip', + meta: { title: 'exportZip' } + } + ] + }, + + { + path: '/pdf', + component: 'layout/Layout', + redirect: '/pdf/index', + children: [ + { + path: 'index', + component: 'views/pdf/index', + name: 'PDF', + meta: { title: 'pdf', icon: 'pdf' } + } + ] + }, + { + path: '/pdf/download', + component: 'views/pdf/download', + hidden: true + }, + + { + path: '/theme', + component: 'layout/Layout', + redirect: 'noredirect', + children: [ + { + path: 'index', + component: 'views/theme/index', + name: 'Theme', + meta: { title: 'theme', icon: 'theme' } + } + ] + }, + + { + path: '/clipboard', + component: 'layout/Layout', + redirect: 'noredirect', + children: [ + { + path: 'index', + component: 'views/clipboard/index', + name: 'ClipboardDemo', + meta: { title: 'clipboardDemo', icon: 'clipboard' } + } + ] + }, + + { + path: '/i18n', + component: 'layout/Layout', + children: [ + { + path: 'index', + component: 'views/i18n-demo/index', + name: 'I18n', + meta: { title: 'i18n', icon: 'international' } + } + ] + }, + + { + path: 'external-link', + component: 'layout/Layout', + children: [ + { + path: 'https://github.com/PanJiaChen/vue-element-admin', + meta: { title: 'externalLink', icon: 'link' } + } + ] + }, + + { path: '*', redirect: '/404', hidden: true } +] diff --git a/mock/user.js b/mock/user.js new file mode 100644 index 0000000..43f93a0 --- /dev/null +++ b/mock/user.js @@ -0,0 +1,84 @@ + +const tokens = { + admin: { + token: 'admin-token' + }, + editor: { + token: 'editor-token' + } +} + +const users = { + 'admin-token': { + roles: ['admin'], + introduction: 'I am a super administrator', + avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', + name: 'Super Admin' + }, + 'editor-token': { + roles: ['editor'], + introduction: 'I am an editor', + avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', + name: 'Normal Editor' + } +} + +export default [ + // user login + { + url: '/user/login', + type: 'post', + response: config => { + const { username } = config.body + const token = tokens[username] + + // mock error + if (!token) { + return { + code: 60204, + message: 'Account and password are incorrect.' + } + } + + return { + code: 20000, + data: token + } + } + }, + + // get user info + { + url: '/user/info\.*', + type: 'get', + response: config => { + const { token } = config.query + const info = users[token] + + // mock error + if (!info) { + return { + code: 50008, + message: 'Login failed, unable to get user details.' + } + } + + return { + code: 20000, + data: info + } + } + }, + + // user logout + { + url: '/user/logout', + type: 'post', + response: _ => { + return { + code: 20000, + data: 'success' + } + } + } +] diff --git a/package.json b/package.json new file mode 100644 index 0000000..12bf3ff --- /dev/null +++ b/package.json @@ -0,0 +1,112 @@ +{ + "name": "vue-element-admin", + "version": "4.0.0", + "description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features", + "author": "Pan ", + "license": "MIT", + "scripts": { + "dev": "vue-cli-service serve", + "build:prod": "vue-cli-service build", + "build:stage": "vue-cli-service build --mode staging", + "preview": "node build/index.js --preview", + "lint": "eslint --ext .js,.vue src", + "test:unit": "vue-cli-service test:unit", + "test:ci": "npm run lint && npm run test:unit", + "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml", + "new": "plop" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "src/**/*.{js,vue}": [ + "eslint --fix", + "git add" + ] + }, + "keywords": [ + "vue", + "admin", + "dashboard", + "element-ui", + "boilerplate", + "admin-template", + "management-system" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/PanJiaChen/vue-element-admin.git" + }, + "bugs": { + "url": "https://github.com/PanJiaChen/vue-element-admin/issues" + }, + "dependencies": { + "axios": "0.18.0", + "clipboard": "2.0.4", + "codemirror": "5.45.0", + "driver.js": "0.9.5", + "dropzone": "5.5.1", + "echarts": "4.2.1", + "element-ui": "2.7.0", + "file-saver": "2.0.1", + "fuse.js": "3.4.4", + "js-cookie": "2.2.0", + "jsonlint": "1.6.3", + "jszip": "3.2.1", + "normalize.css": "7.0.0", + "nprogress": "0.2.0", + "path-to-regexp": "2.4.0", + "screenfull": "4.2.0", + "showdown": "1.9.0", + "sortablejs": "1.8.4", + "tui-editor": "1.3.3", + "vue": "2.6.10", + "vue-count-to": "1.0.13", + "vue-i18n": "7.3.2", + "vue-router": "3.0.2", + "vue-splitpane": "1.0.4", + "vuedraggable": "2.20.0", + "vuex": "3.1.0", + "xlsx": "0.14.1" + }, + "devDependencies": { + "@babel/core": "7.0.0", + "@babel/register": "7.0.0", + "@vue/cli-plugin-babel": "3.5.3", + "@vue/cli-plugin-unit-jest": "3.5.3", + "@vue/cli-service": "3.5.3", + "@vue/test-utils": "1.0.0-beta.29", + "babel-core": "7.0.0-bridge.0", + "babel-eslint": "10.0.1", + "babel-jest": "23.6.0", + "chalk": "2.4.2", + "connect": "3.6.6", + "eslint": "5.15.3", + "eslint-plugin-vue": "5.2.2", + "html-webpack-plugin": "3.2.0", + "husky": "1.3.1", + "lint-staged": "8.1.5", + "mockjs": "1.0.1-beta3", + "node-sass": "^4.9.0", + "plop": "2.3.0", + "runjs": "^4.3.2", + "sass-loader": "^7.1.0", + "script-ext-html-webpack-plugin": "2.1.3", + "script-loader": "0.7.2", + "serve-static": "^1.13.2", + "svg-sprite-loader": "4.1.3", + "svgo": "1.2.0", + "vue-template-compiler": "2.6.10" + }, + "engines": { + "node": ">=8.9", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/plop-templates/component/index.hbs b/plop-templates/component/index.hbs new file mode 100644 index 0000000..7661055 --- /dev/null +++ b/plop-templates/component/index.hbs @@ -0,0 +1,26 @@ +{{#if template}} + +{{/if}} + +{{#if script}} + +{{/if}} + +{{#if style}} + +{{/if}} diff --git a/plop-templates/component/prompt.js b/plop-templates/component/prompt.js new file mode 100644 index 0000000..3723e8e --- /dev/null +++ b/plop-templates/component/prompt.js @@ -0,0 +1,55 @@ +const { notEmpty } = require('../utils.js') + +module.exports = { + description: 'generate vue component', + prompts: [{ + type: 'input', + name: 'name', + message: 'component name please', + validate: notEmpty('name') + }, + { + type: 'checkbox', + name: 'blocks', + message: 'Blocks:', + choices: [{ + name: '