├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── README.md ├── build ├── build.js ├── check-versions.js ├── dev-client.js ├── dev-server.js ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js ├── webpack.prod.conf.js └── webpack.test.conf.js ├── config ├── dev.env.js ├── index.js ├── prod.env.js └── test.env.js ├── dist ├── index.html └── static │ ├── css │ ├── app.dc25af568844368721b7447ec2a8041c.css │ └── app.dc25af568844368721b7447ec2a8041c.css.map │ ├── fonts │ ├── iconfont.42ef16c.eot │ ├── iconfont.4cf6b7c.woff │ ├── iconfont.b5270aa.ttf │ ├── ionicons.05acfdb.woff │ ├── ionicons.24712f6.ttf │ └── ionicons.2c2ae06.eot │ ├── img │ ├── bg_login.7285dd8.jpg │ ├── fullstack.e51bafb.jpg │ ├── fullstack.jpg │ ├── iconfont.ae14f3b.svg │ ├── ionicons.621bd38.svg │ └── logo.png │ └── js │ ├── 0.5e3e713f6a7c36f289bb.js │ ├── 0.5e3e713f6a7c36f289bb.js.map │ ├── 1.5a794239c1dec6d30537.js │ ├── 1.5a794239c1dec6d30537.js.map │ ├── 10.59c75d208fbdc827e31d.js │ ├── 10.59c75d208fbdc827e31d.js.map │ ├── 2.53d43735f0056ff82cb8.js │ ├── 2.53d43735f0056ff82cb8.js.map │ ├── 3.ac8ef93fe5111e371d5a.js │ ├── 3.ac8ef93fe5111e371d5a.js.map │ ├── 4.80576ee168dd2dd7685d.js │ ├── 4.80576ee168dd2dd7685d.js.map │ ├── 5.e1285d2811d2c1d8df51.js │ ├── 5.e1285d2811d2c1d8df51.js.map │ ├── 6.46bb82873bb8d80806a6.js │ ├── 6.46bb82873bb8d80806a6.js.map │ ├── 7.767d02cf34304e62347c.js │ ├── 7.767d02cf34304e62347c.js.map │ ├── 8.a8f1ceef290085f8065b.js │ ├── 8.a8f1ceef290085f8065b.js.map │ ├── 9.dab85558fe3c5df02348.js │ ├── 9.dab85558fe3c5df02348.js.map │ ├── app.cbe980894eec1103c2b7.js │ ├── app.cbe980894eec1103c2b7.js.map │ ├── manifest.9015f7858af4fe545ce6.js │ └── manifest.9015f7858af4fe545ce6.js.map ├── img ├── 1.png ├── 17.png ├── 2.png ├── 74.png ├── add.png ├── chart.png ├── edit.png ├── full.png ├── index.png ├── ip5.png ├── ip5_1.png ├── list.png ├── list2.png ├── login.png ├── 图标.png ├── 图表.png ├── 导航.png ├── 换肤.png ├── 搜索.png ├── 新增.png ├── 注册.png ├── 登录.png ├── 编辑.png ├── 表格.png └── 首页.png ├── index.html ├── package-lock.json ├── package.json ├── process.yml ├── prod.server.js ├── src ├── App.vue ├── api │ ├── api.js │ ├── config.js │ ├── fetch.js │ └── index.js ├── assets │ ├── iconfont │ │ ├── demo.css │ │ ├── icon.js │ │ ├── iconfont.css │ │ ├── iconfont.eot │ │ ├── iconfont.js │ │ ├── iconfont.svg │ │ ├── iconfont.ttf │ │ └── iconfont.woff │ ├── img │ │ ├── bg_login.jpg │ │ ├── fullstack.jpg │ │ └── logo.png │ ├── js │ │ └── app.js │ └── styles │ │ ├── base │ │ └── base.less │ │ ├── cover │ │ └── cover.less │ │ ├── layout │ │ └── layout.less │ │ └── variable │ │ └── variable.less ├── common │ ├── filter │ │ └── index.js │ └── utils │ │ └── index.js ├── components │ ├── Hello.vue │ ├── layout │ │ ├── Home.vue │ │ ├── aside │ │ │ └── aside.vue │ │ ├── base │ │ │ ├── Box.vue │ │ │ └── lock.vue │ │ ├── container │ │ │ └── Container.vue │ │ ├── header │ │ │ └── THeader.vue │ │ └── navbar │ │ │ └── NavBar.vue │ ├── pages │ │ ├── E404.vue │ │ ├── E500.vue │ │ ├── Filter.vue │ │ ├── Icon.vue │ │ ├── Login.vue │ │ ├── NotFound.vue │ │ ├── SetMenu.vue │ │ ├── SetMenu2.vue │ │ └── register.vue │ └── views │ │ ├── Article.vue │ │ ├── Chart.vue │ │ ├── Index.vue │ │ ├── List.vue │ │ ├── Table.vue │ │ ├── UserInfo.vue │ │ └── UserList.vue ├── i18n │ └── zh-CN.js ├── main.js ├── router │ ├── index.js │ ├── menu.js │ └── routes.js └── store │ ├── index.js │ └── modules │ └── app.js ├── static ├── .gitkeep └── img │ ├── fullstack.jpg │ └── logo.png └── test ├── e2e ├── custom-assertions │ └── elementCount.js ├── nightwatch.conf.js ├── runner.js └── specs │ └── test.js └── unit ├── .eslintrc ├── index.js ├── karma.conf.js └── specs └── Hello.spec.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-runtime"], 12 | "env": { 13 | "test": { 14 | "presets": ["env", "stage-2"], 15 | "plugins": ["istanbul"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // http://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parser: 'babel-eslint', 6 | parserOptions: { 7 | sourceType: 'module' 8 | }, 9 | env: { 10 | browser: true, 11 | }, 12 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 13 | extends: 'standard', 14 | // required to lint *.vue files 15 | plugins: [ 16 | 'html' 17 | ], 18 | // add your custom rules here 19 | // 'rules': { 20 | // // allow paren-less arrow functions 21 | // 'arrow-parens': 0, 22 | // // allow async-await 23 | // 'generator-star-spacing': 0, 24 | // // allow debugger during development 25 | // 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 26 | // "space-before-function-paren": ["error", { 27 | // "anonymous": "always", 28 | // "named": "never", //具名函数后不用空格 29 | // "asyncArrow": "always" 30 | // }], 31 | // "padded-blocks": ["error", {"blocks": "never"}] 32 | // } 33 | } 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log* 4 | yarn-debug.log* 5 | yarn-error.log* 6 | test/unit/coverage 7 | test/e2e/reports 8 | selenium-debug.log 9 | 10 | # Editor directories and files 11 | .idea 12 | *.suo 13 | *.ntvs* 14 | *.njsproj 15 | *.sln 16 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserlist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-admin 2 | 3 | > vue-admin by iview 4 | ^_^ 5 | # demo 6 | ant-design版本 https://github.com/artiely/vue-admin (推荐) 7 | 8 | element版 https://github.com/artiely/element-admin 9 | 10 | ## 项目截图 11 | ### 登录 12 | ![](img/登录.png) 13 | ### 注册 14 | ![](img/注册.png) 15 | ### 首页 16 | ![](img/首页.png) 17 | ### 主题切换 18 | ![](img/换肤.png) 19 | ### 搜索 20 | ![](img/搜索.png) 21 | ### 编辑 22 | ![](img/编辑.png) 23 | ### 图表 24 | ![](img/图表.png) 25 | ### 字体图标 26 | ![](img/图标.png) 27 | ### 响应式 28 | 29 | 30 | 31 | ## 技术栈 32 | > vue 33 | 34 | > vue-cli 35 | 36 | > vuex 37 | 38 | > vue-router 39 | 40 | > axios 41 | 42 | > i18n 43 | 44 | > es6/7 45 | 46 | > webpack2/3 47 | 48 | > less 49 | 50 | > ... 51 | 52 | ## 项目结构 53 | 54 | 这里推荐一个输出项目结构的node模块 `treeplus` https://github.com/artiely/treeplus 55 | ```bash 56 | ├─build // 打包环境 57 | │ 58 | ├─config // 开发部署配置 59 | │ 60 | ├─node_modules 61 | │ 62 | ├─src // 项目源文件 63 | │ │ main.js // 入口文件 64 | │ ├─api // 请求接口 65 | │ │ 66 | │ ├─assets // 组件静态资源 67 | │ │ └─styles // 样式 68 | │ │ ├─base // 基础样式 69 | │ │ ├─cover // iview覆盖样式 70 | │ │ ├─layout // 布局样式 71 | │ │ └─variable // 样式变量 72 | │ │ 73 | │ ├─common // 公共 74 | │ │ ├─directive 75 | │ │ └─utils 76 | │ │ 77 | │ ├─i18n // 国际化 78 | │ ├─components 79 | │ │ │ 80 | │ │ ├─layout // 布局组件 81 | │ │ │ Theader.vue 82 | │ │ │ Nav.vue 83 | │ │ ├─pages // 基本组件 84 | │ │ │ E404.vue 85 | │ │ │ Login.vue 86 | │ │ │ 87 | │ │ └─views // 业务组件 88 | │ │ 89 | │ ├─router // 路由管理 90 | │ │ 91 | │ └─store // 状态管理 92 | │ 93 | ├─static // 业务静态资源 94 | │ └─img 95 | │ 96 | └─test // 测试 97 | ├─e2e 98 | │ │ nightwatch.conf.js 99 | │ │ runner.js 100 | │ │ 101 | │ ├─custom-assertions 102 | │ │ elementCount.js 103 | │ │ 104 | │ └─specs 105 | │ test.js 106 | │ 107 | └─unit 108 | │ .eslintrc 109 | │ index.js 110 | │ karma.conf.js 111 | │ 112 | └─specs 113 | Hello.spec.js 114 | │ .babelrc // babel配置 115 | │ .editorconfig // editor配置 116 | │ .gitignore // git忽略配置 117 | │ .eslintrc.js // eslint配置 118 | │ .postcssrc.js // postcss配置 119 | │ index.html // 项目首页 120 | │ package.json // 依赖配置 121 | │ prod.server.js // 打包后启动文件 122 | ``` 123 | 124 | > 代码默认遵循eslint(default)的规范 不习惯的可以在webpack.base.conf.js 关闭相应规则 125 | 126 | ## 浏览器支持 127 | 128 | * IE 9+ 129 | * Firefox(最新) 130 | * Chrome(最新) 131 | * Safari(最新) 132 | 133 | ## Build Setup 134 | 135 | ``` bash 136 | # install dependencies 137 | npm install 138 | 139 | # 国内 140 | npm install --registry=https://registry.npm.taobao.org 141 | 142 | # serve with hot reload at localhost:8080 143 | npm run dev 144 | 145 | # build for production with minification 146 | npm run build 147 | 148 | # build for production and view the bundle analyzer report 149 | npm run build --report 150 | 151 | # run unit tests 152 | npm run unit 153 | 154 | # run e2e tests 155 | npm run e2e 156 | 157 | # run all tests 158 | npm test 159 | ``` 160 | 161 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 162 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | process.env.NODE_ENV = 'production' 4 | 5 | var ora = require('ora') 6 | var rm = require('rimraf') 7 | var path = require('path') 8 | var chalk = require('chalk') 9 | var webpack = require('webpack') 10 | var config = require('../config') 11 | var webpackConfig = require('./webpack.prod.conf') 12 | 13 | var spinner = ora('building for production...') 14 | spinner.start() 15 | 16 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 17 | if (err) throw err 18 | webpack(webpackConfig, function (err, stats) { 19 | spinner.stop() 20 | if (err) throw err 21 | process.stdout.write(stats.toString({ 22 | colors: true, 23 | modules: false, 24 | children: false, 25 | chunks: false, 26 | chunkModules: false 27 | }) + '\n\n') 28 | 29 | console.log(chalk.cyan(' Build complete.\n')) 30 | console.log(chalk.yellow( 31 | ' Tip: built files are meant to be served over an HTTP server.\n' + 32 | ' Opening index.html over file:// won\'t work.\n' 33 | )) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | var chalk = require('chalk') 2 | var semver = require('semver') 3 | var packageConfig = require('../package.json') 4 | var shell = require('shelljs') 5 | function exec (cmd) { 6 | return require('child_process').execSync(cmd).toString().trim() 7 | } 8 | 9 | var versionRequirements = [ 10 | { 11 | name: 'node', 12 | currentVersion: semver.clean(process.version), 13 | versionRequirement: packageConfig.engines.node 14 | }, 15 | ] 16 | 17 | if (shell.which('npm')) { 18 | versionRequirements.push({ 19 | name: 'npm', 20 | currentVersion: exec('npm --version'), 21 | versionRequirement: packageConfig.engines.npm 22 | }) 23 | } 24 | 25 | module.exports = function () { 26 | var warnings = [] 27 | for (var i = 0; i < versionRequirements.length; i++) { 28 | var mod = versionRequirements[i] 29 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 30 | warnings.push(mod.name + ': ' + 31 | chalk.red(mod.currentVersion) + ' should be ' + 32 | chalk.green(mod.versionRequirement) 33 | ) 34 | } 35 | } 36 | 37 | if (warnings.length) { 38 | console.log('') 39 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 40 | console.log() 41 | for (var i = 0; i < warnings.length; i++) { 42 | var warning = warnings[i] 43 | console.log(' ' + warning) 44 | } 45 | console.log() 46 | process.exit(1) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('eventsource-polyfill') 3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 4 | 5 | hotClient.subscribe(function (event) { 6 | if (event.action === 'reload') { 7 | window.location.reload() 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /build/dev-server.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | var config = require('../config') 4 | if (!process.env.NODE_ENV) { 5 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) 6 | } 7 | 8 | var opn = require('opn') 9 | var path = require('path') 10 | var express = require('express') 11 | var webpack = require('webpack') 12 | var proxyMiddleware = require('http-proxy-middleware') 13 | var webpackConfig = process.env.NODE_ENV === 'testing' 14 | ? require('./webpack.prod.conf') 15 | : require('./webpack.dev.conf') 16 | 17 | // default port where dev server listens for incoming traffic 18 | var port = process.env.PORT || config.dev.port 19 | // automatically open browser, if not set will be false 20 | var autoOpenBrowser = !!config.dev.autoOpenBrowser 21 | // Define HTTP proxies to your custom API backend 22 | // https://github.com/chimurai/http-proxy-middleware 23 | var proxyTable = config.dev.proxyTable 24 | 25 | var app = express() 26 | var compiler = webpack(webpackConfig) 27 | 28 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 29 | publicPath: webpackConfig.output.publicPath, 30 | quiet: true 31 | }) 32 | 33 | var hotMiddleware = require('webpack-hot-middleware')(compiler, { 34 | log: () => {} 35 | }) 36 | // force page reload when html-webpack-plugin template changes 37 | compiler.plugin('compilation', function (compilation) { 38 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 39 | hotMiddleware.publish({ action: 'reload' }) 40 | cb() 41 | }) 42 | }) 43 | 44 | // proxy api requests 45 | Object.keys(proxyTable).forEach(function (context) { 46 | var options = proxyTable[context] 47 | if (typeof options === 'string') { 48 | options = { target: options } 49 | } 50 | app.use(proxyMiddleware(options.filter || context, options)) 51 | }) 52 | 53 | // handle fallback for HTML5 history API 54 | app.use(require('connect-history-api-fallback')()) 55 | 56 | // serve webpack bundle output 57 | app.use(devMiddleware) 58 | 59 | // enable hot-reload and state-preserving 60 | // compilation error display 61 | app.use(hotMiddleware) 62 | 63 | // serve pure static assets 64 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 65 | app.use(staticPath, express.static('./static')) 66 | 67 | var uri = 'http://localhost:' + port 68 | 69 | var _resolve 70 | var readyPromise = new Promise(resolve => { 71 | _resolve = resolve 72 | }) 73 | 74 | console.log('> Starting dev server...') 75 | devMiddleware.waitUntilValid(() => { 76 | console.log('> Listening at ' + uri + '\n') 77 | // when env is testing, don't need open it 78 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 79 | opn(uri) 80 | } 81 | _resolve() 82 | }) 83 | 84 | var server = app.listen(port) 85 | 86 | module.exports = { 87 | ready: readyPromise, 88 | close: () => { 89 | server.close() 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | 5 | exports.assetsPath = function (_path) { 6 | var assetsSubDirectory = process.env.NODE_ENV === 'production' 7 | ? config.build.assetsSubDirectory 8 | : config.dev.assetsSubDirectory 9 | return path.posix.join(assetsSubDirectory, _path) 10 | } 11 | 12 | exports.cssLoaders = function (options) { 13 | options = options || {} 14 | 15 | var cssLoader = { 16 | loader: 'css-loader', 17 | options: { 18 | minimize: process.env.NODE_ENV === 'production', 19 | sourceMap: options.sourceMap 20 | } 21 | } 22 | 23 | // generate loader string to be used with extract text plugin 24 | function generateLoaders (loader, loaderOptions) { 25 | var loaders = [cssLoader] 26 | if (loader) { 27 | loaders.push({ 28 | loader: loader + '-loader', 29 | options: Object.assign({}, loaderOptions, { 30 | sourceMap: options.sourceMap 31 | }) 32 | }) 33 | } 34 | 35 | // Extract CSS when that option is specified 36 | // (which is the case during production build) 37 | if (options.extract) { 38 | return ExtractTextPlugin.extract({ 39 | use: loaders, 40 | fallback: 'vue-style-loader' 41 | }) 42 | } else { 43 | return ['vue-style-loader'].concat(loaders) 44 | } 45 | } 46 | 47 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 48 | return { 49 | css: generateLoaders(), 50 | postcss: generateLoaders(), 51 | less: generateLoaders('less'), 52 | sass: generateLoaders('sass', { indentedSyntax: true }), 53 | scss: generateLoaders('sass'), 54 | stylus: generateLoaders('stylus'), 55 | styl: generateLoaders('stylus') 56 | } 57 | } 58 | 59 | // Generate loaders for standalone style files (outside of .vue) 60 | exports.styleLoaders = function (options) { 61 | var output = [] 62 | var loaders = exports.cssLoaders(options) 63 | for (var extension in loaders) { 64 | var loader = loaders[extension] 65 | output.push({ 66 | test: new RegExp('\\.' + extension + '$'), 67 | use: loader 68 | }) 69 | } 70 | return output 71 | } 72 | -------------------------------------------------------------------------------- /build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var config = require('../config') 3 | var isProduction = process.env.NODE_ENV === 'production' 4 | 5 | module.exports = { 6 | loaders: utils.cssLoaders({ 7 | sourceMap: isProduction 8 | ? config.build.productionSourceMap 9 | : config.dev.cssSourceMap, 10 | extract: isProduction 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var utils = require('./utils') 3 | var config = require('../config') 4 | var vueLoaderConfig = require('./vue-loader.conf') 5 | var webpack = require('webpack') 6 | function resolve (dir) { 7 | return path.join(__dirname, '..', dir) 8 | } 9 | 10 | module.exports = { 11 | entry: { 12 | app: ['babel-polyfill', './src/main.js'] 13 | }, 14 | output: { 15 | path: config.build.assetsRoot, 16 | filename: '[name].js', 17 | publicPath: process.env.NODE_ENV === 'production' 18 | ? config.build.assetsPublicPath 19 | : config.dev.assetsPublicPath 20 | }, 21 | resolve: { 22 | extensions: ['.js', '.vue', '.json'], 23 | alias: { 24 | 'vue$': 'vue/dist/vue.esm.js', 25 | '@': resolve('src') 26 | } 27 | }, 28 | module: { 29 | rules: [ 30 | { 31 | test: /\.(js|vue)$/, 32 | loader: 'eslint-loader', 33 | enforce: 'pre', 34 | include: [resolve('src'), resolve('test')], 35 | options: { 36 | formatter: require('eslint-friendly-formatter') 37 | } 38 | }, 39 | { 40 | test: /\.vue$/, 41 | loader: 'vue-loader', 42 | options: vueLoaderConfig 43 | }, 44 | { test: /iview.src.*?js$/, loader: 'babel-loader' }, 45 | { 46 | test: /\.js$/, 47 | loader: 'babel-loader', 48 | include: [resolve('src'), resolve('test'), resolve('config')] 49 | }, 50 | { 51 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 52 | loader: 'url-loader', 53 | options: { 54 | limit: 10000, 55 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 56 | } 57 | }, 58 | { 59 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 60 | loader: 'url-loader', 61 | options: { 62 | limit: 10000, 63 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 64 | } 65 | } 66 | ] 67 | }, 68 | plugins: [ 69 | new webpack.optimize.CommonsChunkPlugin('common.js'), 70 | new webpack.ProvidePlugin({ 71 | jQuery: 'jquery', 72 | $: 'jquery' 73 | }) 74 | ] 75 | } 76 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var webpack = require('webpack') 3 | var config = require('../config') 4 | var merge = require('webpack-merge') 5 | var baseWebpackConfig = require('./webpack.base.conf') 6 | var HtmlWebpackPlugin = require('html-webpack-plugin') 7 | var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 8 | 9 | // add hot-reload related code to entry chunks 10 | Object.keys(baseWebpackConfig.entry).forEach(function (name) { 11 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 12 | }) 13 | 14 | module.exports = merge(baseWebpackConfig, { 15 | module: { 16 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) 17 | }, 18 | // cheap-module-eval-source-map is faster for development 19 | devtool: '#cheap-module-eval-source-map', 20 | plugins: [ 21 | new webpack.DefinePlugin({ 22 | 'process.env': config.dev.env 23 | }), 24 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 25 | new webpack.HotModuleReplacementPlugin(), 26 | new webpack.NoEmitOnErrorsPlugin(), 27 | // https://github.com/ampedandwired/html-webpack-plugin 28 | new HtmlWebpackPlugin({ 29 | filename: 'index.html', 30 | template: 'index.html', 31 | inject: true 32 | }), 33 | new FriendlyErrorsPlugin() 34 | ] 35 | }) 36 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var utils = require('./utils') 3 | var webpack = require('webpack') 4 | var config = require('../config') 5 | var merge = require('webpack-merge') 6 | var baseWebpackConfig = require('./webpack.base.conf') 7 | var CopyWebpackPlugin = require('copy-webpack-plugin') 8 | var HtmlWebpackPlugin = require('html-webpack-plugin') 9 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 10 | var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 11 | 12 | var env = process.env.NODE_ENV === 'testing' 13 | ? require('../config/test.env') 14 | : config.build.env 15 | 16 | var webpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ 19 | sourceMap: config.build.productionSourceMap, 20 | extract: true 21 | }) 22 | }, 23 | devtool: config.build.productionSourceMap ? '#source-map' : false, 24 | output: { 25 | path: config.build.assetsRoot, 26 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 27 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 28 | }, 29 | plugins: [ 30 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 31 | new webpack.DefinePlugin({ 32 | 'process.env': env 33 | }), 34 | new webpack.optimize.UglifyJsPlugin({ 35 | compress: { 36 | warnings: false 37 | }, 38 | sourceMap: true 39 | }), 40 | // extract css into its own file 41 | new ExtractTextPlugin({ 42 | filename: utils.assetsPath('css/[name].[contenthash].css') 43 | }), 44 | // Compress extracted CSS. We are using this plugin so that possible 45 | // duplicated CSS from different components can be deduped. 46 | new OptimizeCSSPlugin({ 47 | cssProcessorOptions: { 48 | safe: true 49 | } 50 | }), 51 | // generate dist index.html with correct asset hash for caching. 52 | // you can customize output by editing /index.html 53 | // see https://github.com/ampedandwired/html-webpack-plugin 54 | new HtmlWebpackPlugin({ 55 | filename: process.env.NODE_ENV === 'testing' 56 | ? 'index.html' 57 | : config.build.index, 58 | template: 'index.html', 59 | inject: true, 60 | minify: { 61 | removeComments: true, 62 | collapseWhitespace: true, 63 | removeAttributeQuotes: true 64 | // more options: 65 | // https://github.com/kangax/html-minifier#options-quick-reference 66 | }, 67 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 68 | chunksSortMode: 'dependency' 69 | }), 70 | // split vendor js into its own file 71 | new webpack.optimize.CommonsChunkPlugin({ 72 | name: 'vendor', 73 | minChunks: function (module, count) { 74 | // any required modules inside node_modules are extracted to vendor 75 | return ( 76 | module.resource && 77 | /\.js$/.test(module.resource) && 78 | module.resource.indexOf( 79 | path.join(__dirname, '../node_modules') 80 | ) === 0 81 | ) 82 | } 83 | }), 84 | // extract webpack runtime and module manifest to its own file in order to 85 | // prevent vendor hash from being updated whenever app bundle is updated 86 | new webpack.optimize.CommonsChunkPlugin({ 87 | name: 'manifest', 88 | chunks: ['vendor'] 89 | }), 90 | // copy custom static assets 91 | new CopyWebpackPlugin([ 92 | { 93 | from: path.resolve(__dirname, '../static'), 94 | to: config.build.assetsSubDirectory, 95 | ignore: ['.*'] 96 | } 97 | ]) 98 | ] 99 | }) 100 | 101 | if (config.build.productionGzip) { 102 | var CompressionWebpackPlugin = require('compression-webpack-plugin') 103 | 104 | webpackConfig.plugins.push( 105 | new CompressionWebpackPlugin({ 106 | asset: '[path].gz[query]', 107 | algorithm: 'gzip', 108 | test: new RegExp( 109 | '\\.(' + 110 | config.build.productionGzipExtensions.join('|') + 111 | ')$' 112 | ), 113 | threshold: 10240, 114 | minRatio: 0.8 115 | }) 116 | ) 117 | } 118 | 119 | if (config.build.bundleAnalyzerReport) { 120 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 121 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 122 | } 123 | 124 | module.exports = webpackConfig 125 | -------------------------------------------------------------------------------- /build/webpack.test.conf.js: -------------------------------------------------------------------------------- 1 | // This is the webpack config used for unit tests. 2 | 3 | var utils = require('./utils') 4 | var webpack = require('webpack') 5 | var merge = require('webpack-merge') 6 | var baseConfig = require('./webpack.base.conf') 7 | 8 | var webpackConfig = merge(baseConfig, { 9 | // use inline sourcemap for karma-sourcemap-loader 10 | module: { 11 | rules: utils.styleLoaders() 12 | }, 13 | devtool: '#inline-source-map', 14 | resolveLoader: { 15 | alias: { 16 | // necessary to to make lang="scss" work in test when using vue-loader's ?inject option 17 | // see discussion at https://github.com/vuejs/vue-loader/issues/724 18 | 'scss-loader': 'sass-loader' 19 | } 20 | }, 21 | plugins: [ 22 | new webpack.DefinePlugin({ 23 | 'process.env': require('../config/test.env') 24 | }) 25 | ] 26 | }) 27 | 28 | // no need for app entry during tests 29 | delete webpackConfig.entry 30 | 31 | module.exports = webpackConfig 32 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | var config = { 5 | build: { 6 | env: require('./prod.env'), 7 | port: 9000, 8 | index: path.resolve(__dirname, '../dist/index.html'), 9 | assetsRoot: path.resolve(__dirname, '../dist'), 10 | assetsSubDirectory: 'static', 11 | assetsPublicPath: '/', 12 | baseServerUrl: 'http://gank.io', 13 | productionSourceMap: true, 14 | // Gzip off by default as many popular static hosts such as 15 | // Surge or Netlify already gzip all static assets for you. 16 | // Before setting to `true`, make sure to: 17 | // npm install --save-dev compression-webpack-plugin 18 | productionGzip: false, 19 | productionGzipExtensions: ['js', 'css'], 20 | // Run the build command with an extra argument to 21 | // View the bundle analyzer report after build finishes: 22 | // `npm run build --report` 23 | // Set to `true` or `false` to always turn it on or off 24 | bundleAnalyzerReport: process.env.npm_config_report 25 | }, 26 | dev: { 27 | env: require('./dev.env'), 28 | port: 9999, 29 | autoOpenBrowser: true, 30 | assetsSubDirectory: 'static', 31 | assetsPublicPath: '/', 32 | baseServerUrl: 'http://gank.io', 33 | proxyTable: {}, 34 | // CSS Sourcemaps off by default because relative paths are "buggy" 35 | // with this option, according to the CSS-Loader README 36 | // (https://github.com/webpack/css-loader#sourcemaps) 37 | // In our experience, they generally work as expected, 38 | // just be aware of this issue when enabling this option. 39 | cssSourceMap: false 40 | } 41 | } 42 | 43 | // 需要代理的接口 44 | var proxyList = [ 45 | '/*/person/**/*' 46 | ] 47 | 48 | const targetPath = config.dev.baseServerUrl // 服务器的地址 可以使www.xx.com 49 | 50 | for (let i = 0; i < proxyList.length; i++) { 51 | config.dev.proxyTable[proxyList[i]] = { 52 | target: targetPath, 53 | secure: false, 54 | changeOrigin: true 55 | } 56 | } 57 | // console.info(Object.keys(config.dev.proxyTable)) 58 | module.exports = config 59 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /config/test.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var devEnv = require('./dev.env') 3 | 4 | module.exports = merge(devEnv, { 5 | NODE_ENV: '"testing"' 6 | }) 7 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | vue-admin-artiely
-------------------------------------------------------------------------------- /dist/static/fonts/iconfont.42ef16c.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/dist/static/fonts/iconfont.42ef16c.eot -------------------------------------------------------------------------------- /dist/static/fonts/iconfont.4cf6b7c.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/dist/static/fonts/iconfont.4cf6b7c.woff -------------------------------------------------------------------------------- /dist/static/fonts/iconfont.b5270aa.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/dist/static/fonts/iconfont.b5270aa.ttf -------------------------------------------------------------------------------- /dist/static/fonts/ionicons.05acfdb.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/dist/static/fonts/ionicons.05acfdb.woff -------------------------------------------------------------------------------- /dist/static/fonts/ionicons.24712f6.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/dist/static/fonts/ionicons.24712f6.ttf -------------------------------------------------------------------------------- /dist/static/fonts/ionicons.2c2ae06.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/dist/static/fonts/ionicons.2c2ae06.eot -------------------------------------------------------------------------------- /dist/static/img/bg_login.7285dd8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/dist/static/img/bg_login.7285dd8.jpg -------------------------------------------------------------------------------- /dist/static/img/fullstack.e51bafb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/dist/static/img/fullstack.e51bafb.jpg -------------------------------------------------------------------------------- /dist/static/img/fullstack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/dist/static/img/fullstack.jpg -------------------------------------------------------------------------------- /dist/static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/dist/static/img/logo.png -------------------------------------------------------------------------------- /dist/static/js/10.59c75d208fbdc827e31d.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([10],{1278:function(e,t,a){e.exports={render:function(){var e=this,t=e.$createElement,o=e._self._c||t;return o("div",{staticClass:"login"},[o("div",{staticClass:"bg"}),e._v(" "),o("Modal",{staticClass:"login-modal",attrs:{width:"360",closable:!1,"mask-closable":!1},model:{value:e.loginModal,callback:function(t){e.loginModal=t},expression:"loginModal"}},[o("div",[o("h2",{staticStyle:{margin:"10px",color:"#abcdef","text-align":"center"}},[o("img",{attrs:{src:a(367),alt:"",height:"50"}})]),e._v(" "),o("Form",{ref:"formValidate",attrs:{model:e.formValidate,rules:e.ruleValidate}},[o("Form-item",{attrs:{prop:"name"}},[o("Input",{attrs:{placeholder:"请输入姓名"},model:{value:e.formValidate.name,callback:function(t){e.$set(e.formValidate,"name",t)},expression:"formValidate.name"}})],1),e._v(" "),o("Form-item",{attrs:{prop:"password"}},[o("Input",{attrs:{type:"password",placeholder:"请输入密码"},nativeOn:{keyup:function(t){if(!("button"in t)&&e._k(t.keyCode,"enter",13,t.key))return null;e.handleSubmit("formValidate")}},model:{value:e.formValidate.password,callback:function(t){e.$set(e.formValidate,"password",t)},expression:"formValidate.password"}})],1),e._v(" "),o("Row",[o("Col",{attrs:{span:"12"}},[o("Checkbox-group",{model:{value:e.formValidate.remember,callback:function(t){e.$set(e.formValidate,"remember",t)},expression:"formValidate.remember"}},[o("Checkbox",{attrs:{label:"记住我"}})],1)],1),e._v(" "),o("Col",{attrs:{span:"12"}},[o("a",{staticStyle:{float:"right"},on:{click:e.toRegister}},[e._v("新用户注册")])])],1)],1)],1),e._v(" "),o("div",{attrs:{slot:"footer"},slot:"footer"},[o("Button",{attrs:{type:"primary",size:"large",long:"",loading:e.modal_loading},on:{click:function(t){e.handleSubmit("formValidate")}}},[e._v("登录\n ")]),e._v(" "),o("small",{staticClass:"subText",staticStyle:{"text-align":"center",display:"block"}},[e._v("©copyright by Artiely")])],1)])],1)},staticRenderFns:[]}},778:function(e,t,a){var o=a(52)(a(960),a(1278),null,null,null);e.exports=o.exports},960:function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=a(72),l=a.n(o);t.default={name:"login",data:function(){return{loginModal:!0,modal_loading:!1,formValidate:{name:"",password:""},ruleValidate:{name:[{required:!0,message:"姓名不能为空",trigger:"blur"}],password:[{required:!0,message:"密码错误",trigger:"blur"}]}}},methods:{handleSubmit:function(e){var t=this;this.$refs[e].validate(function(e){t.modal_loading=!0,setTimeout(function(){t.modal_loading=!1,e?(t.$Message.success("登录成功!"),l.a.set("token",t.formValidate.password),t.$router.push("/index")):(t.$Message.error("表单验证失败!"),t.$Notice.warning({title:"登录提示",desc:"用户名/密码 随意输入..."}))},2e3)})},toRegister:function(){this.$router.push("/register")}}}}}); 2 | //# sourceMappingURL=10.59c75d208fbdc827e31d.js.map -------------------------------------------------------------------------------- /dist/static/js/3.ac8ef93fe5111e371d5a.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([3],{1253:function(t,e,o){var a=o(978);"string"==typeof a&&(a=[[t.i,a,""]]),a.locals&&(t.exports=a.locals);o(773)("779eb5f8",a,!0)},1262:function(t,e,o){t.exports=o.p+"static/img/bg_login.7285dd8.jpg"},1282:function(t,e,o){t.exports={render:function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"type",style:{background:"url("+t.bgUrl+")"},attrs:{id:"app"}},[a("Row",{staticClass:"bg",style:{background:"url("+t.bgUrl+")"}},[a("Col",{attrs:{xs:16,offset:"4"}},[a("Card",{staticStyle:{margin:"100px auto","max-width":"600px","padding-top":"20px","text-align":"left"}},[t.token?a("div",[a("Steps",{staticStyle:{"padding-left":"70px","padding-bottom":"10px","text-align":"left"},attrs:{current:2,size:"small"}},[a("Step",{attrs:{title:"基本信息"}}),t._v(" "),a("Step",{attrs:{title:"邮箱激活"}}),t._v(" "),a("Step",{attrs:{title:"信息登记"}})],1),t._v(" "),a("Form",{ref:"formCustom",attrs:{model:t.formCustom,rules:t.ruleCustom,"label-width":110}},[a("Form-item",{attrs:{label:"类型",prop:"typeId"}},[a("Radio-group",{model:{value:t.formCustom.typeId,callback:function(e){t.$set(t.formCustom,"typeId",e)},expression:"formCustom.typeId"}},[a("Radio",{attrs:{label:"2"}},[t._v("企业")]),t._v(" "),a("Radio",{attrs:{label:"1",disabled:""}},[t._v("个人")])],1)],1),t._v(" "),a("small",{staticClass:"help"},[t._v("需与当地政府颁发的商业许可证或企业注册证上的企业名称完全一致,信息审核成功后,企业名称不可修改")]),t._v(" "),a("Form-item",{attrs:{label:"企业名称",prop:"company"}},[a("Input",{attrs:{placeholder:"请输入"},model:{value:t.formCustom.company,callback:function(e){t.$set(t.formCustom,"company",e)},expression:"formCustom.company"}})],1),t._v(" "),a("small",{staticClass:"help"},[t._v("标示即为公司英文简称")]),t._v(" "),a("Form-item",{attrs:{label:"标示",prop:"mark"}},[a("Input",{attrs:{placeholder:"请输入"},model:{value:t.formCustom.mark,callback:function(e){t.$set(t.formCustom,"mark",e)},expression:"formCustom.mark"}})],1),t._v(" "),a("small",{staticClass:"help"},[t._v("请输入15位营业执照号或18位的统一社会信用代码")]),t._v(" "),a("Form-item",{attrs:{label:"营业执照注册号",prop:"companyId"}},[a("Input",{attrs:{placeholder:"请输入"},model:{value:t.formCustom.companyId,callback:function(e){t.$set(t.formCustom,"companyId",e)},expression:"formCustom.companyId"}})],1),t._v(" "),a("Form-item",{attrs:{label:"管理员姓名",prop:"userName"}},[a("Input",{attrs:{placeholder:"请输入"},model:{value:t.formCustom.userName,callback:function(e){t.$set(t.formCustom,"userName",e)},expression:"formCustom.userName"}})],1),t._v(" "),a("Form-item",{attrs:{label:"管理员身份证号",prop:"idCard"}},[a("Input",{attrs:{placeholder:"请输入"},model:{value:t.formCustom.idCard,callback:function(e){t.$set(t.formCustom,"idCard",e)},expression:"formCustom.idCard"}})],1),t._v(" "),a("Form-item",{attrs:{label:"管理员手机号",prop:"phone"}},[a("Input",{attrs:{placeholder:"请输入"},model:{value:t.formCustom.phone,callback:function(e){t.$set(t.formCustom,"phone",e)},expression:"formCustom.phone"}})],1),t._v(" "),a("Form-item",[a("Button",{attrs:{type:"primary",long:"",loading:t.loading},on:{click:function(e){t.handleSubmit("formCustom")}}},[t._v("提交\n ")])],1)],1)],1):t._e(),t._v(" "),t.token?t._e():a("div",[a("Steps",{staticStyle:{"padding-left":"70px","padding-bottom":"10px"},attrs:{current:1,status:"error",size:"small"}},[a("Step",{attrs:{title:"基本信息"}}),t._v(" "),a("Step",{attrs:{title:"邮箱激活"}}),t._v(" "),a("Step",{attrs:{title:"信息登记"}})],1),t._v(" "),a("h3",{staticStyle:{color:"#ed3f14","text-align":"center"}},[a("p",[t._v("链接过期或失效"),a("a",{attrs:{href:"register.html"}},[t._v(" 重新发送邮件")])])])],1),t._v(" "),a("small",{staticStyle:{display:"block","text-align":"center","line-height":"30px"}},[a("img",{staticStyle:{"vertical-align":"top"},attrs:{src:o(367),height:"30",alt:""}}),a("span",[t._v("Copyright by Artiely ,All rights reserved")])])])],1)],1)],1)},staticRenderFns:[]}},780:function(t,e,o){function a(t){o(1253)}var r=o(52)(o(961),o(1282),a,"data-v-87ce2992",null);t.exports=r.exports},956:function(t,e,o){"use strict";function a(t){var e=new RegExp("(^|&)"+t+"=([^&]*)(&|$)"),o=window.location.search.substr(1).match(e),a=window.location.search,r=window.location.href,s=r.indexOf("?");return""===a&&(o=r.substr(s+1).match(e)),null!=o?unescape(o[2]):null}e.a=a},961:function(t,e,o){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=o(368),r=o.n(a),s=o(956),n=o(1262),i=o.n(n);e.default={name:"type",data:function(){var t=function(t,e,o){15!==e.toString().length&&18!==e.toString().length?o(new Error("请输入正确的营业执照注册号")):o()};return{token:!0,loading:!1,bgUrl:i.a,formCustom:{typeId:2,company:"",mark:"",companyId:"",userName:"",idCard:"",sex:"1",phone:""},ruleCustom:{company:[{required:!0,message:"企业名称不能为空",trigger:"blur"}],mark:[{required:!0,message:"标示不能为空",trigger:"blur"},{message:"标示只支持字母",trigger:"blur",pattern:/^[A-Za-z]$/}],companyId:[{required:!0,message:"营业执照注册号不能为空",trigger:"blur"},{validator:t,trigger:"blur"}],userName:[{required:!0,message:"管理员名称不能为空",trigger:"blur"}],idCard:[{required:!0,message:"身份证号不能为空",trigger:"blur"},{message:"身份证号格式不正确",trigger:"blur",pattern:/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/}],phone:[{required:!0,message:"手机号不能为空",trigger:"blur"},{message:"手机号格式不正确",len:11,trigger:"blur",pattern:/^[1][3,4,5,7,8][0-9]{9}$/}]}}},methods:{handleSubmit:function(t){var e=this;this.loading=!0,this.$refs[t].validate(function(t){if(t){var a={account_type:e.formCustom.typeId,company_name:e.formCustom.company,business_license_number:e.formCustom.companyId,personName:e.formCustom.userName,personSex:e.formCustom.idCard.substring(16,1)%2?"1":"0",idCard:e.formCustom.idCard,telephone:e.formCustom.phone,promotionTableName:o.i(s.a)("promotionTableName")||"",promotionTableId:o.i(s.a)("promotionTableId")||"",email:o.i(s.a)("e")||""};e.$api.postUserInfo(a).then(function(t){if(e.loading=!1,0===t.code){e.$Message.success("提交成功!");var o=window.location.href;o=""===window.location.search?window.location.href:o.split(window.location.search)[0],o=o.replace("type.html","login.html"),window.location.href=o}else alert(r()(t))}).catch(function(t){e.loading=!1,console.error("哎哟~!",t)})}else e.loading=!1,e.$Message.error("表单验证失败!")})},checkToken:function(){var t=this,e={token:o.i(s.a)("token")||"",e:o.i(s.a)("e")||"",p:o.i(s.a)("p")||""};this.$api.checkToken(e).then(function(e){0===e.code&&("1"===e.state?t.token=!0:t.token=!1)})},save:function(){}},created:function(){this.checkToken()}}},978:function(t,e,o){e=t.exports=o(772)(!0),e.push([t.i,"body[data-v-87ce2992],html[data-v-87ce2992]{position:absolute;height:100%;width:100%}#app[data-v-87ce2992]{width:100%;height:100%;overflow:scroll}.help[data-v-87ce2992]{display:block;text-align:left;font-size:12px;color:#9ea7b4}","",{version:3,sources:["D:/Users/Administrator/Desktop/workspace/vue-admin-artiely/vue-admin/src/components/pages/Register.vue"],names:[],mappings:"AACA,4CAEE,kBAAmB,AACnB,YAAa,AACb,UAAY,CACb,AACD,sBACE,WAAY,AACZ,YAAa,AACb,eAAiB,CAClB,AACD,uBACE,cAAe,AACf,gBAAiB,AACjB,eAAgB,AAChB,aAAe,CAChB",file:"Register.vue",sourcesContent:["\nhtml[data-v-87ce2992],\nbody[data-v-87ce2992] {\n position: absolute;\n height: 100%;\n width: 100%;\n}\n#app[data-v-87ce2992] {\n width: 100%;\n height: 100%;\n overflow: scroll;\n}\n.help[data-v-87ce2992] {\n display: block;\n text-align: left;\n font-size: 12px;\n color: #9ea7b4;\n}\n"],sourceRoot:""}])}}); 2 | //# sourceMappingURL=3.ac8ef93fe5111e371d5a.js.map -------------------------------------------------------------------------------- /dist/static/js/4.80576ee168dd2dd7685d.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([4],{1252:function(e,n,t){var _=t(977);"string"==typeof _&&(_=[[e.i,_,""]]),_.locals&&(e.exports=_.locals);t(773)("805c0f58",_,!0)},1281:function(e,n){e.exports={render:function(){var e=this,n=e.$createElement,t=e._self._c||n;return t("div",{staticClass:"filter"},[t("Row",[t("i-col",[t("Card",[t("h2",[e._v("最常见过滤器")]),e._v(" "),t("h4",[e._v("隐藏敏感信息")]),e._v(" "),t("p",[e._v("姓名:"+e._s(e.name)+" => "+e._s(e._f("star")(e.name)))]),e._v(" "),t("p",[e._v("手机号:"+e._s(e.phone)+" =>"+e._s(e._f("star")(e.phone)))]),e._v(" "),t("p",[e._v("身份证:"+e._s(e.idCard)+" =>"+e._s(e._f("star")(e.idCard)))]),e._v(" "),t("p",[e._v("银行卡号:"+e._s(e.bankNum)+" =>"+e._s(e._f("star")(e.bankNum)))]),e._v(" "),t("h4",[e._v("格式化发布时间")]),e._v(" "),t("p",[e._v(e._s(e.itme.one)+" => "+e._s(e._f("timeAgo")(e.itme.one)))]),e._v(" "),t("p",[e._v(e._s(e.itme.now)+" => "+e._s(e._f("timeAgo")(e.itme.now)))]),e._v(" "),t("p",[e._v(e._s(e.itme.now1)+" => "+e._s(e._f("timeAgo")(e.itme.now1)))]),e._v(" "),t("p",[e._v(e._s(e.itme.now3)+" => "+e._s(e._f("timeAgo")(e.itme.now3)))]),e._v(" "),t("p",[e._v(e._s(e.itme.now2)+" => "+e._s(e._f("timeAgo")(e.itme.now2)))]),e._v(" "),t("h4",[e._v("格式化货币")]),e._v(" "),t("p",[e._v(e._s(e.currency.money)+" =>"+e._s(e._f("currency")(e.currency.money)))]),e._v(" "),t("p",[e._v(e._s(e.currency.money)+" =>"+e._s(e._f("currency")(e.currency.money,"¥")))]),e._v(" "),t("p",[e._v(e._s(e.currency.money)+" =>"+e._s(e._f("currency")(e.currency.money,"€",3)))]),e._v(" "),t("h4",[e._v("时间格式化")]),e._v(" "),t("p",[e._v("时间对象默认转换")]),e._v(" "),t("p",[e._v(e._s(e.itme.now)+" =>"+e._s(e._f("timeFormat")(e.itme.now)))]),e._v(" "),t("p",[e._v("时间戳默认转换")]),e._v(" "),t("p",[e._v(e._s(e.itme.now1)+" =>"+e._s(e._f("timeFormat")(e.itme.now1)))]),e._v(" "),t("p",[e._v("时间格式改变")]),e._v(" "),t("p",[e._v(e._s(e.itme.now2)+" =>"+e._s(e._f("timeFormat")(e.itme.now2,"YY/MM/DD HH:mm")))]),e._v(" "),t("h6",{staticClass:"Button--primary Button--blue"},[e._v("欢迎分享")])])],1)],1)],1)},staticRenderFns:[]}},776:function(e,n,t){function _(e){t(1252)}var o=t(52)(t(958),t(1281),_,"data-v-7e1076e8",null);e.exports=o.exports},958:function(e,n,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default={name:"filter",data:function(){return{name:"谭杰",phone:15988880460,idCard:0x5d6042b40285100,bankNum:59162655458634e4,itme:{one:"2017-8-29 13:54",now:new Date,now1:new Date-6e4,now3:new Date-36e5,now2:"2017-7-29 13:54"},currency:{money:1e5}}}}},977:function(e,n,t){n=e.exports=t(772)(!0),n.push([e.i,".Button--primary.Button--blue[data-v-7e1076e8]{color:#fff;padding:10px;background:linear-gradient(90deg,#15b982,#01d18b);box-shadow:0 3px 6px rgba(0,0,0,.16)}","",{version:3,sources:["D:/Users/Administrator/Desktop/workspace/vue-admin-artiely/vue-admin/src/components/pages/Filter.vue"],names:[],mappings:"AACA,+CACE,WAAY,AACZ,aAAc,AACd,kDAAmD,AACnD,oCAAsC,CACvC",file:"Filter.vue",sourcesContent:["\n.Button--primary.Button--blue[data-v-7e1076e8] {\n color: #fff;\n padding: 10px;\n background: linear-gradient(90deg,#15b982,#01d18b);\n box-shadow: 0 3px 6px rgba(0,0,0,.16);\n}\n"],sourceRoot:""}])}}); 2 | //# sourceMappingURL=4.80576ee168dd2dd7685d.js.map -------------------------------------------------------------------------------- /dist/static/js/5.e1285d2811d2c1d8df51.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([5],{1255:function(e,t,a){var n=a(980);"string"==typeof n&&(n=[[e.i,n,""]]),n.locals&&(e.exports=n.locals);a(773)("15de5c59",n,!0)},1285:function(e,t){e.exports={render:function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{staticClass:"lock"},[a("div",{staticClass:"wrapper clearfix"},[a("Avatar",{staticStyle:{cursor:"pointer"},attrs:{src:"https://avatars1.githubusercontent.com/u/19198355?s=400&u=aa18d8f6d07dbd4f8f4dd966f3fbb2b3a1b3ee00&v=4",size:"large"},nativeOn:{click:function(t){e.passwordShow=!0}}},[e._v("Lock\n ")]),e._v(" "),e.passwordShow?a("div",{staticClass:"input-wrapper"},[a("input",{directives:[{name:"model",rawName:"v-model",value:e.password,expression:"password"}],ref:"input",staticClass:"input",attrs:{autofocus:!0,placeholder:"登录密码",type:"password"},domProps:{value:e.password},on:{keyup:function(t){if(!("button"in t)&&e._k(t.keyCode,"enter",13,t.key))return null;e.handleUnlock(t)},input:function(t){t.target.composing||(e.password=t.target.value)}}}),e._v(" "),a("span",{staticClass:"underline"})]):e._e()],1),e._v(" "),e._m(0,!1,!1)])},staticRenderFns:[function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{staticClass:"content"},[a("h1",{staticClass:"date",attrs:{id:"date"}}),e._v(" "),a("h3",{staticClass:"time",attrs:{id:"time"}})])}]}},774:function(e,t,a){function n(e){a(1255)}var o=a(52)(a(957),a(1285),n,"data-v-aeae8f26",null);e.exports=o.exports},957:function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=a(72),o=a.n(n);t.default={name:"Unlock",data:function(){return{avatorLeft:"0px",inputLeft:"400px",password:"",passwordShow:!1}},methods:{handleUnlock:function(){o.a.get("token")===this.password?(this.avatorLeft="0px",this.inputLeft="400px",this.password="",this.$store.commit("SET_LOCK","0"),console.log(this.$store.state.app.lockPage),this.$router.push(this.$store.state.app.lockPage)):this.$Message.error("密码错误,请重新输入。如果忘了密码,清除浏览器缓存重新登录即可,这里没有做后端验证")}},mounted:function(){this.$nextTick(function(){function e(){var t=new Date,a=t.getHours(),n=t.getMinutes(),A=a<=11?"am":"pm",i=[a%12,n<10?"0"+n:n].join(":")+A;o.innerHTML=i,setTimeout(e,1e3)}var t=new Date,a=["January","February","March","April","May","June","July","August","September","October","November","December"],n=document.getElementById("date"),o=document.getElementById("time");!function(){n.innerHTML=a[t.getMonth()]+" "+t.getDate()+","+t.getFullYear()}(),e()})}}},980:function(e,t,a){t=e.exports=a(772)(!0),t.push([e.i,".lock[data-v-aeae8f26]{position:absolute;top:0;left:0;right:0;bottom:0;height:100%;background:#2d2222;width:100%}.input-wrapper[data-v-aeae8f26]{position:relative}.wrapper[data-v-aeae8f26]{box-sizing:border-box;position:relative;margin:100px auto;width:300px;text-align:center}.input[data-v-aeae8f26]{text-align:center;background-color:transparent;border:none;color:#555;font-size:18px;height:40px;position:absolute;top:0;left:0;width:300px}.input[data-v-aeae8f26]:focus{outline:none}input[data-v-aeae8f26]::-webkit-input-placeholder{color:#aaa}input[data-v-aeae8f26]:focus::-webkit-input-placeholder{color:#1e90ff}.input:focus+.underline[data-v-aeae8f26]{-webkit-transform:scale(1);transform:scale(1)}.underline[data-v-aeae8f26]{background-color:#1e90ff;display:inline-block;height:2px;left:0;position:absolute;top:40px;-webkit-transform:scaleX(0);transform:scaleX(0);transition:all .5s linear;width:300px}.content[data-v-aeae8f26]{position:fixed;left:0;top:0;background:#fff;box-shadow:0 0 10px rgba(0,0,0,.5);width:200px}.date[data-v-aeae8f26],.input[data-v-aeae8f26],.time[data-v-aeae8f26]{color:#bdc3c7;font-weight:300;font-size:14px;padding:8px 20px}.input[data-v-aeae8f26]{padding:0}.date[data-v-aeae8f26]{border-bottom:2px solid #eee}.time[data-v-aeae8f26]{font-size:3em}","",{version:3,sources:["D:/Users/Administrator/Desktop/workspace/vue-admin-artiely/vue-admin/src/components/layout/base/Lock.vue"],names:[],mappings:"AACA,uBACE,kBAAmB,AACnB,MAAO,AACP,OAAQ,AACR,QAAS,AACT,SAAU,AACV,YAAa,AACb,mBAAoB,AACpB,UAAY,CACb,AACD,gCACE,iBAAmB,CACpB,AACD,0BACE,sBAAuB,AACvB,kBAAmB,AACnB,kBAAmB,AACnB,YAAa,AACb,iBAAmB,CACpB,AACD,wBACE,kBAAmB,AACnB,6BAA8B,AAC9B,YAAa,AACb,WAAY,AACZ,eAAgB,AAChB,YAAa,AACb,kBAAmB,AACnB,MAAO,AACP,OAAQ,AACR,WAAa,CACd,AACD,8BACE,YAAc,CACf,AACD,kDACE,UAAY,CACb,AACD,wDACE,aAAkB,CACnB,AACD,yCACE,2BAA4B,AACpB,kBAAoB,CAC7B,AACD,4BACE,yBAA6B,AAC7B,qBAAsB,AACtB,WAAY,AACZ,OAAQ,AACR,kBAAmB,AACnB,SAAU,AACV,4BAA+B,AAC/B,oBAAuB,AACvB,0BAA4B,AAC5B,WAAa,CACd,AACD,0BACE,eAAgB,AAChB,OAAQ,AACR,MAAO,AACP,gBAAiB,AACjB,mCAAwC,AACxC,WAAa,CACd,AACD,sEAGE,cAAe,AACf,gBAAiB,AACjB,eAAgB,AAChB,gBAAkB,CACnB,AACD,wBACE,SAAW,CACZ,AACD,uBACE,4BAA8B,CAC/B,AACD,uBACE,aAAe,CAChB",file:"Lock.vue",sourcesContent:["\n.lock[data-v-aeae8f26] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n height: 100%;\n background: #2d2222;\n width: 100%;\n}\n.input-wrapper[data-v-aeae8f26] {\n position: relative;\n}\n.wrapper[data-v-aeae8f26] {\n box-sizing: border-box;\n position: relative;\n margin: 100px auto;\n width: 300px;\n text-align: center;\n}\n.input[data-v-aeae8f26] {\n text-align: center;\n background-color: transparent;\n border: none;\n color: #555;\n font-size: 18px;\n height: 40px;\n position: absolute;\n top: 0;\n left: 0;\n width: 300px;\n}\n.input[data-v-aeae8f26]:focus {\n outline: none;\n}\ninput[data-v-aeae8f26]::-webkit-input-placeholder {\n color: #AAA;\n}\ninput[data-v-aeae8f26]:focus::-webkit-input-placeholder {\n color: dodgerblue;\n}\n.input:focus + .underline[data-v-aeae8f26] {\n -webkit-transform: scale(1);\n transform: scale(1);\n}\n.underline[data-v-aeae8f26] {\n background-color: dodgerblue;\n display: inline-block;\n height: 2px;\n left: 0;\n position: absolute;\n top: 40px;\n -webkit-transform: scale(0, 1);\n transform: scale(0, 1);\n transition: all 0.5s linear;\n width: 300px;\n}\n.content[data-v-aeae8f26] {\n position: fixed;\n left: 0;\n top: 0;\n background: #fff;\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);\n width: 200px;\n}\n.date[data-v-aeae8f26],\n.time[data-v-aeae8f26],\n.input[data-v-aeae8f26] {\n color: #bdc3c7;\n font-weight: 300;\n font-size: 14px;\n padding: 8px 20px;\n}\n.input[data-v-aeae8f26] {\n padding: 0;\n}\n.date[data-v-aeae8f26] {\n border-bottom: 2px solid #eee;\n}\n.time[data-v-aeae8f26] {\n font-size: 3em;\n}\n"],sourceRoot:""}])}}); 2 | //# sourceMappingURL=5.e1285d2811d2c1d8df51.js.map -------------------------------------------------------------------------------- /dist/static/js/6.46bb82873bb8d80806a6.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([6],{1249:function(n,e,t){var o=t(974);"string"==typeof o&&(o=[[n.i,o,""]]),o.locals&&(n.exports=o.locals);t(773)("5a1259f6",o,!0)},1277:function(n,e){n.exports={render:function(){var n=this,e=n.$createElement;return(n._self._c||e)("div",{staticClass:"e404"},[n._v("\n NOT FOUND\n")])},staticRenderFns:[]}},779:function(n,e,t){function o(n){t(1249)}var a=t(52)(null,t(1277),o,"data-v-3498bf03",null);n.exports=a.exports},974:function(n,e,t){e=n.exports=t(772)(!0),e.push([n.i,".e404[data-v-3498bf03]{background-color:#fafafa;width:100%;height:100%;font-size:100px;text-align:center;color:#ddd}","",{version:3,sources:["D:/Users/Administrator/Desktop/workspace/vue-admin-artiely/vue-admin/src/components/pages/NotFound.vue"],names:[],mappings:"AACA,uBACE,yBAA0B,AAC1B,WAAY,AACZ,YAAa,AACb,gBAAiB,AACjB,kBAAmB,AACnB,UAAY,CACb",file:"NotFound.vue",sourcesContent:["\n.e404[data-v-3498bf03]{\n background-color: #fafafa;\n width: 100%;\n height: 100%;\n font-size: 100px;\n text-align: center;\n color: #ddd;\n}\n"],sourceRoot:""}])}}); 2 | //# sourceMappingURL=6.46bb82873bb8d80806a6.js.map -------------------------------------------------------------------------------- /dist/static/js/6.46bb82873bb8d80806a6.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///static/js/6.46bb82873bb8d80806a6.js","webpack:///./src/components/pages/NotFound.vue?7b3b","webpack:///./src/components/pages/NotFound.vue?f6e8","webpack:///./src/components/pages/NotFound.vue","webpack:///./src/components/pages/NotFound.vue?1758"],"names":["webpackJsonp","1249","module","exports","__webpack_require__","content","i","locals","1277","render","_vm","this","_h","$createElement","_self","_c","staticClass","_v","staticRenderFns","779","injectStyle","ssrContext","Component","974","push","version","sources","names","mappings","file","sourcesContent","sourceRoot"],"mappings":"AAAAA,cAAc,IAERC,KACA,SAAUC,EAAQC,EAASC,GCAjC,GAAAC,GAAAD,EAAA,IACA,iBAAAC,SAAAH,EAAAI,EAAAD,EAAA,MACAA,EAAAE,SAAAL,EAAAC,QAAAE,EAAAE,OAEAH,GAAA,gBAAAC,GAAA,IDSMG,KACA,SAAUN,EAAQC,GEjBxBD,EAAAC,SAAgBM,OAAA,WAAmB,GAAAC,GAAAC,KAAaC,EAAAF,EAAAG,cAChD,QAD0EH,EAAAI,MAAAC,IAAAH,GAC1E,OACAI,YAAA,SACGN,EAAAO,GAAA,qBACFC,qBFuBKC,IACA,SAAUjB,EAAQC,EAASC,GG5BjC,QAAAgB,GAAAC,GACAjB,EAAA,MAEA,GAAAkB,GAAAlB,EAAA,IAEA,KAEAA,EAAA,MAEAgB,EAEA,kBAEA,KAGAlB,GAAAC,QAAAmB,EAAAnB,SHmCMoB,IACA,SAAUrB,EAAQC,EAASC,GIpDjCD,EAAAD,EAAAC,QAAAC,EAAA,SAKAD,EAAAqB,MAAAtB,EAAAI,EAAA,uHAA8I,IAAQmB,QAAA,EAAAC,SAAA,0GAAAC,SAAAC,SAAA,kFAAAC,KAAA,eAAAC,gBAAA,6JAAyaC,WAAA","file":"static/js/6.46bb82873bb8d80806a6.js","sourcesContent":["webpackJsonp([6],{\n\n/***/ 1249:\n/***/ (function(module, exports, __webpack_require__) {\n\n// style-loader: Adds some css to the DOM by adding a 90 | 91 | 92 | 93 |
94 |
95 |
96 | 97 |
98 | 99 | 100 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-admin-artiely", 3 | "version": "1.0.1", 4 | "description": "vue-admin bu iview", 5 | "author": "artiely ", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "start": "node build/dev-server.js", 10 | "build": "node build/build.js", 11 | "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run", 12 | "e2e": "node test/e2e/runner.js", 13 | "test": "npm run unit && npm run e2e" 14 | }, 15 | "dependencies": { 16 | "autoprefixer": "^6.7.2", 17 | "axios": "^0.16.2", 18 | "babel-core": "^6.22.1", 19 | "babel-eslint": "^7.1.1", 20 | "babel-loader": "^6.2.10", 21 | "babel-plugin-istanbul": "^4.1.1", 22 | "babel-plugin-transform-runtime": "^6.22.0", 23 | "babel-polyfill": "^6.23.0", 24 | "babel-preset-env": "^1.3.2", 25 | "babel-preset-stage-2": "^6.22.0", 26 | "babel-register": "^6.22.0", 27 | "chai": "^3.5.0", 28 | "chalk": "^1.1.3", 29 | "chromedriver": "^2.27.2", 30 | "clipboard": "^1.7.1", 31 | "phantomjs-prebuilt": "^2.1.14", 32 | "connect-history-api-fallback": "^1.3.0", 33 | "copy-webpack-plugin": "^4.0.1", 34 | "cross-env": "^4.0.0", 35 | "cross-spawn": "^5.0.1", 36 | "css-loader": "^0.28.0", 37 | "echarts": "^3.8.5", 38 | "eslint": "^3.19.0", 39 | "eslint-config-standard": "^6.2.1", 40 | "eslint-friendly-formatter": "^3.0.0", 41 | "eslint-loader": "^1.7.1", 42 | "eslint-plugin-html": "^3.0.0", 43 | "eslint-plugin-promise": "^3.4.0", 44 | "eslint-plugin-standard": "^2.0.1", 45 | "eventsource-polyfill": "^0.9.6", 46 | "express": "^4.14.1", 47 | "extract-text-webpack-plugin": "^2.0.0", 48 | "file-loader": "^0.11.1", 49 | "friendly-errors-webpack-plugin": "^1.1.3", 50 | "html-webpack-plugin": "^2.28.0", 51 | "http-proxy-middleware": "^0.17.3", 52 | "inject-loader": "^3.0.0", 53 | "iview": "^2.4.0", 54 | "jquery": "^2.2.3", 55 | "js-cookie": "^2.1.4", 56 | "karma": "^1.4.1", 57 | "karma-coverage": "^1.1.1", 58 | "karma-mocha": "^1.3.0", 59 | "karma-phantomjs-launcher": "^1.0.2", 60 | "karma-phantomjs-shim": "^1.4.0", 61 | "karma-sinon-chai": "^1.3.1", 62 | "karma-sourcemap-loader": "^0.3.7", 63 | "karma-spec-reporter": "0.0.30", 64 | "karma-webpack": "^2.0.2", 65 | "less": "^2.7.2", 66 | "less-loader": "^4.0.4", 67 | "lolex": "^1.5.2", 68 | "mocha": "^3.2.0", 69 | "moment": "^2.18.1", 70 | "nightwatch": "^0.9.12", 71 | "opn": "^4.0.2", 72 | "optimize-css-assets-webpack-plugin": "^1.3.0", 73 | "ora": "^1.2.0", 74 | "rimraf": "^2.6.0", 75 | "selenium-server": "^3.0.1", 76 | "semver": "^5.3.0", 77 | "shelljs": "^0.7.6", 78 | "sinon": "^2.1.0", 79 | "sinon-chai": "^2.8.0", 80 | "url-loader": "^0.5.8", 81 | "vue": "^2.3.3", 82 | "vue-echarts-v3": "^1.0.15", 83 | "vue-i18n": "^5.0.3", 84 | "vue-loader": "^12.1.0", 85 | "vue-router": "^2.4.0", 86 | "vue-style-loader": "^3.0.1", 87 | "vue-template-compiler": "^2.3.3", 88 | "vuedraggable": "^2.14.1", 89 | "vuex": "^2.3.1", 90 | "webpack": "^2.6.1", 91 | "webpack-bundle-analyzer": "^2.2.1", 92 | "webpack-dev-middleware": "^1.10.0", 93 | "webpack-hot-middleware": "^2.18.0", 94 | "webpack-merge": "^4.1.0" 95 | }, 96 | "devDependencies": {}, 97 | "engines": { 98 | "node": ">= 4.0.0", 99 | "npm": ">= 3.0.0" 100 | }, 101 | "browserslist": [ 102 | "> 1%", 103 | "last 2 versions", 104 | "not ie <= 8" 105 | ] 106 | } 107 | -------------------------------------------------------------------------------- /process.yml: -------------------------------------------------------------------------------- 1 | apps: 2 | - script : prod.server.js 3 | name : 'iview-admin' 4 | watch : true 5 | env : 6 | NODE_ENV: development 7 | env_production: 8 | NODE_ENV: production 9 | deploy : 10 | production : 11 | user : root 12 | key : C:/Windows/SSH-ubuntu.pem 13 | host : 14 | - 120.78.174.212 15 | port : 22 16 | ref : origin/master 17 | repo : git@github.com:artiely/vue-admin-iview.git 18 | path : /www/iview-admin/production 19 | ssh_options : StrictHostKeyChecking=no 20 | pre-deploy : git fetch --all 21 | post-deploy : 'npm install && npm run build && pm2 startOrRestart process.yml --env production' 22 | env : 23 | NODE_ENV : production -------------------------------------------------------------------------------- /prod.server.js: -------------------------------------------------------------------------------- 1 | var express = require('express') 2 | var config = require('./config/index') 3 | var app = express() 4 | app.use(express.static('./dist')) 5 | 6 | var port = process.env.PORT || config.build.port 7 | module.exports = app.listen(port, function (err) { 8 | if (err) { 9 | console.error(err) 10 | return 11 | } 12 | console.log('Listiening at http://localhost:' + port + '\n') 13 | }) 14 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 28 | -------------------------------------------------------------------------------- /src/api/api.js: -------------------------------------------------------------------------------- 1 | import fetch from './fetch.js' 2 | 3 | // // 登录 4 | // export function login (data) { 5 | // return fetch({ 6 | // url: '', 7 | // method: 'post', 8 | // data 9 | // }) 10 | // } 11 | // // 登出 12 | // export function logout () { 13 | // return fetch({ 14 | // url: '', 15 | // method: 'post' 16 | // }) 17 | // } 18 | 19 | const orderList = params => { 20 | return fetch({ 21 | url: `/api/data/${params.category}/${params.limit}/${params.page}`, 22 | method: 'get', 23 | params: '' 24 | }) 25 | } 26 | 27 | const articleList = params => { 28 | return fetch({ 29 | url: `/api/search/query/listview/category/Android/count/${params.limit}/page/${params.page}`, 30 | method: 'get', 31 | params: '' 32 | }) 33 | } 34 | 35 | const userList = params => { 36 | return fetch({ 37 | url: '/api/person/getPersonListByCompany', 38 | method: 'get', 39 | params: params 40 | }) 41 | } 42 | 43 | /** 44 | * 提交用户注册信息 45 | * @param params 46 | */ 47 | const postUserInfo = params => { 48 | return fetch({ 49 | url: '', 50 | method: 'post', 51 | data: params 52 | }) 53 | } 54 | 55 | /** 56 | * 验证邮箱 token是否过期 57 | * @param params 58 | */ 59 | const checkToken = params => { 60 | return fetch({ 61 | url: '', 62 | method: 'get', 63 | params: params 64 | }) 65 | } 66 | const apiList = { 67 | orderList, 68 | articleList, 69 | userList, 70 | postUserInfo, 71 | checkToken 72 | } 73 | 74 | export default apiList 75 | -------------------------------------------------------------------------------- /src/api/config.js: -------------------------------------------------------------------------------- 1 | // 接口配置 2 | // 服务器接口根地址 3 | var config = require('../../config') 4 | var isProduction = process.env.NODE_ENV === 'production' 5 | if (isProduction) { 6 | console.log('%c 如果你看到这条 log , 说明当前是生产环境', 'font-size:14px;color:#f00;background:#000') 7 | } else { 8 | console.log('%c 如果你看到这条 log , 说明当前是开发环境', 'font-size:14px;color:#f00;background:#000') 9 | } 10 | // 服务器地址 11 | // export const SERVER_BASE_URL = isProduction ? 'http://gank.io' : 'www.baidu.com' 12 | export const SERVER_BASE_URL = isProduction ? config.build.baseServerUrl : config.dev.baseServerUrl 13 | 14 | // export const SERVER_BASE_URL = 'http://gank.io/api' 15 | // global.SERVER_BASE_URL='http://localhost:9999/fwone-central' 16 | export const ERR_OK = 0 17 | 18 | -------------------------------------------------------------------------------- /src/api/fetch.js: -------------------------------------------------------------------------------- 1 | // 导入模块 2 | import Vue from 'vue' 3 | import axios from 'axios' 4 | import { SERVER_BASE_URL } from './config' 5 | // import router from '@/router' 6 | import iView, {Notice } from 'iview' 7 | // import store from '@/store' 8 | Vue.use(iView) 9 | // 设置用户信息action 10 | /* const setUserInfo = function (user) { 11 | //store.dispatch(SET_USER_INFO, user) 12 | }; */ 13 | 14 | export default function fetch (options) { 15 | return new Promise((resolve, reject) => { 16 | const instance = axios.create({ 17 | baseURL: SERVER_BASE_URL, 18 | timeout: 5000, 19 | headers: {} 20 | }) 21 | // http request 拦截器 22 | instance.interceptors.request.use( 23 | config => { 24 | iView.LoadingBar.start() 25 | // config.headers.Authorization = 'token' 26 | return config 27 | }, 28 | err => { 29 | iView.LoadingBar.error() 30 | return Promise.reject(err) 31 | }) 32 | 33 | // http response 拦截器 34 | instance.interceptors.response.use( 35 | response => { 36 | iView.LoadingBar.finish() 37 | return response 38 | }, 39 | error => { 40 | iView.LoadingBar.error() 41 | if (error) { 42 | } 43 | return Promise.reject(error) // 返回接口返回的错误信息 44 | }) 45 | 46 | // 请求处理 47 | instance(options) 48 | .then((res) => { 49 | // 请求成功时,根据业务判断状态 50 | /* if (code === port_code.success) { 51 | resolve({code, msg, data}) 52 | return false 53 | } else if (code === port_code.unlogin) { 54 | setUserInfo(null) 55 | router.replace({name: "login"}) 56 | } */ 57 | 58 | resolve(res.data) 59 | return false 60 | }) 61 | .catch((error) => { 62 | // 请求失败时,根据业务判断状态 63 | Notice.error({ 64 | title: '出错了!', 65 | desc: '错误原因 ' + JSON.stringify(error), 66 | duration: 0 67 | }) 68 | reject(error) 69 | }) 70 | }) 71 | } 72 | -------------------------------------------------------------------------------- /src/api/index.js: -------------------------------------------------------------------------------- 1 | // 导入模块 2 | import apiList from './api' 3 | 4 | const install = function (Vue) { 5 | if (install.installed) return 6 | install.installed = true 7 | 8 | // 定义属性到Vue原型中 9 | Object.defineProperties(Vue.prototype, { 10 | $api: { 11 | get () { 12 | return apiList 13 | } 14 | } 15 | }) 16 | } 17 | 18 | export default { 19 | install 20 | } 21 | -------------------------------------------------------------------------------- /src/assets/iconfont/demo.css: -------------------------------------------------------------------------------- 1 | *{margin: 0;padding: 0;list-style: none;} 2 | /* 3 | KISSY CSS Reset 4 | 理念:1. reset 的目的不是清除浏览器的默认样式,这仅是部分工作。清除和重置是紧密不可分的。 5 | 2. reset 的目的不是让默认样式在所有浏览器下一致,而是减少默认样式有可能带来的问题。 6 | 3. reset 期望提供一套普适通用的基础样式。但没有银弹,推荐根据具体需求,裁剪和修改后再使用。 7 | 特色:1. 适应中文;2. 基于最新主流浏览器。 8 | 维护:玉伯, 正淳 9 | */ 10 | 11 | /** 清除内外边距 **/ 12 | body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* structural elements 结构元素 */ 13 | dl, dt, dd, ul, ol, li, /* list elements 列表元素 */ 14 | pre, /* text formatting elements 文本格式元素 */ 15 | form, fieldset, legend, button, input, textarea, /* form elements 表单元素 */ 16 | th, td /* table elements 表格元素 */ { 17 | margin: 0; 18 | padding: 0; 19 | } 20 | 21 | /** 设置默认字体 **/ 22 | body, 23 | button, input, select, textarea /* for ie */ { 24 | font: 12px/1.5 tahoma, arial, \5b8b\4f53, sans-serif; 25 | } 26 | h1, h2, h3, h4, h5, h6 { font-size: 100%; } 27 | address, cite, dfn, em, var { font-style: normal; } /* 将斜体扶正 */ 28 | code, kbd, pre, samp { font-family: courier new, courier, monospace; } /* 统一等宽字体 */ 29 | small { font-size: 12px; } /* 小于 12px 的中文很难阅读,让 small 正常化 */ 30 | 31 | /** 重置列表元素 **/ 32 | ul, ol { list-style: none; } 33 | 34 | /** 重置文本格式元素 **/ 35 | a { text-decoration: none; } 36 | a:hover { text-decoration: underline; } 37 | 38 | 39 | /** 重置表单元素 **/ 40 | legend { color: #000; } /* for ie6 */ 41 | fieldset, img { border: 0; } /* img 搭车:让链接里的 img 无边框 */ 42 | button, input, select, textarea { font-size: 100%; } /* 使得表单元素在 ie 下能继承字体大小 */ 43 | /* 注:optgroup 无法扶正 */ 44 | 45 | /** 重置表格元素 **/ 46 | table { border-collapse: collapse; border-spacing: 0; } 47 | 48 | /* 清除浮动 */ 49 | .ks-clear:after, .clear:after { 50 | content: '\20'; 51 | display: block; 52 | height: 0; 53 | clear: both; 54 | } 55 | .ks-clear, .clear { 56 | *zoom: 1; 57 | } 58 | 59 | .main { 60 | padding: 30px 100px; 61 | width: 960px; 62 | margin: 0 auto; 63 | } 64 | .main h1{font-size:36px; color:#333; text-align:left;margin-bottom:30px; border-bottom: 1px solid #eee;} 65 | 66 | .helps{margin-top:40px;} 67 | .helps pre{ 68 | padding:20px; 69 | margin:10px 0; 70 | border:solid 1px #e7e1cd; 71 | background-color: #fffdef; 72 | overflow: auto; 73 | } 74 | 75 | .icon_lists{ 76 | width: 100% !important; 77 | 78 | } 79 | 80 | .icon_lists li{ 81 | float:left; 82 | width: 60px; 83 | height:60px; 84 | text-align: center; 85 | list-style: none !important; 86 | } 87 | .icon_lists .icon{ 88 | font-size: 30px; 89 | line-height: 60px; 90 | margin: 10px 0; 91 | color:#333; 92 | -webkit-transition: font-size 0.25s ease-out 0s; 93 | -moz-transition: font-size 0.25s ease-out 0s; 94 | transition: font-size 0.25s ease-out 0s; 95 | 96 | } 97 | .icon_lists .icon:hover{ 98 | /*font-size: 100px;*/ 99 | cursor: pointer; 100 | } 101 | 102 | .fontclass{ 103 | display: none; 104 | } 105 | 106 | .markdown { 107 | color: #666; 108 | font-size: 14px; 109 | line-height: 1.8; 110 | } 111 | 112 | .highlight { 113 | line-height: 1.5; 114 | } 115 | 116 | .markdown img { 117 | vertical-align: middle; 118 | max-width: 100%; 119 | } 120 | 121 | .markdown h1 { 122 | color: #404040; 123 | font-weight: 500; 124 | line-height: 40px; 125 | margin-bottom: 24px; 126 | } 127 | 128 | .markdown h2, 129 | .markdown h3, 130 | .markdown h4, 131 | .markdown h5, 132 | .markdown h6 { 133 | color: #404040; 134 | margin: 1.6em 0 0.6em 0; 135 | font-weight: 500; 136 | clear: both; 137 | } 138 | 139 | .markdown h1 { 140 | font-size: 28px; 141 | } 142 | 143 | .markdown h2 { 144 | font-size: 22px; 145 | } 146 | 147 | .markdown h3 { 148 | font-size: 16px; 149 | } 150 | 151 | .markdown h4 { 152 | font-size: 14px; 153 | } 154 | 155 | .markdown h5 { 156 | font-size: 12px; 157 | } 158 | 159 | .markdown h6 { 160 | font-size: 12px; 161 | } 162 | 163 | .markdown hr { 164 | height: 1px; 165 | border: 0; 166 | background: #e9e9e9; 167 | margin: 16px 0; 168 | clear: both; 169 | } 170 | 171 | .markdown p, 172 | .markdown pre { 173 | margin: 1em 0; 174 | } 175 | 176 | .markdown > p, 177 | .markdown > blockquote, 178 | .markdown > .highlight, 179 | .markdown > ol, 180 | .markdown > ul { 181 | width: 80%; 182 | } 183 | 184 | .markdown ul > li { 185 | list-style: circle; 186 | } 187 | 188 | .markdown > ul li, 189 | .markdown blockquote ul > li { 190 | margin-left: 20px; 191 | padding-left: 4px; 192 | } 193 | 194 | .markdown > ul li p, 195 | .markdown > ol li p { 196 | margin: 0.6em 0; 197 | } 198 | 199 | .markdown ol > li { 200 | list-style: decimal; 201 | } 202 | 203 | .markdown > ol li, 204 | .markdown blockquote ol > li { 205 | margin-left: 20px; 206 | padding-left: 4px; 207 | } 208 | 209 | .markdown code { 210 | margin: 0 3px; 211 | padding: 0 5px; 212 | background: #eee; 213 | border-radius: 3px; 214 | } 215 | 216 | .markdown pre { 217 | border-radius: 6px; 218 | background: #f7f7f7; 219 | /*padding: 20px;*/ 220 | } 221 | 222 | .markdown pre code { 223 | border: none; 224 | background: #f7f7f7; 225 | margin: 0; 226 | } 227 | 228 | .markdown strong, 229 | .markdown b { 230 | font-weight: 600; 231 | } 232 | 233 | .markdown > table { 234 | border-collapse: collapse; 235 | border-spacing: 0px; 236 | empty-cells: show; 237 | border: 1px solid #e9e9e9; 238 | width: 95%; 239 | margin-bottom: 24px; 240 | } 241 | 242 | .markdown > table th { 243 | white-space: nowrap; 244 | color: #333; 245 | font-weight: 600; 246 | 247 | } 248 | 249 | .markdown > table th, 250 | .markdown > table td { 251 | border: 1px solid #e9e9e9; 252 | padding: 8px 16px; 253 | text-align: left; 254 | } 255 | 256 | .markdown > table th { 257 | background: #F7F7F7; 258 | } 259 | 260 | .markdown blockquote { 261 | font-size: 90%; 262 | color: #999; 263 | border-left: 4px solid #e9e9e9; 264 | padding-left: 0.8em; 265 | margin: 1em 0; 266 | font-style: italic; 267 | } 268 | 269 | .markdown blockquote p { 270 | margin: 0; 271 | } 272 | 273 | .markdown .anchor { 274 | opacity: 0; 275 | transition: opacity 0.3s ease; 276 | margin-left: 8px; 277 | } 278 | 279 | .markdown .waiting { 280 | color: #ccc; 281 | } 282 | 283 | .markdown h1:hover .anchor, 284 | .markdown h2:hover .anchor, 285 | .markdown h3:hover .anchor, 286 | .markdown h4:hover .anchor, 287 | .markdown h5:hover .anchor, 288 | .markdown h6:hover .anchor { 289 | opacity: 1; 290 | display: inline-block; 291 | } 292 | 293 | .markdown > br, 294 | .markdown > p > br { 295 | clear: both; 296 | } 297 | 298 | 299 | .hljs { 300 | display: block; 301 | background: white; 302 | padding: 0.5em; 303 | color: #333333; 304 | overflow-x: auto; 305 | } 306 | 307 | .hljs-comment, 308 | .hljs-meta { 309 | color: #969896; 310 | } 311 | 312 | .hljs-string, 313 | .hljs-variable, 314 | .hljs-template-variable, 315 | .hljs-strong, 316 | .hljs-emphasis, 317 | .hljs-quote { 318 | color: #df5000; 319 | } 320 | 321 | .hljs-keyword, 322 | .hljs-selector-tag, 323 | .hljs-type { 324 | color: #a71d5d; 325 | } 326 | 327 | .hljs-literal, 328 | .hljs-symbol, 329 | .hljs-bullet, 330 | .hljs-attribute { 331 | color: #0086b3; 332 | } 333 | 334 | .hljs-section, 335 | .hljs-name { 336 | color: #63a35c; 337 | } 338 | 339 | .hljs-tag { 340 | color: #333333; 341 | } 342 | 343 | .hljs-title, 344 | .hljs-attr, 345 | .hljs-selector-id, 346 | .hljs-selector-class, 347 | .hljs-selector-attr, 348 | .hljs-selector-pseudo { 349 | color: #795da3; 350 | } 351 | 352 | .hljs-addition { 353 | color: #55a532; 354 | background-color: #eaffea; 355 | } 356 | 357 | .hljs-deletion { 358 | color: #bd2c00; 359 | background-color: #ffecec; 360 | } 361 | 362 | .hljs-link { 363 | text-decoration: underline; 364 | } 365 | 366 | pre{ 367 | background: #fff; 368 | } 369 | 370 | 371 | 372 | 373 | 374 | -------------------------------------------------------------------------------- /src/assets/iconfont/icon.js: -------------------------------------------------------------------------------- 1 | const iconfont = [ 2 | {name: 'icon-lvshihan'}, 3 | {name: 'icon-law'}, 4 | {name: 'icon-wujiaoxing'}, 5 | {name: 'icon-tuichu1'}, 6 | {name: 'icon-zhengcefagui2'}, 7 | {name: 'icon-falvsolid'}, 8 | {name: 'icon-tianjia'}, 9 | {name: 'icon-huidaodingbu'}, 10 | {name: 'icon-guanjiaowangtubiao35'}, 11 | {name: 'icon-xuanxiang'}, 12 | {name: 'icon-lvshiguanli'}, 13 | {name: 'icon-wenzibida'}, 14 | {name: 'icon-zhengcefagui'}, 15 | {name: 'icon-tupian'}, 16 | {name: 'icon-zhexiantu'}, 17 | {name: 'icon-guanzhu'}, 18 | {name: 'icon-lvshi'}, 19 | {name: 'icon-jiaoliu'}, 20 | {name: 'icon-gengduo'}, 21 | {name: 'icon-zhifubao'}, 22 | {name: 'icon-accessory'}, 23 | {name: 'icon-activity'}, 24 | {name: 'icon-activity_fill'}, 25 | {name: 'icon-add'}, 26 | {name: 'icon-addition_fill'}, 27 | {name: 'icon-addition'}, 28 | {name: 'icon-addpeople_fill'}, 29 | {name: 'icon-addpeople'}, 30 | {name: 'icon-addressbook_fill'}, 31 | {name: 'icon-addressbook'}, 32 | {name: 'icon-barrage_fill'}, 33 | {name: 'icon-barrage'}, 34 | {name: 'icon-browse_fill'}, 35 | {name: 'icon-browse'}, 36 | {name: 'icon-brush'}, 37 | {name: 'icon-brush_fill'}, 38 | {name: 'icon-businesscard_fill'}, 39 | {name: 'icon-businesscard'}, 40 | {name: 'icon-camera_fill'}, 41 | {name: 'icon-camera'}, 42 | {name: 'icon-clock_fill'}, 43 | {name: 'icon-clock'}, 44 | {name: 'icon-close'}, 45 | {name: 'icon-collection_fill'}, 46 | {name: 'icon-collection'}, 47 | {name: 'icon-computer_fill'}, 48 | {name: 'icon-computer'}, 49 | {name: 'icon-coordinates_fill'}, 50 | {name: 'icon-coordinates'}, 51 | {name: 'icon-coupons_fill'}, 52 | {name: 'icon-coupons'}, 53 | {name: 'icon-createtask_fill'}, 54 | {name: 'icon-createtask'}, 55 | {name: 'icon-customerservice_fill'}, 56 | {name: 'icon-customerservice'}, 57 | {name: 'icon-delete_fill'}, 58 | {name: 'icon-delete'}, 59 | {name: 'icon-document'}, 60 | {name: 'icon-document_fill'}, 61 | {name: 'icon-dynamic_fill'}, 62 | {name: 'icon-dynamic'}, 63 | {name: 'icon-editor'}, 64 | {name: 'icon-eit'}, 65 | {name: 'icon-emoji_fill'}, 66 | {name: 'icon-emoji'}, 67 | {name: 'icon-empty'}, 68 | {name: 'icon-empty_fill'}, 69 | {name: 'icon-enter'}, 70 | {name: 'icon-enterinto'}, 71 | {name: 'icon-enterinto_fill'}, 72 | {name: 'icon-feedback_fill'}, 73 | {name: 'icon-feedback'}, 74 | {name: 'icon-flag_fill'}, 75 | {name: 'icon-flag'}, 76 | {name: 'icon-flashlight'}, 77 | {name: 'icon-flashlight_fill'}, 78 | {name: 'icon-flip'}, 79 | {name: 'icon-flip_fill'}, 80 | {name: 'icon-fullscreen'}, 81 | {name: 'icon-group'}, 82 | {name: 'icon-group_fill'}, 83 | {name: 'icon-headlines_fill'}, 84 | {name: 'icon-headlines'}, 85 | {name: 'icon-homepage_fill'}, 86 | {name: 'icon-homepage'}, 87 | {name: 'icon-integral_fill'}, 88 | {name: 'icon-integral'}, 89 | {name: 'icon-interactive_fill'}, 90 | {name: 'icon-interactive'}, 91 | {name: 'icon-keyboard'}, 92 | {name: 'icon-label'}, 93 | {name: 'icon-label_fill'}, 94 | {name: 'icon-like_fill'}, 95 | {name: 'icon-like'}, 96 | {name: 'icon-live_fill'}, 97 | {name: 'icon-live'}, 98 | {name: 'icon-lock_fill'}, 99 | {name: 'icon-lock'}, 100 | {name: 'icon-mail'}, 101 | {name: 'icon-mail_fill'}, 102 | {name: 'icon-manage_fill'}, 103 | {name: 'icon-manage'}, 104 | {name: 'icon-message'}, 105 | {name: 'icon-message_fill'}, 106 | {name: 'icon-mine'}, 107 | {name: 'icon-mine_fill'}, 108 | {name: 'icon-mobilephone_fill'}, 109 | {name: 'icon-mobilephone'}, 110 | {name: 'icon-more'}, 111 | {name: 'icon-narrow'}, 112 | {name: 'icon-offline_fill'}, 113 | {name: 'icon-offline'}, 114 | {name: 'icon-order_fill'}, 115 | {name: 'icon-order'}, 116 | {name: 'icon-other'}, 117 | {name: 'icon-people_fill'}, 118 | {name: 'icon-people'}, 119 | {name: 'icon-picture_fill'}, 120 | {name: 'icon-picture'}, 121 | {name: 'icon-play'}, 122 | {name: 'icon-play_fill'}, 123 | {name: 'icon-playon_fill'}, 124 | {name: 'icon-playon'}, 125 | {name: 'icon-praise_fill'}, 126 | {name: 'icon-praise'}, 127 | {name: 'icon-prompt_fill'}, 128 | {name: 'icon-prompt'}, 129 | {name: 'icon-qrcode_fill'}, 130 | {name: 'icon-qrcode'}, 131 | {name: 'icon-redpacket_fill'}, 132 | {name: 'icon-redpacket'}, 133 | {name: 'icon-refresh'}, 134 | {name: 'icon-remind_fill'}, 135 | {name: 'icon-remind'}, 136 | {name: 'icon-return'}, 137 | {name: 'icon-right'}, 138 | {name: 'icon-scan'}, 139 | {name: 'icon-select_fill'}, 140 | {name: 'icon-select'}, 141 | {name: 'icon-send'}, 142 | {name: 'icon-service_fill'}, 143 | {name: 'icon-service'}, 144 | {name: 'icon-setup_fill'}, 145 | {name: 'icon-setup'}, 146 | {name: 'icon-share_fill'}, 147 | {name: 'icon-share'}, 148 | {name: 'icon-shielding_fill'}, 149 | {name: 'icon-shielding'}, 150 | {name: 'icon-smallscreen_fill'}, 151 | {name: 'icon-smallscreen'}, 152 | {name: 'icon-stealth_fill'}, 153 | {name: 'icon-stealth'}, 154 | {name: 'icon-success_fill'}, 155 | {name: 'icon-success'}, 156 | {name: 'icon-suspend'}, 157 | {name: 'icon-switch'}, 158 | {name: 'icon-systemprompt_fill'}, 159 | {name: 'icon-systemprompt'}, 160 | {name: 'icon-tailor'}, 161 | {name: 'icon-task'}, 162 | {name: 'icon-task_fill'}, 163 | {name: 'icon-tasklist_fill'}, 164 | {name: 'icon-tasklist'}, 165 | {name: 'icon-text'}, 166 | {name: 'icon-time_fill'}, 167 | {name: 'icon-time'}, 168 | {name: 'icon-translation_fill'}, 169 | {name: 'icon-translation'}, 170 | {name: 'icon-trash'}, 171 | {name: 'icon-trash_fill'}, 172 | {name: 'icon-undo'}, 173 | {name: 'icon-unlock_fill'}, 174 | {name: 'icon-unlock'}, 175 | {name: 'icon-video'}, 176 | {name: 'icon-video_fill'}, 177 | {name: 'icon-warning_fill'}, 178 | {name: 'icon-warning'}, 179 | {name: 'icon-workbench_fill'}, 180 | {name: 'icon-workbench'}, 181 | {name: 'icon-search'}, 182 | {name: 'icon-searchfill'}, 183 | {name: 'icon-qianniu'}, 184 | {name: 'icon-publishgoods_fill'}, 185 | {name: 'icon-shop_fill'}, 186 | {name: 'icon-transaction_fill'}, 187 | {name: 'icon-packup'}, 188 | {name: 'icon-unfold'}, 189 | {name: 'icon-wangwang'}, 190 | {name: 'icon-financial_fill'}, 191 | {name: 'icon-marketing_fill'}, 192 | {name: 'icon-huidaodingbu1'}, 193 | {name: 'icon-shake'}, 194 | {name: 'icon-decoration_fill'}, 195 | {name: 'icon-icon-test'}, 196 | {name: 'icon-jingcha'} 197 | ] 198 | export default iconfont 199 | -------------------------------------------------------------------------------- /src/assets/iconfont/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/src/assets/iconfont/iconfont.eot -------------------------------------------------------------------------------- /src/assets/iconfont/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/src/assets/iconfont/iconfont.ttf -------------------------------------------------------------------------------- /src/assets/iconfont/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/src/assets/iconfont/iconfont.woff -------------------------------------------------------------------------------- /src/assets/img/bg_login.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/src/assets/img/bg_login.jpg -------------------------------------------------------------------------------- /src/assets/img/fullstack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/src/assets/img/fullstack.jpg -------------------------------------------------------------------------------- /src/assets/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/src/assets/img/logo.png -------------------------------------------------------------------------------- /src/assets/js/app.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/assets/styles/base/base.less: -------------------------------------------------------------------------------- 1 | //全局变量 2 | @import '../variable/variable.less'; // 基础布局类 3 | 4 | .clearfix::after { 5 | content: ''; 6 | clear: both; 7 | display: block; 8 | height: 0; 9 | overflow: hidden; 10 | } 11 | 12 | .pull-right { 13 | float: right; 14 | } 15 | 16 | .pull-left { 17 | float: left; 18 | } 19 | 20 | .hidden { 21 | display: none; 22 | } 23 | 24 | .a-box { 25 | background: #fff; 26 | border-radius: 4px; 27 | font-size: 12px; 28 | position: relative; 29 | overflow: hidden; 30 | transition: all 0.3s; 31 | 32 | .a-box-body { 33 | padding: 24px; 34 | } 35 | } 36 | 37 | .login { 38 | height: 100%; 39 | background-image: url('../../img/fullstack.jpg'); 40 | background-position: center; 41 | background-repeat: no-repeat; 42 | background-attachment: fixed; 43 | 44 | .bg { 45 | margin: 0 auto; 46 | height: 100%; 47 | } 48 | } 49 | 50 | .subText { 51 | color: @text-color; 52 | font-size: 12px; 53 | } 54 | 55 | .icon { 56 | width: 1em; 57 | height: 1em; 58 | vertical-align: -0.15em; 59 | fill: currentColor; 60 | overflow: hidden; 61 | } 62 | 63 | .ivu-table th, .ivu-table td { 64 | &.min-width { 65 | width: 200px !important; 66 | min-width: 200px 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/assets/styles/cover/cover.less: -------------------------------------------------------------------------------- 1 | //覆盖组件的样式 2 | //导航菜单的样式 3 | #app{ 4 | 5 | .ivu-menu-dark{ 6 | background: transparent !important; 7 | } 8 | .ivu-menu-vertical .ivu-menu-item, .ivu-menu-vertical .ivu-menu-submenu-title{ 9 | text-align: left; 10 | } 11 | .ivu-menu-submenu-title > i, .ivu-menu-submenu-title span > i{ 12 | margin-right: 14px; 13 | } 14 | .ivu-menu-vertical .ivu-menu-submenu .ivu-menu-item{ 15 | padding-left: 44px; 16 | } 17 | .ivu-menu-vertical .ivu-menu-item, .ivu-menu-vertical .ivu-menu-submenu-title{ 18 | padding: 14px; 19 | } 20 | .ivu-menu-item > i{ 21 | margin-right: 14px; 22 | } 23 | .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu .ivu-menu-item-active, .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu .ivu-menu-item-active:hover{ 24 | color: #3399ff; 25 | border-right: 2px solid #3399ff; 26 | background: #313540!important; 27 | } 28 | .ivu-menu-dark.ivu-menu-vertical .ivu-menu-opened{ 29 | background: #333; 30 | } 31 | .ivu-menu-dark.ivu-menu-vertical .ivu-menu-opened .ivu-menu-submenu-title{ 32 | background: #5f5f5f; 33 | } 34 | //去掉表格的边框 35 | .ivu-table-wrapper{ 36 | border:none; 37 | } 38 | // .ivu-table th, .ivu-table td{ 39 | // border:none; 40 | // } 41 | .ivu-table:before{ 42 | background: none; 43 | } 44 | .ivu-table:after{ 45 | background: none; 46 | } 47 | //badge 48 | .ivu-badge-count{ 49 | border:none; 50 | box-shadow: none; 51 | min-width:18px; 52 | height:18px; 53 | } 54 | //登录框背景 55 | .login-modal { 56 | .ivu-modal-content{ 57 | background-color: rgba(255,255,255,.95)!important; 58 | } 59 | .ivu-modal-body{ 60 | padding-bottom: 0 61 | } 62 | } 63 | 64 | } 65 | // 表格 66 | .ivu-table th, .ivu-table td{ 67 | min-width: 100px !important; 68 | width:100px 69 | } 70 | .ivu-table-header{ 71 | background: #f5f7f9 72 | } 73 | -------------------------------------------------------------------------------- /src/assets/styles/layout/layout.less: -------------------------------------------------------------------------------- 1 | //全局变量 2 | @import '../variable/variable.less'; 3 | //容器 4 | .app-wrapper { 5 | position: fixed; 6 | top: 0; 7 | left: 0; 8 | right: 0; 9 | bottom: 0; 10 | //路由内容 11 | .main-wrapper { 12 | //transition: all .28s ease-out; 13 | //transition: all .28s linear; 这里注释掉了运动的动画时间,因为iview-table2.4加入了响应的功能后运动会卡顿 14 | padding-left: 190px; 15 | position: absolute; 16 | right: 0; 17 | top: 0; 18 | left: 0; 19 | bottom: 0; 20 | background: #f8fafc; 21 | } 22 | 23 | // 大屏幕 24 | &.hideSidebar { 25 | .side-wrapper { 26 | transform: translate(-150px, 0); 27 | overflow: hidden; 28 | .navbar { 29 | transform: translate(150px, 0); 30 | overflow: hidden; 31 | } 32 | .logo-box{ 33 | transform: translate(150px, 0); 34 | } 35 | &:hover { 36 | transform: translate(0px, 0); 37 | .navbar { 38 | transform: translate(0px, 0); 39 | } 40 | .logo-box{ 41 | transform: translate(0, 0); 42 | } 43 | } 44 | } 45 | .main-wrapper { 46 | padding-left: 40px; 47 | } 48 | } 49 | // 小屏幕 50 | &.hoverSideBar { 51 | .side-wrapper { 52 | transform: translate(-150px, 0); 53 | .navbar { 54 | transform: translate(150px, 0); 55 | } 56 | .logo-box{ 57 | transform: translate(150px, 0); 58 | } 59 | &.hover { 60 | transform: translate(0px, 0); 61 | .navbar { 62 | transform: translate(0px, 0); 63 | } 64 | .logo-box{ 65 | transform: translate(0, 0); 66 | } 67 | } 68 | } 69 | .main-wrapper { 70 | padding-left: 40px; 71 | } 72 | } 73 | } 74 | 75 | //tHeader 76 | .header { 77 | //background: linear-gradient(-270deg, #16aeff 40%, #4df4ae 120%); 78 | //background: linear-gradient(90deg,#15b982,#01d18b); 79 | //background: linear-gradient(90deg,#404040, rgba(64, 64, 64, 0.9)); 80 | background: @header-bg; 81 | height: 50px; 82 | width: 100%; 83 | color: @header-text; 84 | box-shadow: 1px 2px 10px rgba(0, 0, 0, .2); 85 | z-index: 99; 86 | position: relative; 87 | .userBox { 88 | height: 50px; 89 | line-height: 50px; 90 | float: right; 91 | padding: 0 10px; 92 | } 93 | .nav-icon { 94 | width: 50px; 95 | height: 50px; 96 | line-height: 50px; 97 | text-align: center; 98 | font-size: 24px; 99 | float: left; 100 | &:hover { 101 | background: rgba(0, 0, 0, .1); 102 | cursor: pointer; 103 | } 104 | } 105 | .msg-group-box { 106 | float: right; 107 | } 108 | .messageBox { 109 | height: 50px; 110 | float: left; 111 | .iconBox { 112 | font-size: 24px; 113 | line-height: 50px; 114 | width: 50px; 115 | text-align: center; 116 | cursor: pointer; 117 | display: inline-block; 118 | &.active { 119 | background: #eee 120 | } 121 | } 122 | } 123 | .expand-screen { 124 | //position: absolute; 125 | //right:0; 126 | //top:0; 127 | display: inline-block; 128 | float: right; 129 | height: 50px; 130 | width: 50px; 131 | text-align: center; 132 | line-height: 50px; 133 | font-size: 24px; 134 | color: @legend-color; 135 | cursor: pointer; 136 | } 137 | } 138 | 139 | //navBar 140 | .side-wrapper { 141 | transition: all .28s ease-out; 142 | position: absolute; 143 | width: 190px; 144 | background: @side-bar-bg; 145 | top: 0; 146 | left: 0; 147 | bottom: 0; 148 | z-index: 99; 149 | overflow: hidden; 150 | &.light{ 151 | background: #fff; 152 | .theme-switch{ 153 | background: #f8f8f8; 154 | } 155 | } 156 | .navbar { 157 | transition: all .28s ease-out; 158 | overflow-x: hidden; 159 | overflow-y: scroll; 160 | position: absolute; 161 | top: 50px; 162 | left: 0; 163 | bottom: 0; 164 | right: -17px; 165 | } 166 | .logo-box { 167 | transition: all .28s ease-out; 168 | position: absolute; 169 | top:0; 170 | left:0; 171 | width: 100%; 172 | font-size: 30px; 173 | color: #fff; 174 | text-align: center; 175 | } 176 | .theme-switch{ 177 | position: absolute; 178 | bottom:0; 179 | width: 100%; 180 | height: 40px; 181 | background: @side-bar-bg*0.01; 182 | line-height:40px; 183 | text-align: center; 184 | z-index: 901; 185 | } 186 | } 187 | 188 | .main-container { 189 | height: 100%; 190 | background: @container-bg; 191 | } 192 | 193 | .container { 194 | height: 100%; 195 | overflow: scroll; 196 | text-align: left; 197 | } 198 | 199 | #sticker { 200 | height: auto; 201 | padding: 8px 8px 40px 8px; 202 | min-height: 100%; 203 | } 204 | 205 | #stickerCon { 206 | padding-bottom: 40px; 207 | box-sizing: inherit; 208 | } 209 | 210 | #footer { 211 | margin-top: -75px; 212 | height: 40px; 213 | width: 100%; 214 | text-align: center; 215 | line-height: 40px; 216 | color: #ABA498; 217 | font-size: 12px; 218 | background: #fafafa; 219 | border-top: 1px solid #E7E7E7; 220 | position: relative; 221 | z-index: 9; 222 | } 223 | 224 | -------------------------------------------------------------------------------- /src/assets/styles/variable/variable.less: -------------------------------------------------------------------------------- 1 | @import '~iview/src/styles/index.less'; 2 | 3 | //layout 4 | 5 | @side-bar-bg:#404040; 6 | @container-bg:#ececec; 7 | @header-bg:#fff; 8 | @header-text:#666; 9 | 10 | 11 | 12 | // Prefix 13 | @css-prefix : ivu-; 14 | @css-prefix-iconfont : ivu-icon; 15 | 16 | // Color 17 | @primary-color : #3399ff; 18 | @info-color : #2db7f5; 19 | @success-color : #00cc66; 20 | @warning-color : #ff9900; 21 | @error-color : #ff3300; 22 | @link-color : #3399ff; 23 | @link-hover-color : tint(@link-color, 20%); 24 | @link-active-color : shade(@link-color, 5%); 25 | @selected-color : fade(@primary-color, 90%); 26 | @tooltip-color : #fff; 27 | @subsidiary-color : #9ea7b4; 28 | @rate-star-color : #f5a623; 29 | 30 | // Base 31 | @body-background : #fff; 32 | @font-family : "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; 33 | @code-family : Consolas,Menlo,Courier,monospace; 34 | @title-color : #464c5b; 35 | @text-color : #657180; 36 | @font-size-base : 14px; 37 | @font-size-small : 12px; 38 | @line-height-base : 1.5; 39 | @line-height-computed : floor((@font-size-base * @line-height-base)); 40 | @border-radius-base : 6px; 41 | @border-radius-small : 4px; 42 | @cursor-disabled : not-allowed; 43 | 44 | // Border color 45 | @border-color-base : #d7dde4; // outside 46 | @border-color-split : #e3e8ee; // inside 47 | 48 | // Background color 49 | @background-color-base : #f7f7f7; // base 50 | @background-color-select-hover: @input-disabled-bg; 51 | @tooltip-bg : rgba(70, 76, 91, .9); 52 | @head-bg : #f9fafc; 53 | @table-thead-bg : #f5f7f9; 54 | @table-td-stripe-bg : #f5f7f9; 55 | @table-td-hover-bg : #ebf7ff; 56 | @table-td-highlight-bg : #ebf7ff; 57 | @menu-dark-active-bg : #313540; 58 | //@routes.js-dark-active-bg : #404040; 59 | @date-picker-cell-hover-bg : #e1f0fe; 60 | 61 | // Shadow 62 | @shadow-color : rgba(0, 0, 0, .2); 63 | @shadow-base : @shadow-down; 64 | @shadow-card : 0 1px 1px 0 rgba(0,0,0,.1); 65 | @shadow-up : 0 -1px 6px @shadow-color; 66 | @shadow-down : 0 1px 6px @shadow-color; 67 | @shadow-left : -1px 0 6px @shadow-color; 68 | @shadow-right : 1px 0 6px @shadow-color; 69 | 70 | // Button 71 | @btn-font-weight : normal; 72 | @btn-padding-base : 6px 15px; 73 | @btn-padding-large : 6px 15px 7px 15px; 74 | @btn-padding-small : 2px 7px; 75 | @btn-font-size : 12px; 76 | @btn-font-size-large : 14px; 77 | @btn-border-radius : 4px; 78 | @btn-border-radius-small: 3px; 79 | @btn-group-border : shade(@primary-color, 5%); 80 | 81 | @btn-disable-color : #c3cbd6; 82 | @btn-disable-bg : @background-color-base; 83 | @btn-disable-border : @border-color-base; 84 | 85 | @btn-default-color : @text-color; 86 | @btn-default-bg : @background-color-base; 87 | @btn-default-border : @border-color-base; 88 | 89 | @btn-primary-color : #fff; 90 | @btn-primary-bg : @primary-color; 91 | 92 | @btn-ghost-color : @text-color; 93 | @btn-ghost-bg : transparent; 94 | @btn-ghost-border : @border-color-base; 95 | 96 | @btn-circle-size : 32px; 97 | @btn-circle-size-large : 36px; 98 | @btn-circle-size-small : 24px; 99 | 100 | // Layout and Grid 101 | @grid-columns : 24; 102 | @grid-gutter-width : 0; 103 | 104 | // Legend 105 | @legend-color : #999; 106 | 107 | // Input 108 | @input-height-base : 32px; 109 | @input-height-large : 36px; 110 | @input-height-small : 24px; 111 | 112 | @input-padding-horizontal : 7px; 113 | @input-padding-vertical-base : 4px; 114 | @input-padding-vertical-small: 1px; 115 | @input-padding-vertical-large: 6px; 116 | 117 | @input-placeholder-color : @btn-disable-color; 118 | @input-color : @text-color; 119 | @input-border-color : @border-color-base; 120 | @input-bg : #fff; 121 | 122 | @input-hover-border-color : @primary-color; 123 | @input-focus-border-color : @primary-color; 124 | @input-disabled-bg : #f3f3f3; 125 | 126 | // Tag 127 | @tag-font-size : 12px; 128 | 129 | // Media queries breakpoints 130 | // Extra small screen / phone 131 | @screen-xs : 480px; 132 | @screen-xs-min : @screen-xs; 133 | @screen-xs-max : (@screen-xs-min - 1); 134 | 135 | // Small screen / tablet 136 | @screen-sm : 768px; 137 | @screen-sm-min : @screen-sm; 138 | @screen-sm-max : (@screen-sm-min - 1); 139 | 140 | // Medium screen / desktop 141 | @screen-md : 992px; 142 | @screen-md-min : @screen-md; 143 | @screen-md-max : (@screen-md-min - 1); 144 | 145 | // Large screen / wide desktop 146 | @screen-lg : 1200px; 147 | @screen-lg-min : @screen-lg; 148 | @screen-lg-max : (@screen-lg-min - 1); 149 | 150 | // Z-index 151 | @zindex-spin : 8; 152 | @zindex-affix : 10; 153 | @zindex-back-top : 10; 154 | @zindex-select : 900; 155 | @zindex-modal : 1000; 156 | @zindex-message : 1010; 157 | @zindex-notification : 1010; 158 | @zindex-tooltip : 1060; 159 | @zindex-loading-bar : 2000; 160 | 161 | // Animation 162 | @animation-time : .3s; 163 | @transition-time : .2s; 164 | @ease-in-out : ease-in-out; 165 | 166 | // Slider 167 | @slider-color : tint(@primary-color, 20%); 168 | @slider-height : 4px; 169 | @slider-margin : 16px 0; 170 | @slider-button-wrap-size : 18px; 171 | @slider-button-wrap-offset : -4px; 172 | @slider-disabled-color : #ccc; 173 | -------------------------------------------------------------------------------- /src/common/filter/index.js: -------------------------------------------------------------------------------- 1 | import moment from 'moment' 2 | /** 3 | * 隐藏姓名 手机号 身份证 银行卡 等中间字符信息 4 | * @param str 5 | * @returns {*} 6 | */ 7 | export function star (value) { 8 | let str = value.toString() 9 | if (str.length > 0 && str.length < 3) { 10 | return '*' + str.substring(1) 11 | } else if (str.length > 5 && str.length < 12) { 12 | return str.substr(0, 3) + '****' + str.substr(-4) 13 | } else if (str.length > 14) { 14 | return str.substr(0, 4) + '***********' + str.substr(-4) 15 | } else { 16 | return str 17 | } 18 | } 19 | 20 | /* 格式货币 */ 21 | const digitsRE = /(\d{3})(?=\d)/g 22 | 23 | export function currency (value, currency, decimals) { 24 | value = parseFloat(value) 25 | if (!isFinite(value) || (!value && value !== 0)) return '' 26 | currency = currency != null ? currency : '$' 27 | decimals = decimals != null ? decimals : 2 28 | var stringified = Math.abs(value).toFixed(decimals) 29 | var _int = decimals 30 | ? stringified.slice(0, -1 - decimals) 31 | : stringified 32 | var i = _int.length % 3 33 | var head = i > 0 34 | ? (_int.slice(0, i) + (_int.length > 3 ? ',' : '')) 35 | : '' 36 | var _float = decimals 37 | ? stringified.slice(-1 - decimals) 38 | : '' 39 | var sign = value < 0 ? '-' : '' 40 | return sign + currency + head + 41 | _int.slice(i).replace(digitsRE, '$1,') + 42 | _float 43 | } 44 | 45 | export function host (url) { 46 | const host = url.replace(/^https?:\/\//, '').replace(/\/.*$/, '') 47 | const parts = host.split('.').slice(-3) 48 | if (parts[0] === 'www') parts.shift() 49 | return parts.join('.') 50 | } 51 | 52 | /** 53 | * 时间格式化 54 | * @param time 55 | * @returns {*} 56 | */ 57 | export function timeAgo (time) { 58 | let times = moment(time).format('x') / 1000 59 | const between = Date.now() / 1000 - Number(times) 60 | if (between < 60) { 61 | return pluralize('', '刚刚') 62 | } else if (between < 3600) { 63 | return pluralize(~~(between / 60), '分钟前') 64 | } else if (between < 86400) { 65 | return pluralize(~~(between / 3600), '小时前') 66 | } else { 67 | return pluralize(~~(between / 86400), '天前') 68 | } 69 | } 70 | 71 | function pluralize (time, label) { 72 | return time + label 73 | } 74 | 75 | /** 76 | * 格式化时间 77 | * @param time 78 | * @param format 79 | * @returns {*} 80 | */ 81 | export function timeFormat (time, format) { 82 | if (!time) return '' 83 | format = format != null ? format : 'YYYY-MM-DD HH:mm:ss' 84 | return moment(time).format(format) 85 | } 86 | -------------------------------------------------------------------------------- /src/common/utils/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 获取地址栏参数值 3 | * @param name 4 | * @returns {null} 5 | * @constructor 6 | */ 7 | export function GetQueryString (name) { 8 | var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)') 9 | var r = window.location.search.substr(1).match(reg) 10 | var s = window.location.search 11 | var href = window.location.href 12 | var index = href.indexOf('?') 13 | if (s === '') { 14 | r = href.substr(index + 1).match(reg) 15 | } 16 | if (r != null) return unescape(r[2]) 17 | return null 18 | } 19 | -------------------------------------------------------------------------------- /src/components/Hello.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 54 | -------------------------------------------------------------------------------- /src/components/layout/Home.vue: -------------------------------------------------------------------------------- 1 | 129 | 252 | 253 | 254 | 255 | -------------------------------------------------------------------------------- /src/components/layout/aside/aside.vue: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/src/components/layout/aside/aside.vue -------------------------------------------------------------------------------- /src/components/layout/base/Box.vue: -------------------------------------------------------------------------------- 1 | 8 | 11 | 27 | -------------------------------------------------------------------------------- /src/components/layout/base/lock.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 78 | 173 | -------------------------------------------------------------------------------- /src/components/layout/container/Container.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 21 | -------------------------------------------------------------------------------- /src/components/layout/header/THeader.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 69 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/components/layout/navbar/NavBar.vue: -------------------------------------------------------------------------------- 1 | 7 | 20 | -------------------------------------------------------------------------------- /src/components/pages/E404.vue: -------------------------------------------------------------------------------- 1 | 25 | 130 | 131 | -------------------------------------------------------------------------------- /src/components/pages/E500.vue: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/src/components/pages/E500.vue -------------------------------------------------------------------------------- /src/components/pages/Filter.vue: -------------------------------------------------------------------------------- 1 | 35 | 59 | 69 | 70 | -------------------------------------------------------------------------------- /src/components/pages/Icon.vue: -------------------------------------------------------------------------------- 1 | 26 | 68 | 71 | -------------------------------------------------------------------------------- /src/components/pages/Login.vue: -------------------------------------------------------------------------------- 1 | 38 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/components/pages/NotFound.vue: -------------------------------------------------------------------------------- 1 | 6 | 16 | 17 | -------------------------------------------------------------------------------- /src/components/pages/SetMenu2.vue: -------------------------------------------------------------------------------- 1 | 34 | 136 | 155 | -------------------------------------------------------------------------------- /src/components/pages/register.vue: -------------------------------------------------------------------------------- 1 | 63 | 187 | 188 | 210 | -------------------------------------------------------------------------------- /src/components/views/Article.vue: -------------------------------------------------------------------------------- 1 | 23 | 112 | -------------------------------------------------------------------------------- /src/components/views/Chart.vue: -------------------------------------------------------------------------------- 1 | 18 | 140 | 145 | -------------------------------------------------------------------------------- /src/components/views/Index.vue: -------------------------------------------------------------------------------- 1 | 79 | 167 | 177 | -------------------------------------------------------------------------------- /src/components/views/Table.vue: -------------------------------------------------------------------------------- 1 | 53 | 69 | -------------------------------------------------------------------------------- /src/components/views/UserInfo.vue: -------------------------------------------------------------------------------- 1 | 51 | 109 | -------------------------------------------------------------------------------- /src/components/views/UserList.vue: -------------------------------------------------------------------------------- 1 | 6 | 46 | -------------------------------------------------------------------------------- /src/i18n/zh-CN.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/src/i18n/zh-CN.js -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | import VueI18n from 'vue-i18n' 7 | Vue.use(VueI18n) 8 | import iView from 'iview' 9 | Vue.use(iView) 10 | import api from './api/index.js' 11 | Vue.use(api) 12 | import store from './store' 13 | import Cookies from 'js-cookie' 14 | import 'iview/dist/styles/iview.css' // 使用 CSS 15 | import './assets/styles/layout/layout.less' // 引入布局样式 16 | import './assets/styles/cover/cover.less' // 覆盖样式 17 | import './assets/styles/base/base.less' 18 | 19 | import * as filters from './common/filter' 20 | // register global utility filters. 21 | Object.keys(filters).forEach(key => { 22 | Vue.filter(key, filters[key]) 23 | }) 24 | 25 | var winWidth = document.documentElement.clientWidth 26 | if (winWidth <= 600) { 27 | store.commit('CLOSE_SLIDEBAR') 28 | } else { 29 | store.commit('OPEN_SLIDEBAR') 30 | } 31 | window.onresize = function () { 32 | winWidth = document.documentElement.clientWidth 33 | if (winWidth <= 600) { 34 | store.commit('CLOSE_SLIDEBAR') 35 | } else { 36 | store.commit('OPEN_SLIDEBAR') 37 | } 38 | } 39 | 40 | import zhLocale from 'iview/src/locale/lang/zh-CN' 41 | import enLocale from 'iview/src/locale/lang/en-US' 42 | import twLocale from 'iview/src/locale/lang/zh-TW' 43 | 44 | let lang = Cookies.getJSON('lang') 45 | if (lang && lang === 'CN') { 46 | Vue.config.lang = 'zh-CN' 47 | store.commit('SET_LANG', 'CN') 48 | } else if (lang && lang === 'EN') { 49 | store.commit('SET_LANG', 'EN') 50 | Vue.config.lang = 'en-US' 51 | } else { 52 | Vue.config.lang = 'zh-TW' 53 | store.commit('SET_LANG', 'TW') 54 | } 55 | 56 | Vue.locale('zh-CN', zhLocale) 57 | Vue.locale('en-US', enLocale) 58 | Vue.locale('zh-TW', twLocale) 59 | // 开启debug模式 60 | Vue.config.debug = true 61 | // import $ from 'jquery' 62 | Vue.config.productionTip = false 63 | 64 | /* eslint-disable no-new */ 65 | new Vue({ 66 | el: '#app', 67 | router, 68 | store, 69 | template: '', 70 | components: {App} 71 | }) 72 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import store from '@/store' 3 | import Router from 'vue-router' 4 | import iView from 'iview' 5 | import routes from './routes' 6 | import Cookies from 'js-cookie' 7 | Vue.use(iView) 8 | Vue.use(Router) 9 | 10 | const router = new Router({ 11 | scrollBehavior: () => ({y: 0}), 12 | routes 13 | }) 14 | 15 | router.beforeEach((to, from, next) => { 16 | if (document.documentElement.clientWidth <= 600) { 17 | store.commit('CLOSE_SLIDEBAR') 18 | } 19 | let lock = Cookies.get('lock') 20 | if (to.meta.requiresAuth) { 21 | let token = Cookies.get('token') 22 | if (token != null && token !== undefined) { 23 | store.dispatch('getCurrentPageName', to.name) 24 | if (lock === '1') { 25 | console.log('lock', lock) 26 | next({ 27 | path: '/lock' 28 | }) 29 | } else { 30 | next() 31 | } 32 | } else { 33 | next({ 34 | path: '/login', 35 | query: {redirect: '/index'} 36 | }) 37 | } 38 | } else { 39 | store.dispatch('getCurrentPageName', to.name) 40 | next() 41 | } 42 | // } 43 | }) 44 | 45 | export default router 46 | -------------------------------------------------------------------------------- /src/router/menu.js: -------------------------------------------------------------------------------- 1 | const menu = [ 2 | { 3 | path: '/index', 4 | name: 'index', 5 | icon: 'icon-dynamic_fill', 6 | level: 1, 7 | sort: 1, 8 | children: [], 9 | fixed: false 10 | }, 11 | { 12 | path: '/', 13 | name: '列表页', 14 | icon: 'icon-createtask_fill', 15 | level: 0, 16 | fixed: false, 17 | children: [ 18 | { 19 | path: '/chart', 20 | name: 'chart', 21 | icon: 'icon-dynamic_fill', 22 | level: 1, 23 | children: [], 24 | fixed: false 25 | }, 26 | { 27 | path: '/list', 28 | name: 'list', 29 | level: 1, 30 | children: [], 31 | fixed: false 32 | }, 33 | { 34 | path: '/userInfo', 35 | name: 'userInfo', 36 | icon: 'icon-addpeople_fill', 37 | children: [], 38 | fixed: false, 39 | level: 1 40 | }, 41 | { 42 | level: 1, 43 | path: '/userList', 44 | children: [], 45 | fixed: false, 46 | name: 'userList' 47 | }, 48 | { 49 | level: 1, 50 | path: '/table', 51 | name: 'table', 52 | children: [], 53 | fixed: false, 54 | hidden: true 55 | }, 56 | { 57 | level: 1, 58 | path: '/icon', 59 | name: 'icon', 60 | children: [], 61 | fixed: false, 62 | icon: 'icon-emoji_fill' 63 | }, 64 | { 65 | level: 1, 66 | path: '/filter', 67 | name: 'filter', 68 | children: [], 69 | fixed: false, 70 | icon: 'icon-emoji_fill' 71 | } 72 | ] 73 | }, 74 | { 75 | path: '/', 76 | name: '页面', 77 | level: 0, 78 | icon: 'icon-manage_fill', 79 | fixed: false, 80 | children: [ 81 | { 82 | level: 1, 83 | path: '/error404', 84 | children: [], 85 | fixed: false, 86 | name: '404' 87 | }, 88 | { 89 | level: 1, 90 | path: '/notfound', 91 | children: [], 92 | fixed: false, 93 | name: 'Not found' 94 | }, 95 | { 96 | level: 1, 97 | path: '/login', 98 | children: [], 99 | fixed: false, 100 | name: '登录' 101 | }, 102 | { 103 | level: 1, 104 | path: '/register', 105 | children: [], 106 | fixed: false, 107 | name: '注册' 108 | } 109 | ] 110 | }, 111 | { 112 | path: '/', 113 | name: '管理', 114 | level: 0, 115 | icon: 'icon-manage_fill', 116 | fixed: false, 117 | children: [ 118 | { 119 | level: 1, 120 | path: '/setMenu', 121 | children: [], 122 | fixed: false, 123 | name: 'setMenu' 124 | }, 125 | { 126 | level: 1, 127 | path: '/setMenu2', 128 | children: [], 129 | fixed: false, 130 | name: 'setMenu2' 131 | }, 132 | { 133 | level: 1, 134 | path: '/notFound', 135 | children: [], 136 | fixed: false, 137 | name: 'notFound' 138 | } 139 | ] 140 | }, 141 | { 142 | path: '/index', 143 | name: '123', 144 | icon: 'icon-wujiaoxing', 145 | // hidden: true, 146 | level: 0, 147 | sort: 1, 148 | children: [], 149 | fixed: false 150 | }, 151 | { 152 | path: '/index', 153 | name: '123', 154 | icon: 'icon-wujiaoxing', 155 | // hidden: true, 156 | level: 0, 157 | sort: 1, 158 | children: [], 159 | fixed: false 160 | } 161 | 162 | ] 163 | 164 | export default menu 165 | -------------------------------------------------------------------------------- /src/router/routes.js: -------------------------------------------------------------------------------- 1 | import Home from '@/components/layout/Home' 2 | import Index from '@/components/views/Index' 3 | 4 | const Chart = () => import('@/components/views/Chart') 5 | const NotFound = () => import('@/components/pages/NotFound') 6 | const Register = () => import('@/components/pages/Register') 7 | const E404 = () => import('@/components/pages/E404') 8 | const Icon = () => import('@/components/pages/Icon') 9 | const Login = () => import('@/components/pages/Login') 10 | const Table = () => import('@/components/views/Table') 11 | const UserInfo = () => import('@/components/views/UserInfo') 12 | const List = () => import('@/components/views/List') 13 | const Filter = () => import('@/components/pages/Filter') 14 | const Lock = () => import('@/components/layout/base/Lock') 15 | 16 | const routes = [ 17 | { 18 | path: '/', 19 | name: 'home', 20 | component: Home, 21 | redirect: '/index', 22 | children: [ 23 | { 24 | path: '/index', 25 | name: 'index', 26 | component: Index, 27 | icon: 'icon-wujiaoxing', 28 | level: 1, 29 | meta: { 30 | requiresAuth: true // 是否需要登录 31 | } 32 | }, 33 | { 34 | path: '/chart', 35 | name: 'chart', 36 | component: Chart, 37 | meta: { 38 | requiresAuth: true // 是否需要登录 39 | } 40 | }, 41 | { 42 | path: '/list', 43 | name: 'list', 44 | component: List, 45 | meta: { 46 | requiresAuth: true // 是否需要登录 47 | } 48 | }, 49 | { 50 | path: '/userInfo', 51 | name: 'userInfo', 52 | component: UserInfo, 53 | icon: 'icon-addpeople_fill', 54 | meta: { 55 | requiresAuth: true // 是否需要登录 56 | } 57 | }, 58 | { 59 | path: '/table', 60 | name: 'table', 61 | component: Table, 62 | meta: { 63 | requiresAuth: true // 是否需要登录 64 | } 65 | }, 66 | { 67 | path: '/icon', 68 | name: 'icon', 69 | component: Icon, 70 | meta: { 71 | requiresAuth: true // 是否需要登录 72 | } 73 | }, 74 | { 75 | path: '/filter', 76 | name: 'filter', 77 | component: Filter, 78 | meta: { 79 | requiresAuth: true // 是否需要登录 80 | } 81 | }, 82 | { 83 | path: '/notFound', 84 | name: 'notFound', 85 | component: NotFound, 86 | meta: { 87 | requiresAuth: true // 是否需要登录 88 | } 89 | } 90 | ] 91 | }, 92 | { 93 | path: '/login', 94 | name: 'login', 95 | component: Login 96 | }, 97 | { 98 | path: '/register', 99 | name: 'register', 100 | component: Register 101 | }, 102 | { 103 | path: '/error404', 104 | name: 'error404', 105 | component: E404 106 | }, 107 | { 108 | path: '/lock', 109 | name: 'lock', 110 | component: Lock 111 | }, 112 | { 113 | path: '*', 114 | redirect: '/notFound' 115 | } 116 | 117 | ] 118 | 119 | export default routes 120 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import app from './modules/app' 4 | 5 | Vue.use(Vuex) 6 | 7 | const store = new Vuex.Store({ 8 | modules: { 9 | app 10 | } 11 | }) 12 | 13 | export default store 14 | -------------------------------------------------------------------------------- /src/store/modules/app.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | // import router from '@/router' 3 | import iView from 'iview' 4 | import Vue from 'vue' 5 | Vue.use(iView) 6 | 7 | const app = { 8 | state: { 9 | sidebar: { 10 | opened: !+Cookies.get('sidebarStatus'), 11 | minOpen: false // 小屏时菜单状态 12 | }, 13 | router: { 14 | currentPageName: 'index' 15 | }, 16 | langList: [ 17 | { 18 | value: 'CN', 19 | label: '中文简体' 20 | }, 21 | { 22 | value: 'TW', 23 | label: '中文繁体' 24 | }, 25 | { 26 | value: 'EN', 27 | label: 'English' 28 | } 29 | ], 30 | lang: 'CN', 31 | lock: '0', // 默认不锁 32 | lockPage: '/index' // 锁屏前的页面 33 | }, 34 | mutations: { 35 | /** 36 | * 菜单的缩展 37 | */ 38 | TOGGLE_SIDEBAR: state => { 39 | let winWidth = document.documentElement.clientWidth 40 | if (winWidth <= 600) { 41 | state.sidebar.minOpen = !state.sidebar.minOpen 42 | state.sidebar.opened = false 43 | Cookies.set('sidebarStatus', 0) 44 | return 45 | } else { 46 | if (state.sidebar.opened) { 47 | Cookies.set('sidebarStatus', 1) 48 | } else { 49 | Cookies.set('sidebarStatus', 0) 50 | } 51 | state.sidebar.opened = !state.sidebar.opened 52 | } 53 | }, 54 | CLOSE_SLIDEBAR: state => { 55 | Cookies.set('sidebarStatus', 0) 56 | state.sidebar.opened = false 57 | state.sidebar.minOpen = false 58 | }, 59 | OPEN_SLIDEBAR: state => { 60 | Cookies.set('sidebarStatus', 1) 61 | state.sidebar.opened = true 62 | }, 63 | /** 64 | * 面包屑 65 | */ 66 | GET_CURRENT_PAGE_NAME: (state, payload) => { 67 | state.router.currentPageName = payload 68 | }, 69 | /** 70 | * 设置语言 71 | */ 72 | SET_LANG: (state, payload) => { 73 | state.lang = payload 74 | Cookies.set('lang', payload) 75 | }, 76 | SET_LOCK: (state, payload) => { 77 | state.lock = payload 78 | Cookies.set('lock', payload) 79 | }, 80 | SET_LOCK_PAGE: (state, payload) => { 81 | state.lockPage = payload 82 | Cookies.set('lockPage', payload) 83 | } 84 | }, 85 | actions: { 86 | ToggleSideBar: ({commit}) => { 87 | commit('TOGGLE_SIDEBAR') 88 | }, 89 | getCurrentPageName: ({commit}, payload) => { 90 | commit('GET_CURRENT_PAGE_NAME', payload) 91 | } 92 | } 93 | } 94 | 95 | export default app 96 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/static/.gitkeep -------------------------------------------------------------------------------- /static/img/fullstack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/static/img/fullstack.jpg -------------------------------------------------------------------------------- /static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artiely/vue-admin-iview/2e27feacf49bb5b54545e1907806939309137e5c/static/img/logo.png -------------------------------------------------------------------------------- /test/e2e/custom-assertions/elementCount.js: -------------------------------------------------------------------------------- 1 | // A custom Nightwatch assertion. 2 | // the name of the method is the filename. 3 | // can be used in tests like this: 4 | // 5 | // browser.assert.elementCount(selector, count) 6 | // 7 | // for how to write custom assertions see 8 | // http://nightwatchjs.org/guide#writing-custom-assertions 9 | exports.assertion = function (selector, count) { 10 | this.message = 'Testing if element <' + selector + '> has count: ' + count 11 | this.expected = count 12 | this.pass = function (val) { 13 | return val === this.expected 14 | } 15 | this.value = function (res) { 16 | return res.value 17 | } 18 | this.command = function (cb) { 19 | var self = this 20 | return this.api.execute(function (selector) { 21 | return document.querySelectorAll(selector).length 22 | }, [selector], function (res) { 23 | cb.call(self, res) 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/e2e/nightwatch.conf.js: -------------------------------------------------------------------------------- 1 | require('babel-register') 2 | var config = require('../../config') 3 | 4 | // http://nightwatchjs.org/gettingstarted#settings-file 5 | module.exports = { 6 | src_folders: ['test/e2e/specs'], 7 | output_folder: 'test/e2e/reports', 8 | custom_assertions_path: ['test/e2e/custom-assertions'], 9 | 10 | selenium: { 11 | start_process: true, 12 | server_path: require('selenium-server').path, 13 | host: '127.0.0.1', 14 | port: 4444, 15 | cli_args: { 16 | 'webdriver.chrome.driver': require('chromedriver').path 17 | } 18 | }, 19 | 20 | test_settings: { 21 | default: { 22 | selenium_port: 4444, 23 | selenium_host: 'localhost', 24 | silent: true, 25 | globals: { 26 | devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port) 27 | } 28 | }, 29 | 30 | chrome: { 31 | desiredCapabilities: { 32 | browserName: 'chrome', 33 | javascriptEnabled: true, 34 | acceptSslCerts: true 35 | } 36 | }, 37 | 38 | firefox: { 39 | desiredCapabilities: { 40 | browserName: 'firefox', 41 | javascriptEnabled: true, 42 | acceptSslCerts: true 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test/e2e/runner.js: -------------------------------------------------------------------------------- 1 | // 1. start the dev server using production config 2 | process.env.NODE_ENV = 'testing' 3 | var server = require('../../build/dev-server.js') 4 | 5 | server.ready.then(() => { 6 | // 2. run the nightwatch test suite against it 7 | // to run in additional browsers: 8 | // 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings" 9 | // 2. add it to the --env flag below 10 | // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox` 11 | // For more information on Nightwatch's config file, see 12 | // http://nightwatchjs.org/guide#settings-file 13 | var opts = process.argv.slice(2) 14 | if (opts.indexOf('--config') === -1) { 15 | opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js']) 16 | } 17 | if (opts.indexOf('--env') === -1) { 18 | opts = opts.concat(['--env', 'chrome']) 19 | } 20 | 21 | var spawn = require('cross-spawn') 22 | var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' }) 23 | 24 | runner.on('exit', function (code) { 25 | server.close() 26 | process.exit(code) 27 | }) 28 | 29 | runner.on('error', function (err) { 30 | server.close() 31 | throw err 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /test/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // For authoring Nightwatch tests, see 2 | // http://nightwatchjs.org/guide#usage 3 | 4 | module.exports = { 5 | 'default e2e tests': function (browser) { 6 | // automatically uses dev Server port from /config.index.js 7 | // default: http://localhost:8080 8 | // see nightwatch.conf.js 9 | const devServer = browser.globals.devServerURL 10 | 11 | browser 12 | .url(devServer) 13 | .waitForElementVisible('#app', 5000) 14 | .assert.elementPresent('.hello') 15 | .assert.containsText('h1', 'Welcome to Your Vue.js App') 16 | .assert.elementCount('img', 1) 17 | .end() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/unit/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "globals": { 6 | "expect": true, 7 | "sinon": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/unit/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | Vue.config.productionTip = false 4 | 5 | // require all test files (files that ends with .spec.js) 6 | const testsContext = require.context('./specs', true, /\.spec$/) 7 | testsContext.keys().forEach(testsContext) 8 | 9 | // require all src files except main.js for coverage. 10 | // you can also change this to match only the subset of files that 11 | // you want coverage for. 12 | const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/) 13 | srcContext.keys().forEach(srcContext) 14 | -------------------------------------------------------------------------------- /test/unit/karma.conf.js: -------------------------------------------------------------------------------- 1 | // This is a karma config file. For more details see 2 | // http://karma-runner.github.io/0.13/config/configuration-file.html 3 | // we are also using it with karma-webpack 4 | // https://github.com/webpack/karma-webpack 5 | 6 | var webpackConfig = require('../../build/webpack.test.conf') 7 | 8 | module.exports = function (config) { 9 | config.set({ 10 | // to run in additional browsers: 11 | // 1. install corresponding karma launcher 12 | // http://karma-runner.github.io/0.13/config/browsers.html 13 | // 2. add it to the `browsers` array below. 14 | browsers: ['PhantomJS'], 15 | frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'], 16 | reporters: ['spec', 'coverage'], 17 | files: ['./index.js'], 18 | preprocessors: { 19 | './index.js': ['webpack', 'sourcemap'] 20 | }, 21 | webpack: webpackConfig, 22 | webpackMiddleware: { 23 | noInfo: true 24 | }, 25 | coverageReporter: { 26 | dir: './coverage', 27 | reporters: [ 28 | { type: 'lcov', subdir: '.' }, 29 | { type: 'text-summary' } 30 | ] 31 | } 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /test/unit/specs/Hello.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Hello from '@/components/Hello' 3 | 4 | describe('Full.vue', () => { 5 | it('should render correct contents', () => { 6 | const Constructor = Vue.extend(Hello) 7 | const vm = new Constructor().$mount() 8 | expect(vm.$el.querySelector('.hello h1').textContent) 9 | .to.equal('Welcome to Your Vue.js App') 10 | }) 11 | }) 12 | --------------------------------------------------------------------------------