├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .idea ├── misc.xml ├── modules.xml ├── my-element-admin.iml └── vcs.xml ├── .postcssrc.js ├── .travis.yml ├── LICENSE ├── README.md ├── build ├── build.js ├── check-versions.js ├── logo.png ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── docs ├── favicon.ico ├── index.html └── static │ ├── css │ └── app.e5f81c9b9ae07217a14134dc6772d43f.css │ ├── fonts │ └── element-icons.6f0a763.ttf │ ├── img │ ├── 404.a57b6f3.png │ └── logo.9b66607.png │ ├── js │ ├── 0.ccd5bb0fb0c9af8f6f10.js │ ├── 1.1f835e2f8d5db9dcd59e.js │ ├── 10.875e015d238c6f89b3f2.js │ ├── 11.7dc377066b380271e25f.js │ ├── 12.ba2fc47858f669d8bf9e.js │ ├── 13.76de13fb458034f38728.js │ ├── 14.e6ef9a5ae0e76f51d58a.js │ ├── 15.9558c18d5bf0d9cf8883.js │ ├── 16.c9c6914ea5237adad00c.js │ ├── 17.aae8e809e80ce18439f3.js │ ├── 2.530e37f5617a4bd75689.js │ ├── 20.7a8fbdd65b4340bf3784.js │ ├── 3.1425dc773a8d238d9bfb.js │ ├── 4.41f2384a1c0f6f23aab4.js │ ├── 5.6b4ee609e8f374a75b4d.js │ ├── 6.99ee63f13a7b8da01b96.js │ ├── 7.66d597151b857835171e.js │ ├── 8.50a477be8571bc6592d8.js │ ├── 9.8f0b7074169324f784e8.js │ ├── app.2db2d31c82d2e780386b.js │ ├── manifest.c010323a91f46147066d.js │ └── vendor.27d01a4e45b1f29c663f.js │ └── tinymce │ ├── langs │ └── zh_CN.js │ ├── plugins │ ├── codesample │ │ └── css │ │ │ └── prism.css │ ├── emoticons │ │ └── img │ │ │ ├── smiley-cool.gif │ │ │ ├── smiley-cry.gif │ │ │ ├── smiley-embarassed.gif │ │ │ ├── smiley-foot-in-mouth.gif │ │ │ ├── smiley-frown.gif │ │ │ ├── smiley-innocent.gif │ │ │ ├── smiley-kiss.gif │ │ │ ├── smiley-laughing.gif │ │ │ ├── smiley-money-mouth.gif │ │ │ ├── smiley-sealed.gif │ │ │ ├── smiley-smile.gif │ │ │ ├── smiley-surprised.gif │ │ │ ├── smiley-tongue-out.gif │ │ │ ├── smiley-undecided.gif │ │ │ ├── smiley-wink.gif │ │ │ └── smiley-yell.gif │ └── visualblocks │ │ └── css │ │ └── visualblocks.css │ ├── skins │ └── lightgray │ │ ├── content.inline.min.css │ │ ├── content.min.css │ │ ├── fonts │ │ ├── tinymce-mobile.woff │ │ ├── tinymce-small.eot │ │ ├── tinymce-small.svg │ │ ├── tinymce-small.ttf │ │ ├── tinymce-small.woff │ │ ├── tinymce.eot │ │ ├── tinymce.svg │ │ ├── tinymce.ttf │ │ └── tinymce.woff │ │ ├── img │ │ ├── anchor.gif │ │ ├── loader.gif │ │ ├── object.gif │ │ └── trans.gif │ │ ├── skin.min.css │ │ └── skin.min.css.map │ └── tinymce.min.js ├── favicon.ico ├── index.html ├── package-lock.json ├── package.json ├── src ├── App.vue ├── api │ ├── article.js │ ├── login.js │ ├── table.js │ └── treeApi.js ├── assets │ ├── 404_images │ │ ├── 404.png │ │ └── 404_cloud.png │ └── images │ │ └── logo.png ├── components │ ├── Breadcrumb │ │ └── index.vue │ ├── ErrLog │ │ └── index.vue │ ├── Hamburger │ │ └── index.vue │ ├── Mdinput │ │ └── index.vue │ ├── Screenfull │ │ └── index.vue │ ├── ScrollBar │ │ └── index.vue │ ├── SvgIcon │ │ └── index.vue │ ├── Tinymce │ │ └── index.vue │ ├── month │ │ └── month.vue │ ├── nx-back-to-top │ │ └── index.vue │ ├── nx-top-lock │ │ └── index.vue │ ├── panThumb │ │ └── index.vue │ ├── treeMen │ │ └── index.vue │ └── week_detail │ │ └── week_detail.vue ├── directive │ └── waves │ │ ├── index.js │ │ ├── waves.css │ │ └── waves.js ├── errorLog.js ├── icons │ ├── index.js │ └── svg │ │ ├── 404.svg │ │ ├── TreeMean.svg │ │ ├── bug.svg │ │ ├── chart.svg │ │ ├── clipboard.svg │ │ ├── component.svg │ │ ├── dashboard.svg │ │ ├── documentation.svg │ │ ├── drag.svg │ │ ├── email.svg │ │ ├── example.svg │ │ ├── excel.svg │ │ ├── eye.svg │ │ ├── form.svg │ │ ├── icon.svg │ │ ├── international.svg │ │ ├── language.svg │ │ ├── lock.svg │ │ ├── message.svg │ │ ├── money.svg │ │ ├── password.svg │ │ ├── people.svg │ │ ├── peoples.svg │ │ ├── qq.svg │ │ ├── shoppingCard.svg │ │ ├── star.svg │ │ ├── tab.svg │ │ ├── table.svg │ │ ├── theme.svg │ │ ├── tree.svg │ │ ├── user.svg │ │ ├── wechat.svg │ │ └── zip.svg ├── lang │ ├── en.js │ ├── index.js │ └── zh.js ├── main.js ├── mock │ ├── article.js │ ├── index.js │ └── login.js ├── permission.js ├── router │ ├── _import_development.js │ ├── _import_production.js │ └── index.js ├── screenshots │ ├── easy-mock.png │ ├── index.png │ ├── login.png │ ├── schedule.png │ ├── table.png │ ├── topic.png │ └── xker.gif ├── store │ ├── errLog.js │ ├── getters.js │ ├── index.js │ └── modules │ │ ├── app.js │ │ ├── permission.js │ │ └── user.js ├── styles │ ├── btn.scss │ ├── element-ui.scss │ ├── index.scss │ ├── mixin.scss │ ├── sidebar.scss │ ├── transition.scss │ └── variables.scss ├── utils │ ├── auth.js │ ├── clipboard.js │ ├── genUptoken.js │ ├── i18n.js │ ├── index.js │ ├── request.js │ └── validate.js ├── vendor │ ├── Blob.js │ └── Export2Excel.js └── views │ ├── 404.vue │ ├── components │ ├── backToTop.vue │ └── mixin.vue │ ├── dashboard │ ├── admin │ │ ├── components │ │ │ ├── echart.vue │ │ │ └── panelGroup.vue │ │ └── index.vue │ ├── editor │ │ └── index.vue │ └── index.vue │ ├── excel │ └── exportExcel.vue │ ├── form │ ├── index.vue │ ├── qiniu.vue │ ├── quillEditor.vue │ └── tinymce.vue │ ├── fullcalendar │ └── fullcalendar.vue │ ├── i18n-demo │ ├── indexLang.vue │ └── local.js │ ├── layout │ ├── Layout.vue │ └── components │ │ ├── AppMain.vue │ │ ├── Navbar.vue │ │ ├── Sidebar │ │ ├── SidebarItem.vue │ │ └── index.vue │ │ └── index.js │ ├── login │ └── index.vue │ ├── svg-icon │ ├── generateIconsView.js │ └── index.vue │ ├── tab │ └── index.vue │ ├── table │ └── index.vue │ └── tree │ └── index.vue └── static ├── .gitkeep ├── qiniu.js └── tinymce ├── langs └── zh_CN.js ├── plugins ├── codesample │ └── css │ │ └── prism.css ├── emoticons │ └── img │ │ ├── smiley-cool.gif │ │ ├── smiley-cry.gif │ │ ├── smiley-embarassed.gif │ │ ├── smiley-foot-in-mouth.gif │ │ ├── smiley-frown.gif │ │ ├── smiley-innocent.gif │ │ ├── smiley-kiss.gif │ │ ├── smiley-laughing.gif │ │ ├── smiley-money-mouth.gif │ │ ├── smiley-sealed.gif │ │ ├── smiley-smile.gif │ │ ├── smiley-surprised.gif │ │ ├── smiley-tongue-out.gif │ │ ├── smiley-undecided.gif │ │ ├── smiley-wink.gif │ │ └── smiley-yell.gif └── visualblocks │ └── css │ └── visualblocks.css ├── skins └── lightgray │ ├── content.inline.min.css │ ├── content.min.css │ ├── fonts │ ├── tinymce-mobile.woff │ ├── tinymce-small.eot │ ├── tinymce-small.svg │ ├── tinymce-small.ttf │ ├── tinymce-small.woff │ ├── tinymce.eot │ ├── tinymce.svg │ ├── tinymce.ttf │ └── tinymce.woff │ ├── img │ ├── anchor.gif │ ├── loader.gif │ ├── object.gif │ └── trans.gif │ ├── skin.min.css │ └── skin.min.css.map └── tinymce.min.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins":["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | insert_final_newline = false 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | src/assets 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | package-lock.json 8 | 9 | # Editor directories and files 10 | .idea 11 | .vscode 12 | *.suo 13 | *.ntvs* 14 | *.njsproj 15 | *.sln 16 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/my-element-admin.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserslist" field in package.json 6 | "postcss-import": {}, 7 | "autoprefixer": {} 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: stable 3 | script: npm run test 4 | notifications: 5 | email: false 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-present PanJiaChen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-element-admin 2 | 3 | 技术栈 vue2.0 + elementUI +vuex + easy-mock + vue-router + es6 如果对你有帮助 请点右上角star,谢谢 4 | 5 | 6 | # 概述 7 | 这两个月一直忙于公司的后台管理系统开发,现在准备把我司用到的一些组件抽离出来,在写我司项目之前,也看了各种文档,所以想抽离出来,写一个后台系统, 因为公司的项目还没结束,所以这个项目会在平时有时间继续完善功能。 8 | 9 | 目前数据采用easy-mock进行数据模拟, Easy Mock 是一个可视化,并且能快速生成 模拟数据 的持久化服务。 忘掉下面这些实用但麻烦的 Mock 方式吧。在你用了 Easy Mock 之后,你肯定会爱不释手的。具体用法请看api文档 10 | 11 | 访问: https://www.easy-mock.com/ 12 | 13 | ![image](https://github.com/endless-z/vue-element-admin/blob/master/src/screenshots/easy-mock.png) 14 | 15 | 16 | # 在线演示请点这里 17 | 18 | [Preview] 19 | [在线 Demo](http://endless-z.github.io/vue-element-admin/#/) 20 | # 基于Vue2.0实现后台系统权限控制 21 | 本项目目前设置了两种管理员 1、admin 2、editor 22 | 每种类型的人看到的侧边栏不一样,可以进行的操作也不尽相同,于是就需要程序处理一下各个权限问题。 23 | 24 | 关于这个权限的控制 请看这边文章,说的都比较详情 [手摸手,带你用vue撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac) 25 | 26 | # 参考文档 27 | 28 | 请看这位大神:https://segmentfault.com/a/1190000009506097 29 | 30 | 这是我司的项目首页 效果如下: 31 | 32 | 在线体验功能:后续会把这个项目上线 敬请期待! 33 | # 本项目部分截图预览 34 | 35 | ![image](https://github.com/endless-z/vue-element-admin/blob/master/src/screenshots/login.png) 36 | ![image](https://github.com/endless-z/vue-element-admin/blob/master/src/screenshots/table.png) 37 | 38 | ## Build Setup 39 | 40 | 41 | ``` bash 42 | # install dependencies 43 | npm install 44 | 45 | 46 | 如果 npm install 出现问题 建议安装淘宝镜像 47 | 48 | # serve with hot reload at localhost:9528 49 | npm run dev 50 | 51 | # build for production with minification 52 | npm run build 53 | ``` 54 | 55 | 如果对你有帮助 请点右上角star,谢谢 56 | 57 | 58 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | process.env.NODE_ENV = 'production' 5 | 6 | const ora = require('ora') 7 | const rm = require('rimraf') 8 | const path = require('path') 9 | const chalk = require('chalk') 10 | const webpack = require('webpack') 11 | const config = require('../config') 12 | const webpackConfig = require('./webpack.prod.conf') 13 | 14 | const spinner = ora('building for production...') 15 | spinner.start() 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err 19 | webpack(webpackConfig, (err, stats) => { 20 | spinner.stop() 21 | if (err) throw err 22 | process.stdout.write(stats.toString({ 23 | colors: true, 24 | modules: false, 25 | children: false, 26 | chunks: false, 27 | chunkModules: false 28 | }) + '\n\n') 29 | 30 | if (stats.hasErrors()) { 31 | console.log(chalk.red(' Build failed with errors.\n')) 32 | process.exit(1) 33 | } 34 | 35 | console.log(chalk.cyan(' Build complete.\n')) 36 | console.log(chalk.yellow( 37 | ' Tip: built files are meant to be served over an HTTP server.\n' + 38 | ' Opening index.html over file:// won\'t work.\n' 39 | )) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const chalk = require('chalk') 3 | const semver = require('semver') 4 | const packageConfig = require('../package.json') 5 | const shell = require('shelljs') 6 | 7 | function exec (cmd) { 8 | return require('child_process').execSync(cmd).toString().trim() 9 | } 10 | 11 | const versionRequirements = [ 12 | { 13 | name: 'node', 14 | currentVersion: semver.clean(process.version), 15 | versionRequirement: packageConfig.engines.node 16 | } 17 | ] 18 | 19 | if (shell.which('npm')) { 20 | versionRequirements.push({ 21 | name: 'npm', 22 | currentVersion: exec('npm --version'), 23 | versionRequirement: packageConfig.engines.npm 24 | }) 25 | } 26 | 27 | module.exports = function () { 28 | const warnings = [] 29 | 30 | for (let i = 0; i < versionRequirements.length; i++) { 31 | const mod = versionRequirements[i] 32 | 33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 34 | warnings.push(mod.name + ': ' + 35 | chalk.red(mod.currentVersion) + ' should be ' + 36 | chalk.green(mod.versionRequirement) 37 | ) 38 | } 39 | } 40 | 41 | if (warnings.length) { 42 | console.log('') 43 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 44 | console.log() 45 | 46 | for (let i = 0; i < warnings.length; i++) { 47 | const warning = warnings[i] 48 | console.log(' ' + warning) 49 | } 50 | 51 | console.log() 52 | process.exit(1) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /build/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/build/logo.png -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const config = require('../config') 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | const packageConfig = require('../package.json') 6 | 7 | exports.assetsPath = function (_path) { 8 | const assetsSubDirectory = process.env.NODE_ENV === 'production' 9 | ? config.build.assetsSubDirectory 10 | : config.dev.assetsSubDirectory 11 | 12 | return path.posix.join(assetsSubDirectory, _path) 13 | } 14 | 15 | exports.cssLoaders = function (options) { 16 | options = options || {} 17 | 18 | const cssLoader = { 19 | loader: 'css-loader', 20 | options: { 21 | sourceMap: options.sourceMap 22 | } 23 | } 24 | 25 | const postcssLoader = { 26 | loader: 'postcss-loader', 27 | options: { 28 | sourceMap: options.sourceMap 29 | } 30 | } 31 | 32 | // generate loader string to be used with extract text plugin 33 | function generateLoaders (loader, loaderOptions) { 34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] 35 | 36 | if (loader) { 37 | loaders.push({ 38 | loader: loader + '-loader', 39 | options: Object.assign({}, loaderOptions, { 40 | sourceMap: options.sourceMap 41 | }) 42 | }) 43 | } 44 | 45 | // Extract CSS when that option is specified 46 | // (which is the case during production build) 47 | if (options.extract) { 48 | return ExtractTextPlugin.extract({ 49 | use: loaders, 50 | fallback: 'vue-style-loader' 51 | }) 52 | } else { 53 | return ['vue-style-loader'].concat(loaders) 54 | } 55 | } 56 | 57 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 58 | return { 59 | css: generateLoaders(), 60 | postcss: generateLoaders(), 61 | less: generateLoaders('less'), 62 | sass: generateLoaders('sass', { indentedSyntax: true }), 63 | scss: generateLoaders('sass'), 64 | stylus: generateLoaders('stylus'), 65 | styl: generateLoaders('stylus') 66 | } 67 | } 68 | 69 | // Generate loaders for standalone style files (outside of .vue) 70 | exports.styleLoaders = function (options) { 71 | const output = [] 72 | const loaders = exports.cssLoaders(options) 73 | 74 | for (const extension in loaders) { 75 | const loader = loaders[extension] 76 | output.push({ 77 | test: new RegExp('\\.' + extension + '$'), 78 | use: loader 79 | }) 80 | } 81 | 82 | return output 83 | } 84 | 85 | exports.createNotifierCallback = () => { 86 | const notifier = require('node-notifier') 87 | 88 | return (severity, errors) => { 89 | if (severity !== 'error') return 90 | 91 | const error = errors[0] 92 | const filename = error.file && error.file.split('!').pop() 93 | 94 | notifier.notify({ 95 | title: packageConfig.name, 96 | message: severity + ': ' + error.name, 97 | subtitle: filename || '', 98 | icon: path.join(__dirname, 'logo.png') 99 | }) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('../config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | const sourceMapEnabled = isProduction 6 | ? config.build.productionSourceMap 7 | : config.dev.cssSourceMap 8 | 9 | module.exports = { 10 | loaders: utils.cssLoaders({ 11 | sourceMap: sourceMapEnabled, 12 | extract: isProduction 13 | }), 14 | cssSourceMap: sourceMapEnabled, 15 | cacheBusting: config.dev.cacheBusting, 16 | transformToRequire: { 17 | video: ['src', 'poster'], 18 | source: 'src', 19 | img: 'src', 20 | image: 'xlink:href' 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const path = require("path"); 3 | const utils = require("./utils"); 4 | const config = require("../config"); 5 | const vueLoaderConfig = require("./vue-loader.conf"); 6 | 7 | function resolve(dir) { 8 | return path.join(__dirname, "..", dir); 9 | } 10 | 11 | const createLintingRule = () => ({ 12 | test: /\.(js|vue)$/, 13 | loader: "eslint-loader", 14 | enforce: "pre", 15 | include: [resolve("src"), resolve("test")], 16 | options: { 17 | formatter: require("eslint-friendly-formatter"), 18 | emitWarning: !config.dev.showEslintErrorsInOverlay 19 | } 20 | }); 21 | 22 | module.exports = { 23 | context: path.resolve(__dirname, "../"), 24 | entry: { 25 | app: "./src/main.js" 26 | }, 27 | output: { 28 | path: config.build.assetsRoot, 29 | filename: "[name].js", 30 | publicPath: 31 | process.env.NODE_ENV === "production" 32 | ? config.build.assetsPublicPath 33 | : config.dev.assetsPublicPath 34 | }, 35 | resolve: { 36 | extensions: [".js", ".vue", ".json"], 37 | alias: { 38 | vue$: "vue/dist/vue.js", 39 | "@": resolve("src"), 40 | 'components': path.resolve(__dirname, '../src/components'), 41 | } 42 | }, 43 | module: { 44 | rules: [ 45 | ...(config.dev.useEslint ? [createLintingRule()] : []), 46 | { 47 | test: /\.vue$/, 48 | loader: "vue-loader", 49 | options: vueLoaderConfig 50 | }, 51 | { 52 | test: /\.js$/, 53 | loader: "babel-loader", 54 | include: [ 55 | resolve("src"), 56 | resolve("test"), 57 | resolve("node_modules/webpack-dev-server/client") 58 | ] 59 | }, 60 | { 61 | test: /\.svg$/, 62 | loader: "svg-sprite-loader", 63 | include: [resolve("src/icons")], 64 | options: { 65 | symbolId: "icon-[name]" 66 | } 67 | }, 68 | { 69 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 70 | loader: "url-loader", 71 | exclude: [resolve("src/icons")], 72 | options: { 73 | limit: 10000, 74 | name: utils.assetsPath("img/[name].[hash:7].[ext]") 75 | } 76 | }, 77 | { 78 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 79 | loader: "url-loader", 80 | options: { 81 | limit: 10000, 82 | name: utils.assetsPath("media/[name].[hash:7].[ext]") 83 | } 84 | }, 85 | { 86 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 87 | loader: "url-loader", 88 | options: { 89 | limit: 10000, 90 | name: utils.assetsPath("fonts/[name].[hash:7].[ext]") 91 | } 92 | } 93 | ] 94 | }, 95 | node: { 96 | // prevent webpack from injecting useless setImmediate polyfill because Vue 97 | // source contains it (although only uses it if it's native). 98 | setImmediate: false, 99 | // prevent webpack from injecting mocks to Node native modules 100 | // that does not make sense for the client 101 | dgram: "empty", 102 | fs: "empty", 103 | net: "empty", 104 | tls: "empty", 105 | child_process: "empty" 106 | } 107 | }; 108 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const webpack = require('webpack') 5 | const config = require('../config') 6 | const merge = require('webpack-merge') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const HtmlWebpackPlugin = require('html-webpack-plugin') 9 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 10 | const portfinder = require('portfinder') 11 | 12 | function resolve (dir) { 13 | return path.join(__dirname, '..', dir) 14 | } 15 | 16 | const HOST = process.env.HOST 17 | const PORT = process.env.PORT && Number(process.env.PORT) 18 | 19 | const devWebpackConfig = merge(baseWebpackConfig, { 20 | module: { 21 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) 22 | }, 23 | // cheap-module-eval-source-map is faster for development 24 | devtool: config.dev.devtool, 25 | 26 | // these devServer options should be customized in /config/index.js 27 | devServer: { 28 | clientLogLevel: 'warning', 29 | historyApiFallback: true, 30 | hot: true, 31 | compress: true, 32 | host: HOST || config.dev.host, 33 | port: PORT || config.dev.port, 34 | open: config.dev.autoOpenBrowser, 35 | overlay: config.dev.errorOverlay 36 | ? { warnings: false, errors: true } 37 | : false, 38 | publicPath: config.dev.assetsPublicPath, 39 | proxy: config.dev.proxyTable, 40 | quiet: true, // necessary for FriendlyErrorsPlugin 41 | watchOptions: { 42 | poll: config.dev.poll, 43 | } 44 | }, 45 | plugins: [ 46 | new webpack.DefinePlugin({ 47 | 'process.env': require('../config/dev.env') 48 | }), 49 | new webpack.HotModuleReplacementPlugin(), 50 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. 51 | new webpack.NoEmitOnErrorsPlugin(), 52 | // https://github.com/ampedandwired/html-webpack-plugin 53 | new HtmlWebpackPlugin({ 54 | filename: 'index.html', 55 | template: 'index.html', 56 | inject: true, 57 | favicon: resolve('favicon.ico'), 58 | title: 'vue-element-admin' 59 | }), 60 | ] 61 | }) 62 | 63 | module.exports = new Promise((resolve, reject) => { 64 | portfinder.basePort = process.env.PORT || config.dev.port 65 | portfinder.getPort((err, port) => { 66 | if (err) { 67 | reject(err) 68 | } else { 69 | // publish the new Port, necessary for e2e tests 70 | process.env.PORT = port 71 | // add port to devServer config 72 | devWebpackConfig.devServer.port = port 73 | 74 | // Add FriendlyErrorsPlugin 75 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ 76 | compilationSuccessInfo: { 77 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], 78 | }, 79 | onErrors: config.dev.notifyOnErrors 80 | ? utils.createNotifierCallback() 81 | : undefined 82 | })) 83 | 84 | resolve(devWebpackConfig) 85 | } 86 | }) 87 | }) 88 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"', 7 | BASE_API: '" https://www.easy-mock.com/mock/5aa5f401a99e172c9fe77f05/vue-element-admin"', 8 | }) -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.2.6 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: 'localhost', // can be overwritten by process.env.HOST 17 | port: 9529, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: true, 19 | errorOverlay: true, 20 | notifyOnErrors: false, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | // Use Eslint Loader? 24 | // If true, your code will be linted during bundling and 25 | // linting errors and warnings will be shown in the console. 26 | useEslint: true, 27 | // If true, eslint errors and warnings will also be shown in the error overlay 28 | // in the browser. 29 | showEslintErrorsInOverlay: false, 30 | devtool: 'cheap-source-map', 31 | cacheBusting: true, 32 | cssSourceMap: false, 33 | }, 34 | 35 | build: { 36 | // Template for index.html 37 | index: path.resolve(__dirname, '../docs/index.html'), 38 | 39 | // Paths 40 | assetsRoot: path.resolve(__dirname, '../docs'), 41 | assetsSubDirectory: 'static', 42 | 43 | // you can set by youself according to actual condition 44 | assetsPublicPath: './', 45 | 46 | /** 47 | * Source Maps 48 | */ 49 | 50 | productionSourceMap: false, 51 | devtool: '#source-map', 52 | productionGzip: false, 53 | productionGzipExtensions: ['js', 'css'], 54 | bundleAnalyzerReport: process.env.npm_config_report 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"', 4 | BASE_API: '"https://easy-mock.com/mock/5aa5f401a99e172c9fe77f05/vue-element-admin"', 5 | } 6 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/favicon.ico -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | vue-element-admin

初次加载,请耐心等待...

-------------------------------------------------------------------------------- /docs/static/fonts/element-icons.6f0a763.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/fonts/element-icons.6f0a763.ttf -------------------------------------------------------------------------------- /docs/static/img/404.a57b6f3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/img/404.a57b6f3.png -------------------------------------------------------------------------------- /docs/static/img/logo.9b66607.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/img/logo.9b66607.png -------------------------------------------------------------------------------- /docs/static/js/15.9558c18d5bf0d9cf8883.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([15],{"16Yb":function(n,a,t){var e=t("uTky");"string"==typeof e&&(e=[[n.i,e,""]]),e.locals&&(n.exports=e.locals);t("8bSs")("35dbd851",e,!0)},DY7s:function(n,a,t){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var e=t("4YfN"),i=t.n(e),o=t("9rMa"),s={name:"dashboard-editor",data:function(){return{emptyGif:"https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3"}},components:{PanThumb:t("kCe2").a},computed:i()({},Object(o.b)(["name","avatar","roles"]))},r={render:function(){var n=this,a=n.$createElement,t=n._self._c||a;return t("div",{staticClass:"dashboard-editor-container"},[t("div",{staticClass:" clearfix"},[t("pan-thumb",{staticStyle:{float:"left"},attrs:{image:n.avatar}},[n._v(" 你的权限:\n "),n._l(n.roles,function(a){return t("span",{key:a,staticClass:"pan-info-roles"},[n._v(n._s(a))])})],2),n._v(" "),t("div",{staticClass:"info-container"},[t("span",{staticClass:"display_name"},[n._v(n._s(n.name))]),n._v(" "),t("span",{staticStyle:{"font-size":"20px","padding-top":"20px",display:"inline-block"}},[n._v("欢迎来到Vue后台管理系统")])])],1),n._v(" "),t("div",[t("img",{staticClass:"emptyGif",attrs:{src:n.emptyGif}})])])},staticRenderFns:[]};var d=t("/Xao")(s,r,!1,function(n){t("16Yb")},"data-v-7ec10b44",null);a.default=d.exports},uTky:function(n,a,t){(n.exports=t("BkJT")(!1)).push([n.i,"\n.emptyGif[data-v-7ec10b44] {\n display: block;\n width: 45%;\n margin: 0 auto;\n}\n.dashboard-editor-container[data-v-7ec10b44] {\n background-color: #e3e3e3;\n min-height: 100vh;\n margin-top: -50px;\n padding: 100px 60px 0px;\n}\n.dashboard-editor-container .pan-info-roles[data-v-7ec10b44] {\n font-size: 12px;\n font-weight: 700;\n color: #333;\n display: block;\n}\n.dashboard-editor-container .info-container[data-v-7ec10b44] {\n position: relative;\n margin-left: 190px;\n height: 150px;\n line-height: 200px;\n}\n.dashboard-editor-container .info-container .display_name[data-v-7ec10b44] {\n font-size: 48px;\n line-height: 48px;\n color: #212121;\n position: absolute;\n top: 25px;\n}\n",""])}}); -------------------------------------------------------------------------------- /docs/static/js/17.aae8e809e80ce18439f3.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([17],{"1Rx3":function(a,t,e){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=e("Mv28"),r=e("YBuj"),o={newVisitis:{expectedData:[100,120,161,134,105,160,165],actualData:[120,82,91,154,162,140,145]},messages:{expectedData:[200,192,120,144,160,130,140],actualData:[180,160,151,106,145,150,130]},purchases:{expectedData:[80,100,121,104,105,90,100],actualData:[120,90,100,138,142,130,130]},shoppings:{expectedData:[130,140,141,142,145,150,160],actualData:[120,82,91,154,162,140,130]}},i={name:"dashboard-admin",components:{PanelGroup:n.default,echart:r.default},data:function(){return{lineChartData:o.newVisitis}},methods:{handleSetLineChartData:function(a){this.lineChartData=o[a]}}},d={render:function(){var a=this.$createElement,t=this._self._c||a;return t("div",{staticClass:"dashboard-editor-container"},[t("panel-group",{on:{handleSetLineChartData:this.handleSetLineChartData}}),this._v(" "),t("el-row",{staticStyle:{background:"#fff",padding:"16px 16px 0","margin-bottom":"32px"}},[t("echart")],1)],1)},staticRenderFns:[]};var c=e("/Xao")(i,d,!1,function(a){e("GcNI")},"data-v-2152a60c",null);t.default=c.exports},GcNI:function(a,t,e){var n=e("S4do");"string"==typeof n&&(n=[[a.i,n,""]]),n.locals&&(a.exports=n.locals);e("8bSs")("d722e60a",n,!0)},S4do:function(a,t,e){(a.exports=e("BkJT")(!1)).push([a.i,"\n.dashboard-editor-container[data-v-2152a60c] {\n padding: 32px;\n background-color: #f0f2f5;\n}\n.dashboard-editor-container .chart-wrapper[data-v-2152a60c] {\n background: #fff;\n padding: 16px 16px 0;\n margin-bottom: 32px;\n}\n",""])}}); -------------------------------------------------------------------------------- /docs/static/js/manifest.c010323a91f46147066d.js: -------------------------------------------------------------------------------- 1 | !function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,f,a){for(var c,d,i,u=0,b=[];u code[class*="language-"], 58 | pre[class*="language-"] { 59 | background: #f5f2f0; 60 | } 61 | 62 | /* Inline code */ 63 | :not(pre) > code[class*="language-"] { 64 | padding: .1em; 65 | border-radius: .3em; 66 | } 67 | 68 | .token.comment, 69 | .token.prolog, 70 | .token.doctype, 71 | .token.cdata { 72 | color: slategray; 73 | } 74 | 75 | .token.punctuation { 76 | color: #999; 77 | } 78 | 79 | .namespace { 80 | opacity: .7; 81 | } 82 | 83 | .token.property, 84 | .token.tag, 85 | .token.boolean, 86 | .token.number, 87 | .token.constant, 88 | .token.symbol, 89 | .token.deleted { 90 | color: #905; 91 | } 92 | 93 | .token.selector, 94 | .token.attr-name, 95 | .token.string, 96 | .token.char, 97 | .token.builtin, 98 | .token.inserted { 99 | color: #690; 100 | } 101 | 102 | .token.operator, 103 | .token.entity, 104 | .token.url, 105 | .language-css .token.string, 106 | .style .token.string { 107 | color: #a67f59; 108 | background: hsla(0, 0%, 100%, .5); 109 | } 110 | 111 | .token.atrule, 112 | .token.attr-value, 113 | .token.keyword { 114 | color: #07a; 115 | } 116 | 117 | .token.function { 118 | color: #DD4A68; 119 | } 120 | 121 | .token.regex, 122 | .token.important, 123 | .token.variable { 124 | color: #e90; 125 | } 126 | 127 | .token.important, 128 | .token.bold { 129 | font-weight: bold; 130 | } 131 | .token.italic { 132 | font-style: italic; 133 | } 134 | 135 | .token.entity { 136 | cursor: help; 137 | } 138 | 139 | -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-cool.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-cool.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-cry.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-cry.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-embarassed.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-embarassed.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-frown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-frown.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-innocent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-innocent.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-kiss.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-kiss.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-laughing.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-laughing.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-money-mouth.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-money-mouth.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-sealed.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-sealed.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-smile.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-smile.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-surprised.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-surprised.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-tongue-out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-tongue-out.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-undecided.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-undecided.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-wink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-wink.gif -------------------------------------------------------------------------------- /docs/static/tinymce/plugins/emoticons/img/smiley-yell.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/plugins/emoticons/img/smiley-yell.gif -------------------------------------------------------------------------------- /docs/static/tinymce/skins/lightgray/content.inline.min.css: -------------------------------------------------------------------------------- 1 | .word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid rgba(208,2,27,0.5);cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2}.mce-content-body{line-height:1.3} -------------------------------------------------------------------------------- /docs/static/tinymce/skins/lightgray/fonts/tinymce-mobile.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/skins/lightgray/fonts/tinymce-mobile.woff -------------------------------------------------------------------------------- /docs/static/tinymce/skins/lightgray/fonts/tinymce-small.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/skins/lightgray/fonts/tinymce-small.eot -------------------------------------------------------------------------------- /docs/static/tinymce/skins/lightgray/fonts/tinymce-small.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/skins/lightgray/fonts/tinymce-small.ttf -------------------------------------------------------------------------------- /docs/static/tinymce/skins/lightgray/fonts/tinymce-small.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/skins/lightgray/fonts/tinymce-small.woff -------------------------------------------------------------------------------- /docs/static/tinymce/skins/lightgray/fonts/tinymce.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/skins/lightgray/fonts/tinymce.eot -------------------------------------------------------------------------------- /docs/static/tinymce/skins/lightgray/fonts/tinymce.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/skins/lightgray/fonts/tinymce.ttf -------------------------------------------------------------------------------- /docs/static/tinymce/skins/lightgray/fonts/tinymce.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/skins/lightgray/fonts/tinymce.woff -------------------------------------------------------------------------------- /docs/static/tinymce/skins/lightgray/img/anchor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/skins/lightgray/img/anchor.gif -------------------------------------------------------------------------------- /docs/static/tinymce/skins/lightgray/img/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/skins/lightgray/img/loader.gif -------------------------------------------------------------------------------- /docs/static/tinymce/skins/lightgray/img/object.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/skins/lightgray/img/object.gif -------------------------------------------------------------------------------- /docs/static/tinymce/skins/lightgray/img/trans.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/docs/static/tinymce/skins/lightgray/img/trans.gif -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/favicon.ico -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue-element-admin 6 | 7 | 8 | 9 | 10 |
11 |
12 | 77 |
78 | 79 | 80 | 81 | 82 |
83 | 84 |

初次加载,请耐心等待...

85 |
86 |
87 | 88 | 89 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-admin-template", 3 | "version": "3.0.0", 4 | "license": "MIT", 5 | "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint", 6 | "author": "Pan ", 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js", 11 | "build:report": "npm_config_report=true node build/build.js", 12 | "lint": "eslint --ext .js,.vue src", 13 | "test": "npm run lint" 14 | }, 15 | "dependencies": { 16 | "@tinymce/tinymce-vue": "^1.0.8", 17 | "axios": "0.17.1", 18 | "clipboard": "^2.0.0", 19 | "echarts": "^4.1.0", 20 | "element-ui": "2.0.8", 21 | "file-saver": "^1.3.8", 22 | "fullcalendar-scheduler": "1.9.0", 23 | "jquery": "^3.3.1", 24 | "js-cookie": "2.2.0", 25 | "mock": "^0.1.1", 26 | "mockjs": "^1.0.1-beta3", 27 | "normalize.css": "7.0.0", 28 | "nprogress": "0.2.0", 29 | "screenfull": "^3.3.2", 30 | "tinymce": "^4.8.0", 31 | "vue": "^2.5.17", 32 | "vue-count-to": "^1.0.13", 33 | "vue-full-calendar": "^2.5.2", 34 | "vue-i18n": "^8.1.0", 35 | "vue-quill-editor": "^3.0.6", 36 | "vue-router": "3.0.1", 37 | "vue-transition.css": "^1.0.2", 38 | "vuex": "3.0.1", 39 | "xlsx": "^0.14.0" 40 | }, 41 | "devDependencies": { 42 | "autoprefixer": "7.2.3", 43 | "babel-core": "6.26.0", 44 | "babel-eslint": "8.0.3", 45 | "babel-helper-vue-jsx-merge-props": "2.0.3", 46 | "babel-loader": "7.1.2", 47 | "babel-plugin-syntax-jsx": "6.18.0", 48 | "babel-plugin-transform-runtime": "6.23.0", 49 | "babel-plugin-transform-vue-jsx": "3.5.0", 50 | "babel-preset-env": "1.6.1", 51 | "babel-preset-stage-2": "6.24.1", 52 | "chalk": "2.3.0", 53 | "copy-webpack-plugin": "4.2.3", 54 | "css-loader": "0.28.7", 55 | "eslint": "4.13.1", 56 | "eslint-friendly-formatter": "3.0.0", 57 | "eslint-loader": "1.9.0", 58 | "eslint-plugin-html": "4.0.1", 59 | "eventsource-polyfill": "0.9.6", 60 | "extract-text-webpack-plugin": "3.0.2", 61 | "file-loader": "1.1.5", 62 | "friendly-errors-webpack-plugin": "1.6.1", 63 | "html-webpack-plugin": "2.30.1", 64 | "node-notifier": "5.1.2", 65 | "node-sass": "^4.7.2", 66 | "optimize-css-assets-webpack-plugin": "3.2.0", 67 | "ora": "1.3.0", 68 | "portfinder": "1.0.13", 69 | "postcss-import": "11.0.0", 70 | "postcss-loader": "2.0.9", 71 | "rimraf": "2.6.2", 72 | "sass-loader": "6.0.6", 73 | "script-loader": "^0.7.2", 74 | "semver": "5.4.1", 75 | "shelljs": "0.7.8", 76 | "svg-sprite-loader": "3.5.2", 77 | "uglifyjs-webpack-plugin": "1.1.3", 78 | "url-loader": "0.6.2", 79 | "vue-loader": "13.5.0", 80 | "vue-style-loader": "3.0.3", 81 | "vue-template-compiler": "^2.5.10", 82 | "webpack": "3.10.0", 83 | "webpack-bundle-analyzer": "2.9.1", 84 | "webpack-dev-server": "2.9.7", 85 | "webpack-merge": "4.1.1" 86 | }, 87 | "engines": { 88 | "node": ">= 4.0.0", 89 | "npm": ">= 3.0.0" 90 | }, 91 | "browserslist": [ 92 | "> 1%", 93 | "last 2 versions", 94 | "not ie <= 8" 95 | ] 96 | } 97 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 16 | 30 | -------------------------------------------------------------------------------- /src/api/article.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function fetchList(query) { 4 | return request({ 5 | url: '/excel/exportExcel', 6 | method: 'get', 7 | params: query 8 | }) 9 | } 10 | 11 | export function fetchArticle(id) { 12 | return request({ 13 | url: '/article/detail', 14 | method: 'get', 15 | params: { id } 16 | }) 17 | } 18 | 19 | export function fetchPv(pv) { 20 | return request({ 21 | url: '/article/pv', 22 | method: 'get', 23 | params: { pv } 24 | }) 25 | } 26 | 27 | export function createArticle(data) { 28 | return request({ 29 | url: '/article/create', 30 | method: 'post', 31 | data 32 | }) 33 | } 34 | 35 | export function updateArticle(data) { 36 | return request({ 37 | url: '/article/update', 38 | method: 'post', 39 | data 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /src/api/login.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function login(username, password) { 4 | return request({ 5 | url: '/user/login' + '?username=' + username, 6 | method: 'post' 7 | }) 8 | } 9 | 10 | export function getInfo(token) { 11 | return request({ 12 | url: '/user/info' + '?username=' + token, 13 | method: 'get' 14 | }) 15 | } 16 | 17 | export function logout() { 18 | return request({ 19 | url: '/user/logout', 20 | method: 'post' 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /src/api/table.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getList(params) { 4 | return request({ 5 | url: '/user/table', 6 | method: 'get', 7 | params 8 | }) 9 | } 10 | 11 | export function getMonth(params) { 12 | return request({ 13 | url: '/schedule/month', 14 | method: 'post', 15 | params 16 | }) 17 | } 18 | 19 | export function updateArticle(data) { 20 | return request({ 21 | url: '/article/update', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /src/assets/404_images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/src/assets/404_images/404.png -------------------------------------------------------------------------------- /src/assets/404_images/404_cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/src/assets/404_images/404_cloud.png -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/components/Breadcrumb/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 39 | 40 | 52 | -------------------------------------------------------------------------------- /src/components/ErrLog/index.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 47 | 48 | 57 | -------------------------------------------------------------------------------- /src/components/Hamburger/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 30 | 31 | 46 | -------------------------------------------------------------------------------- /src/components/Screenfull/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 47 | 48 | 55 | -------------------------------------------------------------------------------- /src/components/ScrollBar/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 43 | 44 | 58 | -------------------------------------------------------------------------------- /src/components/SvgIcon/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 33 | 34 | 43 | -------------------------------------------------------------------------------- /src/components/Tinymce/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 84 | 85 | 103 | -------------------------------------------------------------------------------- /src/components/month/month.vue: -------------------------------------------------------------------------------- 1 | 6 | 37 | -------------------------------------------------------------------------------- /src/components/nx-back-to-top/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 85 | 86 | 113 | -------------------------------------------------------------------------------- /src/components/nx-top-lock/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 61 | 66 | -------------------------------------------------------------------------------- /src/components/panThumb/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 35 | 36 | 141 | -------------------------------------------------------------------------------- /src/components/treeMen/index.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 50 | 51 | -------------------------------------------------------------------------------- /src/components/week_detail/week_detail.vue: -------------------------------------------------------------------------------- 1 | 6 | 69 | -------------------------------------------------------------------------------- /src/directive/waves/index.js: -------------------------------------------------------------------------------- 1 | import waves from './waves' 2 | 3 | const install = function(Vue) { 4 | Vue.directive('waves', waves) 5 | } 6 | 7 | if (window.Vue) { 8 | window.waves = waves 9 | Vue.use(install); // eslint-disable-line 10 | } 11 | 12 | waves.install = install 13 | export default waves 14 | -------------------------------------------------------------------------------- /src/directive/waves/waves.css: -------------------------------------------------------------------------------- 1 | .waves-ripple { 2 | position: absolute; 3 | border-radius: 100%; 4 | background-color: rgba(0, 0, 0, 0.15); 5 | background-clip: padding-box; 6 | pointer-events: none; 7 | -webkit-user-select: none; 8 | -moz-user-select: none; 9 | -ms-user-select: none; 10 | user-select: none; 11 | -webkit-transform: scale(0); 12 | -ms-transform: scale(0); 13 | transform: scale(0); 14 | opacity: 1; 15 | } 16 | 17 | .waves-ripple.z-active { 18 | opacity: 0; 19 | -webkit-transform: scale(2); 20 | -ms-transform: scale(2); 21 | transform: scale(2); 22 | -webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out; 23 | transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out; 24 | transition: opacity 1.2s ease-out, transform 0.6s ease-out; 25 | transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out; 26 | } -------------------------------------------------------------------------------- /src/directive/waves/waves.js: -------------------------------------------------------------------------------- 1 | import './waves.css' 2 | 3 | export default{ 4 | bind(el, binding) { 5 | el.addEventListener('click', e => { 6 | const customOpts = Object.assign({}, binding.value) 7 | const opts = Object.assign({ 8 | ele: el, // 波纹作用元素 9 | type: 'hit', // hit点击位置扩散center中心点扩展 10 | color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色 11 | }, customOpts) 12 | const target = opts.ele 13 | if (target) { 14 | target.style.position = 'relative' 15 | target.style.overflow = 'hidden' 16 | const rect = target.getBoundingClientRect() 17 | let ripple = target.querySelector('.waves-ripple') 18 | if (!ripple) { 19 | ripple = document.createElement('span') 20 | ripple.className = 'waves-ripple' 21 | ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px' 22 | target.appendChild(ripple) 23 | } else { 24 | ripple.className = 'waves-ripple' 25 | } 26 | switch (opts.type) { 27 | case 'center': 28 | ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px' 29 | ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px' 30 | break 31 | default: 32 | ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.body.scrollTop) + 'px' 33 | ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.body.scrollLeft) + 'px' 34 | } 35 | ripple.style.backgroundColor = opts.color 36 | ripple.className = 'waves-ripple z-active' 37 | return false 38 | } 39 | }, false) 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/errorLog.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import errLog from '@/store/errLog' 3 | 4 | // 生产环境错误日志 5 | if (process.env.NODE_ENV === 'production') { 6 | Vue.config.errorHandler = function(err, vm) { 7 | console.log(err, window.location.href) 8 | errLog.pushLog({ 9 | err, 10 | url: window.location.href, 11 | vm 12 | }) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/icons/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import SvgIcon from '../components/SvgIcon'// svg组件 3 | import generateIconsView from '../views/svg-icon/generateIconsView'// just for @/views/icons , you can delete it 4 | 5 | // register globally 6 | Vue.component('svg-icon', SvgIcon) 7 | 8 | const requireAll = requireContext => requireContext.keys().map(requireContext) 9 | const req = require.context('./svg', false, /\.svg$/) 10 | const iconMap = requireAll(req) 11 | console.log(iconMap) 12 | generateIconsView.generate(iconMap) // just for @/views/icons , you can delete it 13 | -------------------------------------------------------------------------------- /src/icons/svg/404.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/TreeMean.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/email.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/example.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/excel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/eye.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/form.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/international.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/language.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/svg/lock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/message.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/money.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/password.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/people.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/peoples.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/shoppingCard.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 | 2 | -------------------------------------------------------------------------------- /src/icons/svg/tree.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/wechat.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/svg/zip.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/lang/en.js: -------------------------------------------------------------------------------- 1 | export default { 2 | navbar: { 3 | title: 'Automatic charging system', 4 | languageSwitch: 'languageSwitch', 5 | theme: 'Theme' 6 | }, 7 | skin: { 8 | Blue: 'Blue', 9 | Green: 'Green', 10 | Red: 'Red', 11 | Purple: 'Purple', 12 | Default: 'Default' 13 | }, 14 | route: { 15 | AliIcons: 'AliIcons', 16 | list: 'list', 17 | Digitalanimation: 'Digitalanimation', 18 | Rollingpositioning: 'Rollingpositioning', 19 | PDF: 'PDF', 20 | HightLightinViewer: 'HightLightinViewer', 21 | contextmenu: 'contextmenu', 22 | simple: 'simple', 23 | divier: 'divier', 24 | group: 'group', 25 | submenu: 'submenu', 26 | disabled: 'disabled', 27 | customtrigger: 'custom-trigger', 28 | form: 'form', 29 | quillEditor: 'quillEditor', 30 | calendar: 'calendar', 31 | Tabs: 'Tabs', 32 | Table: 'Table', 33 | Icons: 'Icons', 34 | from: 'from', 35 | BaseForm: 'BaseForm', 36 | VueEditor: 'VueEditor', 37 | Upload: 'Upload', 38 | Components: 'Components', 39 | dragKanban: 'dragKanban', 40 | componentMixin: 'componentMixin', 41 | markdown: 'markdown', 42 | treeMen: 'treeMen', 43 | backToTop: 'backToTop', 44 | dashboard: 'dashboard', 45 | DiscountFigure: 'DiscountFigure', 46 | columnar: 'columnar', 47 | treeMenu: 'treeMenu', 48 | wel: 'wel', 49 | Lockscreenpage: 'Lockscreenpage', 50 | countenance: 'countenance', 51 | clipboard: 'clipboard', 52 | permission: 'Permission', 53 | pagePermission: 'Page Permission', 54 | directivePermission: 'Directive Permission', 55 | complexTable: 'Complex Table', 56 | treeTable: 'Tree Table', 57 | errorPages: 'Error Pages', 58 | page401: '401', 59 | page404: '404', 60 | i18n: 'i18n', 61 | svgicons: 'svgicons' 62 | }, 63 | excel: { 64 | export: 'Export', 65 | selectedExport: 'Export selected items', 66 | placeholder: 'Please enter the file name(default excel-list)' 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/lang/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | import Cookies from 'js-cookie' 4 | import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang 5 | import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang 6 | import enLocale from './en' 7 | import zhLocale from './zh' 8 | 9 | Vue.use(VueI18n) 10 | 11 | const messages = { 12 | en: { 13 | ...enLocale, 14 | ...elementEnLocale 15 | }, 16 | zh: { 17 | ...zhLocale, 18 | ...elementZhLocale 19 | } 20 | } 21 | 22 | const i18n = new VueI18n({ 23 | locale: Cookies.get('language') || 'zh', // set locale 24 | messages // set locale messages 25 | }) 26 | 27 | export default i18n 28 | -------------------------------------------------------------------------------- /src/lang/zh.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | // 导航栏 4 | navbar: { 5 | title: '自动化管理系统', 6 | languageSwitch: '语言切换', 7 | theme: '主题' 8 | }, 9 | skin: { 10 | Blue: '天空蓝', 11 | Green: '典雅绿', 12 | Red: '樱桃红', 13 | Purple: '贵族紫', 14 | Default: '默认' 15 | }, 16 | route: { 17 | AliIcons: '阿里图标', 18 | contextmenu: '右键菜单', 19 | simple: '基础', 20 | divier: '分割线', 21 | group: '按钮组', 22 | submenu: '子菜单', 23 | disabled: '禁用', 24 | customtrigger: '自定义事件', 25 | form: '表单', 26 | Tabs: 'table选项卡', 27 | Table: '表格', 28 | Icons: 'icon图标', 29 | calendar: '日历', 30 | from: '表单', 31 | BaseForm: 'from表单', 32 | VueEditor: '文本编辑', 33 | Upload: '文件上传', 34 | Components: '组件', 35 | dragKanban: '可拖拽看板', 36 | componentMixin: 'componentMixin', 37 | markdown: 'Markdown', 38 | treeMen: '树形菜单', 39 | quillEditor: '富文本编辑器', 40 | backToTop: '返回顶部', 41 | dashboard: '首页', 42 | DiscountFigure: '折线图', 43 | columnar: '柱状图', 44 | treeMenu: '树形菜单', 45 | countenance: '表情', 46 | clipboard: '复制', 47 | Chartmember: '图表成员', 48 | permission: '权限测试页', 49 | pagePermission: '页面权限', 50 | directivePermission: '按钮权限', 51 | complexTable: '综合Table', 52 | treeTable: '树形表格', 53 | errorPages: '错误页面', 54 | page401: '401', 55 | page404: '404', 56 | i18n: '国际化', 57 | svgicons: 'svg图标' 58 | }, 59 | permission: { 60 | roles: '你的权限', 61 | switchRoles: '切换权限' 62 | }, 63 | excel: { 64 | export: '导出', 65 | selectedExport: '导出已选择项', 66 | placeholder: '请输入文件名(默认excel-list)' 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | import 'normalize.css/normalize.css' // A modern alternative to CSS resets 4 | 5 | import ElementUI from 'element-ui' 6 | import 'element-ui/lib/theme-chalk/index.css' 7 | import locale from 'element-ui/lib/locale/lang/en' 8 | import 'fullcalendar/dist/fullcalendar.min.css' 9 | import '@/styles/index.scss' // global css 10 | import App from './App' 11 | import router from './router' 12 | import store from './store' 13 | import '@/icons' // icon 14 | import '@/permission' // permission control 15 | import i18n from './lang' 16 | import FullCalendar from 'vue-full-calendar' 17 | 18 | Vue.use(FullCalendar) 19 | Vue.use(ElementUI, { locale }) 20 | Vue.use(ElementUI, { 21 | size: 'medium', // set element-ui default size 22 | i18n: (key, value) => i18n.t(key, value) 23 | }) 24 | Vue.use(ElementUI) 25 | 26 | Vue.config.productionTip = false 27 | 28 | new Vue({ 29 | el: '#app', 30 | router, 31 | store, 32 | i18n, 33 | template: '', 34 | components: { App } 35 | }) 36 | -------------------------------------------------------------------------------- /src/mock/article.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/src/mock/article.js -------------------------------------------------------------------------------- /src/mock/index.js: -------------------------------------------------------------------------------- 1 | import Mock from 'mockjs' 2 | import loginAPI from './login' 3 | import articleAPI from './article' 4 | import remoteSearchAPI from './remoteSearch' 5 | import transactionAPI from './transaction' 6 | // Mock.setup({ 7 | // timeout: '350-600' 8 | // }) 9 | 10 | 11 | 12 | // 登录相关 13 | Mock.mock(/\/login\/login/, 'post', loginAPI.loginByUsername) 14 | Mock.mock(/\/login\/logout/, 'post', loginAPI.logout) 15 | Mock.mock(/\/user\/info\.*/, 'get', loginAPI.getUserInfo) 16 | 17 | export default Mock -------------------------------------------------------------------------------- /src/mock/login.js: -------------------------------------------------------------------------------- 1 | import { param2Obj } from '@/utils' 2 | 3 | const userMap = { 4 | // admin: { 5 | // roles: ['admin'], 6 | // token: 'admin', 7 | // introduction: '我是超级管理员', 8 | // avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', 9 | // name: 'Super Admin' 10 | // }, 11 | // editor: { 12 | // roles: ['editor'], 13 | // token: 'editor', 14 | // introduction: '我是编辑', 15 | // avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', 16 | // name: 'Normal Editor' 17 | // } 18 | } 19 | 20 | export default { 21 | loginByUsername: config => { 22 | const { username } = JSON.parse(config.body) 23 | return userMap[username] 24 | }, 25 | getUserInfo: config => { 26 | const { token } = param2Obj(config.url) 27 | if (userMap[token]) { 28 | return userMap[token] 29 | } else { 30 | return false 31 | } 32 | }, 33 | logout: () => 'success' 34 | } 35 | -------------------------------------------------------------------------------- /src/permission.js: -------------------------------------------------------------------------------- 1 | import router from './router' 2 | import store from './store' 3 | import NProgress from 'nprogress' // Progress 进度条 4 | import 'nprogress/nprogress.css'// Progress 进度条样式 5 | import { Message } from 'element-ui' 6 | import { getToken } from '@/utils/auth' // 验权 7 | 8 | // permissiom judge 9 | function hasPermission(roles, permissionRoles) { 10 | if (roles.indexOf('admin') >= 0) return true // admin权限 直接通过 11 | if (!permissionRoles) return true 12 | return roles.some(role => permissionRoles.indexOf(role) >= 0) 13 | } 14 | 15 | // register global progress. 16 | const whiteList = ['/login', '/authredirect']// 不重定向白名单 17 | router.beforeEach((to, from, next) => { 18 | NProgress.start() // 开启Progress 19 | if (getToken()) { // 判断是否有token 20 | if (to.path === '/login') { 21 | next({ path: '/' }) 22 | NProgress.done() // router在hash模式下 手动改变hash 重定向回来 不会触发afterEach 暂时hack方案 ps:history模式下无问题,可删除该行! 23 | } else { 24 | console.log('from', from) 25 | console.log('to', to) 26 | console.log('用户是否已拉取完user_info信息==src==', store.getters.roles.length === 0) 27 | if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息 28 | store.dispatch('GetInfo').then(res => { // 拉取user_info 29 | var roles = store.getters.roles 30 | console.log(roles) 31 | store.dispatch('GenerateRoutes', { roles }).then(() => { // 生成可访问的路由表 32 | router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表 33 | console.log(store.getters.addRouters) 34 | console.log(2222222222) 35 | next({ ...to }) // hack方法 确保addRoutes已完成 36 | }) 37 | }).catch(() => { 38 | store.dispatch('FedLogOut').then(() => { 39 | Message.error('验证失败,请重新登录') 40 | next({ path: '/login' }) 41 | }) 42 | }) 43 | } else { 44 | // 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓ 45 | console.log('没有动态改变权限的需求可直接next() 删除下方权限判断 ↓', store.getters.roles, to.meta.role) 46 | if (hasPermission(store.getters.roles, to.meta.role)) { 47 | next()// 48 | } else { 49 | next({ path: '/401', query: { noGoBack: true }}) 50 | NProgress.done() // router在hash模式下 手动改变hash 重定向回来 不会触发afterEach 暂时hack方案 ps:history模式下无问题,可删除该行! 51 | } 52 | // 可删 ↑ 53 | } 54 | } 55 | } else { 56 | if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入 57 | next() 58 | } else { 59 | next('/login') // 否则全部重定向到登录页 60 | NProgress.done() // router在hash模式下 手动改变hash 重定向回来 不会触发afterEach 暂时hack方案 ps:history模式下无问题,可删除该行! 61 | } 62 | } 63 | }) 64 | 65 | router.afterEach(() => { 66 | NProgress.done() // 结束Progress 67 | }) 68 | -------------------------------------------------------------------------------- /src/router/_import_development.js: -------------------------------------------------------------------------------- 1 | module.exports = file => require('@/views/' + file + '.vue').default // vue-loader at least v13.0.0+ 2 | -------------------------------------------------------------------------------- /src/router/_import_production.js: -------------------------------------------------------------------------------- 1 | module.exports = file => () => import('@/views/' + file + '.vue') 2 | -------------------------------------------------------------------------------- /src/screenshots/easy-mock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/src/screenshots/easy-mock.png -------------------------------------------------------------------------------- /src/screenshots/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/src/screenshots/index.png -------------------------------------------------------------------------------- /src/screenshots/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/src/screenshots/login.png -------------------------------------------------------------------------------- /src/screenshots/schedule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/src/screenshots/schedule.png -------------------------------------------------------------------------------- /src/screenshots/table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/src/screenshots/table.png -------------------------------------------------------------------------------- /src/screenshots/topic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/src/screenshots/topic.png -------------------------------------------------------------------------------- /src/screenshots/xker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/src/screenshots/xker.gif -------------------------------------------------------------------------------- /src/store/errLog.js: -------------------------------------------------------------------------------- 1 | const errLog = { 2 | state: { 3 | errLog: [] 4 | }, 5 | pushLog(log) { 6 | this.state.errLog.unshift(log) 7 | }, 8 | clearLog() { 9 | this.state.errLog = [] 10 | } 11 | } 12 | 13 | export default errLog 14 | -------------------------------------------------------------------------------- /src/store/getters.js: -------------------------------------------------------------------------------- 1 | const getters = { 2 | sidebar: state => state.app.sidebar, 3 | language: state => state.app.language, 4 | visitedViews: state => state.app.visitedViews, 5 | token: state => state.user.token, 6 | avatar: state => state.user.avatar, 7 | name: state => state.user.name, 8 | introduction: state => state.user.introduction, 9 | status: state => state.user.status, 10 | roles: state => state.user.roles, 11 | resource: state => state.user.resource, 12 | setting: state => state.user.setting, 13 | permission_routers: state => state.permission.routers, 14 | addRouters: state => state.permission.addRouters 15 | } 16 | export default getters 17 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import app from './modules/app' 4 | import user from './modules/user' 5 | import permission from './modules/permission' 6 | import getters from './getters' 7 | 8 | Vue.use(Vuex) 9 | 10 | const store = new Vuex.Store({ 11 | modules: { 12 | app, 13 | user, 14 | permission 15 | }, 16 | getters 17 | }) 18 | 19 | export default store 20 | -------------------------------------------------------------------------------- /src/store/modules/app.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | const app = { 4 | state: { 5 | // 中英文 6 | language: Cookies.get('language') || 'zh', 7 | sidebar: { 8 | opened: !+Cookies.get('sidebarStatus') 9 | } 10 | }, 11 | mutations: { 12 | TOGGLE_SIDEBAR: state => { 13 | if (state.sidebar.opened) { 14 | Cookies.set('sidebarStatus', 1) 15 | } else { 16 | Cookies.set('sidebarStatus', 0) 17 | } 18 | state.sidebar.opened = !state.sidebar.opened 19 | }, 20 | // 中英文 21 | SET_LANGUAGE: (state, language) => { 22 | state.language = language 23 | Cookies.set('language', language) 24 | } 25 | }, 26 | actions: { 27 | ToggleSideBar: ({ commit }) => { 28 | commit('TOGGLE_SIDEBAR') 29 | }, 30 | // 中英文 31 | setLanguage({ commit }, language) { 32 | commit('SET_LANGUAGE', language) 33 | } 34 | } 35 | } 36 | 37 | export default app 38 | -------------------------------------------------------------------------------- /src/store/modules/permission.js: -------------------------------------------------------------------------------- 1 | import { asyncRouterMap, constantRouterMap } from '@/router' 2 | 3 | /** 4 | * 通过meta.role判断是否与当前用户权限匹配 5 | * @param roles 6 | * @param route 7 | */ 8 | function hasPermission(roles, route) { 9 | if (route.meta && route.meta.roles) { 10 | return roles.some(role => route.meta.roles.indexOf(role) >= 0) 11 | } else { 12 | return true 13 | } 14 | } 15 | 16 | /** 17 | * 递归过滤异步路由表,返回符合用户角色权限的路由表 18 | * @param asyncRouterMap 19 | * @param roles 20 | */ 21 | function filterAsyncRouter(asyncRouterMap, roles) { 22 | const accessedRouters = asyncRouterMap.filter(route => { 23 | if (hasPermission(roles, route)) { 24 | if (route.children && route.children.length) { 25 | route.children = filterAsyncRouter(route.children, roles) 26 | } 27 | return true 28 | } 29 | return false 30 | }) 31 | return accessedRouters 32 | } 33 | 34 | const permission = { 35 | state: { 36 | routers: constantRouterMap, 37 | addRouters: [] 38 | }, 39 | mutations: { 40 | SET_ROUTERS: (state, routers) => { 41 | state.addRouters = routers 42 | state.routers = constantRouterMap.concat(routers) 43 | console.log('state.routers', state.routers) 44 | } 45 | }, 46 | actions: { 47 | GenerateRoutes({ commit }, data) { 48 | return new Promise(resolve => { 49 | const { roles } = data 50 | let accessedRouters 51 | if (roles.indexOf('admin') >= 0) { 52 | accessedRouters = asyncRouterMap 53 | } else { 54 | accessedRouters = filterAsyncRouter(asyncRouterMap, roles) 55 | } 56 | commit('SET_ROUTERS', accessedRouters) 57 | resolve() 58 | }) 59 | } 60 | } 61 | } 62 | 63 | export default permission 64 | -------------------------------------------------------------------------------- /src/store/modules/user.js: -------------------------------------------------------------------------------- 1 | import { login, logout, getInfo } from '@/api/login' 2 | import { getToken, setToken, removeToken } from '@/utils/auth' 3 | 4 | const user = { 5 | state: { 6 | token: getToken(), 7 | name: '', 8 | avatar: '', 9 | roles: [] 10 | }, 11 | 12 | mutations: { 13 | SET_TOKEN: (state, token) => { 14 | state.token = token 15 | }, 16 | SET_NAME: (state, name) => { 17 | state.name = name 18 | }, 19 | SET_AVATAR: (state, avatar) => { 20 | state.avatar = avatar 21 | }, 22 | SET_ROLES: (state, roles) => { 23 | state.roles = roles 24 | } 25 | }, 26 | 27 | actions: { 28 | // 登录 29 | Login({ commit }, userInfo) { 30 | const username = userInfo.username.trim() 31 | return new Promise((resolve, reject) => { 32 | login(username, userInfo.password).then(response => { 33 | const data = response.data 34 | setToken(data.token) 35 | commit('SET_TOKEN', data.token) 36 | resolve() 37 | }).catch(error => { 38 | reject(error) 39 | }) 40 | }) 41 | }, 42 | 43 | // 获取用户信息 44 | GetInfo({ commit, state }) { 45 | return new Promise((resolve, reject) => { 46 | getInfo(state.token).then(response => { 47 | const data = response.data 48 | commit('SET_ROLES', data.roles) 49 | commit('SET_NAME', data.name) 50 | commit('SET_AVATAR', data.avatar) 51 | resolve(response) 52 | }).catch(error => { 53 | reject(error) 54 | }) 55 | }) 56 | }, 57 | 58 | // 登出 59 | LogOut({ commit, state }) { 60 | return new Promise((resolve, reject) => { 61 | logout(state.token).then(() => { 62 | commit('SET_TOKEN', '') 63 | commit('SET_ROLES', []) 64 | removeToken() 65 | resolve() 66 | }).catch(error => { 67 | reject(error) 68 | }) 69 | }) 70 | }, 71 | 72 | // 前端 登出 73 | FedLogOut({ commit }) { 74 | return new Promise(resolve => { 75 | commit('SET_TOKEN', '') 76 | removeToken() 77 | resolve() 78 | }) 79 | } 80 | } 81 | } 82 | 83 | export default user 84 | -------------------------------------------------------------------------------- /src/styles/btn.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | 3 | @mixin colorBtn($color) { 4 | background: $color; 5 | &:hover { 6 | color: $color; 7 | &:before, 8 | &:after { 9 | background: $color; 10 | } 11 | } 12 | } 13 | 14 | .blue-btn { 15 | @include colorBtn($blue) 16 | } 17 | 18 | .light-blue-btn { 19 | @include colorBtn($light-blue) 20 | } 21 | 22 | .red-btn { 23 | @include colorBtn($red) 24 | } 25 | 26 | .pink-btn { 27 | @include colorBtn($pink) 28 | } 29 | 30 | .green-btn { 31 | @include colorBtn($green) 32 | } 33 | 34 | .tiffany-btn { 35 | @include colorBtn($tiffany) 36 | } 37 | 38 | .yellow-btn { 39 | @include colorBtn($yellow) 40 | } 41 | 42 | .pan-btn { 43 | font-size: 14px; 44 | color: #fff; 45 | padding: 14px 36px; 46 | border-radius: 8px; 47 | border: none; 48 | outline: none; 49 | margin-right: 25px; 50 | transition: 600ms ease all; 51 | position: relative; 52 | display: inline-block; 53 | &:hover { 54 | background: #fff; 55 | &:before, 56 | &:after { 57 | width: 100%; 58 | transition: 600ms ease all; 59 | } 60 | } 61 | &:before, 62 | &:after { 63 | content: ''; 64 | position: absolute; 65 | top: 0; 66 | right: 0; 67 | height: 2px; 68 | width: 0; 69 | transition: 400ms ease all; 70 | } 71 | &::after { 72 | right: inherit; 73 | top: inherit; 74 | left: 0; 75 | bottom: 0; 76 | } 77 | } 78 | 79 | .custom-button { 80 | display: inline-block; 81 | line-height: 1; 82 | white-space: nowrap; 83 | cursor: pointer; 84 | background: #fff; 85 | color: #fff; 86 | -webkit-appearance: none; 87 | text-align: center; 88 | box-sizing: border-box; 89 | outline: 0; 90 | margin: 0; 91 | padding: 10px 15px; 92 | font-size: 14px; 93 | border-radius: 4px; 94 | } 95 | 96 | -------------------------------------------------------------------------------- /src/styles/element-ui.scss: -------------------------------------------------------------------------------- 1 | //to reset element-ui default css 2 | .el-upload { 3 | input[type="file"] { 4 | display: none !important; 5 | } 6 | } 7 | 8 | .el-upload__input { 9 | display: none; 10 | } 11 | 12 | //暂时性解决diolag 问题 https://github.com/ElemeFE/element/issues/2461 13 | .el-dialog { 14 | transform: none; 15 | left: 0; 16 | position: relative; 17 | margin: 0 auto; 18 | } 19 | 20 | //element ui upload 21 | .upload-container { 22 | .el-upload { 23 | width: 100%; 24 | .el-upload-dragger { 25 | width: 100%; 26 | height: 200px; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/styles/index.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | @import './mixin.scss'; 3 | @import './btn.scss'; 4 | @import './transition.scss'; 5 | @import './element-ui.scss'; 6 | @import './sidebar.scss'; 7 | 8 | body { 9 | height: 100%; 10 | -moz-osx-font-smoothing: grayscale; 11 | -webkit-font-smoothing: antialiased; 12 | text-rendering: optimizeLegibility; 13 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; 14 | } 15 | 16 | html { 17 | height: 100%; 18 | box-sizing: border-box; 19 | } 20 | 21 | #app { 22 | height: 100%; 23 | } 24 | *, 25 | *:before, 26 | *:after { 27 | box-sizing: inherit; 28 | } 29 | 30 | div:focus{ 31 | outline: none; 32 | } 33 | 34 | a:focus, 35 | a:active { 36 | outline: none; 37 | } 38 | 39 | a, 40 | a:focus, 41 | a:hover { 42 | cursor: pointer; 43 | color: inherit; 44 | text-decoration: none; 45 | } 46 | 47 | .clearfix { 48 | &:after { 49 | visibility: hidden; 50 | display: block; 51 | font-size: 0; 52 | content: " "; 53 | clear: both; 54 | height: 0; 55 | } 56 | } 57 | 58 | //main-container全局样式 59 | .app-main{ 60 | min-height: 100% 61 | } 62 | 63 | .app-container { 64 | padding: 20px; 65 | } 66 | -------------------------------------------------------------------------------- /src/styles/mixin.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix { 2 | &:after { 3 | content: ""; 4 | display: table; 5 | clear: both; 6 | } 7 | } 8 | 9 | @mixin scrollBar { 10 | &::-webkit-scrollbar-track-piece { 11 | background: #d3dce6; 12 | } 13 | &::-webkit-scrollbar { 14 | width: 6px; 15 | } 16 | &::-webkit-scrollbar-thumb { 17 | background: #99a9bf; 18 | border-radius: 20px; 19 | } 20 | } 21 | 22 | @mixin relative { 23 | position: relative; 24 | width: 100%; 25 | height: 100%; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/styles/sidebar.scss: -------------------------------------------------------------------------------- 1 | #app { 2 | // 主体区域 3 | .main-container { 4 | min-height: 100%; 5 | transition: margin-left 0.28s; 6 | margin-left: 180px; 7 | } // 侧边栏 8 | .sidebar-container { 9 | transition: width 0.28s; 10 | width: 180px!important; 11 | height: 100%; 12 | position: fixed; 13 | top: 0; 14 | bottom: 0; 15 | left: 0; 16 | z-index: 1001; 17 | a { 18 | display: inline-block; 19 | width: 100%; 20 | } 21 | .svg-icon { 22 | margin-right: 16px; 23 | } 24 | .el-menu { 25 | border: none; 26 | width: 100%; 27 | } 28 | } 29 | .hideSidebar { 30 | .sidebar-container,.sidebar-container .el-menu { 31 | width: 36px!important; 32 | // overflow: inherit; 33 | } 34 | .main-container { 35 | margin-left: 36px; 36 | } 37 | } 38 | .hideSidebar { 39 | .submenu-title-noDropdown { 40 | padding-left: 10px!important; 41 | position: relative; 42 | span { 43 | height: 0; 44 | width: 0; 45 | overflow: hidden; 46 | visibility: hidden; 47 | transition: opacity .3s cubic-bezier(.55, 0, .1, 1); 48 | opacity: 0; 49 | display: inline-block; 50 | } 51 | &:hover { 52 | span { 53 | display: block; 54 | border-radius: 3px; 55 | z-index: 1002; 56 | width: 140px; 57 | height: 56px; 58 | visibility: visible; 59 | position: absolute; 60 | right: -145px; 61 | text-align: left; 62 | text-indent: 20px; 63 | top: 0px; 64 | background-color: $subMenuBg!important; 65 | opacity: 1; 66 | } 67 | } 68 | } 69 | .el-submenu { 70 | &>.el-submenu__title { 71 | padding-left: 10px!important; 72 | &>span { 73 | display: none; 74 | } 75 | .el-submenu__icon-arrow { 76 | display: none; 77 | } 78 | } 79 | .nest-menu { 80 | .el-submenu__icon-arrow { 81 | display: block!important; 82 | } 83 | span { 84 | display: inline-block!important; 85 | } 86 | } 87 | } 88 | } 89 | .nest-menu .el-submenu>.el-submenu__title, 90 | .el-submenu .el-menu-item { 91 | min-width: 180px!important; 92 | background-color: $subMenuBg!important; 93 | &:hover { 94 | background-color: $menuHover!important; 95 | } 96 | } 97 | .el-menu--collapse .el-menu .el-submenu{ 98 | min-width: 180px!important; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/styles/transition.scss: -------------------------------------------------------------------------------- 1 | //globl transition css 2 | 3 | /*fade*/ 4 | .fade-enter-active, 5 | .fade-leave-active { 6 | transition: opacity 0.28s; 7 | } 8 | 9 | .fade-enter, 10 | .fade-leave-active { 11 | opacity: 0; 12 | } 13 | 14 | /*fade-transform*/ 15 | .fade-transform-leave-active, 16 | .fade-transform-enter-active { 17 | transition: all .5s; 18 | } 19 | .fade-transform-enter { 20 | opacity: 0; 21 | transform: translateX(-30px); 22 | } 23 | .fade-transform-leave-to { 24 | opacity: 0; 25 | transform: translateX(30px); 26 | } 27 | 28 | /*breadcrumb transition*/ 29 | .breadcrumb-enter-active, 30 | .breadcrumb-leave-active { 31 | transition: all .5s; 32 | } 33 | 34 | .breadcrumb-enter, 35 | .breadcrumb-leave-active { 36 | opacity: 0; 37 | transform: translateX(20px); 38 | } 39 | 40 | .breadcrumb-move { 41 | transition: all .5s; 42 | } 43 | 44 | .breadcrumb-leave-active { 45 | position: absolute; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/styles/variables.scss: -------------------------------------------------------------------------------- 1 | //sidebar 2 | $menuBg:#304156; 3 | $subMenuBg:#1f2d3d; 4 | $menuHover:#001528; 5 | $blue:#324157; 6 | $light-blue:#3A71A8; 7 | $red:#C03639; 8 | $pink: #E65D6E; 9 | $green: #30B08F; 10 | $tiffany: #4AB7BD; 11 | $yellow:#FEC171; 12 | $panGreen: #30B08F; 13 | //sidebar -------------------------------------------------------------------------------- /src/utils/auth.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | const TokenKey = 'Admin-Token' 4 | 5 | export function getToken() { 6 | return Cookies.get(TokenKey) 7 | } 8 | 9 | export function setToken(token) { 10 | return Cookies.set(TokenKey, token) 11 | } 12 | 13 | export function removeToken() { 14 | return Cookies.remove(TokenKey) 15 | } 16 | -------------------------------------------------------------------------------- /src/utils/clipboard.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Clipboard from 'clipboard' 3 | 4 | function clipboardSuccess() { 5 | Vue.prototype.$message({ 6 | message: 'Copy successfully', 7 | type: 'success', 8 | duration: 1500 9 | }) 10 | } 11 | 12 | function clipboardError() { 13 | Vue.prototype.$message({ 14 | message: 'Copy failed', 15 | type: 'error' 16 | }) 17 | } 18 | 19 | export default function handleClipboard(text, event) { 20 | const clipboard = new Clipboard(event.target, { 21 | text: () => text 22 | }) 23 | clipboard.on('success', () => { 24 | clipboardSuccess() 25 | clipboard.off('error') 26 | clipboard.off('success') 27 | clipboard.destroy() 28 | }) 29 | clipboard.on('error', () => { 30 | clipboardError() 31 | clipboard.off('error') 32 | clipboard.off('success') 33 | clipboard.destroy() 34 | }) 35 | clipboard.onClick(event) 36 | } 37 | -------------------------------------------------------------------------------- /src/utils/i18n.js: -------------------------------------------------------------------------------- 1 | // translate router.meta.title, be used in breadcrumb sidebar tagsview 2 | export function generateTitle(title) { 3 | const hasKey = this.$te('route.' + title) 4 | const translatedTitle = this.$t('route.' + title) // $t :this method from vue-i18n, inject in @/lang/index.js 5 | if (hasKey) { 6 | return translatedTitle 7 | } 8 | return title 9 | } 10 | export function generateSkinColor(color) { 11 | const hasKey = this.$te('skin.' + color) 12 | const translatedTitle = this.$t('skin.' + color) // $t :this method from vue-i18n, inject in @/lang/index.js 13 | 14 | if (hasKey) { 15 | return translatedTitle 16 | } 17 | return color 18 | } 19 | -------------------------------------------------------------------------------- /src/utils/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by jiachenpan on 16/11/18. 3 | */ 4 | 5 | export function parseTime(time, cFormat) { 6 | if (arguments.length === 0) { 7 | return null 8 | } 9 | const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' 10 | let date 11 | if (typeof time === 'object') { 12 | date = time 13 | } else { 14 | if (('' + time).length === 10) time = parseInt(time) * 1000 15 | date = new Date(time) 16 | } 17 | const formatObj = { 18 | y: date.getFullYear(), 19 | m: date.getMonth() + 1, 20 | d: date.getDate(), 21 | h: date.getHours(), 22 | i: date.getMinutes(), 23 | s: date.getSeconds(), 24 | a: date.getDay() 25 | } 26 | const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { 27 | let value = formatObj[key] 28 | if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1] 29 | if (result.length > 0 && value < 10) { 30 | value = '0' + value 31 | } 32 | return value || 0 33 | }) 34 | return time_str 35 | } 36 | 37 | export function param2Obj(url) { 38 | const search = url.split('?')[1] 39 | if (!search) { 40 | return {} 41 | } 42 | return JSON.parse('{"' + decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}') 43 | } 44 | 45 | export function formatTime(time, option) { 46 | time = +time * 1000 47 | const d = new Date(time) 48 | const now = Date.now() 49 | 50 | const diff = (now - d) / 1000 51 | 52 | if (diff < 30) { 53 | return '刚刚' 54 | } else if (diff < 3600) { // less 1 hour 55 | return Math.ceil(diff / 60) + '分钟前' 56 | } else if (diff < 3600 * 24) { 57 | return Math.ceil(diff / 3600) + '小时前' 58 | } else if (diff < 3600 * 24 * 2) { 59 | return '1天前' 60 | } 61 | if (option) { 62 | return parseTime(time, option) 63 | } else { 64 | return d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分' 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/utils/request.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { Message, MessageBox } from 'element-ui' 3 | import store from '../store' 4 | import { getToken } from '@/utils/auth' 5 | 6 | // 创建axios实例 7 | const service = axios.create({ 8 | baseURL: process.env.BASE_API, // api的base_url 9 | timeout: 15000 // 请求超时时间 10 | }) 11 | 12 | // request拦截器 13 | service.interceptors.request.use(config => { 14 | if (store.getters.token) { 15 | config.headers['X-Token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 16 | } 17 | return config 18 | }, error => { 19 | // Do something with request error 20 | console.log(error) // for debug 21 | Promise.reject(error) 22 | }) 23 | 24 | // respone拦截器 25 | service.interceptors.response.use( 26 | response => { 27 | /** 28 | * code为非20000是抛错 可结合自己业务进行修改 29 | */ 30 | const res = response.data 31 | if (res.code !== 20000) { 32 | Message({ 33 | message: res.data, 34 | type: 'error', 35 | duration: 5 * 1000 36 | }) 37 | 38 | // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; 39 | if (res.code === 50008 || res.code === 50012 || res.code === 50014) { 40 | MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', { 41 | confirmButtonText: '重新登录', 42 | cancelButtonText: '取消', 43 | type: 'warning' 44 | }).then(() => { 45 | store.dispatch('FedLogOut').then(() => { 46 | location.reload()// 为了重新实例化vue-router对象 避免bug 47 | }) 48 | }) 49 | } 50 | return Promise.reject('error') 51 | } else { 52 | return response.data 53 | } 54 | }, 55 | error => { 56 | console.log('err' + error)// for debug 57 | Message({ 58 | message: error.message, 59 | type: 'error', 60 | duration: 5 * 1000 61 | }) 62 | return Promise.reject(error) 63 | } 64 | ) 65 | 66 | export default service 67 | -------------------------------------------------------------------------------- /src/utils/validate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by jiachenpan on 16/11/18. 3 | */ 4 | 5 | export function isvalidUsername(str) { 6 | const valid_map = ['admin', 'editor'] 7 | return valid_map.indexOf(str.trim()) >= 0 8 | } 9 | 10 | /* 合法uri*/ 11 | export function validateURL(textval) { 12 | const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ 13 | return urlregex.test(textval) 14 | } 15 | 16 | /* 小写字母*/ 17 | export function validateLowerCase(str) { 18 | const reg = /^[a-z]+$/ 19 | return reg.test(str) 20 | } 21 | 22 | /* 大写字母*/ 23 | export function validateUpperCase(str) { 24 | const reg = /^[A-Z]+$/ 25 | return reg.test(str) 26 | } 27 | 28 | /* 大小写字母*/ 29 | export function validatAlphabets(str) { 30 | const reg = /^[A-Za-z]+$/ 31 | return reg.test(str) 32 | } 33 | 34 | /** 35 | * 判断是否为空 36 | */ 37 | export function validatenull(val) { 38 | if (typeof val === 'boolean') { 39 | return false 40 | } 41 | if (val instanceof Array) { 42 | if (val.length === 0) return true 43 | } else if (val instanceof Object) { 44 | if (JSON.stringify(val) === '{}') return true 45 | } else { 46 | if (val === 'null' || val == null || val === 'undefined' || val === undefined || val === '') return true 47 | return false 48 | } 49 | return false 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/views/dashboard/admin/components/echart.vue: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /src/views/dashboard/admin/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 49 | 50 | 61 | -------------------------------------------------------------------------------- /src/views/dashboard/editor/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 38 | 39 | 72 | -------------------------------------------------------------------------------- /src/views/dashboard/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 32 | -------------------------------------------------------------------------------- /src/views/form/qiniu.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 77 | 78 | -------------------------------------------------------------------------------- /src/views/form/quillEditor.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 49 | -------------------------------------------------------------------------------- /src/views/form/tinymce.vue: -------------------------------------------------------------------------------- 1 | 2 | 14 | 40 | -------------------------------------------------------------------------------- /src/views/fullcalendar/fullcalendar.vue: -------------------------------------------------------------------------------- 1 | 53 | 102 | 105 | -------------------------------------------------------------------------------- /src/views/i18n-demo/local.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | zh: { 4 | i18nView: { 5 | title: '切换语言', 6 | note: '目前只翻译了当前页面和侧边栏和导航,未完待续,敬请期待...', 7 | datePlaceholder: '请选择日期', 8 | tableDate: '日期', 9 | tableName: '姓名', 10 | tableAddress: '地址', 11 | default: '默认按钮', 12 | primary: '主要按钮', 13 | success: '成功按钮', 14 | info: '信息按钮', 15 | warning: '警告按钮', 16 | danger: '危险按钮' 17 | } 18 | 19 | }, 20 | en: { 21 | i18nView: { 22 | title: 'Switch Language', 23 | note: 'Currently only translated the i18n page and the sidebar and levelbar, please look forword to...', 24 | datePlaceholder: 'Pick a day', 25 | tableDate: 'tableDate', 26 | tableName: 'tableName', 27 | tableAddress: 'tableAddress', 28 | default: 'default:', 29 | primary: 'primary', 30 | success: 'success', 31 | info: 'info', 32 | warning: 'warning', 33 | danger: 'danger' 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/views/layout/Layout.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /src/views/layout/components/AppMain.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | -------------------------------------------------------------------------------- /src/views/layout/components/Navbar.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 62 | 63 | -------------------------------------------------------------------------------- /src/views/layout/components/Sidebar/SidebarItem.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 81 | 82 | -------------------------------------------------------------------------------- /src/views/layout/components/Sidebar/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 27 | -------------------------------------------------------------------------------- /src/views/layout/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as Navbar } from './Navbar' 2 | export { default as Sidebar } from './Sidebar' 3 | export { default as AppMain } from './AppMain' 4 | -------------------------------------------------------------------------------- /src/views/svg-icon/generateIconsView.js: -------------------------------------------------------------------------------- 1 | const data = { 2 | state: { 3 | iconsMap: [] 4 | }, 5 | generate(iconsMap) { 6 | console.log(iconsMap) 7 | this.state.iconsMap = iconsMap 8 | } 9 | } 10 | console.log(data) 11 | export default data 12 | -------------------------------------------------------------------------------- /src/views/svg-icon/index.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 51 | 52 | 88 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/.gitkeep -------------------------------------------------------------------------------- /static/tinymce/plugins/codesample/css/prism.css: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */ 2 | /** 3 | * prism.js default theme for JavaScript, CSS and HTML 4 | * Based on dabblet (http://dabblet.com) 5 | * @author Lea Verou 6 | */ 7 | 8 | code[class*="language-"], 9 | pre[class*="language-"] { 10 | color: black; 11 | text-shadow: 0 1px white; 12 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 13 | direction: ltr; 14 | text-align: left; 15 | white-space: pre; 16 | word-spacing: normal; 17 | word-break: normal; 18 | word-wrap: normal; 19 | line-height: 1.5; 20 | 21 | -moz-tab-size: 4; 22 | -o-tab-size: 4; 23 | tab-size: 4; 24 | 25 | -webkit-hyphens: none; 26 | -moz-hyphens: none; 27 | -ms-hyphens: none; 28 | hyphens: none; 29 | } 30 | 31 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, 32 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { 33 | text-shadow: none; 34 | background: #b3d4fc; 35 | } 36 | 37 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, 38 | code[class*="language-"]::selection, code[class*="language-"] ::selection { 39 | text-shadow: none; 40 | background: #b3d4fc; 41 | } 42 | 43 | @media print { 44 | code[class*="language-"], 45 | pre[class*="language-"] { 46 | text-shadow: none; 47 | } 48 | } 49 | 50 | /* Code blocks */ 51 | pre[class*="language-"] { 52 | padding: 1em; 53 | margin: .5em 0; 54 | overflow: auto; 55 | } 56 | 57 | :not(pre) > code[class*="language-"], 58 | pre[class*="language-"] { 59 | background: #f5f2f0; 60 | } 61 | 62 | /* Inline code */ 63 | :not(pre) > code[class*="language-"] { 64 | padding: .1em; 65 | border-radius: .3em; 66 | } 67 | 68 | .token.comment, 69 | .token.prolog, 70 | .token.doctype, 71 | .token.cdata { 72 | color: slategray; 73 | } 74 | 75 | .token.punctuation { 76 | color: #999; 77 | } 78 | 79 | .namespace { 80 | opacity: .7; 81 | } 82 | 83 | .token.property, 84 | .token.tag, 85 | .token.boolean, 86 | .token.number, 87 | .token.constant, 88 | .token.symbol, 89 | .token.deleted { 90 | color: #905; 91 | } 92 | 93 | .token.selector, 94 | .token.attr-name, 95 | .token.string, 96 | .token.char, 97 | .token.builtin, 98 | .token.inserted { 99 | color: #690; 100 | } 101 | 102 | .token.operator, 103 | .token.entity, 104 | .token.url, 105 | .language-css .token.string, 106 | .style .token.string { 107 | color: #a67f59; 108 | background: hsla(0, 0%, 100%, .5); 109 | } 110 | 111 | .token.atrule, 112 | .token.attr-value, 113 | .token.keyword { 114 | color: #07a; 115 | } 116 | 117 | .token.function { 118 | color: #DD4A68; 119 | } 120 | 121 | .token.regex, 122 | .token.important, 123 | .token.variable { 124 | color: #e90; 125 | } 126 | 127 | .token.important, 128 | .token.bold { 129 | font-weight: bold; 130 | } 131 | .token.italic { 132 | font-style: italic; 133 | } 134 | 135 | .token.entity { 136 | cursor: help; 137 | } 138 | 139 | -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-cool.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-cool.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-cry.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-cry.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-embarassed.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-embarassed.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-frown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-frown.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-innocent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-innocent.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-kiss.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-kiss.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-laughing.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-laughing.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-money-mouth.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-money-mouth.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-sealed.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-sealed.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-smile.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-smile.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-surprised.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-surprised.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-tongue-out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-tongue-out.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-undecided.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-undecided.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-wink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-wink.gif -------------------------------------------------------------------------------- /static/tinymce/plugins/emoticons/img/smiley-yell.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/plugins/emoticons/img/smiley-yell.gif -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/content.inline.min.css: -------------------------------------------------------------------------------- 1 | .word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid rgba(208,2,27,0.5);cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2}.mce-content-body{line-height:1.3} -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/content.min.css: -------------------------------------------------------------------------------- 1 | body{background-color:#FFFFFF;color:#000000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px;line-height:1.3;scrollbar-3dlight-color:#F0F0EE;scrollbar-arrow-color:#676662;scrollbar-base-color:#F0F0EE;scrollbar-darkshadow-color:#DDDDDD;scrollbar-face-color:#E0E0DD;scrollbar-highlight-color:#F0F0EE;scrollbar-shadow-color:#F0F0EE;scrollbar-track-color:#F5F5F5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px}.word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid rgba(208,2,27,0.5);cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2} a {color: #1478F0;} 2 | -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/fonts/tinymce-mobile.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/skins/lightgray/fonts/tinymce-mobile.woff -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/fonts/tinymce-small.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/skins/lightgray/fonts/tinymce-small.eot -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/fonts/tinymce-small.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/skins/lightgray/fonts/tinymce-small.ttf -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/fonts/tinymce-small.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/skins/lightgray/fonts/tinymce-small.woff -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/fonts/tinymce.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/skins/lightgray/fonts/tinymce.eot -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/fonts/tinymce.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/skins/lightgray/fonts/tinymce.ttf -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/fonts/tinymce.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/skins/lightgray/fonts/tinymce.woff -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/img/anchor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/skins/lightgray/img/anchor.gif -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/img/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/skins/lightgray/img/loader.gif -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/img/object.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/skins/lightgray/img/object.gif -------------------------------------------------------------------------------- /static/tinymce/skins/lightgray/img/trans.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ningtiao/vue-element-admin/e936842dfd84699ff0f6ee40f344aa640862624d/static/tinymce/skins/lightgray/img/trans.gif --------------------------------------------------------------------------------