diff --git a/.electron-vue/webpack.renderer.config.js b/.electron-vue/webpack.renderer.config.js index f52186e..814696c 100644 --- a/.electron-vue/webpack.renderer.config.js +++ b/.electron-vue/webpack.renderer.config.js @@ -5,6 +5,7 @@ process.env.BABEL_ENV = 'renderer' const path = require('path') const { dependencies } = require('../package.json') const webpack = require('webpack') +const config = require('../config/index.js') const BabiliWebpackPlugin = require('babili-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin') @@ -74,8 +75,17 @@ let rendererConfig = { } } }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [path.join(__dirname, '../src/renderer/icons')], + options: { + symbolId: 'icon-[name]' + } + }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + exclude: [path.join(__dirname, '../src/renderer/icons')], use: { loader: 'url-loader', query: { @@ -110,6 +120,9 @@ let rendererConfig = { }, plugins: [ new ExtractTextPlugin('styles.css'), + new webpack.DefinePlugin({ + 'process.env': config.dev.env + }), new HtmlWebpackPlugin({ filename: 'index.html', template: path.resolve(__dirname, '../src/index.ejs'), diff --git a/.gitignore b/.gitignore index 6d09910..e875f8e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ dist/electron/* dist/web/* build/* !build/icons +package-lock.json node_modules/ npm-debug.log npm-debug.log.* diff --git a/README.md b/README.md index 47f7a31..84c828a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ -# my-project +# electron-vue-admin > An electron-vue project -#### Build Setup +This is a vue electron admin project base on [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template) , and was generated from [electron-vue](https://github.com/SimulatedGREG/electron-vue) using [vue-cli](https://github.com/vuejs/vue-cli). Documentation about this project can be found [here](https://simulatedgreg.gitbooks.io/electron-vue/content/index.html). + +## Build Setup ``` bash # install dependencies @@ -11,15 +13,20 @@ npm install # serve with hot reload at localhost:9080 npm run dev -# build electron application for production +# build electron app for production npm run build - -# lint all JS/Vue component files in `src/` +# lint all JS/Vue component files in `app/src` npm run lint +# run webpack in production +npm run pack ``` - --- -This project was generated with [electron-vue](https://github.com/SimulatedGREG/electron-vue)@[7c4e3e9](https://github.com/SimulatedGREG/electron-vue/tree/7c4e3e90a772bd4c27d2dd4790f61f09bae0fcef) using [vue-cli](https://github.com/vuejs/vue-cli). Documentation about the original structure can be found [here](https://simulatedgreg.gitbooks.io/electron-vue/content/index.html). + +## Demo + +![](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/electron-login.png) + +![](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/electron-admin.gif) diff --git a/config/dev.env.js b/config/dev.env.js new file mode 100644 index 0000000..bb359c4 --- /dev/null +++ b/config/dev.env.js @@ -0,0 +1,4 @@ +module.exports = { + NODE_ENV: '"development"', + BASE_API: '"https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin"' +} diff --git a/config/index.js b/config/index.js new file mode 100644 index 0000000..c10cd85 --- /dev/null +++ b/config/index.js @@ -0,0 +1,8 @@ +module.exports = { + build: { + env: require('./prod.env') + }, + dev: { + env: require('./dev.env') + } +} diff --git a/config/prod.env.js b/config/prod.env.js new file mode 100644 index 0000000..29c242d --- /dev/null +++ b/config/prod.env.js @@ -0,0 +1,4 @@ +module.exports = { + NODE_ENV: '"production"', + BASE_API: '"https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin"' +} diff --git a/package-lock.json b/package-lock.json index 5dd17ca..4cee258 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "my-project", - "version": "0.0.0", + "name": "electron-vue-admin", + "version": "3.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -22,6 +22,12 @@ "integrity": "sha512-FM7tvbjbn2BUzM/Qsdk9LUGq3zeh7li8NcHoS398dBzqLzfmSqSP1+yKbMRTCcZzLcu2JAR5lq3IKIEYkto7iQ==", "dev": true }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, "accepts": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", @@ -212,6 +218,16 @@ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, + "are-we-there-yet": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "dev": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.6" + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -363,6 +379,20 @@ "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", "dev": true }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "dev": true + }, + "async-validator": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-1.8.2.tgz", + "integrity": "sha1-t3WXIm6WJC+NUxwNRq4pX2JCK6Q=", + "requires": { + "babel-runtime": "6.26.0" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -414,9 +444,9 @@ "dev": true }, "axios": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.16.2.tgz", - "integrity": "sha1-uk+S8XFn37q0CYN4VFS5rBScPG0=", + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.17.1.tgz", + "integrity": "sha1-LY4+XQvb1zJ/kbyBT1xXZg+Bgk0=", "requires": { "follow-redirects": "1.4.1", "is-buffer": "1.1.6" @@ -706,6 +736,11 @@ "integrity": "sha1-XxuDKznkrPlU6RN/AlE5XHEZazU=", "dev": true }, + "babel-helper-vue-jsx-merge-props": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz", + "integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg==" + }, "babel-helpers": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", @@ -1486,7 +1521,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, "requires": { "core-js": "2.5.5", "regenerator-runtime": "0.11.1" @@ -1617,6 +1651,15 @@ "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", "dev": true }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", @@ -2460,6 +2503,38 @@ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true }, + "clone-deep": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.3.0.tgz", + "integrity": "sha1-NIxhrpzb4O3+BT2R/0zFIdeQ7eg=", + "dev": true, + "requires": { + "for-own": "1.0.0", + "is-plain-object": "2.0.4", + "kind-of": "3.2.2", + "shallow-clone": "0.1.2" + }, + "dependencies": { + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -2670,6 +2745,12 @@ "date-now": "0.1.4" } }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, "consolidate": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.14.5.tgz", @@ -2764,8 +2845,7 @@ "core-js": { "version": "2.5.5", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz", - "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=", - "dev": true + "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=" }, "core-util-is": { "version": "1.0.2", @@ -3135,6 +3215,11 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "deepmerge": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", + "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==" + }, "define-properties": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", @@ -3211,6 +3296,12 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -3402,6 +3493,12 @@ "domelementtype": "1.3.0" } }, + "domready": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/domready/-/domready-1.0.8.tgz", + "integrity": "sha1-kfJS5Ze2Wvd+dFriTdAYXV4m1Yw=", + "dev": true + }, "domutils": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", @@ -3781,6 +3878,18 @@ "integrity": "sha1-RYrBscXHYM6IEaFtK/vZfsMLr7g=", "dev": true }, + "element-ui": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/element-ui/-/element-ui-2.3.4.tgz", + "integrity": "sha512-wJij9v2kNn23a1PjsNMviYAQF1yRrHbO9q3yyyJls49tIauJp+DfoESRVXR+l7qhnUKaocvKmHf5fmBoEzZMoQ==", + "requires": { + "async-validator": "1.8.2", + "babel-helper-vue-jsx-merge-props": "2.0.3", + "deepmerge": "1.5.2", + "normalize-wheel": "1.0.1", + "throttle-debounce": "1.0.1" + } + }, "elliptic": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", @@ -5484,6 +5593,18 @@ } } }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -5496,6 +5617,46 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "gaze": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", + "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=", + "dev": true, + "requires": { + "globule": "1.2.0" + } + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "1.0.2" + } + }, "get-caller-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", @@ -5629,6 +5790,17 @@ "slash": "1.0.0" } }, + "globule": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz", + "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=", + "dev": true, + "requires": { + "glob": "7.1.2", + "lodash": "4.17.10", + "minimatch": "3.0.4" + } + }, "got": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", @@ -5706,6 +5878,12 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -6168,6 +6346,12 @@ "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", "dev": true }, + "image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "dev": true + }, "import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", @@ -6190,6 +6374,12 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "in-publish": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", + "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", + "dev": true + }, "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", @@ -6494,6 +6684,25 @@ "lower-case": "1.1.4" } }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true + }, + "is-my-json-valid": { + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz", + "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", + "dev": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "is-my-ip-valid": "1.0.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, "is-npm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", @@ -6600,6 +6809,12 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, "is-redirect": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", @@ -6797,6 +7012,12 @@ "graceful-fs": "4.1.11" } }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -7064,6 +7285,12 @@ "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", "dev": true }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true + }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -7163,6 +7390,12 @@ } } }, + "lodash.mergewith": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", + "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "dev": true + }, "lodash.restparam": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", @@ -7175,6 +7408,12 @@ "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", "dev": true }, + "lodash.tail": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", + "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=", + "dev": true + }, "lodash.toplainobject": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash.toplainobject/-/lodash.toplainobject-3.0.0.tgz", @@ -7405,6 +7644,15 @@ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", "dev": true }, + "merge-options": { + "version": "0.0.64", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-0.0.64.tgz", + "integrity": "sha1-y+BPWUppheryf3+PCyo6z2+dVi0=", + "dev": true, + "requires": { + "is-plain-obj": "1.1.0" + } + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -7526,6 +7774,12 @@ "through2": "2.0.3" } }, + "mitt": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.2.tgz", + "integrity": "sha1-OA5hSA1qYVtmDwertg1R4KTkvtY=", + "dev": true + }, "mixin-deep": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", @@ -7547,6 +7801,24 @@ } } }, + "mixin-object": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", + "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", + "dev": true, + "requires": { + "for-in": "0.1.8", + "is-extendable": "0.1.1" + }, + "dependencies": { + "for-in": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", + "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=", + "dev": true + } + } + }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", @@ -7649,8 +7921,7 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true, - "optional": true + "dev": true }, "nanomatch": { "version": "1.2.9", @@ -7732,6 +8003,35 @@ "integrity": "sha1-naYR6giYL0uUIGs760zJZl8gwwA=", "dev": true }, + "node-gyp": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz", + "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=", + "dev": true, + "requires": { + "fstream": "1.0.11", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "npmlog": "4.1.2", + "osenv": "0.1.5", + "request": "2.85.0", + "rimraf": "2.6.2", + "semver": "5.3.0", + "tar": "2.2.1", + "which": "1.3.0" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + } + } + }, "node-libs-browser": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", @@ -7769,6 +8069,210 @@ "integrity": "sha1-x5fvUQle1YWZArFX9jhPY2HgWug=", "dev": true }, + "node-sass": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.0.tgz", + "integrity": "sha512-QFHfrZl6lqRU3csypwviz2XLgGNOoWQbo2GOvtsfQqOfL4cy1BtWnhx/XUeAO9LT3ahBzSRXcEO6DdvAH9DzSg==", + "dev": true, + "requires": { + "async-foreach": "0.1.3", + "chalk": "1.1.3", + "cross-spawn": "3.0.1", + "gaze": "1.1.2", + "get-stdin": "4.0.1", + "glob": "7.1.2", + "in-publish": "2.0.0", + "lodash.assign": "4.2.0", + "lodash.clonedeep": "4.5.0", + "lodash.mergewith": "4.6.1", + "meow": "3.7.0", + "mkdirp": "0.5.1", + "nan": "2.10.0", + "node-gyp": "3.6.2", + "npmlog": "4.1.2", + "request": "2.79.0", + "sass-graph": "2.2.4", + "stdout-stream": "1.4.0", + "true-case-path": "1.0.2" + }, + "dependencies": { + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "dev": true, + "requires": { + "lru-cache": "4.1.2", + "which": "1.3.0" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.18" + } + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "commander": "2.15.1", + "is-my-json-valid": "2.17.2", + "pinkie-promise": "2.0.1" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.14.1" + } + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "qs": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", + "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", + "dev": true + }, + "request": { + "version": "2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.7.0", + "caseless": "0.11.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "oauth-sign": "0.8.2", + "qs": "6.3.2", + "stringstream": "0.0.5", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.4.3", + "uuid": "3.2.1" + } + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1.1.1" + } + }, "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", @@ -7808,6 +8312,16 @@ "sort-keys": "1.1.2" } }, + "normalize-wheel": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz", + "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU=" + }, + "normalize.css": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-7.0.0.tgz", + "integrity": "sha1-q/sd2CRwZ04DIrU86xqvQSk45L8=" + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -7817,6 +8331,23 @@ "path-key": "2.0.1" } }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E=" + }, "nth-check": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", @@ -8102,6 +8633,16 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -8886,6 +9427,15 @@ "postcss-value-parser": "3.3.0" } }, + "postcss-prefix-selector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/postcss-prefix-selector/-/postcss-prefix-selector-1.6.0.tgz", + "integrity": "sha1-tJWUnWOcYxRxRWSDJoUyFvPBCQA=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, "postcss-reduce-idents": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", @@ -8967,6 +9517,64 @@ "uniqs": "2.0.0" } }, + "posthtml": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.9.2.tgz", + "integrity": "sha1-9MBtufZ7Yf0XxOJW5+PZUVv3Jv0=", + "dev": true, + "requires": { + "posthtml-parser": "0.2.1", + "posthtml-render": "1.1.3" + } + }, + "posthtml-parser": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.2.1.tgz", + "integrity": "sha1-NdUw3jhnQMK6JP8usvrznM3ycd0=", + "dev": true, + "requires": { + "htmlparser2": "3.9.2", + "isobject": "2.1.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "posthtml-rename-id": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/posthtml-rename-id/-/posthtml-rename-id-1.0.6.tgz", + "integrity": "sha512-tz9SHDiDM/viYbBScFRK9Cq/QpkDK3y2U/pUBzszoSrewJRj2PUkcyPBt5rgi8mRLQ+oL/21B6wpNg+6iVYRew==", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "posthtml-render": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.1.3.tgz", + "integrity": "sha512-aYvEMUxvKAv7D+ob2qlosyEL5qzsxCvauN/gjkRxr7fsW3+R2CJ1L3YHxx9kAjBJehmSwbNkSKzREdVfz1NWew==", + "dev": true + }, + "posthtml-svg-mode": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/posthtml-svg-mode/-/posthtml-svg-mode-1.0.2.tgz", + "integrity": "sha512-yH4w0CULTg6v3YW5hVUY2z14R+11XWvtxMRqk30FDgxg0JWv+BhS9FLtKNIu858/1mrO1NcIC4heb6IezLAfHw==", + "dev": true, + "requires": { + "merge-options": "0.0.64", + "posthtml": "0.9.2", + "posthtml-parser": "0.2.1", + "posthtml-render": "1.1.3" + } + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -9506,8 +10114,7 @@ "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, "regenerator-transform": { "version": "0.10.1", @@ -9915,6 +10522,101 @@ "truncate-utf8-bytes": "1.0.2" } }, + "sass-graph": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", + "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", + "dev": true, + "requires": { + "glob": "7.1.2", + "lodash": "4.17.10", + "scss-tokenizer": "0.2.3", + "yargs": "7.1.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "y18n": "3.2.1", + "yargs-parser": "5.0.0" + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "requires": { + "camelcase": "3.0.0" + } + } + } + }, + "sass-loader": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.6.tgz", + "integrity": "sha512-c3/Zc+iW+qqDip6kXPYLEgsAu2lf4xz0EZDplB7EmSUMda12U1sGJPetH55B/j9eu0bTtKzKlNPWWyYC7wFNyQ==", + "dev": true, + "requires": { + "async": "2.6.0", + "clone-deep": "0.3.0", + "loader-utils": "1.1.0", + "lodash.tail": "4.1.1", + "pify": "3.0.0" + } + }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -9930,6 +10632,27 @@ "ajv": "5.5.2" } }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "dev": true, + "requires": { + "js-base64": "2.4.3", + "source-map": "0.4.4" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -10109,6 +10832,35 @@ "safe-buffer": "5.1.2" } }, + "shallow-clone": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-0.1.2.tgz", + "integrity": "sha1-WQnodLp3EG1zrEFM/sH/yofZcGA=", + "dev": true, + "requires": { + "is-extendable": "0.1.1", + "kind-of": "2.0.1", + "lazy-cache": "0.2.7", + "mixin-object": "2.0.1" + }, + "dependencies": { + "kind-of": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz", + "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "lazy-cache": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz", + "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=", + "dev": true + } + } + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -10625,6 +11377,15 @@ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", "dev": true }, + "stdout-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", + "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=", + "dev": true, + "requires": { + "readable-stream": "2.3.6" + } + }, "stream-browserify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", @@ -10772,6 +11533,114 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, + "svg-baker": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/svg-baker/-/svg-baker-1.2.17.tgz", + "integrity": "sha512-Tjx9jgFoNpWQPLFgxEXKvCOjbo+8xoAxR9beUcdeR4k+5RFISfteWu6Y6OR7FPEXVBBrQzoZQM5/gSYTVfKxiA==", + "dev": true, + "requires": { + "bluebird": "3.5.1", + "clone": "2.1.1", + "he": "1.1.1", + "image-size": "0.5.5", + "loader-utils": "1.1.0", + "merge-options": "0.0.64", + "micromatch": "3.1.0", + "postcss": "5.2.18", + "postcss-prefix-selector": "1.6.0", + "posthtml-rename-id": "1.0.6", + "posthtml-svg-mode": "1.0.2", + "query-string": "4.3.4", + "traverse": "0.6.6" + }, + "dependencies": { + "clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "dev": true + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + }, + "micromatch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.0.tgz", + "integrity": "sha512-3StSelAE+hnRvMs8IdVW7Uhk8CVed5tp+kLLGlBP6WiRAXS21GPGu/Nat4WNPXj2Eoc24B02SaeoyozPMfj0/g==", + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.2", + "define-property": "1.0.0", + "extend-shallow": "2.0.1", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "5.1.0", + "nanomatch": "1.2.9", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + } + } + } + }, + "svg-baker-runtime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/svg-baker-runtime/-/svg-baker-runtime-1.3.5.tgz", + "integrity": "sha512-BKxJT/Zz9M+K043zXbZf7CA3c10NKWByxobAukO30VLv71OvmpagjG32Z0UIay6ctMaOUmywOKHuceiSDqwUOA==", + "dev": true, + "requires": { + "deepmerge": "1.3.2", + "mitt": "1.1.2", + "svg-baker": "1.2.17" + }, + "dependencies": { + "deepmerge": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.3.2.tgz", + "integrity": "sha1-FmNpFinU2/42T6EqKk8KqGqjoFA=", + "dev": true + } + } + }, + "svg-sprite-loader": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/svg-sprite-loader/-/svg-sprite-loader-3.5.2.tgz", + "integrity": "sha512-YVYlOjPGUF5bdMXHXUHw0uGN61sbV1SOhlTLkhzQFDB1S65sjh9AJ4QjRkQtcKXD6aOxeaiMNGVRdZYhGiqmsw==", + "dev": true, + "requires": { + "bluebird": "3.5.1", + "deepmerge": "1.3.2", + "domready": "1.0.8", + "escape-string-regexp": "1.0.5", + "loader-utils": "1.1.0", + "svg-baker": "1.2.17", + "svg-baker-runtime": "1.3.5", + "url-slug": "2.0.0" + }, + "dependencies": { + "deepmerge": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.3.2.tgz", + "integrity": "sha1-FmNpFinU2/42T6EqKk8KqGqjoFA=", + "dev": true + } + } + }, "svgo": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", @@ -10850,6 +11719,17 @@ "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", "dev": true }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, "temp-file": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.1.2.tgz", @@ -10877,6 +11757,11 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "throttle-debounce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-1.0.1.tgz", + "integrity": "sha1-2tD+Ew+drzcZ/eoz3Dao5rp/MLU=" + }, "throttleit": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", @@ -11026,6 +11911,12 @@ "punycode": "1.4.1" } }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "dev": true + }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", @@ -11038,6 +11929,30 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "true-case-path": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz", + "integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=", + "dev": true, + "requires": { + "glob": "6.0.4" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, "truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", @@ -11183,6 +12098,12 @@ } } }, + "unidecode": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/unidecode/-/unidecode-0.1.8.tgz", + "integrity": "sha1-77swFTi8RSRqmsjFWdcvAVMFBT4=", + "dev": true + }, "union-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", @@ -11449,6 +12370,15 @@ "prepend-http": "1.0.4" } }, + "url-slug": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/url-slug/-/url-slug-2.0.0.tgz", + "integrity": "sha1-p4nVrtSZXA2VrzM3etHVxo1NcCc=", + "dev": true, + "requires": { + "unidecode": "0.1.8" + } + }, "use": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", @@ -11548,9 +12478,9 @@ } }, "vue": { - "version": "2.5.16", - "resolved": "https://registry.npmjs.org/vue/-/vue-2.5.16.tgz", - "integrity": "sha512-/ffmsiVuPC8PsWcFkZngdpas19ABm5mh2wA7iDqcltyCTwlgZjHGeJYOXkBMo422iPwIcviOtrTCUpSfXmToLQ==" + "version": "2.5.10", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.5.10.tgz", + "integrity": "sha512-svnce7F8Oe0cWscno2ABnq5ir3tQoQYXe2CkR7SiNGKmNyBDXhJj9Y7mXUodZytsssIvbooEH9DRrp58cOuWNA==" }, "vue-electron": { "version": "1.0.6", @@ -11749,9 +12679,9 @@ } }, "vue-router": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-2.8.1.tgz", - "integrity": "sha512-MC4jacHBhTPKtmcfzvaj2N7g6jgJ/Z/eIjZdt+yUaUOM1iKC0OUIlO/xCtz6OZFFTNUJs/1YNro2GN/lE+nOXA==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.0.1.tgz", + "integrity": "sha512-vLLoY452L+JBpALMP5UHum9+7nzR9PeIBCghU9ZtJ1eWm6ieUI8Zb/DI3MYxH32bxkjzYV1LRjNv4qr8d+uX/w==" }, "vue-style-loader": { "version": "3.1.2", @@ -11764,9 +12694,9 @@ } }, "vue-template-compiler": { - "version": "2.5.16", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.5.16.tgz", - "integrity": "sha512-ZbuhCcF/hTYmldoUOVcu2fcbeSAZnfzwDskGduOrnjBiIWHgELAd+R8nAtX80aZkceWDKGQ6N9/0/EUpt+l22A==", + "version": "2.5.10", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.5.10.tgz", + "integrity": "sha512-vVpOik9YOCmtQCGhOmse+bepA6bbNLBkWYG8GJfWpZdOFfyq11zL7WiU6PnUl1P09XX0ZTyj44bT5IZn3La0ww==", "dev": true, "requires": { "de-indent": "1.0.2", @@ -11780,9 +12710,9 @@ "dev": true }, "vuex": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/vuex/-/vuex-2.5.0.tgz", - "integrity": "sha512-5oJPOJySBgSgSzoeO+gZB/BbN/XsapgIF6tz34UwJqnGZMQurzIO3B4KIBf862gfc9ya+oduY5sSkq+5/oOilQ==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.0.1.tgz", + "integrity": "sha512-wLoqz0B7DSZtgbWL1ShIBBCjv22GV5U+vcBFox658g6V0s4wZV9P4YjCNyoHSyIBpj1f29JBoNQIqD82cR4O3w==" }, "watchpack": { "version": "1.6.0", @@ -12224,6 +13154,15 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "wide-align": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "dev": true, + "requires": { + "string-width": "1.0.2" + } + }, "widest-line": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.0.tgz", diff --git a/package.json b/package.json index 8d6b888..1bc9445 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "my-project", + "name": "electron-vue-admin", "version": "3.0.0", "author": "Pan ", "description": "An electron-vue project", @@ -19,7 +19,7 @@ "postinstall": "npm run lint:fix" }, "build": { - "productName": "my-project", + "productName": "electron-vue-admin", "appId": "org.simulatedgreg.electron-vue", "directories": { "output": "build" @@ -53,11 +53,14 @@ } }, "dependencies": { - "vue": "^2.3.3", - "axios": "^0.16.1", + "axios": "0.17.1", + "element-ui": "2.3.4", + "normalize.css": "7.0.0", + "nprogress": "0.2.0", + "vue": "2.5.10", "vue-electron": "^1.0.6", - "vue-router": "^2.5.3", - "vuex": "^2.3.1" + "vue-router": "3.0.1", + "vuex": "3.0.1" }, "devDependencies": { "babel-core": "^6.25.0", @@ -88,12 +91,15 @@ "html-webpack-plugin": "^2.30.1", "multispinner": "^0.2.1", "node-loader": "^0.6.0", + "node-sass": "^4.7.2", "style-loader": "^0.18.2", + "sass-loader": "6.0.6", + "svg-sprite-loader": "3.5.2", "url-loader": "^0.5.9", "vue-html-loader": "^1.2.4", "vue-loader": "^13.0.5", "vue-style-loader": "^3.0.1", - "vue-template-compiler": "^2.4.2", + "vue-template-compiler": "2.5.10", "webpack": "^3.5.2", "webpack-dev-server": "^2.7.1", "webpack-hot-middleware": "^2.18.2" diff --git a/src/index.ejs b/src/index.ejs index 241d101..5d04cd6 100644 --- a/src/index.ejs +++ b/src/index.ejs @@ -2,7 +2,7 @@ - my-project + electron-vue-admin <% if (htmlWebpackPlugin.options.nodeModules) { %> - - diff --git a/src/renderer/api/login.js b/src/renderer/api/login.js new file mode 100644 index 0000000..3758dec --- /dev/null +++ b/src/renderer/api/login.js @@ -0,0 +1,27 @@ +import request from '@/utils/request' + +export function login(username, password) { + return request({ + url: '/user/login', + method: 'post', + data: { + username, + password + } + }) +} + +export function getInfo(token) { + return request({ + url: '/user/info', + method: 'get', + params: { token } + }) +} + +export function logout() { + return request({ + url: '/user/logout', + method: 'post' + }) +} diff --git a/src/renderer/api/table.js b/src/renderer/api/table.js new file mode 100644 index 0000000..e29c294 --- /dev/null +++ b/src/renderer/api/table.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +export function getList(params) { + return request({ + url: '/table/list', + method: 'get', + params + }) +} diff --git a/src/renderer/assets/.gitkeep b/src/renderer/assets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/renderer/assets/404_images/404.png b/src/renderer/assets/404_images/404.png new file mode 100644 index 0000000..3d8e230 Binary files /dev/null and b/src/renderer/assets/404_images/404.png differ diff --git a/src/renderer/assets/404_images/404_cloud.png b/src/renderer/assets/404_images/404_cloud.png new file mode 100644 index 0000000..c6281d0 Binary files /dev/null and b/src/renderer/assets/404_images/404_cloud.png differ diff --git a/src/renderer/components/Breadcrumb/index.vue b/src/renderer/components/Breadcrumb/index.vue new file mode 100644 index 0000000..b5d9471 --- /dev/null +++ b/src/renderer/components/Breadcrumb/index.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/src/renderer/components/Hamburger/index.vue b/src/renderer/components/Hamburger/index.vue new file mode 100644 index 0000000..fbdf72c --- /dev/null +++ b/src/renderer/components/Hamburger/index.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/src/renderer/components/LandingPage.vue b/src/renderer/components/LandingPage.vue deleted file mode 100644 index 0639ad2..0000000 --- a/src/renderer/components/LandingPage.vue +++ /dev/null @@ -1,128 +0,0 @@ - - - - - diff --git a/src/renderer/components/LandingPage/SystemInformation.vue b/src/renderer/components/LandingPage/SystemInformation.vue deleted file mode 100644 index 88e7b5a..0000000 --- a/src/renderer/components/LandingPage/SystemInformation.vue +++ /dev/null @@ -1,73 +0,0 @@ - - - - - diff --git a/src/renderer/components/ScrollBar/index.vue b/src/renderer/components/ScrollBar/index.vue new file mode 100644 index 0000000..dc32f5c --- /dev/null +++ b/src/renderer/components/ScrollBar/index.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/src/renderer/components/SvgIcon/index.vue b/src/renderer/components/SvgIcon/index.vue new file mode 100644 index 0000000..e331a27 --- /dev/null +++ b/src/renderer/components/SvgIcon/index.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/renderer/icons/index.js b/src/renderer/icons/index.js new file mode 100644 index 0000000..14e2e13 --- /dev/null +++ b/src/renderer/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg组件 + +// register globally +Vue.component('svg-icon', SvgIcon) + +const requireAll = requireContext => requireContext.keys().map(requireContext) +const req = require.context('./svg', false, /\.svg$/) +requireAll(req) diff --git a/src/renderer/icons/svg/example.svg b/src/renderer/icons/svg/example.svg new file mode 100644 index 0000000..19cd9ed --- /dev/null +++ b/src/renderer/icons/svg/example.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/icons/svg/eye.svg b/src/renderer/icons/svg/eye.svg new file mode 100644 index 0000000..194aa45 --- /dev/null +++ b/src/renderer/icons/svg/eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/icons/svg/form.svg b/src/renderer/icons/svg/form.svg new file mode 100644 index 0000000..d848c8a --- /dev/null +++ b/src/renderer/icons/svg/form.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/icons/svg/password.svg b/src/renderer/icons/svg/password.svg new file mode 100644 index 0000000..920b500 --- /dev/null +++ b/src/renderer/icons/svg/password.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/icons/svg/table.svg b/src/renderer/icons/svg/table.svg new file mode 100644 index 0000000..da6ffff --- /dev/null +++ b/src/renderer/icons/svg/table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/icons/svg/tree.svg b/src/renderer/icons/svg/tree.svg new file mode 100644 index 0000000..11cedc0 --- /dev/null +++ b/src/renderer/icons/svg/tree.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/icons/svg/user.svg b/src/renderer/icons/svg/user.svg new file mode 100644 index 0000000..5971dee --- /dev/null +++ b/src/renderer/icons/svg/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/main.js b/src/renderer/main.js index a883628..87a3b9f 100644 --- a/src/renderer/main.js +++ b/src/renderer/main.js @@ -1,15 +1,24 @@ import Vue from 'vue' -import axios from 'axios' + +import 'normalize.css/normalize.css'// A modern alternative to CSS resets + +import ElementUI from 'element-ui' +import 'element-ui/lib/theme-chalk/index.css' +import locale from 'element-ui/lib/locale/lang/en' // lang i18n import App from './App' import router from './router' import store from './store' +import '@/icons' // icon +import '@/permission' // permission control + if (!process.env.IS_WEB) Vue.use(require('vue-electron')) -Vue.http = Vue.prototype.$http = axios + +Vue.use(ElementUI, { locale }) + Vue.config.productionTip = false -/* eslint-disable no-new */ new Vue({ components: { App }, router, diff --git a/src/renderer/permission.js b/src/renderer/permission.js new file mode 100644 index 0000000..3e83c1b --- /dev/null +++ b/src/renderer/permission.js @@ -0,0 +1,40 @@ +import router from './router' +import store from './store' +import NProgress from 'nprogress' // Progress 进度条 +import 'nprogress/nprogress.css'// Progress 进度条样式 +import { Message } from 'element-ui' + +const whiteList = ['/login'] // 不重定向白名单 +router.beforeEach((to, from, next) => { + NProgress.start() + if (store.getters.token) { + if (to.path === '/login') { + next({ path: '/' }) + NProgress.done() // if current page is dashboard will not trigger afterEach hook, so manually handle it + } else { + if (store.getters.roles.length === 0) { + store.dispatch('GetInfo').then(res => { // 拉取用户信息 + next() + }).catch((err) => { + store.dispatch('FedLogOut').then(() => { + Message.error(err || 'Verification failed, please login again') + next({ path: '/' }) + }) + }) + } else { + next() + } + } + } else { + if (whiteList.indexOf(to.path) !== -1) { + next() + } else { + next('/login') + NProgress.done() + } + } +}) + +router.afterEach(() => { + NProgress.done() // 结束Progress +}) diff --git a/src/renderer/router/index.js b/src/renderer/router/index.js index 3c9e078..30b8872 100644 --- a/src/renderer/router/index.js +++ b/src/renderer/router/index.js @@ -1,18 +1,83 @@ import Vue from 'vue' import Router from 'vue-router' +// in development-env not use lazy-loading, because lazy-loading too many pages will cause webpack hot update too slow. so only in production use lazy-loading; +// detail: https://panjiachen.github.io/vue-element-admin-site/#/lazy-loading + Vue.use(Router) +/* Layout */ +import Layout from '../views/layout/Layout' + +/** +* hidden: true if `hidden:true` will not show in the sidebar(default is false) +* alwaysShow: true if set true, will always show the root menu, whatever its child routes length +* if not set alwaysShow, only more than one route under the children +* it will becomes nested mode, otherwise not show the root menu +* redirect: noredirect if `redirect:noredirect` will no redirct in the breadcrumb +* name:'router-name' the name is used by (must set!!!) +* meta : { + title: 'title' the name show in submenu and breadcrumb (recommend set) + icon: 'svg-name' the icon show in the sidebar, + } +**/ +export const constantRouterMap = [ + { path: '/login', component: () => import('@/views/login/index'), hidden: true }, + { path: '/404', component: () => import('@/views/404'), hidden: true }, + + { + path: '/', + component: Layout, + redirect: '/dashboard', + name: 'Dashboard', + hidden: true, + children: [{ + path: 'dashboard', + component: () => import('@/views/dashboard/index') + }] + }, + + { + path: '/example', + component: Layout, + redirect: '/example/table', + name: 'Example', + meta: { title: 'Example', icon: 'example' }, + children: [ + { + path: 'table', + name: 'Table', + component: () => import('@/views/table/index'), + meta: { title: 'Table', icon: 'table' } + }, + { + path: 'tree', + name: 'Tree', + component: () => import('@/views/tree/index'), + meta: { title: 'Tree', icon: 'tree' } + } + ] + }, + + { + path: '/form', + component: Layout, + children: [ + { + path: 'index', + name: 'Form', + component: () => import('@/views/form/index'), + meta: { title: 'Form', icon: 'form' } + } + ] + }, + + { path: '*', redirect: '/404', hidden: true } +] + export default new Router({ - routes: [ - { - path: '/', - name: 'landing-page', - component: require('@/components/LandingPage').default - }, - { - path: '*', - redirect: '/' - } - ] + // mode: 'history', //后端支持可开 + scrollBehavior: () => ({ y: 0 }), + routes: constantRouterMap }) + diff --git a/src/renderer/store/getters.js b/src/renderer/store/getters.js new file mode 100644 index 0000000..7fbf1f4 --- /dev/null +++ b/src/renderer/store/getters.js @@ -0,0 +1,9 @@ +const getters = { + sidebar: state => state.app.sidebar, + device: state => state.app.device, + token: state => state.user.token, + avatar: state => state.user.avatar, + name: state => state.user.name, + roles: state => state.user.roles +} +export default getters diff --git a/src/renderer/store/index.js b/src/renderer/store/index.js index 913f0a2..6b6be08 100644 --- a/src/renderer/store/index.js +++ b/src/renderer/store/index.js @@ -1,11 +1,17 @@ import Vue from 'vue' import Vuex from 'vuex' - -import modules from './modules' +import app from './modules/app' +import user from './modules/user' +import getters from './getters' Vue.use(Vuex) -export default new Vuex.Store({ - modules, - strict: process.env.NODE_ENV !== 'production' +const store = new Vuex.Store({ + modules: { + app, + user + }, + getters }) + +export default store diff --git a/src/renderer/store/modules/Counter.js b/src/renderer/store/modules/Counter.js deleted file mode 100644 index aa9d75d..0000000 --- a/src/renderer/store/modules/Counter.js +++ /dev/null @@ -1,25 +0,0 @@ -const state = { - main: 0 -} - -const mutations = { - DECREMENT_MAIN_COUNTER(state) { - state.main-- - }, - INCREMENT_MAIN_COUNTER(state) { - state.main++ - } -} - -const actions = { - someAsyncTask({ commit }) { - // do something async - commit('INCREMENT_MAIN_COUNTER') - } -} - -export default { - state, - mutations, - actions -} diff --git a/src/renderer/store/modules/app.js b/src/renderer/store/modules/app.js new file mode 100644 index 0000000..0b2cf39 --- /dev/null +++ b/src/renderer/store/modules/app.js @@ -0,0 +1,34 @@ +const app = { + state: { + sidebar: { + opened: true, + withoutAnimation: false + }, + device: 'desktop' + }, + mutations: { + TOGGLE_SIDEBAR: state => { + state.sidebar.opened = !state.sidebar.opened + }, + CLOSE_SIDEBAR: (state, withoutAnimation) => { + state.sidebar.opened = false + state.sidebar.withoutAnimation = withoutAnimation + }, + TOGGLE_DEVICE: (state, device) => { + state.device = device + } + }, + actions: { + ToggleSideBar: ({ commit }) => { + commit('TOGGLE_SIDEBAR') + }, + CloseSideBar({ commit }, { withoutAnimation }) { + commit('CLOSE_SIDEBAR', withoutAnimation) + }, + ToggleDevice({ commit }, device) { + commit('TOGGLE_DEVICE', device) + } + } +} + +export default app diff --git a/src/renderer/store/modules/index.js b/src/renderer/store/modules/index.js deleted file mode 100644 index 428c6be..0000000 --- a/src/renderer/store/modules/index.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * The file enables `@/store/index.js` to import all vuex modules - * in a one-shot manner. There should not be any reason to edit this file. - */ - -const files = require.context('.', false, /\.js$/) -const modules = {} - -files.keys().forEach(key => { - if (key === './index.js') return - modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default -}) - -export default modules diff --git a/src/renderer/store/modules/user.js b/src/renderer/store/modules/user.js new file mode 100644 index 0000000..e5bbed4 --- /dev/null +++ b/src/renderer/store/modules/user.js @@ -0,0 +1,83 @@ +import { login, logout, getInfo } from '@/api/login' + +const user = { + state: { + token: '', + name: '', + avatar: '', + roles: [] + }, + + mutations: { + SET_TOKEN: (state, token) => { + state.token = token + }, + SET_NAME: (state, name) => { + state.name = name + }, + SET_AVATAR: (state, avatar) => { + state.avatar = avatar + }, + SET_ROLES: (state, roles) => { + state.roles = roles + } + }, + + actions: { + // 登录 + Login({ commit }, userInfo) { + const username = userInfo.username.trim() + return new Promise((resolve, reject) => { + login(username, userInfo.password).then(response => { + const data = response.data + commit('SET_TOKEN', data.token) + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + + // 获取用户信息 + GetInfo({ commit, state }) { + return new Promise((resolve, reject) => { + getInfo(state.token).then(response => { + const data = response.data + if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组 + commit('SET_ROLES', data.roles) + } else { + reject('getInfo: roles must be a non-null array !') + } + commit('SET_NAME', data.name) + commit('SET_AVATAR', data.avatar) + resolve(response) + }).catch(error => { + reject(error) + }) + }) + }, + + // 登出 + LogOut({ commit, state }) { + return new Promise((resolve, reject) => { + logout(state.token).then(() => { + commit('SET_TOKEN', '') + commit('SET_ROLES', []) + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + + // 前端 登出 + FedLogOut({ commit }) { + return new Promise(resolve => { + commit('SET_TOKEN', '') + resolve() + }) + } + } +} + +export default user diff --git a/src/renderer/styles/element-ui.scss b/src/renderer/styles/element-ui.scss new file mode 100644 index 0000000..ef7bb5d --- /dev/null +++ b/src/renderer/styles/element-ui.scss @@ -0,0 +1,29 @@ + //to reset element-ui default css +.el-upload { + input[type="file"] { + display: none !important; + } +} + +.el-upload__input { + display: none; +} + +//暂时性解决diolag 问题 https://github.com/ElemeFE/element/issues/2461 +.el-dialog { + transform: none; + left: 0; + position: relative; + margin: 0 auto; +} + +//element ui upload +.upload-container { + .el-upload { + width: 100%; + .el-upload-dragger { + width: 100%; + height: 200px; + } + } +} diff --git a/src/renderer/styles/index.scss b/src/renderer/styles/index.scss new file mode 100644 index 0000000..7ab8db8 --- /dev/null +++ b/src/renderer/styles/index.scss @@ -0,0 +1,59 @@ +@import './variables.scss'; +@import './mixin.scss'; +@import './transition.scss'; +@import './element-ui.scss'; +@import './sidebar.scss'; + +body { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; +} + +html { + box-sizing: border-box; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +div:focus{ + outline: none; +} + +a:focus, +a:active { + outline: none; +} + +a, +a:focus, +a:hover { + cursor: pointer; + color: inherit; + text-decoration: none; +} + +.clearfix { + &:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; + } +} + +//main-container全局样式 +.app-main{ + min-height: 100% +} + +.app-container { + padding: 20px; +} diff --git a/src/renderer/styles/mixin.scss b/src/renderer/styles/mixin.scss new file mode 100644 index 0000000..601d7a0 --- /dev/null +++ b/src/renderer/styles/mixin.scss @@ -0,0 +1,27 @@ +@mixin clearfix { + &:after { + content: ""; + display: table; + clear: both; + } +} + +@mixin scrollBar { + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + &::-webkit-scrollbar { + width: 6px; + } + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } +} + +@mixin relative { + position: relative; + width: 100%; + height: 100%; +} + diff --git a/src/renderer/styles/sidebar.scss b/src/renderer/styles/sidebar.scss new file mode 100644 index 0000000..d69c434 --- /dev/null +++ b/src/renderer/styles/sidebar.scss @@ -0,0 +1,105 @@ +#app { + + // 主体区域 + .main-container { + min-height: 100%; + transition: margin-left .28s; + margin-left: 180px; + } + + // 侧边栏 + .sidebar-container { + .horizontal-collapse-transition { + transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; + } + transition: width .28s; + width: 180px !important; + height: 100%; + position: fixed; + font-size: 0px; + top: 0; + bottom: 0; + left: 0; + z-index: 1001; + overflow: hidden; + a { + display: inline-block; + width: 100%; + } + .svg-icon { + margin-right: 16px; + } + .el-menu { + border: none; + width: 100% !important; + } + } + + .hideSidebar { + .sidebar-container { + width: 36px !important; + } + .main-container { + margin-left: 36px; + } + .submenu-title-noDropdown { + padding-left: 10px !important; + position: relative; + .el-tooltip { + padding: 0 10px !important; + } + } + .el-submenu { + &>.el-submenu__title { + padding-left: 10px !important; + &>span { + height: 0; + width: 0; + overflow: hidden; + visibility: hidden; + display: inline-block; + } + .el-submenu__icon-arrow { + display: none; + } + } + } + } + + .sidebar-container .nest-menu .el-submenu>.el-submenu__title, + .sidebar-container .el-submenu .el-menu-item { + min-width: 180px !important; + background-color: $subMenuBg !important; + &:hover { + background-color: $menuHover !important; + } + } + .el-menu--collapse .el-menu .el-submenu { + min-width: 180px !important; + } + + //适配移动端 + .mobile { + .main-container { + margin-left: 0px; + } + .sidebar-container { + top: 50px; + transition: transform .28s; + width: 180px !important; + } + &.hideSidebar { + .sidebar-container { + transition-duration: 0.3s; + transform: translate3d(-180px, 0, 0); + } + } + } + + .withoutAnimation { + .main-container, + .sidebar-container { + transition: none; + } + } +} diff --git a/src/renderer/styles/transition.scss b/src/renderer/styles/transition.scss new file mode 100644 index 0000000..c4d47ad --- /dev/null +++ b/src/renderer/styles/transition.scss @@ -0,0 +1,32 @@ +//globl transition css + +/*fade*/ +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.28s; +} + +.fade-enter, +.fade-leave-active { + opacity: 0; +} + +/*fade*/ +.breadcrumb-enter-active, +.breadcrumb-leave-active { + transition: all .5s; +} + +.breadcrumb-enter, +.breadcrumb-leave-active { + opacity: 0; + transform: translateX(20px); +} + +.breadcrumb-move { + transition: all .5s; +} + +.breadcrumb-leave-active { + position: absolute; +} diff --git a/src/renderer/styles/variables.scss b/src/renderer/styles/variables.scss new file mode 100644 index 0000000..2fee827 --- /dev/null +++ b/src/renderer/styles/variables.scss @@ -0,0 +1,4 @@ +//sidebar +$menuBg:#304156; +$subMenuBg:#1f2d3d; +$menuHover:#001528; diff --git a/src/renderer/utils/index.js b/src/renderer/utils/index.js new file mode 100644 index 0000000..9657c9c --- /dev/null +++ b/src/renderer/utils/index.js @@ -0,0 +1,58 @@ +/** + * Created by jiachenpan on 16/11/18. + */ + +export function parseTime(time, cFormat) { + if (arguments.length === 0) { + return null + } + const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' + let date + if (typeof time === 'object') { + date = time + } else { + if (('' + time).length === 10) time = parseInt(time) * 1000 + date = new Date(time) + } + const formatObj = { + y: date.getFullYear(), + m: date.getMonth() + 1, + d: date.getDate(), + h: date.getHours(), + i: date.getMinutes(), + s: date.getSeconds(), + a: date.getDay() + } + const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { + let value = formatObj[key] + if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1] + if (result.length > 0 && value < 10) { + value = '0' + value + } + return value || 0 + }) + return time_str +} + +export function formatTime(time, option) { + time = +time * 1000 + const d = new Date(time) + const now = Date.now() + + const diff = (now - d) / 1000 + + if (diff < 30) { + return '刚刚' + } else if (diff < 3600) { // less 1 hour + return Math.ceil(diff / 60) + '分钟前' + } else if (diff < 3600 * 24) { + return Math.ceil(diff / 3600) + '小时前' + } else if (diff < 3600 * 24 * 2) { + return '1天前' + } + if (option) { + return parseTime(time, option) + } else { + return d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分' + } +} diff --git a/src/renderer/utils/request.js b/src/renderer/utils/request.js new file mode 100644 index 0000000..1a74436 --- /dev/null +++ b/src/renderer/utils/request.js @@ -0,0 +1,65 @@ +import axios from 'axios' +import { Message, MessageBox } from 'element-ui' +import store from '../store' + +// 创建axios实例 +const service = axios.create({ + baseURL: process.env.BASE_API, // api的base_url + timeout: 15000 // 请求超时时间 +}) + +// request拦截器 +service.interceptors.request.use(config => { + if (store.getters.token) { + config.headers['X-Token'] = store.getters.token// 让每个请求携带自定义token 请根据实际情况自行修改 + } + return config +}, error => { + // Do something with request error + console.log(error) // for debug + Promise.reject(error) +}) + +// respone拦截器 +service.interceptors.response.use( + response => { + /** + * code为非20000是抛错 可结合自己业务进行修改 + */ + const res = response.data + if (res.code !== 20000) { + Message({ + message: res.message, + type: 'error', + duration: 5 * 1000 + }) + + // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; + if (res.code === 50008 || res.code === 50012 || res.code === 50014) { + MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', { + confirmButtonText: '重新登录', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + store.dispatch('FedLogOut').then(() => { + location.reload()// 为了重新实例化vue-router对象 避免bug + }) + }) + } + return Promise.reject('error') + } else { + return response.data + } + }, + error => { + console.log('err' + error)// for debug + Message({ + message: error.message, + type: 'error', + duration: 5 * 1000 + }) + return Promise.reject(error) + } +) + +export default service diff --git a/src/renderer/utils/validate.js b/src/renderer/utils/validate.js new file mode 100644 index 0000000..834a8dd --- /dev/null +++ b/src/renderer/utils/validate.js @@ -0,0 +1,33 @@ +/** + * Created by jiachenpan on 16/11/18. + */ + +export function isvalidUsername(str) { + const valid_map = ['admin', 'editor'] + return valid_map.indexOf(str.trim()) >= 0 +} + +/* 合法uri*/ +export function validateURL(textval) { + const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ + return urlregex.test(textval) +} + +/* 小写字母*/ +export function validateLowerCase(str) { + const reg = /^[a-z]+$/ + return reg.test(str) +} + +/* 大写字母*/ +export function validateUpperCase(str) { + const reg = /^[A-Z]+$/ + return reg.test(str) +} + +/* 大小写字母*/ +export function validatAlphabets(str) { + const reg = /^[A-Za-z]+$/ + return reg.test(str) +} + diff --git a/src/renderer/views/404.vue b/src/renderer/views/404.vue new file mode 100644 index 0000000..ca160fa --- /dev/null +++ b/src/renderer/views/404.vue @@ -0,0 +1,229 @@ + + + + + diff --git a/src/renderer/views/dashboard/index.vue b/src/renderer/views/dashboard/index.vue new file mode 100644 index 0000000..4b4625c --- /dev/null +++ b/src/renderer/views/dashboard/index.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/src/renderer/views/form/index.vue b/src/renderer/views/form/index.vue new file mode 100644 index 0000000..bfec9a2 --- /dev/null +++ b/src/renderer/views/form/index.vue @@ -0,0 +1,85 @@ + + + + + + diff --git a/src/renderer/views/layout/Layout.vue b/src/renderer/views/layout/Layout.vue new file mode 100644 index 0000000..60f2784 --- /dev/null +++ b/src/renderer/views/layout/Layout.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/src/renderer/views/layout/components/AppMain.vue b/src/renderer/views/layout/components/AppMain.vue new file mode 100644 index 0000000..4babff5 --- /dev/null +++ b/src/renderer/views/layout/components/AppMain.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/renderer/views/layout/components/Navbar.vue b/src/renderer/views/layout/components/Navbar.vue new file mode 100644 index 0000000..eb36b1a --- /dev/null +++ b/src/renderer/views/layout/components/Navbar.vue @@ -0,0 +1,94 @@ + + + + + + diff --git a/src/renderer/views/layout/components/Sidebar/SidebarItem.vue b/src/renderer/views/layout/components/Sidebar/SidebarItem.vue new file mode 100644 index 0000000..aa719d1 --- /dev/null +++ b/src/renderer/views/layout/components/Sidebar/SidebarItem.vue @@ -0,0 +1,59 @@ + + + diff --git a/src/renderer/views/layout/components/Sidebar/index.vue b/src/renderer/views/layout/components/Sidebar/index.vue new file mode 100644 index 0000000..c4bd38f --- /dev/null +++ b/src/renderer/views/layout/components/Sidebar/index.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/renderer/views/layout/components/index.js b/src/renderer/views/layout/components/index.js new file mode 100644 index 0000000..97ee3cd --- /dev/null +++ b/src/renderer/views/layout/components/index.js @@ -0,0 +1,3 @@ +export { default as Navbar } from './Navbar' +export { default as Sidebar } from './Sidebar' +export { default as AppMain } from './AppMain' diff --git a/src/renderer/views/layout/mixin/ResizeHandler.js b/src/renderer/views/layout/mixin/ResizeHandler.js new file mode 100644 index 0000000..b22c8bb --- /dev/null +++ b/src/renderer/views/layout/mixin/ResizeHandler.js @@ -0,0 +1,41 @@ +import store from '@/store' + +const { body } = document +const WIDTH = 1024 +const RATIO = 3 + +export default { + watch: { + $route(route) { + if (this.device === 'mobile' && this.sidebar.opened) { + store.dispatch('CloseSideBar', { withoutAnimation: false }) + } + } + }, + beforeMount() { + window.addEventListener('resize', this.resizeHandler) + }, + mounted() { + const isMobile = this.isMobile() + if (isMobile) { + store.dispatch('ToggleDevice', 'mobile') + store.dispatch('CloseSideBar', { withoutAnimation: true }) + } + }, + methods: { + isMobile() { + const rect = body.getBoundingClientRect() + return rect.width - RATIO < WIDTH + }, + resizeHandler() { + if (!document.hidden) { + const isMobile = this.isMobile() + store.dispatch('ToggleDevice', isMobile ? 'mobile' : 'desktop') + + if (isMobile) { + store.dispatch('CloseSideBar', { withoutAnimation: true }) + } + } + } + } +} diff --git a/src/renderer/views/login/index.vue b/src/renderer/views/login/index.vue new file mode 100644 index 0000000..6f790ef --- /dev/null +++ b/src/renderer/views/login/index.vue @@ -0,0 +1,182 @@ + + + + + + + diff --git a/src/renderer/views/table/index.vue b/src/renderer/views/table/index.vue new file mode 100644 index 0000000..899c341 --- /dev/null +++ b/src/renderer/views/table/index.vue @@ -0,0 +1,72 @@ + + + diff --git a/src/renderer/views/tree/index.vue b/src/renderer/views/tree/index.vue new file mode 100644 index 0000000..2bfa696 --- /dev/null +++ b/src/renderer/views/tree/index.vue @@ -0,0 +1,71 @@ + + + +