├── .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 |
5 |
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 | 
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 | 
36 | 
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 |
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 |
2 |
3 |
4 |
5 |
6 |
7 |
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 |
2 |
3 |
4 |
5 | {{item.meta.title}}
6 | {{item.meta.title}}
7 |
8 |
9 |
10 |
11 |
12 |
39 |
40 |
52 |
--------------------------------------------------------------------------------
/src/components/ErrLog/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | msg:{{ scope.row.err.message }}
17 |
18 | url: {{scope.row.url}}
19 |
20 |
21 |
22 |
23 | {{ scope.row.err.stack}}
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
47 |
48 |
57 |
--------------------------------------------------------------------------------
/src/components/Hamburger/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
15 |
30 |
31 |
46 |
--------------------------------------------------------------------------------
/src/components/Screenfull/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
47 |
48 |
55 |
--------------------------------------------------------------------------------
/src/components/ScrollBar/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
43 |
44 |
58 |
--------------------------------------------------------------------------------
/src/components/SvgIcon/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
33 |
34 |
43 |
--------------------------------------------------------------------------------
/src/components/Tinymce/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
84 |
85 |
103 |
--------------------------------------------------------------------------------
/src/components/month/month.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
37 |
--------------------------------------------------------------------------------
/src/components/nx-back-to-top/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 |
85 |
86 |
113 |
--------------------------------------------------------------------------------
/src/components/nx-top-lock/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
61 |
66 |
--------------------------------------------------------------------------------
/src/components/panThumb/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
![]()
9 |
10 |
11 |
12 |
35 |
36 |
141 |
--------------------------------------------------------------------------------
/src/components/treeMen/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
13 | {{DATA.name}}
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
50 |
51 |
--------------------------------------------------------------------------------
/src/components/week_detail/week_detail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
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 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/views/dashboard/admin/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
49 |
50 |
61 |
--------------------------------------------------------------------------------
/src/views/dashboard/editor/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
你的权限:
5 | {{item}}
6 |
7 |
8 | {{name}}
9 | 欢迎来到Vue后台管理系统
10 |
11 |
12 |
13 |
![]()
14 |
15 |
16 |
17 |
18 |
38 |
39 |
72 |
--------------------------------------------------------------------------------
/src/views/dashboard/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
32 |
--------------------------------------------------------------------------------
/src/views/form/qiniu.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
ElementUI的Upload上传图片到七牛云
4 |
13 |
14 |
15 |
16 |
将文件拖到此处,或点击上传
17 |
18 | 只能上传jpg/png文件,且不超过2MB
19 |
20 |
21 |
22 |
23 |
77 |
78 |
--------------------------------------------------------------------------------
/src/views/form/quillEditor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 表单
6 | 编辑器
7 |
8 |
9 |
17 |
18 |
19 |
20 |
49 |
--------------------------------------------------------------------------------
/src/views/form/tinymce.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 富文本是管理后台一个核心的功能,但同时又是一个有很多坑的地方。在选择富文本的过程中我也走了不少的弯路,市面上常见的富文本都基本用过了,最终权衡了一下选择了Tinymce。更详细的富文本比较和介绍见
6 | 文档
7 |
8 |
9 | content = content">
10 |
11 |
12 |
13 |
14 |
40 |
--------------------------------------------------------------------------------
/src/views/fullcalendar/fullcalendar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
27 |
28 |
31 |
32 |
33 |
34 |
35 |
36 | 搜索
37 |
38 |
39 | 新增排课
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
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 |
2 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/views/layout/components/AppMain.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
19 |
--------------------------------------------------------------------------------
/src/views/layout/components/Navbar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
![]()
11 |
12 |
13 |
14 |
15 |
16 | Home
17 |
18 |
19 |
20 | LogOut
21 |
22 |
23 |
24 |
25 |
26 |
27 |
62 |
63 |
--------------------------------------------------------------------------------
/src/views/layout/components/Sidebar/SidebarItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
30 |
31 |
32 |
81 |
82 |
--------------------------------------------------------------------------------
/src/views/layout/components/Sidebar/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
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 |
2 |
3 |
4 | Add and use
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{generateIconCode(item)}}
12 |
13 |
14 |
15 | {{item}}
16 |
17 |
18 |
19 |
20 |
21 |
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
--------------------------------------------------------------------------------