Commit 668e9078 authored by smallwei's avatar smallwei

chomd(cli): merge avue-cli2

parents
{
"presets": [
["env", { "modules": false }],
"stage-2"
],
"plugins": ["transform-runtime"],
"comments": false
}
> 1%
last 2 versions
not ie <= 8
\ No newline at end of file
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false
build/*.js
config/*.js
src/assets
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'eslint:recommended'
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
},
parserOptions: {
parser: 'babel-eslint'
}
}
\ No newline at end of file
.DS_Store
node_modules
/dist
/tests/e2e/videos/
/tests/e2e/screenshots/
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
module.exports = {
plugins: {
autoprefixer: {}
}
}
\ No newline at end of file
# avue-cli
这是基于vue-cli@3.0改的一个脚手架
## Run vueUI
* 1.npm install -g @vue/cli 全局安装vue脚手架最新版
* 2.vue --version 查看版本是否为3.x版本
* 3.vue-ui 运行管理工具,导入avue-cli项目
* 4.剩下的自己摸索吧,下面时图示
![图例1](https://gitee.wang/avue/avue-cli/raw/master/public/img/mock/cli/1.png)
![图例2](https://gitee.wang/avue/avue-cli/raw/master/public/img/mock/cli/2.png)
![图例3](https://gitee.wang/avue/avue-cli/raw/master/public/img/mock/cli/3.png)
## Run setup
```
cd avue-cli
```
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Run your unit tests
```
npm run test:unit
```
### Run your end-to-end tests
```
npm run test:e2e
```
module.exports = {
presets: [
'@vue/app'
]
}
\ No newline at end of file
{
"pluginsFile": "tests/e2e/plugins/index.js"
}
{
"name": "avue-cli",
"version": "2.0.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"test:unit": "vue-cli-service test:unit",
"test:e2e": "vue-cli-service test:e2e"
},
"dependencies": {
"@smallwei/avue": "^1.1.17",
"avue-plugin-transfer": "^0.0.2",
"avue-plugin-ueditor": "^0.0.1",
"axios": "^0.18.0",
"babel-polyfill": "^6.26.0",
"classlist-polyfill": "^1.2.0",
"driver.js": "^0.6.2",
"element-ui": "^2.4.5",
"file-saver": "^1.3.8",
"html2canvas": "^1.0.0-alpha.12",
"js-cookie": "^2.2.0",
"mockjs": "^1.0.1-beta3",
"moment": "^2.22.2",
"nprogress": "^0.2.0",
"script-loader": "^0.7.2",
"vue": "^2.5.16",
"vue-axios": "^2.1.2",
"vue-clipboard2": "^0.2.1",
"vue-json-tree-view": "^2.1.4",
"vue-quill-editor": "^3.0.6",
"vue-router": "^3.0.1",
"vuedraggable": "^2.16.0",
"vuex": "^3.0.1",
"xlsx": "^0.13.3"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.0.0",
"@vue/cli-plugin-e2e-cypress": "^3.0.0",
"@vue/cli-plugin-eslint": "^3.0.0",
"@vue/cli-plugin-unit-mocha": "^3.0.0",
"@vue/cli-service": "^3.0.0",
"@vue/test-utils": "^1.0.0-beta.20",
"chai": "^4.1.2",
"node-sass": "^4.9.0",
"sass-loader": "^7.0.1",
"vue-template-compiler": "^2.5.17"
},
"lint-staged": {
"*.js": [
"vue-cli-service lint",
"git add"
],
"*.vue": [
"vue-cli-service lint",
"git add"
]
}
}
\ No newline at end of file
@charset "UTF-8";
/*!
* animate.css -http://daneden.me/animate
* Version - 3.5.1
* Licensed under the MIT license - http://opensource.org/licenses/MIT
*
* Copyright (c) 2016 Daniel Eden
*/
.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}.animated.bounceIn,.animated.bounceOut,.animated.flipOutX,.animated.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounce{0%,20%,53%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);transform:translateZ(0)}40%,43%{-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}40%,43%,70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06)}70%{-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{0%,20%,53%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);transform:translateZ(0)}40%,43%{-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}40%,43%,70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06)}70%{-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}.headShake{-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-name:headShake;animation-name:headShake}@-webkit-keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:none;transform:none}}@keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{0%,11.1%,to{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{0%,11.1%,to{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:none;transform:none}}@keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:none;transform:none}}@keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px) rotateY(-1turn);transform:perspective(400px) rotateY(-1turn)}0%,40%{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(-190deg);transform:perspective(400px) translateZ(150px) rotateY(-190deg)}50%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(-170deg);transform:perspective(400px) translateZ(150px) rotateY(-170deg)}50%,80%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95)}to{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{0%{-webkit-transform:perspective(400px) rotateY(-1turn);transform:perspective(400px) rotateY(-1turn)}0%,40%{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(-190deg);transform:perspective(400px) translateZ(150px) rotateY(-190deg)}50%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(-170deg);transform:perspective(400px) translateZ(150px) rotateY(-170deg)}50%,80%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95)}to{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}0%,40%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}40%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg)}60%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}0%,40%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}40%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg)}60%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}0%,40%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}40%{-webkit-transform:perspective(400px) rotateY(-20deg);transform:perspective(400px) rotateY(-20deg)}60%{-webkit-transform:perspective(400px) rotateY(10deg);transform:perspective(400px) rotateY(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}0%,40%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}40%{-webkit-transform:perspective(400px) rotateY(-20deg);transform:perspective(400px) rotateY(-20deg)}60%{-webkit-transform:perspective(400px) rotateY(10deg);transform:perspective(400px) rotateY(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);transform:perspective(400px) rotateY(-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);transform:perspective(400px) rotateY(-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg)}60%,80%{opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg)}to{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg)}60%,80%{opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg)}to{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{transform-origin:center;-webkit-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}0%,to{-webkit-transform-origin:center}to{transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{0%{transform-origin:center;-webkit-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}0%,to{-webkit-transform-origin:center}to{transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{0%{transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{transform-origin:right bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{0%{transform-origin:right bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{0%{transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{transform-origin:right bottom;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{0%{transform-origin:right bottom;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{transform-origin:center;opacity:1}0%,to{-webkit-transform-origin:center}to{transform-origin:center;-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}@keyframes rotateOut{0%{transform-origin:center;opacity:1}0%,to{-webkit-transform-origin:center}to{transform-origin:center;-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{transform-origin:left bottom;opacity:1}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}}@keyframes rotateOutDownLeft{0%{transform-origin:left bottom;opacity:1}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{transform-origin:right bottom;opacity:1}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}@keyframes rotateOutDownRight{0%{transform-origin:right bottom;opacity:1}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{transform-origin:left bottom;opacity:1}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}@keyframes rotateOutUpLeft{0%{transform-origin:left bottom;opacity:1}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{transform-origin:right bottom;opacity:1}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}@keyframes rotateOutUpRight{0%{transform-origin:right bottom;opacity:1}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{transform-origin:top left}0%,20%,60%{-webkit-transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);transform:rotate(80deg);transform-origin:top left}40%,80%{-webkit-transform:rotate(60deg);transform:rotate(60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{transform-origin:top left}0%,20%,60%{-webkit-transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);transform:rotate(80deg);transform-origin:top left}40%,80%{-webkit-transform:rotate(60deg);transform:rotate(60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);transform:translate3d(-100%,0,0) rotate(-120deg)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);transform:translate3d(-100%,0,0) rotate(-120deg)}to{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate(120deg);transform:translate3d(100%,0,0) rotate(120deg)}}@keyframes rollOut{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate(120deg);transform:translate3d(100%,0,0) rotate(120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%,to{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%,to{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}
\ No newline at end of file
/* axios v0.17.1 | (c) 2017 by Matt Zabriskie */
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.axios=t():e.axios=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";function r(e){var t=new s(e),n=i(s.prototype.request,t);return o.extend(n,s.prototype,t),o.extend(n,t),n}var o=n(2),i=n(3),s=n(5),u=n(6),a=r(u);a.Axios=s,a.create=function(e){return r(o.merge(u,e))},a.Cancel=n(23),a.CancelToken=n(24),a.isCancel=n(20),a.all=function(e){return Promise.all(e)},a.spread=n(25),e.exports=a,e.exports.default=a},function(e,t,n){"use strict";function r(e){return"[object Array]"===R.call(e)}function o(e){return"[object ArrayBuffer]"===R.call(e)}function i(e){return"undefined"!=typeof FormData&&e instanceof FormData}function s(e){var t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer}function u(e){return"string"==typeof e}function a(e){return"number"==typeof e}function c(e){return"undefined"==typeof e}function f(e){return null!==e&&"object"==typeof e}function p(e){return"[object Date]"===R.call(e)}function d(e){return"[object File]"===R.call(e)}function l(e){return"[object Blob]"===R.call(e)}function h(e){return"[object Function]"===R.call(e)}function m(e){return f(e)&&h(e.pipe)}function y(e){return"undefined"!=typeof URLSearchParams&&e instanceof URLSearchParams}function w(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function g(){return("undefined"==typeof navigator||"ReactNative"!==navigator.product)&&("undefined"!=typeof window&&"undefined"!=typeof document)}function v(e,t){if(null!==e&&"undefined"!=typeof e)if("object"!=typeof e&&(e=[e]),r(e))for(var n=0,o=e.length;n<o;n++)t.call(null,e[n],n,e);else for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.call(null,e[i],i,e)}function x(){function e(e,n){"object"==typeof t[n]&&"object"==typeof e?t[n]=x(t[n],e):t[n]=e}for(var t={},n=0,r=arguments.length;n<r;n++)v(arguments[n],e);return t}function b(e,t,n){return v(t,function(t,r){n&&"function"==typeof t?e[r]=E(t,n):e[r]=t}),e}var E=n(3),C=n(4),R=Object.prototype.toString;e.exports={isArray:r,isArrayBuffer:o,isBuffer:C,isFormData:i,isArrayBufferView:s,isString:u,isNumber:a,isObject:f,isUndefined:c,isDate:p,isFile:d,isBlob:l,isFunction:h,isStream:m,isURLSearchParams:y,isStandardBrowserEnv:g,forEach:v,merge:x,extend:b,trim:w}},function(e,t){"use strict";e.exports=function(e,t){return function(){for(var n=new Array(arguments.length),r=0;r<n.length;r++)n[r]=arguments[r];return e.apply(t,n)}}},function(e,t){function n(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function r(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&n(e.slice(0,0))}/*!
* Determine if an object is a Buffer
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
e.exports=function(e){return null!=e&&(n(e)||r(e)||!!e._isBuffer)}},function(e,t,n){"use strict";function r(e){this.defaults=e,this.interceptors={request:new s,response:new s}}var o=n(6),i=n(2),s=n(17),u=n(18);r.prototype.request=function(e){"string"==typeof e&&(e=i.merge({url:arguments[0]},arguments[1])),e=i.merge(o,this.defaults,{method:"get"},e),e.method=e.method.toLowerCase();var t=[u,void 0],n=Promise.resolve(e);for(this.interceptors.request.forEach(function(e){t.unshift(e.fulfilled,e.rejected)}),this.interceptors.response.forEach(function(e){t.push(e.fulfilled,e.rejected)});t.length;)n=n.then(t.shift(),t.shift());return n},i.forEach(["delete","get","head","options"],function(e){r.prototype[e]=function(t,n){return this.request(i.merge(n||{},{method:e,url:t}))}}),i.forEach(["post","put","patch"],function(e){r.prototype[e]=function(t,n,r){return this.request(i.merge(r||{},{method:e,url:t,data:n}))}}),e.exports=r},function(e,t,n){"use strict";function r(e,t){!i.isUndefined(e)&&i.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}function o(){var e;return"undefined"!=typeof XMLHttpRequest?e=n(8):"undefined"!=typeof process&&(e=n(8)),e}var i=n(2),s=n(7),u={"Content-Type":"application/x-www-form-urlencoded"},a={adapter:o(),transformRequest:[function(e,t){return s(t,"Content-Type"),i.isFormData(e)||i.isArrayBuffer(e)||i.isBuffer(e)||i.isStream(e)||i.isFile(e)||i.isBlob(e)?e:i.isArrayBufferView(e)?e.buffer:i.isURLSearchParams(e)?(r(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):i.isObject(e)?(r(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return e>=200&&e<300}};a.headers={common:{Accept:"application/json, text/plain, */*"}},i.forEach(["delete","get","head"],function(e){a.headers[e]={}}),i.forEach(["post","put","patch"],function(e){a.headers[e]=i.merge(u)}),e.exports=a},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t){r.forEach(e,function(n,r){r!==t&&r.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[r])})}},function(e,t,n){"use strict";var r=n(2),o=n(9),i=n(12),s=n(13),u=n(14),a=n(10),c="undefined"!=typeof window&&window.btoa&&window.btoa.bind(window)||n(15);e.exports=function(e){return new Promise(function(t,f){var p=e.data,d=e.headers;r.isFormData(p)&&delete d["Content-Type"];var l=new XMLHttpRequest,h="onreadystatechange",m=!1;if("undefined"==typeof window||!window.XDomainRequest||"withCredentials"in l||u(e.url)||(l=new window.XDomainRequest,h="onload",m=!0,l.onprogress=function(){},l.ontimeout=function(){}),e.auth){var y=e.auth.username||"",w=e.auth.password||"";d.Authorization="Basic "+c(y+":"+w)}if(l.open(e.method.toUpperCase(),i(e.url,e.params,e.paramsSerializer),!0),l.timeout=e.timeout,l[h]=function(){if(l&&(4===l.readyState||m)&&(0!==l.status||l.responseURL&&0===l.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in l?s(l.getAllResponseHeaders()):null,r=e.responseType&&"text"!==e.responseType?l.response:l.responseText,i={data:r,status:1223===l.status?204:l.status,statusText:1223===l.status?"No Content":l.statusText,headers:n,config:e,request:l};o(t,f,i),l=null}},l.onerror=function(){f(a("Network Error",e,null,l)),l=null},l.ontimeout=function(){f(a("timeout of "+e.timeout+"ms exceeded",e,"ECONNABORTED",l)),l=null},r.isStandardBrowserEnv()){var g=n(16),v=(e.withCredentials||u(e.url))&&e.xsrfCookieName?g.read(e.xsrfCookieName):void 0;v&&(d[e.xsrfHeaderName]=v)}if("setRequestHeader"in l&&r.forEach(d,function(e,t){"undefined"==typeof p&&"content-type"===t.toLowerCase()?delete d[t]:l.setRequestHeader(t,e)}),e.withCredentials&&(l.withCredentials=!0),e.responseType)try{l.responseType=e.responseType}catch(t){if("json"!==e.responseType)throw t}"function"==typeof e.onDownloadProgress&&l.addEventListener("progress",e.onDownloadProgress),"function"==typeof e.onUploadProgress&&l.upload&&l.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then(function(e){l&&(l.abort(),f(e),l=null)}),void 0===p&&(p=null),l.send(p)})}},function(e,t,n){"use strict";var r=n(10);e.exports=function(e,t,n){var o=n.config.validateStatus;n.status&&o&&!o(n.status)?t(r("Request failed with status code "+n.status,n.config,null,n.request,n)):e(n)}},function(e,t,n){"use strict";var r=n(11);e.exports=function(e,t,n,o,i){var s=new Error(e);return r(s,t,n,o,i)}},function(e,t){"use strict";e.exports=function(e,t,n,r,o){return e.config=t,n&&(e.code=n),e.request=r,e.response=o,e}},function(e,t,n){"use strict";function r(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}var o=n(2);e.exports=function(e,t,n){if(!t)return e;var i;if(n)i=n(t);else if(o.isURLSearchParams(t))i=t.toString();else{var s=[];o.forEach(t,function(e,t){null!==e&&"undefined"!=typeof e&&(o.isArray(e)&&(t+="[]"),o.isArray(e)||(e=[e]),o.forEach(e,function(e){o.isDate(e)?e=e.toISOString():o.isObject(e)&&(e=JSON.stringify(e)),s.push(r(t)+"="+r(e))}))}),i=s.join("&")}return i&&(e+=(e.indexOf("?")===-1?"?":"&")+i),e}},function(e,t,n){"use strict";var r=n(2),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,i,s={};return e?(r.forEach(e.split("\n"),function(e){if(i=e.indexOf(":"),t=r.trim(e.substr(0,i)).toLowerCase(),n=r.trim(e.substr(i+1)),t){if(s[t]&&o.indexOf(t)>=0)return;"set-cookie"===t?s[t]=(s[t]?s[t]:[]).concat([n]):s[t]=s[t]?s[t]+", "+n:n}}),s):s}},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){function e(e){var t=e;return n&&(o.setAttribute("href",t),t=o.href),o.setAttribute("href",t),{href:o.href,protocol:o.protocol?o.protocol.replace(/:$/,""):"",host:o.host,search:o.search?o.search.replace(/^\?/,""):"",hash:o.hash?o.hash.replace(/^#/,""):"",hostname:o.hostname,port:o.port,pathname:"/"===o.pathname.charAt(0)?o.pathname:"/"+o.pathname}}var t,n=/(msie|trident)/i.test(navigator.userAgent),o=document.createElement("a");return t=e(window.location.href),function(n){var o=r.isString(n)?e(n):n;return o.protocol===t.protocol&&o.host===t.host}}():function(){return function(){return!0}}()},function(e,t){"use strict";function n(){this.message="String contains an invalid character"}function r(e){for(var t,r,i=String(e),s="",u=0,a=o;i.charAt(0|u)||(a="=",u%1);s+=a.charAt(63&t>>8-u%1*8)){if(r=i.charCodeAt(u+=.75),r>255)throw new n;t=t<<8|r}return s}var o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";n.prototype=new Error,n.prototype.code=5,n.prototype.name="InvalidCharacterError",e.exports=r},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){return{write:function(e,t,n,o,i,s){var u=[];u.push(e+"="+encodeURIComponent(t)),r.isNumber(n)&&u.push("expires="+new Date(n).toGMTString()),r.isString(o)&&u.push("path="+o),r.isString(i)&&u.push("domain="+i),s===!0&&u.push("secure"),document.cookie=u.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},function(e,t,n){"use strict";function r(){this.handlers=[]}var o=n(2);r.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},r.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},r.prototype.forEach=function(e){o.forEach(this.handlers,function(t){null!==t&&e(t)})},e.exports=r},function(e,t,n){"use strict";function r(e){e.cancelToken&&e.cancelToken.throwIfRequested()}var o=n(2),i=n(19),s=n(20),u=n(6),a=n(21),c=n(22);e.exports=function(e){r(e),e.baseURL&&!a(e.url)&&(e.url=c(e.baseURL,e.url)),e.headers=e.headers||{},e.data=i(e.data,e.headers,e.transformRequest),e.headers=o.merge(e.headers.common||{},e.headers[e.method]||{},e.headers||{}),o.forEach(["delete","get","head","post","put","patch","common"],function(t){delete e.headers[t]});var t=e.adapter||u.adapter;return t(e).then(function(t){return r(e),t.data=i(t.data,t.headers,e.transformResponse),t},function(t){return s(t)||(r(e),t&&t.response&&(t.response.data=i(t.response.data,t.response.headers,e.transformResponse))),Promise.reject(t)})}},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t,n){return r.forEach(n,function(n){e=n(e,t)}),e}},function(e,t){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},function(e,t){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t){"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},function(e,t){"use strict";function n(e){this.message=e}n.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},n.prototype.__CANCEL__=!0,e.exports=n},function(e,t,n){"use strict";function r(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(e){t=e});var n=this;e(function(e){n.reason||(n.reason=new o(e),t(n.reason))})}var o=n(23);r.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},r.source=function(){var e,t=new r(function(t){e=t});return{token:t,cancel:e}},e.exports=r},function(e,t){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}}])});
//# sourceMappingURL=axios.min.map
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
[class^="icon-"]{
font-family: "iconfont" !important;
/* 以下内容参照第三方图标库本身的规则 */
font-size: 18px !important;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.el-menu-item [class^=icon-] {
margin-right: 5px;
width: 24px;
text-align: center;
font-size: 18px;
vertical-align: middle;
}
.el-submenu [class^=icon-] {
vertical-align: middle;
margin-right: 5px;
width: 24px;
text-align: center;
font-size: 18px;
}
"use strict"
// Module export pattern from
// https://github.com/umdjs/umd/blob/master/returnExports.js
;(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
// Browser globals (root is window)
root.store = factory();
}
}(this, function () {
// Store.js
var store = {},
win = (typeof window != 'undefined' ? window : global),
doc = win.document,
localStorageName = 'localStorage',
scriptTag = 'script',
storage
store.disabled = false
store.version = '1.3.20'
store.set = function(key, value) {}
store.get = function(key, defaultVal) {}
store.has = function(key) { return store.get(key) !== undefined }
store.remove = function(key) {}
store.clear = function() {}
store.transact = function(key, defaultVal, transactionFn) {
if (transactionFn == null) {
transactionFn = defaultVal
defaultVal = null
}
if (defaultVal == null) {
defaultVal = {}
}
var val = store.get(key, defaultVal)
transactionFn(val)
store.set(key, val)
}
store.getAll = function() {}
store.forEach = function() {}
store.serialize = function(value) {
return JSON.stringify(value)
}
store.deserialize = function(value) {
if (typeof value != 'string') { return undefined }
try { return JSON.parse(value) }
catch(e) { return value || undefined }
}
// Functions to encapsulate questionable FireFox 3.6.13 behavior
// when about.config::dom.storage.enabled === false
// See https://github.com/marcuswestin/store.js/issues#issue/13
function isLocalStorageNameSupported() {
try { return (localStorageName in win && win[localStorageName]) }
catch(err) { return false }
}
if (isLocalStorageNameSupported()) {
storage = win[localStorageName]
store.set = function(key, val) {
if (val === undefined) { return store.remove(key) }
storage.setItem(key, store.serialize(val))
return val
}
store.get = function(key, defaultVal) {
var val = store.deserialize(storage.getItem(key))
return (val === undefined ? defaultVal : val)
}
store.remove = function(key) { storage.removeItem(key) }
store.clear = function() { storage.clear() }
store.getAll = function() {
var ret = {}
store.forEach(function(key, val) {
ret[key] = val
})
return ret
}
store.forEach = function(callback) {
for (var i=0; i<storage.length; i++) {
var key = storage.key(i)
callback(key, store.get(key))
}
}
} else if (doc && doc.documentElement.addBehavior) {
var storageOwner,
storageContainer
// Since #userData storage applies only to specific paths, we need to
// somehow link our data to a specific path. We choose /favicon.ico
// as a pretty safe option, since all browsers already make a request to
// this URL anyway and being a 404 will not hurt us here. We wrap an
// iframe pointing to the favicon in an ActiveXObject(htmlfile) object
// (see: http://msdn.microsoft.com/en-us/library/aa752574(v=VS.85).aspx)
// since the iframe access rules appear to allow direct access and
// manipulation of the document element, even for a 404 page. This
// document can be used instead of the current document (which would
// have been limited to the current path) to perform #userData storage.
try {
storageContainer = new ActiveXObject('htmlfile')
storageContainer.open()
storageContainer.write('<'+scriptTag+'>document.w=window</'+scriptTag+'><iframe src="/favicon.ico"></iframe>')
storageContainer.close()
storageOwner = storageContainer.w.frames[0].document
storage = storageOwner.createElement('div')
} catch(e) {
// somehow ActiveXObject instantiation failed (perhaps some special
// security settings or otherwse), fall back to per-path storage
storage = doc.createElement('div')
storageOwner = doc.body
}
var withIEStorage = function(storeFunction) {
return function() {
var args = Array.prototype.slice.call(arguments, 0)
args.unshift(storage)
// See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
// and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
storageOwner.appendChild(storage)
storage.addBehavior('#default#userData')
storage.load(localStorageName)
var result = storeFunction.apply(store, args)
storageOwner.removeChild(storage)
return result
}
}
// In IE7, keys cannot start with a digit or contain certain chars.
// See https://github.com/marcuswestin/store.js/issues/40
// See https://github.com/marcuswestin/store.js/issues/83
var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]", "g")
var ieKeyFix = function(key) {
return key.replace(/^d/, '___$&').replace(forbiddenCharsRegex, '___')
}
store.set = withIEStorage(function(storage, key, val) {
key = ieKeyFix(key)
if (val === undefined) { return store.remove(key) }
storage.setAttribute(key, store.serialize(val))
storage.save(localStorageName)
return val
})
store.get = withIEStorage(function(storage, key, defaultVal) {
key = ieKeyFix(key)
var val = store.deserialize(storage.getAttribute(key))
return (val === undefined ? defaultVal : val)
})
store.remove = withIEStorage(function(storage, key) {
key = ieKeyFix(key)
storage.removeAttribute(key)
storage.save(localStorageName)
})
store.clear = withIEStorage(function(storage) {
var attributes = storage.XMLDocument.documentElement.attributes
storage.load(localStorageName)
for (var i=attributes.length-1; i>=0; i--) {
storage.removeAttribute(attributes[i].name)
}
storage.save(localStorageName)
})
store.getAll = function(storage) {
var ret = {}
store.forEach(function(key, val) {
ret[key] = val
})
return ret
}
store.forEach = withIEStorage(function(storage, callback) {
var attributes = storage.XMLDocument.documentElement.attributes
for (var i=0, attr; attr=attributes[i]; ++i) {
callback(attr.name, store.deserialize(storage.getAttribute(attr.name)))
}
})
}
try {
var testKey = '__storejs__'
store.set(testKey, testKey)
if (store.get(testKey) != testKey) { store.disabled = true }
store.remove(testKey)
} catch(e) {
store.disabled = true
}
store.enabled = !store.disabled
return store
}));
\ No newline at end of file
/**
* vue-router v3.0.1
* (c) 2017 Evan You
* @license MIT
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.VueRouter = factory());
}(this, (function () { 'use strict';
/* */
function assert (condition, message) {
if (!condition) {
throw new Error(("[vue-router] " + message))
}
}
function warn (condition, message) {
if ("development" !== 'production' && !condition) {
typeof console !== 'undefined' && console.warn(("[vue-router] " + message));
}
}
function isError (err) {
return Object.prototype.toString.call(err).indexOf('Error') > -1
}
var View = {
name: 'router-view',
functional: true,
props: {
name: {
type: String,
default: 'default'
}
},
render: function render (_, ref) {
var props = ref.props;
var children = ref.children;
var parent = ref.parent;
var data = ref.data;
data.routerView = true;
// directly use parent context's createElement() function
// so that components rendered by router-view can resolve named slots
var h = parent.$createElement;
var name = props.name;
var route = parent.$route;
var cache = parent._routerViewCache || (parent._routerViewCache = {});
// determine current view depth, also check to see if the tree
// has been toggled inactive but kept-alive.
var depth = 0;
var inactive = false;
while (parent && parent._routerRoot !== parent) {
if (parent.$vnode && parent.$vnode.data.routerView) {
depth++;
}
if (parent._inactive) {
inactive = true;
}
parent = parent.$parent;
}
data.routerViewDepth = depth;
// render previous view if the tree is inactive and kept-alive
if (inactive) {
return h(cache[name], data, children)
}
var matched = route.matched[depth];
// render empty node if no matched route
if (!matched) {
cache[name] = null;
return h()
}
var component = cache[name] = matched.components[name];
// attach instance registration hook
// this will be called in the instance's injected lifecycle hooks
data.registerRouteInstance = function (vm, val) {
// val could be undefined for unregistration
var current = matched.instances[name];
if (
(val && current !== vm) ||
(!val && current === vm)
) {
matched.instances[name] = val;
}
}
// also register instance in prepatch hook
// in case the same component instance is reused across different routes
;(data.hook || (data.hook = {})).prepatch = function (_, vnode) {
matched.instances[name] = vnode.componentInstance;
};
// resolve props
var propsToPass = data.props = resolveProps(route, matched.props && matched.props[name]);
if (propsToPass) {
// clone to prevent mutation
propsToPass = data.props = extend({}, propsToPass);
// pass non-declared props as attrs
var attrs = data.attrs = data.attrs || {};
for (var key in propsToPass) {
if (!component.props || !(key in component.props)) {
attrs[key] = propsToPass[key];
delete propsToPass[key];
}
}
}
return h(component, data, children)
}
};
function resolveProps (route, config) {
switch (typeof config) {
case 'undefined':
return
case 'object':
return config
case 'function':
return config(route)
case 'boolean':
return config ? route.params : undefined
default:
{
warn(
false,
"props in \"" + (route.path) + "\" is a " + (typeof config) + ", " +
"expecting an object, function or boolean."
);
}
}
}
function extend (to, from) {
for (var key in from) {
to[key] = from[key];
}
return to
}
/* */
var encodeReserveRE = /[!'()*]/g;
var encodeReserveReplacer = function (c) { return '%' + c.charCodeAt(0).toString(16); };
var commaRE = /%2C/g;
// fixed encodeURIComponent which is more conformant to RFC3986:
// - escapes [!'()*]
// - preserve commas
var encode = function (str) { return encodeURIComponent(str)
.replace(encodeReserveRE, encodeReserveReplacer)
.replace(commaRE, ','); };
var decode = decodeURIComponent;
function resolveQuery (
query,
extraQuery,
_parseQuery
) {
if ( extraQuery === void 0 ) extraQuery = {};
var parse = _parseQuery || parseQuery;
var parsedQuery;
try {
parsedQuery = parse(query || '');
} catch (e) {
"development" !== 'production' && warn(false, e.message);
parsedQuery = {};
}
for (var key in extraQuery) {
parsedQuery[key] = extraQuery[key];
}
return parsedQuery
}
function parseQuery (query) {
var res = {};
query = query.trim().replace(/^(\?|#|&)/, '');
if (!query) {
return res
}
query.split('&').forEach(function (param) {
var parts = param.replace(/\+/g, ' ').split('=');
var key = decode(parts.shift());
var val = parts.length > 0
? decode(parts.join('='))
: null;
if (res[key] === undefined) {
res[key] = val;
} else if (Array.isArray(res[key])) {
res[key].push(val);
} else {
res[key] = [res[key], val];
}
});
return res
}
function stringifyQuery (obj) {
var res = obj ? Object.keys(obj).map(function (key) {
var val = obj[key];
if (val === undefined) {
return ''
}
if (val === null) {
return encode(key)
}
if (Array.isArray(val)) {
var result = [];
val.forEach(function (val2) {
if (val2 === undefined) {
return
}
if (val2 === null) {
result.push(encode(key));
} else {
result.push(encode(key) + '=' + encode(val2));
}
});
return result.join('&')
}
return encode(key) + '=' + encode(val)
}).filter(function (x) { return x.length > 0; }).join('&') : null;
return res ? ("?" + res) : ''
}
/* */
var trailingSlashRE = /\/?$/;
function createRoute (
record,
location,
redirectedFrom,
router
) {
var stringifyQuery$$1 = router && router.options.stringifyQuery;
var query = location.query || {};
try {
query = clone(query);
} catch (e) {}
var route = {
name: location.name || (record && record.name),
meta: (record && record.meta) || {},
path: location.path || '/',
hash: location.hash || '',
query: query,
params: location.params || {},
fullPath: getFullPath(location, stringifyQuery$$1),
matched: record ? formatMatch(record) : []
};
if (redirectedFrom) {
route.redirectedFrom = getFullPath(redirectedFrom, stringifyQuery$$1);
}
return Object.freeze(route)
}
function clone (value) {
if (Array.isArray(value)) {
return value.map(clone)
} else if (value && typeof value === 'object') {
var res = {};
for (var key in value) {
res[key] = clone(value[key]);
}
return res
} else {
return value
}
}
// the starting route that represents the initial state
var START = createRoute(null, {
path: '/'
});
function formatMatch (record) {
var res = [];
while (record) {
res.unshift(record);
record = record.parent;
}
return res
}
function getFullPath (
ref,
_stringifyQuery
) {
var path = ref.path;
var query = ref.query; if ( query === void 0 ) query = {};
var hash = ref.hash; if ( hash === void 0 ) hash = '';
var stringify = _stringifyQuery || stringifyQuery;
return (path || '/') + stringify(query) + hash
}
function isSameRoute (a, b) {
if (b === START) {
return a === b
} else if (!b) {
return false
} else if (a.path && b.path) {
return (
a.path.replace(trailingSlashRE, '') === b.path.replace(trailingSlashRE, '') &&
a.hash === b.hash &&
isObjectEqual(a.query, b.query)
)
} else if (a.name && b.name) {
return (
a.name === b.name &&
a.hash === b.hash &&
isObjectEqual(a.query, b.query) &&
isObjectEqual(a.params, b.params)
)
} else {
return false
}
}
function isObjectEqual (a, b) {
if ( a === void 0 ) a = {};
if ( b === void 0 ) b = {};
// handle null value #1566
if (!a || !b) { return a === b }
var aKeys = Object.keys(a);
var bKeys = Object.keys(b);
if (aKeys.length !== bKeys.length) {
return false
}
return aKeys.every(function (key) {
var aVal = a[key];
var bVal = b[key];
// check nested equality
if (typeof aVal === 'object' && typeof bVal === 'object') {
return isObjectEqual(aVal, bVal)
}
return String(aVal) === String(bVal)
})
}
function isIncludedRoute (current, target) {
return (
current.path.replace(trailingSlashRE, '/').indexOf(
target.path.replace(trailingSlashRE, '/')
) === 0 &&
(!target.hash || current.hash === target.hash) &&
queryIncludes(current.query, target.query)
)
}
function queryIncludes (current, target) {
for (var key in target) {
if (!(key in current)) {
return false
}
}
return true
}
/* */
// work around weird flow bug
var toTypes = [String, Object];
var eventTypes = [String, Array];
var Link = {
name: 'router-link',
props: {
to: {
type: toTypes,
required: true
},
tag: {
type: String,
default: 'a'
},
exact: Boolean,
append: Boolean,
replace: Boolean,
activeClass: String,
exactActiveClass: String,
event: {
type: eventTypes,
default: 'click'
}
},
render: function render (h) {
var this$1 = this;
var router = this.$router;
var current = this.$route;
var ref = router.resolve(this.to, current, this.append);
var location = ref.location;
var route = ref.route;
var href = ref.href;
var classes = {};
var globalActiveClass = router.options.linkActiveClass;
var globalExactActiveClass = router.options.linkExactActiveClass;
// Support global empty active class
var activeClassFallback = globalActiveClass == null
? 'router-link-active'
: globalActiveClass;
var exactActiveClassFallback = globalExactActiveClass == null
? 'router-link-exact-active'
: globalExactActiveClass;
var activeClass = this.activeClass == null
? activeClassFallback
: this.activeClass;
var exactActiveClass = this.exactActiveClass == null
? exactActiveClassFallback
: this.exactActiveClass;
var compareTarget = location.path
? createRoute(null, location, null, router)
: route;
classes[exactActiveClass] = isSameRoute(current, compareTarget);
classes[activeClass] = this.exact
? classes[exactActiveClass]
: isIncludedRoute(current, compareTarget);
var handler = function (e) {
if (guardEvent(e)) {
if (this$1.replace) {
router.replace(location);
} else {
router.push(location);
}
}
};
var on = { click: guardEvent };
if (Array.isArray(this.event)) {
this.event.forEach(function (e) { on[e] = handler; });
} else {
on[this.event] = handler;
}
var data = {
class: classes
};
if (this.tag === 'a') {
data.on = on;
data.attrs = { href: href };
} else {
// find the first <a> child and apply listener and href
var a = findAnchor(this.$slots.default);
if (a) {
// in case the <a> is a static node
a.isStatic = false;
var extend = _Vue.util.extend;
var aData = a.data = extend({}, a.data);
aData.on = on;
var aAttrs = a.data.attrs = extend({}, a.data.attrs);
aAttrs.href = href;
} else {
// doesn't have <a> child, apply listener to self
data.on = on;
}
}
return h(this.tag, data, this.$slots.default)
}
};
function guardEvent (e) {
// don't redirect with control keys
if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) { return }
// don't redirect when preventDefault called
if (e.defaultPrevented) { return }
// don't redirect on right click
if (e.button !== undefined && e.button !== 0) { return }
// don't redirect if `target="_blank"`
if (e.currentTarget && e.currentTarget.getAttribute) {
var target = e.currentTarget.getAttribute('target');
if (/\b_blank\b/i.test(target)) { return }
}
// this may be a Weex event which doesn't have this method
if (e.preventDefault) {
e.preventDefault();
}
return true
}
function findAnchor (children) {
if (children) {
var child;
for (var i = 0; i < children.length; i++) {
child = children[i];
if (child.tag === 'a') {
return child
}
if (child.children && (child = findAnchor(child.children))) {
return child
}
}
}
}
var _Vue;
function install (Vue) {
if (install.installed && _Vue === Vue) { return }
install.installed = true;
_Vue = Vue;
var isDef = function (v) { return v !== undefined; };
var registerInstance = function (vm, callVal) {
var i = vm.$options._parentVnode;
if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
i(vm, callVal);
}
};
Vue.mixin({
beforeCreate: function beforeCreate () {
if (isDef(this.$options.router)) {
this._routerRoot = this;
this._router = this.$options.router;
this._router.init(this);
Vue.util.defineReactive(this, '_route', this._router.history.current);
} else {
this._routerRoot = (this.$parent && this.$parent._routerRoot) || this;
}
registerInstance(this, this);
},
destroyed: function destroyed () {
registerInstance(this);
}
});
Object.defineProperty(Vue.prototype, '$router', {
get: function get () { return this._routerRoot._router }
});
Object.defineProperty(Vue.prototype, '$route', {
get: function get () { return this._routerRoot._route }
});
Vue.component('router-view', View);
Vue.component('router-link', Link);
var strats = Vue.config.optionMergeStrategies;
// use the same hook merging strategy for route hooks
strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created;
}
/* */
var inBrowser = typeof window !== 'undefined';
/* */
function resolvePath (
relative,
base,
append
) {
var firstChar = relative.charAt(0);
if (firstChar === '/') {
return relative
}
if (firstChar === '?' || firstChar === '#') {
return base + relative
}
var stack = base.split('/');
// remove trailing segment if:
// - not appending
// - appending to trailing slash (last segment is empty)
if (!append || !stack[stack.length - 1]) {
stack.pop();
}
// resolve relative path
var segments = relative.replace(/^\//, '').split('/');
for (var i = 0; i < segments.length; i++) {
var segment = segments[i];
if (segment === '..') {
stack.pop();
} else if (segment !== '.') {
stack.push(segment);
}
}
// ensure leading slash
if (stack[0] !== '') {
stack.unshift('');
}
return stack.join('/')
}
function parsePath (path) {
var hash = '';
var query = '';
var hashIndex = path.indexOf('#');
if (hashIndex >= 0) {
hash = path.slice(hashIndex);
path = path.slice(0, hashIndex);
}
var queryIndex = path.indexOf('?');
if (queryIndex >= 0) {
query = path.slice(queryIndex + 1);
path = path.slice(0, queryIndex);
}
return {
path: path,
query: query,
hash: hash
}
}
function cleanPath (path) {
return path.replace(/\/\//g, '/')
}
var isarray = Array.isArray || function (arr) {
return Object.prototype.toString.call(arr) == '[object Array]';
};
/**
* Expose `pathToRegexp`.
*/
var pathToRegexp_1 = pathToRegexp;
var parse_1 = parse;
var compile_1 = compile;
var tokensToFunction_1 = tokensToFunction;
var tokensToRegExp_1 = tokensToRegExp;
/**
* The main path matching regexp utility.
*
* @type {RegExp}
*/
var PATH_REGEXP = new RegExp([
// Match escaped characters that would otherwise appear in future matches.
// This allows the user to escape special characters that won't transform.
'(\\\\.)',
// Match Express-style parameters and un-named parameters with a prefix
// and optional suffixes. Matches appear as:
//
// "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined]
// "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined]
// "/*" => ["/", undefined, undefined, undefined, undefined, "*"]
'([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))'
].join('|'), 'g');
/**
* Parse a string for the raw tokens.
*
* @param {string} str
* @param {Object=} options
* @return {!Array}
*/
function parse (str, options) {
var tokens = [];
var key = 0;
var index = 0;
var path = '';
var defaultDelimiter = options && options.delimiter || '/';
var res;
while ((res = PATH_REGEXP.exec(str)) != null) {
var m = res[0];
var escaped = res[1];
var offset = res.index;
path += str.slice(index, offset);
index = offset + m.length;
// Ignore already escaped sequences.
if (escaped) {
path += escaped[1];
continue
}
var next = str[index];
var prefix = res[2];
var name = res[3];
var capture = res[4];
var group = res[5];
var modifier = res[6];
var asterisk = res[7];
// Push the current path onto the tokens.
if (path) {
tokens.push(path);
path = '';
}
var partial = prefix != null && next != null && next !== prefix;
var repeat = modifier === '+' || modifier === '*';
var optional = modifier === '?' || modifier === '*';
var delimiter = res[2] || defaultDelimiter;
var pattern = capture || group;
tokens.push({
name: name || key++,
prefix: prefix || '',
delimiter: delimiter,
optional: optional,
repeat: repeat,
partial: partial,
asterisk: !!asterisk,
pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?')
});
}
// Match any characters still remaining.
if (index < str.length) {
path += str.substr(index);
}
// If the path exists, push it onto the end.
if (path) {
tokens.push(path);
}
return tokens
}
/**
* Compile a string to a template function for the path.
*
* @param {string} str
* @param {Object=} options
* @return {!function(Object=, Object=)}
*/
function compile (str, options) {
return tokensToFunction(parse(str, options))
}
/**
* Prettier encoding of URI path segments.
*
* @param {string}
* @return {string}
*/
function encodeURIComponentPretty (str) {
return encodeURI(str).replace(/[\/?#]/g, function (c) {
return '%' + c.charCodeAt(0).toString(16).toUpperCase()
})
}
/**
* Encode the asterisk parameter. Similar to `pretty`, but allows slashes.
*
* @param {string}
* @return {string}
*/
function encodeAsterisk (str) {
return encodeURI(str).replace(/[?#]/g, function (c) {
return '%' + c.charCodeAt(0).toString(16).toUpperCase()
})
}
/**
* Expose a method for transforming tokens into the path function.
*/
function tokensToFunction (tokens) {
// Compile all the tokens into regexps.
var matches = new Array(tokens.length);
// Compile all the patterns before compilation.
for (var i = 0; i < tokens.length; i++) {
if (typeof tokens[i] === 'object') {
matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$');
}
}
return function (obj, opts) {
var path = '';
var data = obj || {};
var options = opts || {};
var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent;
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i];
if (typeof token === 'string') {
path += token;
continue
}
var value = data[token.name];
var segment;
if (value == null) {
if (token.optional) {
// Prepend partial segment prefixes.
if (token.partial) {
path += token.prefix;
}
continue
} else {
throw new TypeError('Expected "' + token.name + '" to be defined')
}
}
if (isarray(value)) {
if (!token.repeat) {
throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`')
}
if (value.length === 0) {
if (token.optional) {
continue
} else {
throw new TypeError('Expected "' + token.name + '" to not be empty')
}
}
for (var j = 0; j < value.length; j++) {
segment = encode(value[j]);
if (!matches[i].test(segment)) {
throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`')
}
path += (j === 0 ? token.prefix : token.delimiter) + segment;
}
continue
}
segment = token.asterisk ? encodeAsterisk(value) : encode(value);
if (!matches[i].test(segment)) {
throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
}
path += token.prefix + segment;
}
return path
}
}
/**
* Escape a regular expression string.
*
* @param {string} str
* @return {string}
*/
function escapeString (str) {
return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1')
}
/**
* Escape the capturing group by escaping special characters and meaning.
*
* @param {string} group
* @return {string}
*/
function escapeGroup (group) {
return group.replace(/([=!:$\/()])/g, '\\$1')
}
/**
* Attach the keys as a property of the regexp.
*
* @param {!RegExp} re
* @param {Array} keys
* @return {!RegExp}
*/
function attachKeys (re, keys) {
re.keys = keys;
return re
}
/**
* Get the flags for a regexp from the options.
*
* @param {Object} options
* @return {string}
*/
function flags (options) {
return options.sensitive ? '' : 'i'
}
/**
* Pull out keys from a regexp.
*
* @param {!RegExp} path
* @param {!Array} keys
* @return {!RegExp}
*/
function regexpToRegexp (path, keys) {
// Use a negative lookahead to match only capturing groups.
var groups = path.source.match(/\((?!\?)/g);
if (groups) {
for (var i = 0; i < groups.length; i++) {
keys.push({
name: i,
prefix: null,
delimiter: null,
optional: false,
repeat: false,
partial: false,
asterisk: false,
pattern: null
});
}
}
return attachKeys(path, keys)
}
/**
* Transform an array into a regexp.
*
* @param {!Array} path
* @param {Array} keys
* @param {!Object} options
* @return {!RegExp}
*/
function arrayToRegexp (path, keys, options) {
var parts = [];
for (var i = 0; i < path.length; i++) {
parts.push(pathToRegexp(path[i], keys, options).source);
}
var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options));
return attachKeys(regexp, keys)
}
/**
* Create a path regexp from string input.
*
* @param {string} path
* @param {!Array} keys
* @param {!Object} options
* @return {!RegExp}
*/
function stringToRegexp (path, keys, options) {
return tokensToRegExp(parse(path, options), keys, options)
}
/**
* Expose a function for taking tokens and returning a RegExp.
*
* @param {!Array} tokens
* @param {(Array|Object)=} keys
* @param {Object=} options
* @return {!RegExp}
*/
function tokensToRegExp (tokens, keys, options) {
if (!isarray(keys)) {
options = /** @type {!Object} */ (keys || options);
keys = [];
}
options = options || {};
var strict = options.strict;
var end = options.end !== false;
var route = '';
// Iterate over the tokens and create our regexp string.
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i];
if (typeof token === 'string') {
route += escapeString(token);
} else {
var prefix = escapeString(token.prefix);
var capture = '(?:' + token.pattern + ')';
keys.push(token);
if (token.repeat) {
capture += '(?:' + prefix + capture + ')*';
}
if (token.optional) {
if (!token.partial) {
capture = '(?:' + prefix + '(' + capture + '))?';
} else {
capture = prefix + '(' + capture + ')?';
}
} else {
capture = prefix + '(' + capture + ')';
}
route += capture;
}
}
var delimiter = escapeString(options.delimiter || '/');
var endsWithDelimiter = route.slice(-delimiter.length) === delimiter;
// In non-strict mode we allow a slash at the end of match. If the path to
// match already ends with a slash, we remove it for consistency. The slash
// is valid at the end of a path match, not in the middle. This is important
// in non-ending mode, where "/test/" shouldn't match "/test//route".
if (!strict) {
route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?';
}
if (end) {
route += '$';
} else {
// In non-ending mode, we need the capturing groups to match as much as
// possible by using a positive lookahead to the end or next path segment.
route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)';
}
return attachKeys(new RegExp('^' + route, flags(options)), keys)
}
/**
* Normalize the given path string, returning a regular expression.
*
* An empty array can be passed in for the keys, which will hold the
* placeholder key descriptions. For example, using `/user/:id`, `keys` will
* contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
*
* @param {(string|RegExp|Array)} path
* @param {(Array|Object)=} keys
* @param {Object=} options
* @return {!RegExp}
*/
function pathToRegexp (path, keys, options) {
if (!isarray(keys)) {
options = /** @type {!Object} */ (keys || options);
keys = [];
}
options = options || {};
if (path instanceof RegExp) {
return regexpToRegexp(path, /** @type {!Array} */ (keys))
}
if (isarray(path)) {
return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)
}
return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)
}
pathToRegexp_1.parse = parse_1;
pathToRegexp_1.compile = compile_1;
pathToRegexp_1.tokensToFunction = tokensToFunction_1;
pathToRegexp_1.tokensToRegExp = tokensToRegExp_1;
/* */
// $flow-disable-line
var regexpCompileCache = Object.create(null);
function fillParams (
path,
params,
routeMsg
) {
try {
var filler =
regexpCompileCache[path] ||
(regexpCompileCache[path] = pathToRegexp_1.compile(path));
return filler(params || {}, { pretty: true })
} catch (e) {
{
warn(false, ("missing param for " + routeMsg + ": " + (e.message)));
}
return ''
}
}
/* */
function createRouteMap (
routes,
oldPathList,
oldPathMap,
oldNameMap
) {
// the path list is used to control path matching priority
var pathList = oldPathList || [];
// $flow-disable-line
var pathMap = oldPathMap || Object.create(null);
// $flow-disable-line
var nameMap = oldNameMap || Object.create(null);
routes.forEach(function (route) {
addRouteRecord(pathList, pathMap, nameMap, route);
});
// ensure wildcard routes are always at the end
for (var i = 0, l = pathList.length; i < l; i++) {
if (pathList[i] === '*') {
pathList.push(pathList.splice(i, 1)[0]);
l--;
i--;
}
}
return {
pathList: pathList,
pathMap: pathMap,
nameMap: nameMap
}
}
function addRouteRecord (
pathList,
pathMap,
nameMap,
route,
parent,
matchAs
) {
var path = route.path;
var name = route.name;
{
assert(path != null, "\"path\" is required in a route configuration.");
assert(
typeof route.component !== 'string',
"route config \"component\" for path: " + (String(path || name)) + " cannot be a " +
"string id. Use an actual component instead."
);
}
var pathToRegexpOptions = route.pathToRegexpOptions || {};
var normalizedPath = normalizePath(
path,
parent,
pathToRegexpOptions.strict
);
if (typeof route.caseSensitive === 'boolean') {
pathToRegexpOptions.sensitive = route.caseSensitive;
}
var record = {
path: normalizedPath,
regex: compileRouteRegex(normalizedPath, pathToRegexpOptions),
components: route.components || { default: route.component },
instances: {},
name: name,
parent: parent,
matchAs: matchAs,
redirect: route.redirect,
beforeEnter: route.beforeEnter,
meta: route.meta || {},
props: route.props == null
? {}
: route.components
? route.props
: { default: route.props }
};
if (route.children) {
// Warn if route is named, does not redirect and has a default child route.
// If users navigate to this route by name, the default child will
// not be rendered (GH Issue #629)
{
if (route.name && !route.redirect && route.children.some(function (child) { return /^\/?$/.test(child.path); })) {
warn(
false,
"Named Route '" + (route.name) + "' has a default child route. " +
"When navigating to this named route (:to=\"{name: '" + (route.name) + "'\"), " +
"the default child route will not be rendered. Remove the name from " +
"this route and use the name of the default child route for named " +
"links instead."
);
}
}
route.children.forEach(function (child) {
var childMatchAs = matchAs
? cleanPath((matchAs + "/" + (child.path)))
: undefined;
addRouteRecord(pathList, pathMap, nameMap, child, record, childMatchAs);
});
}
if (route.alias !== undefined) {
var aliases = Array.isArray(route.alias)
? route.alias
: [route.alias];
aliases.forEach(function (alias) {
var aliasRoute = {
path: alias,
children: route.children
};
addRouteRecord(
pathList,
pathMap,
nameMap,
aliasRoute,
parent,
record.path || '/' // matchAs
);
});
}
if (!pathMap[record.path]) {
pathList.push(record.path);
pathMap[record.path] = record;
}
if (name) {
if (!nameMap[name]) {
nameMap[name] = record;
} else if ("development" !== 'production' && !matchAs) {
warn(
false,
"Duplicate named routes definition: " +
"{ name: \"" + name + "\", path: \"" + (record.path) + "\" }"
);
}
}
}
function compileRouteRegex (path, pathToRegexpOptions) {
var regex = pathToRegexp_1(path, [], pathToRegexpOptions);
{
var keys = Object.create(null);
regex.keys.forEach(function (key) {
warn(!keys[key.name], ("Duplicate param keys in route with path: \"" + path + "\""));
keys[key.name] = true;
});
}
return regex
}
function normalizePath (path, parent, strict) {
if (!strict) { path = path.replace(/\/$/, ''); }
if (path[0] === '/') { return path }
if (parent == null) { return path }
return cleanPath(((parent.path) + "/" + path))
}
/* */
function normalizeLocation (
raw,
current,
append,
router
) {
var next = typeof raw === 'string' ? { path: raw } : raw;
// named target
if (next.name || next._normalized) {
return next
}
// relative params
if (!next.path && next.params && current) {
next = assign({}, next);
next._normalized = true;
var params = assign(assign({}, current.params), next.params);
if (current.name) {
next.name = current.name;
next.params = params;
} else if (current.matched.length) {
var rawPath = current.matched[current.matched.length - 1].path;
next.path = fillParams(rawPath, params, ("path " + (current.path)));
} else {
warn(false, "relative params navigation requires a current route.");
}
return next
}
var parsedPath = parsePath(next.path || '');
var basePath = (current && current.path) || '/';
var path = parsedPath.path
? resolvePath(parsedPath.path, basePath, append || next.append)
: basePath;
var query = resolveQuery(
parsedPath.query,
next.query,
router && router.options.parseQuery
);
var hash = next.hash || parsedPath.hash;
if (hash && hash.charAt(0) !== '#') {
hash = "#" + hash;
}
return {
_normalized: true,
path: path,
query: query,
hash: hash
}
}
function assign (a, b) {
for (var key in b) {
a[key] = b[key];
}
return a
}
/* */
function createMatcher (
routes,
router
) {
var ref = createRouteMap(routes);
var pathList = ref.pathList;
var pathMap = ref.pathMap;
var nameMap = ref.nameMap;
function addRoutes (routes) {
createRouteMap(routes, pathList, pathMap, nameMap);
}
function match (
raw,
currentRoute,
redirectedFrom
) {
var location = normalizeLocation(raw, currentRoute, false, router);
var name = location.name;
if (name) {
var record = nameMap[name];
{
warn(record, ("Route with name '" + name + "' does not exist"));
}
if (!record) { return _createRoute(null, location) }
var paramNames = record.regex.keys
.filter(function (key) { return !key.optional; })
.map(function (key) { return key.name; });
if (typeof location.params !== 'object') {
location.params = {};
}
if (currentRoute && typeof currentRoute.params === 'object') {
for (var key in currentRoute.params) {
if (!(key in location.params) && paramNames.indexOf(key) > -1) {
location.params[key] = currentRoute.params[key];
}
}
}
if (record) {
location.path = fillParams(record.path, location.params, ("named route \"" + name + "\""));
return _createRoute(record, location, redirectedFrom)
}
} else if (location.path) {
location.params = {};
for (var i = 0; i < pathList.length; i++) {
var path = pathList[i];
var record$1 = pathMap[path];
if (matchRoute(record$1.regex, location.path, location.params)) {
return _createRoute(record$1, location, redirectedFrom)
}
}
}
// no match
return _createRoute(null, location)
}
function redirect (
record,
location
) {
var originalRedirect = record.redirect;
var redirect = typeof originalRedirect === 'function'
? originalRedirect(createRoute(record, location, null, router))
: originalRedirect;
if (typeof redirect === 'string') {
redirect = { path: redirect };
}
if (!redirect || typeof redirect !== 'object') {
{
warn(
false, ("invalid redirect option: " + (JSON.stringify(redirect)))
);
}
return _createRoute(null, location)
}
var re = redirect;
var name = re.name;
var path = re.path;
var query = location.query;
var hash = location.hash;
var params = location.params;
query = re.hasOwnProperty('query') ? re.query : query;
hash = re.hasOwnProperty('hash') ? re.hash : hash;
params = re.hasOwnProperty('params') ? re.params : params;
if (name) {
// resolved named direct
var targetRecord = nameMap[name];
{
assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found."));
}
return match({
_normalized: true,
name: name,
query: query,
hash: hash,
params: params
}, undefined, location)
} else if (path) {
// 1. resolve relative redirect
var rawPath = resolveRecordPath(path, record);
// 2. resolve params
var resolvedPath = fillParams(rawPath, params, ("redirect route with path \"" + rawPath + "\""));
// 3. rematch with existing query and hash
return match({
_normalized: true,
path: resolvedPath,
query: query,
hash: hash
}, undefined, location)
} else {
{
warn(false, ("invalid redirect option: " + (JSON.stringify(redirect))));
}
return _createRoute(null, location)
}
}
function alias (
record,
location,
matchAs
) {
var aliasedPath = fillParams(matchAs, location.params, ("aliased route with path \"" + matchAs + "\""));
var aliasedMatch = match({
_normalized: true,
path: aliasedPath
});
if (aliasedMatch) {
var matched = aliasedMatch.matched;
var aliasedRecord = matched[matched.length - 1];
location.params = aliasedMatch.params;
return _createRoute(aliasedRecord, location)
}
return _createRoute(null, location)
}
function _createRoute (
record,
location,
redirectedFrom
) {
if (record && record.redirect) {
return redirect(record, redirectedFrom || location)
}
if (record && record.matchAs) {
return alias(record, location, record.matchAs)
}
return createRoute(record, location, redirectedFrom, router)
}
return {
match: match,
addRoutes: addRoutes
}
}
function matchRoute (
regex,
path,
params
) {
var m = path.match(regex);
if (!m) {
return false
} else if (!params) {
return true
}
for (var i = 1, len = m.length; i < len; ++i) {
var key = regex.keys[i - 1];
var val = typeof m[i] === 'string' ? decodeURIComponent(m[i]) : m[i];
if (key) {
params[key.name] = val;
}
}
return true
}
function resolveRecordPath (path, record) {
return resolvePath(path, record.parent ? record.parent.path : '/', true)
}
/* */
var positionStore = Object.create(null);
function setupScroll () {
// Fix for #1585 for Firefox
window.history.replaceState({ key: getStateKey() }, '');
window.addEventListener('popstate', function (e) {
saveScrollPosition();
if (e.state && e.state.key) {
setStateKey(e.state.key);
}
});
}
function handleScroll (
router,
to,
from,
isPop
) {
if (!router.app) {
return
}
var behavior = router.options.scrollBehavior;
if (!behavior) {
return
}
{
assert(typeof behavior === 'function', "scrollBehavior must be a function");
}
// wait until re-render finishes before scrolling
router.app.$nextTick(function () {
var position = getScrollPosition();
var shouldScroll = behavior(to, from, isPop ? position : null);
if (!shouldScroll) {
return
}
if (typeof shouldScroll.then === 'function') {
shouldScroll.then(function (shouldScroll) {
scrollToPosition((shouldScroll), position);
}).catch(function (err) {
{
assert(false, err.toString());
}
});
} else {
scrollToPosition(shouldScroll, position);
}
});
}
function saveScrollPosition () {
var key = getStateKey();
if (key) {
positionStore[key] = {
x: window.pageXOffset,
y: window.pageYOffset
};
}
}
function getScrollPosition () {
var key = getStateKey();
if (key) {
return positionStore[key]
}
}
function getElementPosition (el, offset) {
var docEl = document.documentElement;
var docRect = docEl.getBoundingClientRect();
var elRect = el.getBoundingClientRect();
return {
x: elRect.left - docRect.left - offset.x,
y: elRect.top - docRect.top - offset.y
}
}
function isValidPosition (obj) {
return isNumber(obj.x) || isNumber(obj.y)
}
function normalizePosition (obj) {
return {
x: isNumber(obj.x) ? obj.x : window.pageXOffset,
y: isNumber(obj.y) ? obj.y : window.pageYOffset
}
}
function normalizeOffset (obj) {
return {
x: isNumber(obj.x) ? obj.x : 0,
y: isNumber(obj.y) ? obj.y : 0
}
}
function isNumber (v) {
return typeof v === 'number'
}
function scrollToPosition (shouldScroll, position) {
var isObject = typeof shouldScroll === 'object';
if (isObject && typeof shouldScroll.selector === 'string') {
var el = document.querySelector(shouldScroll.selector);
if (el) {
var offset = shouldScroll.offset && typeof shouldScroll.offset === 'object' ? shouldScroll.offset : {};
offset = normalizeOffset(offset);
position = getElementPosition(el, offset);
} else if (isValidPosition(shouldScroll)) {
position = normalizePosition(shouldScroll);
}
} else if (isObject && isValidPosition(shouldScroll)) {
position = normalizePosition(shouldScroll);
}
if (position) {
window.scrollTo(position.x, position.y);
}
}
/* */
var supportsPushState = inBrowser && (function () {
var ua = window.navigator.userAgent;
if (
(ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
ua.indexOf('Mobile Safari') !== -1 &&
ua.indexOf('Chrome') === -1 &&
ua.indexOf('Windows Phone') === -1
) {
return false
}
return window.history && 'pushState' in window.history
})();
// use User Timing api (if present) for more accurate key precision
var Time = inBrowser && window.performance && window.performance.now
? window.performance
: Date;
var _key = genKey();
function genKey () {
return Time.now().toFixed(3)
}
function getStateKey () {
return _key
}
function setStateKey (key) {
_key = key;
}
function pushState (url, replace) {
saveScrollPosition();
// try...catch the pushState call to get around Safari
// DOM Exception 18 where it limits to 100 pushState calls
var history = window.history;
try {
if (replace) {
history.replaceState({ key: _key }, '', url);
} else {
_key = genKey();
history.pushState({ key: _key }, '', url);
}
} catch (e) {
window.location[replace ? 'replace' : 'assign'](url);
}
}
function replaceState (url) {
pushState(url, true);
}
/* */
function runQueue (queue, fn, cb) {
var step = function (index) {
if (index >= queue.length) {
cb();
} else {
if (queue[index]) {
fn(queue[index], function () {
step(index + 1);
});
} else {
step(index + 1);
}
}
};
step(0);
}
/* */
function resolveAsyncComponents (matched) {
return function (to, from, next) {
var hasAsync = false;
var pending = 0;
var error = null;
flatMapComponents(matched, function (def, _, match, key) {
// if it's a function and doesn't have cid attached,
// assume it's an async component resolve function.
// we are not using Vue's default async resolving mechanism because
// we want to halt the navigation until the incoming component has been
// resolved.
if (typeof def === 'function' && def.cid === undefined) {
hasAsync = true;
pending++;
var resolve = once(function (resolvedDef) {
if (isESModule(resolvedDef)) {
resolvedDef = resolvedDef.default;
}
// save resolved on async factory in case it's used elsewhere
def.resolved = typeof resolvedDef === 'function'
? resolvedDef
: _Vue.extend(resolvedDef);
match.components[key] = resolvedDef;
pending--;
if (pending <= 0) {
next();
}
});
var reject = once(function (reason) {
var msg = "Failed to resolve async component " + key + ": " + reason;
"development" !== 'production' && warn(false, msg);
if (!error) {
error = isError(reason)
? reason
: new Error(msg);
next(error);
}
});
var res;
try {
res = def(resolve, reject);
} catch (e) {
reject(e);
}
if (res) {
if (typeof res.then === 'function') {
res.then(resolve, reject);
} else {
// new syntax in Vue 2.3
var comp = res.component;
if (comp && typeof comp.then === 'function') {
comp.then(resolve, reject);
}
}
}
}
});
if (!hasAsync) { next(); }
}
}
function flatMapComponents (
matched,
fn
) {
return flatten(matched.map(function (m) {
return Object.keys(m.components).map(function (key) { return fn(
m.components[key],
m.instances[key],
m, key
); })
}))
}
function flatten (arr) {
return Array.prototype.concat.apply([], arr)
}
var hasSymbol =
typeof Symbol === 'function' &&
typeof Symbol.toStringTag === 'symbol';
function isESModule (obj) {
return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module')
}
// in Webpack 2, require.ensure now also returns a Promise
// so the resolve/reject functions may get called an extra time
// if the user uses an arrow function shorthand that happens to
// return that Promise.
function once (fn) {
var called = false;
return function () {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
if (called) { return }
called = true;
return fn.apply(this, args)
}
}
/* */
var History = function History (router, base) {
this.router = router;
this.base = normalizeBase(base);
// start with a route object that stands for "nowhere"
this.current = START;
this.pending = null;
this.ready = false;
this.readyCbs = [];
this.readyErrorCbs = [];
this.errorCbs = [];
};
History.prototype.listen = function listen (cb) {
this.cb = cb;
};
History.prototype.onReady = function onReady (cb, errorCb) {
if (this.ready) {
cb();
} else {
this.readyCbs.push(cb);
if (errorCb) {
this.readyErrorCbs.push(errorCb);
}
}
};
History.prototype.onError = function onError (errorCb) {
this.errorCbs.push(errorCb);
};
History.prototype.transitionTo = function transitionTo (location, onComplete, onAbort) {
var this$1 = this;
var route = this.router.match(location, this.current);
this.confirmTransition(route, function () {
this$1.updateRoute(route);
onComplete && onComplete(route);
this$1.ensureURL();
// fire ready cbs once
if (!this$1.ready) {
this$1.ready = true;
this$1.readyCbs.forEach(function (cb) { cb(route); });
}
}, function (err) {
if (onAbort) {
onAbort(err);
}
if (err && !this$1.ready) {
this$1.ready = true;
this$1.readyErrorCbs.forEach(function (cb) { cb(err); });
}
});
};
History.prototype.confirmTransition = function confirmTransition (route, onComplete, onAbort) {
var this$1 = this;
var current = this.current;
var abort = function (err) {
if (isError(err)) {
if (this$1.errorCbs.length) {
this$1.errorCbs.forEach(function (cb) { cb(err); });
} else {
warn(false, 'uncaught error during route navigation:');
console.error(err);
}
}
onAbort && onAbort(err);
};
if (
isSameRoute(route, current) &&
// in the case the route map has been dynamically appended to
route.matched.length === current.matched.length
) {
this.ensureURL();
return abort()
}
var ref = resolveQueue(this.current.matched, route.matched);
var updated = ref.updated;
var deactivated = ref.deactivated;
var activated = ref.activated;
var queue = [].concat(
// in-component leave guards
extractLeaveGuards(deactivated),
// global before hooks
this.router.beforeHooks,
// in-component update hooks
extractUpdateHooks(updated),
// in-config enter guards
activated.map(function (m) { return m.beforeEnter; }),
// async components
resolveAsyncComponents(activated)
);
this.pending = route;
var iterator = function (hook, next) {
if (this$1.pending !== route) {
return abort()
}
try {
hook(route, current, function (to) {
if (to === false || isError(to)) {
// next(false) -> abort navigation, ensure current URL
this$1.ensureURL(true);
abort(to);
} else if (
typeof to === 'string' ||
(typeof to === 'object' && (
typeof to.path === 'string' ||
typeof to.name === 'string'
))
) {
// next('/') or next({ path: '/' }) -> redirect
abort();
if (typeof to === 'object' && to.replace) {
this$1.replace(to);
} else {
this$1.push(to);
}
} else {
// confirm transition and pass on the value
next(to);
}
});
} catch (e) {
abort(e);
}
};
runQueue(queue, iterator, function () {
var postEnterCbs = [];
var isValid = function () { return this$1.current === route; };
// wait until async components are resolved before
// extracting in-component enter guards
var enterGuards = extractEnterGuards(activated, postEnterCbs, isValid);
var queue = enterGuards.concat(this$1.router.resolveHooks);
runQueue(queue, iterator, function () {
if (this$1.pending !== route) {
return abort()
}
this$1.pending = null;
onComplete(route);
if (this$1.router.app) {
this$1.router.app.$nextTick(function () {
postEnterCbs.forEach(function (cb) { cb(); });
});
}
});
});
};
History.prototype.updateRoute = function updateRoute (route) {
var prev = this.current;
this.current = route;
this.cb && this.cb(route);
this.router.afterHooks.forEach(function (hook) {
hook && hook(route, prev);
});
};
function normalizeBase (base) {
if (!base) {
if (inBrowser) {
// respect <base> tag
var baseEl = document.querySelector('base');
base = (baseEl && baseEl.getAttribute('href')) || '/';
// strip full URL origin
base = base.replace(/^https?:\/\/[^\/]+/, '');
} else {
base = '/';
}
}
// make sure there's the starting slash
if (base.charAt(0) !== '/') {
base = '/' + base;
}
// remove trailing slash
return base.replace(/\/$/, '')
}
function resolveQueue (
current,
next
) {
var i;
var max = Math.max(current.length, next.length);
for (i = 0; i < max; i++) {
if (current[i] !== next[i]) {
break
}
}
return {
updated: next.slice(0, i),
activated: next.slice(i),
deactivated: current.slice(i)
}
}
function extractGuards (
records,
name,
bind,
reverse
) {
var guards = flatMapComponents(records, function (def, instance, match, key) {
var guard = extractGuard(def, name);
if (guard) {
return Array.isArray(guard)
? guard.map(function (guard) { return bind(guard, instance, match, key); })
: bind(guard, instance, match, key)
}
});
return flatten(reverse ? guards.reverse() : guards)
}
function extractGuard (
def,
key
) {
if (typeof def !== 'function') {
// extend now so that global mixins are applied.
def = _Vue.extend(def);
}
return def.options[key]
}
function extractLeaveGuards (deactivated) {
return extractGuards(deactivated, 'beforeRouteLeave', bindGuard, true)
}
function extractUpdateHooks (updated) {
return extractGuards(updated, 'beforeRouteUpdate', bindGuard)
}
function bindGuard (guard, instance) {
if (instance) {
return function boundRouteGuard () {
return guard.apply(instance, arguments)
}
}
}
function extractEnterGuards (
activated,
cbs,
isValid
) {
return extractGuards(activated, 'beforeRouteEnter', function (guard, _, match, key) {
return bindEnterGuard(guard, match, key, cbs, isValid)
})
}
function bindEnterGuard (
guard,
match,
key,
cbs,
isValid
) {
return function routeEnterGuard (to, from, next) {
return guard(to, from, function (cb) {
next(cb);
if (typeof cb === 'function') {
cbs.push(function () {
// #750
// if a router-view is wrapped with an out-in transition,
// the instance may not have been registered at this time.
// we will need to poll for registration until current route
// is no longer valid.
poll(cb, match.instances, key, isValid);
});
}
})
}
}
function poll (
cb, // somehow flow cannot infer this is a function
instances,
key,
isValid
) {
if (instances[key]) {
cb(instances[key]);
} else if (isValid()) {
setTimeout(function () {
poll(cb, instances, key, isValid);
}, 16);
}
}
/* */
var HTML5History = (function (History$$1) {
function HTML5History (router, base) {
var this$1 = this;
History$$1.call(this, router, base);
var expectScroll = router.options.scrollBehavior;
if (expectScroll) {
setupScroll();
}
var initLocation = getLocation(this.base);
window.addEventListener('popstate', function (e) {
var current = this$1.current;
// Avoiding first `popstate` event dispatched in some browsers but first
// history route not updated since async guard at the same time.
var location = getLocation(this$1.base);
if (this$1.current === START && location === initLocation) {
return
}
this$1.transitionTo(location, function (route) {
if (expectScroll) {
handleScroll(router, route, current, true);
}
});
});
}
if ( History$$1 ) HTML5History.__proto__ = History$$1;
HTML5History.prototype = Object.create( History$$1 && History$$1.prototype );
HTML5History.prototype.constructor = HTML5History;
HTML5History.prototype.go = function go (n) {
window.history.go(n);
};
HTML5History.prototype.push = function push (location, onComplete, onAbort) {
var this$1 = this;
var ref = this;
var fromRoute = ref.current;
this.transitionTo(location, function (route) {
pushState(cleanPath(this$1.base + route.fullPath));
handleScroll(this$1.router, route, fromRoute, false);
onComplete && onComplete(route);
}, onAbort);
};
HTML5History.prototype.replace = function replace (location, onComplete, onAbort) {
var this$1 = this;
var ref = this;
var fromRoute = ref.current;
this.transitionTo(location, function (route) {
replaceState(cleanPath(this$1.base + route.fullPath));
handleScroll(this$1.router, route, fromRoute, false);
onComplete && onComplete(route);
}, onAbort);
};
HTML5History.prototype.ensureURL = function ensureURL (push) {
if (getLocation(this.base) !== this.current.fullPath) {
var current = cleanPath(this.base + this.current.fullPath);
push ? pushState(current) : replaceState(current);
}
};
HTML5History.prototype.getCurrentLocation = function getCurrentLocation () {
return getLocation(this.base)
};
return HTML5History;
}(History));
function getLocation (base) {
var path = window.location.pathname;
if (base && path.indexOf(base) === 0) {
path = path.slice(base.length);
}
return (path || '/') + window.location.search + window.location.hash
}
/* */
var HashHistory = (function (History$$1) {
function HashHistory (router, base, fallback) {
History$$1.call(this, router, base);
// check history fallback deeplinking
if (fallback && checkFallback(this.base)) {
return
}
ensureSlash();
}
if ( History$$1 ) HashHistory.__proto__ = History$$1;
HashHistory.prototype = Object.create( History$$1 && History$$1.prototype );
HashHistory.prototype.constructor = HashHistory;
// this is delayed until the app mounts
// to avoid the hashchange listener being fired too early
HashHistory.prototype.setupListeners = function setupListeners () {
var this$1 = this;
var router = this.router;
var expectScroll = router.options.scrollBehavior;
var supportsScroll = supportsPushState && expectScroll;
if (supportsScroll) {
setupScroll();
}
window.addEventListener(supportsPushState ? 'popstate' : 'hashchange', function () {
var current = this$1.current;
if (!ensureSlash()) {
return
}
this$1.transitionTo(getHash(), function (route) {
if (supportsScroll) {
handleScroll(this$1.router, route, current, true);
}
if (!supportsPushState) {
replaceHash(route.fullPath);
}
});
});
};
HashHistory.prototype.push = function push (location, onComplete, onAbort) {
var this$1 = this;
var ref = this;
var fromRoute = ref.current;
this.transitionTo(location, function (route) {
pushHash(route.fullPath);
handleScroll(this$1.router, route, fromRoute, false);
onComplete && onComplete(route);
}, onAbort);
};
HashHistory.prototype.replace = function replace (location, onComplete, onAbort) {
var this$1 = this;
var ref = this;
var fromRoute = ref.current;
this.transitionTo(location, function (route) {
replaceHash(route.fullPath);
handleScroll(this$1.router, route, fromRoute, false);
onComplete && onComplete(route);
}, onAbort);
};
HashHistory.prototype.go = function go (n) {
window.history.go(n);
};
HashHistory.prototype.ensureURL = function ensureURL (push) {
var current = this.current.fullPath;
if (getHash() !== current) {
push ? pushHash(current) : replaceHash(current);
}
};
HashHistory.prototype.getCurrentLocation = function getCurrentLocation () {
return getHash()
};
return HashHistory;
}(History));
function checkFallback (base) {
var location = getLocation(base);
if (!/^\/#/.test(location)) {
window.location.replace(
cleanPath(base + '/#' + location)
);
return true
}
}
function ensureSlash () {
var path = getHash();
if (path.charAt(0) === '/') {
return true
}
replaceHash('/' + path);
return false
}
function getHash () {
// We can't use window.location.hash here because it's not
// consistent across browsers - Firefox will pre-decode it!
var href = window.location.href;
var index = href.indexOf('#');
return index === -1 ? '' : href.slice(index + 1)
}
function getUrl (path) {
var href = window.location.href;
var i = href.indexOf('#');
var base = i >= 0 ? href.slice(0, i) : href;
return (base + "#" + path)
}
function pushHash (path) {
if (supportsPushState) {
pushState(getUrl(path));
} else {
window.location.hash = path;
}
}
function replaceHash (path) {
if (supportsPushState) {
replaceState(getUrl(path));
} else {
window.location.replace(getUrl(path));
}
}
/* */
var AbstractHistory = (function (History$$1) {
function AbstractHistory (router, base) {
History$$1.call(this, router, base);
this.stack = [];
this.index = -1;
}
if ( History$$1 ) AbstractHistory.__proto__ = History$$1;
AbstractHistory.prototype = Object.create( History$$1 && History$$1.prototype );
AbstractHistory.prototype.constructor = AbstractHistory;
AbstractHistory.prototype.push = function push (location, onComplete, onAbort) {
var this$1 = this;
this.transitionTo(location, function (route) {
this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route);
this$1.index++;
onComplete && onComplete(route);
}, onAbort);
};
AbstractHistory.prototype.replace = function replace (location, onComplete, onAbort) {
var this$1 = this;
this.transitionTo(location, function (route) {
this$1.stack = this$1.stack.slice(0, this$1.index).concat(route);
onComplete && onComplete(route);
}, onAbort);
};
AbstractHistory.prototype.go = function go (n) {
var this$1 = this;
var targetIndex = this.index + n;
if (targetIndex < 0 || targetIndex >= this.stack.length) {
return
}
var route = this.stack[targetIndex];
this.confirmTransition(route, function () {
this$1.index = targetIndex;
this$1.updateRoute(route);
});
};
AbstractHistory.prototype.getCurrentLocation = function getCurrentLocation () {
var current = this.stack[this.stack.length - 1];
return current ? current.fullPath : '/'
};
AbstractHistory.prototype.ensureURL = function ensureURL () {
// noop
};
return AbstractHistory;
}(History));
/* */
var VueRouter = function VueRouter (options) {
if ( options === void 0 ) options = {};
this.app = null;
this.apps = [];
this.options = options;
this.beforeHooks = [];
this.resolveHooks = [];
this.afterHooks = [];
this.matcher = createMatcher(options.routes || [], this);
var mode = options.mode || 'hash';
this.fallback = mode === 'history' && !supportsPushState && options.fallback !== false;
if (this.fallback) {
mode = 'hash';
}
if (!inBrowser) {
mode = 'abstract';
}
this.mode = mode;
switch (mode) {
case 'history':
this.history = new HTML5History(this, options.base);
break
case 'hash':
this.history = new HashHistory(this, options.base, this.fallback);
break
case 'abstract':
this.history = new AbstractHistory(this, options.base);
break
default:
{
assert(false, ("invalid mode: " + mode));
}
}
};
var prototypeAccessors = { currentRoute: { configurable: true } };
VueRouter.prototype.match = function match (
raw,
current,
redirectedFrom
) {
return this.matcher.match(raw, current, redirectedFrom)
};
prototypeAccessors.currentRoute.get = function () {
return this.history && this.history.current
};
VueRouter.prototype.init = function init (app /* Vue component instance */) {
var this$1 = this;
"development" !== 'production' && assert(
install.installed,
"not installed. Make sure to call `Vue.use(VueRouter)` " +
"before creating root instance."
);
this.apps.push(app);
// main app already initialized.
if (this.app) {
return
}
this.app = app;
var history = this.history;
if (history instanceof HTML5History) {
history.transitionTo(history.getCurrentLocation());
} else if (history instanceof HashHistory) {
var setupHashListener = function () {
history.setupListeners();
};
history.transitionTo(
history.getCurrentLocation(),
setupHashListener,
setupHashListener
);
}
history.listen(function (route) {
this$1.apps.forEach(function (app) {
app._route = route;
});
});
};
VueRouter.prototype.beforeEach = function beforeEach (fn) {
return registerHook(this.beforeHooks, fn)
};
VueRouter.prototype.beforeResolve = function beforeResolve (fn) {
return registerHook(this.resolveHooks, fn)
};
VueRouter.prototype.afterEach = function afterEach (fn) {
return registerHook(this.afterHooks, fn)
};
VueRouter.prototype.onReady = function onReady (cb, errorCb) {
this.history.onReady(cb, errorCb);
};
VueRouter.prototype.onError = function onError (errorCb) {
this.history.onError(errorCb);
};
VueRouter.prototype.push = function push (location, onComplete, onAbort) {
this.history.push(location, onComplete, onAbort);
};
VueRouter.prototype.replace = function replace (location, onComplete, onAbort) {
this.history.replace(location, onComplete, onAbort);
};
VueRouter.prototype.go = function go (n) {
this.history.go(n);
};
VueRouter.prototype.back = function back () {
this.go(-1);
};
VueRouter.prototype.forward = function forward () {
this.go(1);
};
VueRouter.prototype.getMatchedComponents = function getMatchedComponents (to) {
var route = to
? to.matched
? to
: this.resolve(to).route
: this.currentRoute;
if (!route) {
return []
}
return [].concat.apply([], route.matched.map(function (m) {
return Object.keys(m.components).map(function (key) {
return m.components[key]
})
}))
};
VueRouter.prototype.resolve = function resolve (
to,
current,
append
) {
var location = normalizeLocation(
to,
current || this.history.current,
append,
this
);
var route = this.match(location, current);
var fullPath = route.redirectedFrom || route.fullPath;
var base = this.history.base;
var href = createHref(base, fullPath, this.mode);
return {
location: location,
route: route,
href: href,
// for backwards compat
normalizedTo: location,
resolved: route
}
};
VueRouter.prototype.addRoutes = function addRoutes (routes) {
this.matcher.addRoutes(routes);
if (this.history.current !== START) {
this.history.transitionTo(this.history.getCurrentLocation());
}
};
Object.defineProperties( VueRouter.prototype, prototypeAccessors );
function registerHook (list, fn) {
list.push(fn);
return function () {
var i = list.indexOf(fn);
if (i > -1) { list.splice(i, 1); }
}
}
function createHref (base, fullPath, mode) {
var path = mode === 'hash' ? '#' + fullPath : fullPath;
return base ? cleanPath(base + '/' + path) : path
}
VueRouter.install = install;
VueRouter.version = '3.0.1';
if (inBrowser && window.Vue) {
window.Vue.use(VueRouter);
}
return VueRouter;
})));
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* vuex v2.4.1
* (c) 2017 Evan You
* @license MIT
*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Vuex=e()}(this,function(){"use strict";function t(t){b&&(t._devtoolHook=b,b.emit("vuex:init",t),b.on("vuex:travel-to-state",function(e){t.replaceState(e)}),t.subscribe(function(t,e){b.emit("vuex:mutation",t,e)}))}function e(t,e){Object.keys(t).forEach(function(n){return e(t[n],n)})}function n(t){return null!==t&&"object"==typeof t}function o(t){return t&&"function"==typeof t.then}function i(t,e,n){if(e.update(n),n.modules)for(var o in n.modules){if(!e.getChild(o))return;i(t.concat(o),e.getChild(o),n.modules[o])}}function r(t,e){t._actions=Object.create(null),t._mutations=Object.create(null),t._wrappedGetters=Object.create(null),t._modulesNamespaceMap=Object.create(null);var n=t.state;a(t,n,[],t._modules.root,!0),s(t,n,e)}function s(t,n,o){var i=t._vm;t.getters={};var r={};e(t._wrappedGetters,function(e,n){r[n]=function(){return e(t)},Object.defineProperty(t.getters,n,{get:function(){return t._vm[n]},enumerable:!0})});var s=j.config.silent;j.config.silent=!0,t._vm=new j({data:{$$state:n},computed:r}),j.config.silent=s,t.strict&&l(t),i&&(o&&t._withCommit(function(){i._data.$$state=null}),j.nextTick(function(){return i.$destroy()}))}function a(t,e,n,o,i){var r=!n.length,s=t._modules.getNamespace(n);if(o.namespaced&&(t._modulesNamespaceMap[s]=o),!r&&!i){var u=d(e,n.slice(0,-1)),l=n[n.length-1];t._withCommit(function(){j.set(u,l,o.state)})}var m=o.context=c(t,s,n);o.forEachMutation(function(e,n){f(t,s+n,e,m)}),o.forEachAction(function(e,n){p(t,s+n,e,m)}),o.forEachGetter(function(e,n){h(t,s+n,e,m)}),o.forEachChild(function(o,r){a(t,e,n.concat(r),o,i)})}function c(t,e,n){var o=""===e,i={dispatch:o?t.dispatch:function(n,o,i){var r=m(n,o,i),s=r.payload,a=r.options,c=r.type;return a&&a.root||(c=e+c),t.dispatch(c,s)},commit:o?t.commit:function(n,o,i){var r=m(n,o,i),s=r.payload,a=r.options,c=r.type;a&&a.root||(c=e+c),t.commit(c,s,a)}};return Object.defineProperties(i,{getters:{get:o?function(){return t.getters}:function(){return u(t,e)}},state:{get:function(){return d(t.state,n)}}}),i}function u(t,e){var n={},o=e.length;return Object.keys(t.getters).forEach(function(i){if(i.slice(0,o)===e){var r=i.slice(o);Object.defineProperty(n,r,{get:function(){return t.getters[i]},enumerable:!0})}}),n}function f(t,e,n,o){(t._mutations[e]||(t._mutations[e]=[])).push(function(e){n.call(t,o.state,e)})}function p(t,e,n,i){(t._actions[e]||(t._actions[e]=[])).push(function(e,r){var s=n.call(t,{dispatch:i.dispatch,commit:i.commit,getters:i.getters,state:i.state,rootGetters:t.getters,rootState:t.state},e,r);return o(s)||(s=Promise.resolve(s)),t._devtoolHook?s.catch(function(e){throw t._devtoolHook.emit("vuex:error",e),e}):s})}function h(t,e,n,o){t._wrappedGetters[e]||(t._wrappedGetters[e]=function(t){return n(o.state,o.getters,t.state,t.getters)})}function l(t){t._vm.$watch(function(){return this._data.$$state},function(){},{deep:!0,sync:!0})}function d(t,e){return e.length?e.reduce(function(t,e){return t[e]},t):t}function m(t,e,o){return n(t)&&t.type&&(o=e,e=t,t=t.type),{type:t,payload:e,options:o}}function v(t){j&&t===j||w(j=t)}function _(t){return Array.isArray(t)?t.map(function(t){return{key:t,val:t}}):Object.keys(t).map(function(e){return{key:e,val:t[e]}})}function y(t){return function(e,n){return"string"!=typeof e?(n=e,e=""):"/"!==e.charAt(e.length-1)&&(e+="/"),t(e,n)}}function g(t,e,n){var o=t._modulesNamespaceMap[n];return o}var w=function(t){function e(){var t=this.$options;t.store?this.$store="function"==typeof t.store?t.store():t.store:t.parent&&t.parent.$store&&(this.$store=t.parent.$store)}if(Number(t.version.split(".")[0])>=2)t.mixin({beforeCreate:e});else{var n=t.prototype._init;t.prototype._init=function(t){void 0===t&&(t={}),t.init=t.init?[e].concat(t.init):e,n.call(this,t)}}},b="undefined"!=typeof window&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__,$=function(t,e){this.runtime=e,this._children=Object.create(null),this._rawModule=t;var n=t.state;this.state=("function"==typeof n?n():n)||{}},M={namespaced:{configurable:!0}};M.namespaced.get=function(){return!!this._rawModule.namespaced},$.prototype.addChild=function(t,e){this._children[t]=e},$.prototype.removeChild=function(t){delete this._children[t]},$.prototype.getChild=function(t){return this._children[t]},$.prototype.update=function(t){this._rawModule.namespaced=t.namespaced,t.actions&&(this._rawModule.actions=t.actions),t.mutations&&(this._rawModule.mutations=t.mutations),t.getters&&(this._rawModule.getters=t.getters)},$.prototype.forEachChild=function(t){e(this._children,t)},$.prototype.forEachGetter=function(t){this._rawModule.getters&&e(this._rawModule.getters,t)},$.prototype.forEachAction=function(t){this._rawModule.actions&&e(this._rawModule.actions,t)},$.prototype.forEachMutation=function(t){this._rawModule.mutations&&e(this._rawModule.mutations,t)},Object.defineProperties($.prototype,M);var O=function(t){this.register([],t,!1)};O.prototype.get=function(t){return t.reduce(function(t,e){return t.getChild(e)},this.root)},O.prototype.getNamespace=function(t){var e=this.root;return t.reduce(function(t,n){return e=e.getChild(n),t+(e.namespaced?n+"/":"")},"")},O.prototype.update=function(t){i([],this.root,t)},O.prototype.register=function(t,n,o){var i=this;void 0===o&&(o=!0);var r=new $(n,o);0===t.length?this.root=r:this.get(t.slice(0,-1)).addChild(t[t.length-1],r),n.modules&&e(n.modules,function(e,n){i.register(t.concat(n),e,o)})},O.prototype.unregister=function(t){var e=this.get(t.slice(0,-1)),n=t[t.length-1];e.getChild(n).runtime&&e.removeChild(n)};var j,C=function(e){var n=this;void 0===e&&(e={}),!j&&"undefined"!=typeof window&&window.Vue&&v(window.Vue);var o=e.plugins;void 0===o&&(o=[]);var i=e.strict;void 0===i&&(i=!1);var r=e.state;void 0===r&&(r={}),"function"==typeof r&&(r=r()),this._committing=!1,this._actions=Object.create(null),this._mutations=Object.create(null),this._wrappedGetters=Object.create(null),this._modules=new O(e),this._modulesNamespaceMap=Object.create(null),this._subscribers=[],this._watcherVM=new j;var c=this,u=this,f=u.dispatch,p=u.commit;this.dispatch=function(t,e){return f.call(c,t,e)},this.commit=function(t,e,n){return p.call(c,t,e,n)},this.strict=i,a(this,r,[],this._modules.root),s(this,r),o.forEach(function(t){return t(n)}),j.config.devtools&&t(this)},E={state:{configurable:!0}};E.state.get=function(){return this._vm._data.$$state},E.state.set=function(t){},C.prototype.commit=function(t,e,n){var o=this,i=m(t,e,n),r=i.type,s=i.payload,a=(i.options,{type:r,payload:s}),c=this._mutations[r];c&&(this._withCommit(function(){c.forEach(function(t){t(s)})}),this._subscribers.forEach(function(t){return t(a,o.state)}))},C.prototype.dispatch=function(t,e){var n=m(t,e),o=n.type,i=n.payload,r=this._actions[o];if(r)return r.length>1?Promise.all(r.map(function(t){return t(i)})):r[0](i)},C.prototype.subscribe=function(t){var e=this._subscribers;return e.indexOf(t)<0&&e.push(t),function(){var n=e.indexOf(t);n>-1&&e.splice(n,1)}},C.prototype.watch=function(t,e,n){var o=this;return this._watcherVM.$watch(function(){return t(o.state,o.getters)},e,n)},C.prototype.replaceState=function(t){var e=this;this._withCommit(function(){e._vm._data.$$state=t})},C.prototype.registerModule=function(t,e){"string"==typeof t&&(t=[t]),this._modules.register(t,e),a(this,this.state,t,this._modules.get(t)),s(this,this.state)},C.prototype.unregisterModule=function(t){var e=this;"string"==typeof t&&(t=[t]),this._modules.unregister(t),this._withCommit(function(){var n=d(e.state,t.slice(0,-1));j.delete(n,t[t.length-1])}),r(this)},C.prototype.hotUpdate=function(t){this._modules.update(t),r(this,!0)},C.prototype._withCommit=function(t){var e=this._committing;this._committing=!0,t(),this._committing=e},Object.defineProperties(C.prototype,E);var x=y(function(t,e){var n={};return _(e).forEach(function(e){var o=e.key,i=e.val;n[o]=function(){var e=this.$store.state,n=this.$store.getters;if(t){var o=g(this.$store,0,t);if(!o)return;e=o.context.state,n=o.context.getters}return"function"==typeof i?i.call(this,e,n):e[i]},n[o].vuex=!0}),n}),k=y(function(t,e){var n={};return _(e).forEach(function(e){var o=e.key,i=e.val;n[o]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var o=this.$store.commit;if(t){var r=g(this.$store,0,t);if(!r)return;o=r.context.commit}return"function"==typeof i?i.apply(this,[o].concat(e)):o.apply(this.$store,[i].concat(e))}}),n}),G=y(function(t,e){var n={};return _(e).forEach(function(e){var o=e.key,i=e.val;i=t+i,n[o]=function(){if(!t||g(this.$store,0,t))return this.$store.getters[i]},n[o].vuex=!0}),n}),A=y(function(t,e){var n={};return _(e).forEach(function(e){var o=e.key,i=e.val;n[o]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var o=this.$store.dispatch;if(t){var r=g(this.$store,0,t);if(!r)return;o=r.context.dispatch}return"function"==typeof i?i.apply(this,[o].concat(e)):o.apply(this.$store,[i].concat(e))}}),n});return{Store:C,install:v,version:"2.4.1",mapState:x,mapMutations:k,mapGetters:G,mapActions:A,createNamespacedHelpers:function(t){return{mapState:x.bind(null,t),mapGetters:G.bind(null,t),mapMutations:k.bind(null,t),mapActions:A.bind(null,t)}}}});
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<link rel="stylesheet" href="<%= BASE_URL %>cdn/element-ui/2.4.0/theme-chalk/index.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/animate/3.5.2/animate.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/1.0.0/index.css">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>Avue 通用管理 系统快速开发框架</title>
</head>
<body>
<noscript>
<strong>We're sorry but avue2.0 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script src="<%= BASE_URL %>util/aes.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>util/aes.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>util/crypto-js.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>util/mode-ecb.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>util/pad-zeropadding.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/vue/2.5.2/vue.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/vuex/2.4.1/vuex.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/vue-router/3.0.1/vue-router.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/axios/1.0.0/axios.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/element-ui/2.4.0/index.js" charset="utf-8"></script>
</body>
</html>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="186px" height="49.5px" viewBox="0 0 186 49.5" style="enable-background:new 0 0 186 49.5;" xml:space="preserve">
<style type="text/css">
.st0{fill:#333;}
</style>
<g>
<polygon class="st0" points="76.6,1.7 71.7,1.7 71.7,33 87.5,33 87.5,28.1 76.6,28.1 "/>
<path class="st0" d="M114.2,6.3c-3.1-3.1-6.8-4.6-11.1-4.6c-4.3,0-8,1.5-11.1,4.6C89,9.3,87.5,13,87.5,17.3c0,4.3,1.6,8,4.6,11
c3.1,3.1,6.8,4.6,11.1,4.6c4.3,0,8-1.5,11.1-4.6c3-3.1,4.6-6.8,4.6-11C118.8,13,117.3,9.3,114.2,6.3z M110.8,25
c-2.1,2.1-4.7,3.2-7.7,3.2c-3,0-5.5-1.1-7.6-3.2c-2.1-2.1-3.2-4.7-3.2-7.6c0-3,1.1-5.5,3.2-7.7c2.1-2.1,4.7-3.2,7.6-3.2
c3,0,5.5,1.1,7.7,3.2c2.1,2.1,3.2,4.7,3.2,7.7C114,20.3,112.9,22.9,110.8,25z"/>
<path class="st0" d="M181.4,28.4c3.1-3.1,4.6-6.8,4.6-11c0-4.3-1.5-8-4.6-11.1c-3.1-3.1-6.8-4.6-11.1-4.6c-4.3,0-8,1.5-11.1,4.6
c-3.1,3.1-4.6,6.8-4.6,11.1c0,4.3,1.6,8,4.6,11c3.1,3.1,6.8,4.6,11.1,4.6C174.6,33,178.4,31.4,181.4,28.4z M159.5,17.3
c0-3,1.1-5.5,3.2-7.7c2.1-2.1,4.7-3.2,7.6-3.2c3,0,5.5,1.1,7.7,3.2c2.1,2.1,3.2,4.7,3.2,7.7c0,3-1.1,5.5-3.2,7.6
c-2.1,2.1-4.7,3.2-7.7,3.2c-3,0-5.5-1.1-7.6-3.2C160.6,22.9,159.5,20.3,159.5,17.3z"/>
<path class="st0" d="M147.7,28.4c1.6-1.6,2.8-3.3,3.5-5.3c0.2-0.6,1.1-2.8,1.1-5.8c0-1-0.1-1.8-0.2-2.4c-5.2,0-10.3,0-15.5,0
c0,1.6,0,3.2,0,4.8h10.6c-0.4,2-1.4,3.7-2.9,5.2c-2.1,2.1-4.7,3.2-7.7,3.2c-3,0-5.5-1.1-7.6-3.2c-2.1-2.1-3.2-4.7-3.2-7.6
c0-3,1.1-5.5,3.2-7.7c2.1-2.1,4.7-3.2,7.6-3.2c2.2,0,4.2,0.6,6,1.8l3.5-3.5c-2.7-2.1-5.9-3.2-9.4-3.2c-4.3,0-8,1.5-11.1,4.6
c-3.1,3.1-4.6,6.8-4.6,11.1c0,4.3,1.6,8,4.6,11c3.1,3.1,6.8,4.6,11.1,4.6C140.9,33,144.6,31.4,147.7,28.4z"/>
</g>
</svg>
!function(t,n){"object"==typeof exports?module.exports=exports=n():"function"==typeof define&&define.amd?define([],n):t.CryptoJS=n()}(this,function(){var t=t||function(t,n){var i=Object.create||function(){function t(){}return function(n){var i;return t.prototype=n,i=new t,t.prototype=null,i}}(),e={},r=e.lib={},o=r.Base=function(){return{extend:function(t){var n=i(this);return t&&n.mixIn(t),n.hasOwnProperty("init")&&this.init!==n.init||(n.init=function(){n.$super.init.apply(this,arguments)}),n.init.prototype=n,n.$super=this,n},create:function(){var t=this.extend();return t.init.apply(t,arguments),t},init:function(){},mixIn:function(t){for(var n in t)t.hasOwnProperty(n)&&(this[n]=t[n]);t.hasOwnProperty("toString")&&(this.toString=t.toString)},clone:function(){return this.init.prototype.extend(this)}}}(),s=r.WordArray=o.extend({init:function(t,i){t=this.words=t||[],i!=n?this.sigBytes=i:this.sigBytes=4*t.length},toString:function(t){return(t||c).stringify(this)},concat:function(t){var n=this.words,i=t.words,e=this.sigBytes,r=t.sigBytes;if(this.clamp(),e%4)for(var o=0;o<r;o++){var s=i[o>>>2]>>>24-o%4*8&255;n[e+o>>>2]|=s<<24-(e+o)%4*8}else for(var o=0;o<r;o+=4)n[e+o>>>2]=i[o>>>2];return this.sigBytes+=r,this},clamp:function(){var n=this.words,i=this.sigBytes;n[i>>>2]&=4294967295<<32-i%4*8,n.length=t.ceil(i/4)},clone:function(){var t=o.clone.call(this);return t.words=this.words.slice(0),t},random:function(n){for(var i,e=[],r=function(n){var n=n,i=987654321,e=4294967295;return function(){i=36969*(65535&i)+(i>>16)&e,n=18e3*(65535&n)+(n>>16)&e;var r=(i<<16)+n&e;return r/=4294967296,r+=.5,r*(t.random()>.5?1:-1)}},o=0;o<n;o+=4){var a=r(4294967296*(i||t.random()));i=987654071*a(),e.push(4294967296*a()|0)}return new s.init(e,n)}}),a=e.enc={},c=a.Hex={stringify:function(t){for(var n=t.words,i=t.sigBytes,e=[],r=0;r<i;r++){var o=n[r>>>2]>>>24-r%4*8&255;e.push((o>>>4).toString(16)),e.push((15&o).toString(16))}return e.join("")},parse:function(t){for(var n=t.length,i=[],e=0;e<n;e+=2)i[e>>>3]|=parseInt(t.substr(e,2),16)<<24-e%8*4;return new s.init(i,n/2)}},u=a.Latin1={stringify:function(t){for(var n=t.words,i=t.sigBytes,e=[],r=0;r<i;r++){var o=n[r>>>2]>>>24-r%4*8&255;e.push(String.fromCharCode(o))}return e.join("")},parse:function(t){for(var n=t.length,i=[],e=0;e<n;e++)i[e>>>2]|=(255&t.charCodeAt(e))<<24-e%4*8;return new s.init(i,n)}},f=a.Utf8={stringify:function(t){try{return decodeURIComponent(escape(u.stringify(t)))}catch(t){throw new Error("Malformed UTF-8 data")}},parse:function(t){return u.parse(unescape(encodeURIComponent(t)))}},h=r.BufferedBlockAlgorithm=o.extend({reset:function(){this._data=new s.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=f.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(n){var i=this._data,e=i.words,r=i.sigBytes,o=this.blockSize,a=4*o,c=r/a;c=n?t.ceil(c):t.max((0|c)-this._minBufferSize,0);var u=c*o,f=t.min(4*u,r);if(u){for(var h=0;h<u;h+=o)this._doProcessBlock(e,h);var p=e.splice(0,u);i.sigBytes-=f}return new s.init(p,f)},clone:function(){var t=o.clone.call(this);return t._data=this._data.clone(),t},_minBufferSize:0}),p=(r.Hasher=h.extend({cfg:o.extend(),init:function(t){this.cfg=this.cfg.extend(t),this.reset()},reset:function(){h.reset.call(this),this._doReset()},update:function(t){return this._append(t),this._process(),this},finalize:function(t){t&&this._append(t);var n=this._doFinalize();return n},blockSize:16,_createHelper:function(t){return function(n,i){return new t.init(i).finalize(n)}},_createHmacHelper:function(t){return function(n,i){return new p.HMAC.init(t,i).finalize(n)}}}),e.algo={});return e}(Math);return t});
//# sourceMappingURL=core.min.js.map
!function(e,t,i){"object"==typeof exports?module.exports=exports=t(require("./core.min"),require("./sha1.min"),require("./hmac.min")):"function"==typeof define&&define.amd?define(["./core.min","./sha1.min","./hmac.min"],t):t(e.CryptoJS)}(this,function(e){return function(){var t=e,i=t.lib,r=i.Base,n=i.WordArray,o=t.algo,a=o.MD5,c=o.EvpKDF=r.extend({cfg:r.extend({keySize:4,hasher:a,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var i=this.cfg,r=i.hasher.create(),o=n.create(),a=o.words,c=i.keySize,f=i.iterations;a.length<c;){s&&r.update(s);var s=r.update(e).finalize(t);r.reset();for(var u=1;u<f;u++)s=r.finalize(s),r.reset();o.concat(s)}return o.sigBytes=4*c,o}});t.EvpKDF=function(e,t,i){return c.create(i).compute(e,t)}}(),e.EvpKDF});
//# sourceMappingURL=evpkdf.min.js.map
!function(r,e){"object"==typeof exports?module.exports=exports=e(require("./core.min")):"function"==typeof define&&define.amd?define(["./core.min"],e):e(r.CryptoJS)}(this,function(r){return function(){function e(r,e,t){for(var n=[],i=0,o=0;o<e;o++)if(o%4){var f=t[r.charCodeAt(o-1)]<<o%4*2,c=t[r.charCodeAt(o)]>>>6-o%4*2;n[i>>>2]|=(f|c)<<24-i%4*8,i++}return a.create(n,i)}var t=r,n=t.lib,a=n.WordArray,i=t.enc;i.Base64={stringify:function(r){var e=r.words,t=r.sigBytes,n=this._map;r.clamp();for(var a=[],i=0;i<t;i+=3)for(var o=e[i>>>2]>>>24-i%4*8&255,f=e[i+1>>>2]>>>24-(i+1)%4*8&255,c=e[i+2>>>2]>>>24-(i+2)%4*8&255,s=o<<16|f<<8|c,h=0;h<4&&i+.75*h<t;h++)a.push(n.charAt(s>>>6*(3-h)&63));var p=n.charAt(64);if(p)for(;a.length%4;)a.push(p);return a.join("")},parse:function(r){var t=r.length,n=this._map,a=this._reverseMap;if(!a){a=this._reverseMap=[];for(var i=0;i<n.length;i++)a[n.charCodeAt(i)]=i}var o=n.charAt(64);if(o){var f=r.indexOf(o);f!==-1&&(t=f)}return e(r,t,a)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}}(),r.enc.Base64});
//# sourceMappingURL=enc-base64.min.js.map
!function(e,t,r){"object"==typeof exports?module.exports=exports=t(require("./core.min"),require("./evpkdf.min")):"function"==typeof define&&define.amd?define(["./core.min","./evpkdf.min"],t):t(e.CryptoJS)}(this,function(e){e.lib.Cipher||function(t){var r=e,i=r.lib,n=i.Base,c=i.WordArray,o=i.BufferedBlockAlgorithm,s=r.enc,a=(s.Utf8,s.Base64),f=r.algo,p=f.EvpKDF,d=i.Cipher=o.extend({cfg:n.extend(),createEncryptor:function(e,t){return this.create(this._ENC_XFORM_MODE,e,t)},createDecryptor:function(e,t){return this.create(this._DEC_XFORM_MODE,e,t)},init:function(e,t,r){this.cfg=this.cfg.extend(r),this._xformMode=e,this._key=t,this.reset()},reset:function(){o.reset.call(this),this._doReset()},process:function(e){return this._append(e),this._process()},finalize:function(e){e&&this._append(e);var t=this._doFinalize();return t},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(){function e(e){return"string"==typeof e?B:x}return function(t){return{encrypt:function(r,i,n){return e(i).encrypt(t,r,i,n)},decrypt:function(r,i,n){return e(i).decrypt(t,r,i,n)}}}}()}),h=(i.StreamCipher=d.extend({_doFinalize:function(){var e=this._process(!0);return e},blockSize:1}),r.mode={}),u=i.BlockCipherMode=n.extend({createEncryptor:function(e,t){return this.Encryptor.create(e,t)},createDecryptor:function(e,t){return this.Decryptor.create(e,t)},init:function(e,t){this._cipher=e,this._iv=t}}),l=h.CBC=function(){function e(e,r,i){var n=this._iv;if(n){var c=n;this._iv=t}else var c=this._prevBlock;for(var o=0;o<i;o++)e[r+o]^=c[o]}var r=u.extend();return r.Encryptor=r.extend({processBlock:function(t,r){var i=this._cipher,n=i.blockSize;e.call(this,t,r,n),i.encryptBlock(t,r),this._prevBlock=t.slice(r,r+n)}}),r.Decryptor=r.extend({processBlock:function(t,r){var i=this._cipher,n=i.blockSize,c=t.slice(r,r+n);i.decryptBlock(t,r),e.call(this,t,r,n),this._prevBlock=c}}),r}(),_=r.pad={},v=_.Pkcs7={pad:function(e,t){for(var r=4*t,i=r-e.sigBytes%r,n=i<<24|i<<16|i<<8|i,o=[],s=0;s<i;s+=4)o.push(n);var a=c.create(o,i);e.concat(a)},unpad:function(e){var t=255&e.words[e.sigBytes-1>>>2];e.sigBytes-=t}},y=(i.BlockCipher=d.extend({cfg:d.cfg.extend({mode:l,padding:v}),reset:function(){d.reset.call(this);var e=this.cfg,t=e.iv,r=e.mode;if(this._xformMode==this._ENC_XFORM_MODE)var i=r.createEncryptor;else{var i=r.createDecryptor;this._minBufferSize=1}this._mode&&this._mode.__creator==i?this._mode.init(this,t&&t.words):(this._mode=i.call(r,this,t&&t.words),this._mode.__creator=i)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else{var t=this._process(!0);e.unpad(t)}return t},blockSize:4}),i.CipherParams=n.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}})),m=r.format={},k=m.OpenSSL={stringify:function(e){var t=e.ciphertext,r=e.salt;if(r)var i=c.create([1398893684,1701076831]).concat(r).concat(t);else var i=t;return i.toString(a)},parse:function(e){var t=a.parse(e),r=t.words;if(1398893684==r[0]&&1701076831==r[1]){var i=c.create(r.slice(2,4));r.splice(0,4),t.sigBytes-=16}return y.create({ciphertext:t,salt:i})}},x=i.SerializableCipher=n.extend({cfg:n.extend({format:k}),encrypt:function(e,t,r,i){i=this.cfg.extend(i);var n=e.createEncryptor(r,i),c=n.finalize(t),o=n.cfg;return y.create({ciphertext:c,key:r,iv:o.iv,algorithm:e,mode:o.mode,padding:o.padding,blockSize:e.blockSize,formatter:i.format})},decrypt:function(e,t,r,i){i=this.cfg.extend(i),t=this._parse(t,i.format);var n=e.createDecryptor(r,i).finalize(t.ciphertext);return n},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}}),g=r.kdf={},S=g.OpenSSL={execute:function(e,t,r,i){i||(i=c.random(8));var n=p.create({keySize:t+r}).compute(e,i),o=c.create(n.words.slice(t),4*r);return n.sigBytes=4*t,y.create({key:n,iv:o,salt:i})}},B=i.PasswordBasedCipher=x.extend({cfg:x.cfg.extend({kdf:S}),encrypt:function(e,t,r,i){i=this.cfg.extend(i);var n=i.kdf.execute(r,e.keySize,e.ivSize);i.iv=n.iv;var c=x.encrypt.call(this,e,t,n.key,i);return c.mixIn(n),c},decrypt:function(e,t,r,i){i=this.cfg.extend(i),t=this._parse(t,i.format);var n=i.kdf.execute(r,e.keySize,e.ivSize,t.salt);i.iv=n.iv;var c=x.decrypt.call(this,e,t,n.key,i);return c}})}()});
//# sourceMappingURL=cipher-core.min.js.map
!function(e,i){"object"==typeof exports?module.exports=exports=i(require("./core.min")):"function"==typeof define&&define.amd?define(["./core.min"],i):i(e.CryptoJS)}(this,function(e){!function(){var i=e,t=i.lib,n=t.Base,s=i.enc,r=s.Utf8,o=i.algo;o.HMAC=n.extend({init:function(e,i){e=this._hasher=new e.init,"string"==typeof i&&(i=r.parse(i));var t=e.blockSize,n=4*t;i.sigBytes>n&&(i=e.finalize(i)),i.clamp();for(var s=this._oKey=i.clone(),o=this._iKey=i.clone(),a=s.words,f=o.words,c=0;c<t;c++)a[c]^=1549556828,f[c]^=909522486;s.sigBytes=o.sigBytes=n,this.reset()},reset:function(){var e=this._hasher;e.reset(),e.update(this._iKey)},update:function(e){return this._hasher.update(e),this},finalize:function(e){var i=this._hasher,t=i.finalize(e);i.reset();var n=i.finalize(this._oKey.clone().concat(t));return n}})}()});
//# sourceMappingURL=hmac.min.js.map
!function(e,o,r){"object"==typeof exports?module.exports=exports=o(require("./core.min"),require("./cipher-core.min")):"function"==typeof define&&define.amd?define(["./core.min","./cipher-core.min"],o):o(e.CryptoJS)}(this,function(e){return e.mode.ECB=function(){var o=e.lib.BlockCipherMode.extend();return o.Encryptor=o.extend({processBlock:function(e,o){this._cipher.encryptBlock(e,o)}}),o.Decryptor=o.extend({processBlock:function(e,o){this._cipher.decryptBlock(e,o)}}),o}(),e.mode.ECB});
//# sourceMappingURL=mode-ecb.min.js.map
!function(e,r,i){"object"==typeof exports?module.exports=exports=r(require("./core.min"),require("./cipher-core.min")):"function"==typeof define&&define.amd?define(["./core.min","./cipher-core.min"],r):r(e.CryptoJS)}(this,function(e){return e.pad.Pkcs7});
//# sourceMappingURL=pad-pkcs7.min.js.map
!function(e,r,i){"object"==typeof exports?module.exports=exports=r(require("./core.min"),require("./enc-base64.min"),require("./md5.min"),require("./evpkdf.min"),require("./cipher-core.min")):"function"==typeof define&&define.amd?define(["./core.min","./enc-base64.min","./md5.min","./evpkdf.min","./cipher-core.min"],r):r(e.CryptoJS)}(this,function(e){return function(){var r=e,i=r.lib,n=i.BlockCipher,o=r.algo,t=[],c=[],s=[],f=[],a=[],d=[],u=[],v=[],h=[],y=[];!function(){for(var e=[],r=0;r<256;r++)r<128?e[r]=r<<1:e[r]=r<<1^283;for(var i=0,n=0,r=0;r<256;r++){var o=n^n<<1^n<<2^n<<3^n<<4;o=o>>>8^255&o^99,t[i]=o,c[o]=i;var p=e[i],l=e[p],_=e[l],k=257*e[o]^16843008*o;s[i]=k<<24|k>>>8,f[i]=k<<16|k>>>16,a[i]=k<<8|k>>>24,d[i]=k;var k=16843009*_^65537*l^257*p^16843008*i;u[o]=k<<24|k>>>8,v[o]=k<<16|k>>>16,h[o]=k<<8|k>>>24,y[o]=k,i?(i=p^e[e[e[_^p]]],n^=e[e[n]]):i=n=1}}();var p=[0,1,2,4,8,16,32,64,128,27,54],l=o.AES=n.extend({_doReset:function(){if(!this._nRounds||this._keyPriorReset!==this._key){for(var e=this._keyPriorReset=this._key,r=e.words,i=e.sigBytes/4,n=this._nRounds=i+6,o=4*(n+1),c=this._keySchedule=[],s=0;s<o;s++)if(s<i)c[s]=r[s];else{var f=c[s-1];s%i?i>6&&s%i==4&&(f=t[f>>>24]<<24|t[f>>>16&255]<<16|t[f>>>8&255]<<8|t[255&f]):(f=f<<8|f>>>24,f=t[f>>>24]<<24|t[f>>>16&255]<<16|t[f>>>8&255]<<8|t[255&f],f^=p[s/i|0]<<24),c[s]=c[s-i]^f}for(var a=this._invKeySchedule=[],d=0;d<o;d++){var s=o-d;if(d%4)var f=c[s];else var f=c[s-4];d<4||s<=4?a[d]=f:a[d]=u[t[f>>>24]]^v[t[f>>>16&255]]^h[t[f>>>8&255]]^y[t[255&f]]}}},encryptBlock:function(e,r){this._doCryptBlock(e,r,this._keySchedule,s,f,a,d,t)},decryptBlock:function(e,r){var i=e[r+1];e[r+1]=e[r+3],e[r+3]=i,this._doCryptBlock(e,r,this._invKeySchedule,u,v,h,y,c);var i=e[r+1];e[r+1]=e[r+3],e[r+3]=i},_doCryptBlock:function(e,r,i,n,o,t,c,s){for(var f=this._nRounds,a=e[r]^i[0],d=e[r+1]^i[1],u=e[r+2]^i[2],v=e[r+3]^i[3],h=4,y=1;y<f;y++){var p=n[a>>>24]^o[d>>>16&255]^t[u>>>8&255]^c[255&v]^i[h++],l=n[d>>>24]^o[u>>>16&255]^t[v>>>8&255]^c[255&a]^i[h++],_=n[u>>>24]^o[v>>>16&255]^t[a>>>8&255]^c[255&d]^i[h++],k=n[v>>>24]^o[a>>>16&255]^t[d>>>8&255]^c[255&u]^i[h++];a=p,d=l,u=_,v=k}var p=(s[a>>>24]<<24|s[d>>>16&255]<<16|s[u>>>8&255]<<8|s[255&v])^i[h++],l=(s[d>>>24]<<24|s[u>>>16&255]<<16|s[v>>>8&255]<<8|s[255&a])^i[h++],_=(s[u>>>24]<<24|s[v>>>16&255]<<16|s[a>>>8&255]<<8|s[255&d])^i[h++],k=(s[v>>>24]<<24|s[a>>>16&255]<<16|s[d>>>8&255]<<8|s[255&u])^i[h++];e[r]=p,e[r+1]=l,e[r+2]=_,e[r+3]=k},keySize:8});r.AES=n._createHelper(l)}(),e.AES});
//# sourceMappingURL=aes.min.js.map
!function(e,n){"object"==typeof exports?module.exports=exports=n(require("./core.min")):"function"==typeof define&&define.amd?define(["./core.min"],n):n(e.CryptoJS)}(this,function(e){return e.enc.Utf8});
//# sourceMappingURL=enc-utf8.min.js.map
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
CryptoJS.mode.ECB=function(){var a=CryptoJS.lib.BlockCipherMode.extend();a.Encryptor=a.extend({processBlock:function(a,b){this._cipher.encryptBlock(a,b)}});a.Decryptor=a.extend({processBlock:function(a,b){this._cipher.decryptBlock(a,b)}});return a}();
/**
* Zero padding strategy.
*/
CryptoJS.pad.ZeroPadding = {
pad: function (data, blockSize) {
// Shortcut
var blockSizeBytes = blockSize * 4;
// Pad
data.clamp();
data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);
},
unpad: function (data) {
// Shortcut
var dataWords = data.words;
// Unpad
var i = data.sigBytes - 1;
while (!((dataWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff)) {
i--;
}
data.sigBytes = i + 1;
}
};
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {}
},
watch: {},
created () { },
methods: {},
computed: {}
}
</script>
<style lang="scss">
#app {
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
\ No newline at end of file
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export function fetchList(query) {
return request({
url: '/admin/client/page',
method: 'get',
params: query
})
}
export function addObj(obj) {
return request({
url: '/admin/client/',
method: 'post',
data: obj
})
}
export function getObj(id) {
return request({
url: '/admin/client/' + id,
method: 'get'
})
}
export function delObj(id) {
return request({
url: '/admin/client/' + id,
method: 'delete'
})
}
export function putObj(obj) {
return request({
url: '/admin/client',
method: 'put',
data: obj
})
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export function fetchTree(query) {
return request({
url: '/admin/dept/tree',
method: 'get',
params: query
})
}
export function addObj(obj) {
return request({
url: '/admin/dept/',
method: 'post',
data: obj
})
}
export function getObj(id) {
return request({
url: '/admin/dept/' + id,
method: 'get'
})
}
export function delObj(id) {
return request({
url: '/admin/dept/' + id,
method: 'delete'
})
}
export function putObj(obj) {
return request({
url: '/admin/dept/',
method: 'put',
data: obj
})
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export function fetchList(query) {
return request({
url: '/admin/dict/dictPage',
method: 'get',
params: query
})
}
export function addObj(obj) {
return request({
url: '/admin/dict/',
method: 'post',
data: obj
})
}
export function getObj(id) {
return request({
url: '/admin/dict/' + id,
method: 'get'
})
}
export function delObj(row) {
return request({
url: '/admin/dict/' + row.id + '/' + row.type,
method: 'delete'
})
}
export function putObj(obj) {
return request({
url: '/admin/dict/',
method: 'put',
data: obj
})
}
export function remote(type) {
return request({
url: '/admin/dict/type/' + type,
method: 'get'
})
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export function fetchList(query) {
return request({
url: '/gen/generator/page',
method: 'get',
params: query
})
}
export function handleDown(table) {
request({
url: '/gen/generator/code',
method: 'post',
data: table,
responseType: 'arraybuffer'
}).then((response) => { // 处理返回的文件流
let blob = new Blob([response.data], { type: 'application/zip' } )
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = table.tableName + '.zip'
link.click()
})
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export function fetchList(query) {
return request({
url: '/admin/log/logPage',
method: 'get',
params: query
})
}
export function delObj(id) {
return request({
url: '/admin/log/' + id,
method: 'delete'
})
}
export function addObj(obj) {
return request({
url: '/admin/log/',
method: 'post',
data: obj
})
}
export function getObj(id) {
return request({
url: '/admin/log/' + id,
method: 'get'
})
}
export function putObj(obj) {
return request({
url: '/admin/log/',
method: 'put',
data: obj
})
}
export function sendLogs(logsList) {
return request({
url: '/admin/log/logs',
method: 'post',
data: logsList
})
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export const loginByUsername = (username, password, code, randomStr) => {
var grant_type = 'password'
var scope = 'server'
return request({
url: '/auth/oauth/token',
headers: {
'TENANT_ID': '1',
'Authorization': 'Basic cGlnOnBpZw=='
},
method: 'post',
params: { username, password, randomStr, code, grant_type, scope }
})
}
export const loginBySocial = (state, code) => {
var grant_type = 'mobile'
return request({
url: '/auth/mobile/token',
headers: {
'TENANT_ID': '1',
'Authorization': 'Basic cGlnOnBpZw=='
},
method: 'post',
params: { mobile: state + '@' + code, grant_type }
})
}
export const getUserInfo = () => {
return request({
url: '/admin/user/info',
method: 'get'
})
}
export const logout = () => {
return request({
url: '/auth/oauth/removeToken',
method: 'get'
})
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export function GetMenu() {
return request({
url: '/admin/menu/userMenu',
method: 'get'
})
}
export function fetchTree(query) {
return request({
url: '/admin/menu/allTree',
method: 'get',
params: query
})
}
export function addObj(obj) {
return request({
url: '/admin/menu/',
method: 'post',
data: obj
})
}
export function getObj(id) {
return request({
url: '/admin/menu/' + id,
method: 'get'
})
}
export function delObj(id) {
return request({
url: '/admin/menu/' + id,
method: 'delete'
})
}
export function putObj(obj) {
return request({
url: '/admin/menu/',
method: 'put',
data: obj
})
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export function getToken() {
return request({
url: '/zuul/admin/user/upload', // 假地址,自行替换
method: 'post'
})
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export function roleList() {
return request({
url: '/admin/role/roleList',
method: 'get'
})
}
export function fetchList(query) {
return request({
url: '/admin/role/rolePage',
method: 'get',
params: query
})
}
export function deptRoleList(deptId) {
return request({
url: '/admin/role/roleList/' + deptId,
method: 'get'
})
}
export function getObj(id) {
return request({
url: '/admin/role/' + id,
method: 'get'
})
}
export function addObj(obj) {
return request({
url: '/admin/role',
method: 'post',
data: obj
})
}
export function putObj(obj) {
return request({
url: '/admin/role',
method: 'put',
data: obj
})
}
export function delObj(id) {
return request({
url: '/admin/role/' + id,
method: 'delete'
})
}
export function permissionUpd(roleId, menuIds) {
return request({
url: '/admin/role/roleMenuUpd',
method: 'put',
params: {
roleId: roleId,
menuIds: menuIds
}
})
}
export function fetchRoleTree(roleName) {
return request({
url: '/admin/menu/roleTree/' + roleName,
method: 'get'
})
}
export function fetchDeptTree(query) {
return request({
url: '/admin/dept/tree',
method: 'get',
params: query
})
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export function fetchList(query) {
return request({
url: '/admin/route/page',
method: 'get',
params: query
})
}
export function addObj(obj) {
return request({
url: '/admin/route/',
method: 'post',
data: obj
})
}
export function getObj(id) {
return request({
url: '/admin/route/' + id,
method: 'get'
})
}
export function delObj(id) {
return request({
url: '/admin/route/' + id,
method: 'delete'
})
}
export function putObj(obj) {
return request({
url: '/admin/route',
method: 'put',
data: obj
})
}
export function applyObj() {
return request({
url: '/admin/route/apply',
method: 'get'
})
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export function fetchList(query) {
return request({
url: '/daemon/statustracelog/page',
method: 'get',
params: query
})
}
export function addObj(obj) {
return request({
url: '/daemon/statustracelog/',
method: 'post',
data: obj
})
}
export function getObj(id) {
return request({
url: '/daemon/statustracelog/' + id,
method: 'get'
})
}
export function delObj(id) {
return request({
url: '/daemon/statustracelog/' + id,
method: 'delete'
})
}
export function putObj(obj) {
return request({
url: '/daemon/statustracelog/',
method: 'put',
data: obj
})
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export function fetchList(query) {
return request({
url: '/admin/social/page',
method: 'get',
params: query
})
}
export function addObj(obj) {
return request({
url: '/admin/social/',
method: 'post',
data: obj
})
}
export function getObj(id) {
return request({
url: '/admin/social/' + id,
method: 'get'
})
}
export function delObj(id) {
return request({
url: '/admin/social/' + id,
method: 'delete'
})
}
export function putObj(obj) {
return request({
url: '/admin/social/',
method: 'put',
data: obj
})
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
import request from '@/router/axios'
export function fetchList(query) {
return request({
url: '/admin/user/userPage',
method: 'get',
params: query
})
}
export function addObj(obj) {
return request({
url: '/admin/user/',
method: 'post',
data: obj
})
}
export function getObj(id) {
return request({
url: '/admin/user/' + id,
method: 'get'
})
}
export function delObj(id) {
return request({
url: '/admin/user/' + id,
method: 'delete'
})
}
export function putObj(obj) {
return request({
url: '/admin/user',
method: 'put',
data: obj
})
}
<template>
<div class="basic-container">
<el-card>
<slot></slot>
</el-card>
</div>
</template>
<script>
export default {
name: "basicContainer"
};
</script>
<style lang="scss">
.basic-container {
padding: 8px 10px;
border-radius: 10px;
box-sizing: border-box;
.el-card {
width: 100%;
}
&:first-child {
padding-top: 0;
}
}
</style>
<template>
<div class="error403">
<div class="error403-body-con">
<el-card class="box-card">
<div class="error403-body-con-title">4
<span class="error403-0-span">
<i class="icon-quanxian"></i>
</span>
<span class="error403-key-span">
<i class="icon-iconset0216"></i>
</span>
</div>
<p class="error403-body-con-message">You don't have permission</p>
<div class="error403-btn-con">
<el-button @click="goHome" size="large" style="width: 200px;" type="text">返回首页</el-button>
<el-button @click="backPage" size="large" style="width: 200px;margin-left: 40px;" type="primary">返回上一页</el-button>
</div>
</el-card>
</div>
</div>
</template>
<script>
export default {
name: "Error403",
methods: {
backPage() {
this.$router.go(-1);
},
goHome() {
this.$router.push({
path: "/"
});
}
}
};
</script>
<style lang="scss" scoped>
@keyframes error403animation {
0% {
transform: rotateZ(0deg);
}
40% {
transform: rotateZ(-20deg);
}
45% {
transform: rotateZ(-15deg);
}
50% {
transform: rotateZ(-20deg);
}
55% {
transform: rotateZ(-15deg);
}
60% {
transform: rotateZ(-20deg);
}
100% {
transform: rotateZ(0deg);
}
}
.error403 {
&-body-con {
width: 700px;
height: 500px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
&-title {
text-align: center;
font-size: 240px;
font-weight: 700;
color: #2d8cf0;
height: 260px;
line-height: 260px;
margin-top: 40px;
.error403-0-span {
display: inline-block;
position: relative;
width: 170px;
height: 170px;
border-radius: 50%;
border: 20px solid #ed3f14;
color: #ed3f14;
margin-right: 10px;
i {
display: inline-block;
font-size: 120px !important;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
.error403-key-span {
display: inline-block;
position: relative;
width: 100px;
height: 190px;
border-radius: 50%;
margin-right: 10px;
i {
display: inline-block;
font-size: 190px !important;
position: absolute;
left: 20px;
transform: translate(-50%, -60%);
transform-origin: center bottom;
animation: error403animation 2.8s ease 0s infinite;
}
}
}
&-message {
display: block;
text-align: center;
font-size: 30px;
font-weight: 500;
letter-spacing: 4px;
color: #dddde2;
}
}
&-btn-con {
text-align: center;
padding: 20px 0;
margin-bottom: 40px;
}
}
</style>
<template>
<div class="error404">
<div class="error404-body-con">
<el-card class="box-card">
<div class="error404-body-con-title">4
<span>0</span>4</div>
<p class="error404-body-con-message">YOU&nbsp;&nbsp;LOOK&nbsp;&nbsp;LOST</p>
<div class="error404-btn-con">
<el-button @click="goHome" size="large" style="width: 200px;" type="text">返回首页</el-button>
<el-button @click="backPage" size="large" style="width: 200px;margin-left: 40px;" type="primary">返回上一页</el-button>
</div>
</el-card>
</div>
</div>
</template>
<script>
export default {
name: "Error404",
methods: {
backPage() {
this.$router.go(-1);
},
goHome() {
this.$router.push({
path: "/"
});
}
}
};
</script>
<style lang="scss" scoped>
@keyframes error404animation {
0% {
transform: rotateZ(0deg);
}
20% {
transform: rotateZ(-60deg);
}
40% {
transform: rotateZ(-10deg);
}
60% {
transform: rotateZ(50deg);
}
80% {
transform: rotateZ(-20deg);
}
100% {
transform: rotateZ(0deg);
}
}
.error404 {
&-body-con {
width: 700px;
height: 500px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
&-title {
text-align: center;
font-size: 240px;
font-weight: 700;
color: #2d8cf0;
height: 260px;
line-height: 260px;
margin-top: 40px;
span {
display: inline-block;
color: #19be6b;
font-size: 230px;
animation: error404animation 3s ease 0s infinite alternate;
}
}
&-message {
display: block;
text-align: center;
font-size: 30px;
font-weight: 500;
letter-spacing: 12px;
color: #dddde2;
}
}
&-btn-con {
text-align: center;
padding: 20px 0;
margin-bottom: 40px;
}
}
</style>
<template>
<div class="error500">
<div class="error500-body-con">
<el-card class="box-card">
<div class="error500-body-con-title">
5
<span class="error500-0-span">
<i class="icon-debug"></i>
</span>
<span class="error500-0-span">
<i class="icon-debug"></i>
</span>
</div>
<p class="error500-body-con-message">Oops! the server is wrong</p>
<div class="error500-btn-con">
<el-button @click="goHome" size="large" style="width: 200px;" type="text">返回首页</el-button>
<el-button @click="backPage" size="large" style="width: 200px;margin-left: 40px;" type="primary">返回上一页</el-button>
</div>
</el-card>
</div>
</div>
</template>
<script>
export default {
name: "Error500",
methods: {
backPage() {
this.$router.go(-1);
},
goHome() {
this.$router.push({
path: "/"
});
}
}
};
</script>
<style lang="scss" scoped>
@keyframes error500animation {
0% {
transform: rotateZ(0deg);
}
20% {
transform: rotateZ(-10deg);
}
40% {
transform: rotateZ(5deg);
}
60% {
transform: rotateZ(-5deg);
}
80% {
transform: rotateZ(10deg);
}
100% {
transform: rotateZ(0deg);
}
}
.error500 {
&-body-con {
width: 700px;
height: 500px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
&-title {
text-align: center;
font-size: 240px;
font-weight: 700;
color: #2d8cf0;
height: 260px;
line-height: 260px;
margin-top: 40px;
.error500-0-span {
display: inline-block;
position: relative;
width: 170px;
height: 170px;
border-radius: 50%;
border: 20px solid #ed3f14;
color: #ed3f14;
margin-right: 10px;
i {
display: inline-block;
font-size: 120px !important;
position: absolute;
bottom: -43px;
left: 20px;
transform-origin: center bottom;
animation: error500animation 3s ease 0s infinite alternate;
}
}
}
&-message {
display: block;
text-align: center;
font-size: 30px;
font-weight: 500;
letter-spacing: 4px;
color: #dddde2;
}
}
&-btn-con {
text-align: center;
padding: 20px 0;
margin-bottom: 40px;
}
}
</style>
<template>
<div>
<basic-container>
<iframe v-if="$route.query.src"
:src='$route.query.src'
class="iframe"
ref="iframe"></iframe>
<iframe v-else
:src="urlPath"
class="iframe"
ref="iframe"></iframe>
</basic-container>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
export default {
name: 'AvueIframe',
data () {
return {
urlPath: this.getUrlPath() //iframe src 路径
}
},
created () {
NProgress.configure({ showSpinner: false })
},
mounted () {
this.load()
this.resize()
},
props: ['routerPath'],
watch: {
$route: function () {
this.load()
},
routerPath: function () {
// 监听routerPath变化,改变src路径
this.urlPath = this.getUrlPath()
}
},
components: {
...mapGetters(['screen']),
},
methods: {
// 显示等待框
show () {
NProgress.start()
},
// 隐藏等待狂
hide () {
NProgress.done()
},
// 加载浏览器窗口变化自适应
resize () {
window.onresize = () => {
this.iframeInit()
}
},
// 加载组件
load () {
this.show()
var flag = true //URL是否包含问号
if (this.$route.query.src.indexOf('?') == -1) {
flag = false
}
var list = []
for (var key in this.$route.query) {
if (key != 'src' && key != 'name') {
list.push(`${key}= this.$route.query[key]`)
}
}
list = list.join('&').toString()
if (flag) {
this.$route.query.src = `${this.$route.query.src}${
list.length > 0 ? `&list` : ''
}`
} else {
this.$route.query.src = `${this.$route.query.src}${
list.length > 0 ? `?list` : ''
}`
}
//超时3s自动隐藏等待狂,加强用户体验
let time = 3
const timeFunc = setInterval(() => {
time--
if (time == 0) {
this.hide()
clearInterval(timeFunc)
}
}, 1000)
this.iframeInit()
},
//iframe窗口初始化
iframeInit () {
const iframe = this.$refs.iframe
const clientHeight = document.documentElement.clientHeight - (screen > 1 ? 200 : 130);
iframe.style.height = `${clientHeight}px`
if (iframe.attachEvent) {
iframe.attachEvent('onload', () => {
this.hide()
})
} else {
iframe.onload = () => {
this.hide()
}
}
},
getUrlPath: function () {
//获取 iframe src 路径
let url = window.location.href
url = url.replace('/myiframe', '')
return url
}
}
}
</script>
<style lang="scss">
.iframe {
width: 100%;
height: 100%;
border: 0;
overflow: hidden;
box-sizing: border-box;
}
</style>
\ No newline at end of file
// 配置编译环境和线上环境之间的切换
let baseUrl = '';
let iconfontVersion = ['567566_r22zi6t8noas8aor', '567566_qo5lxgtishg', '599693_dfa50fge714', '667895_2ek3wqcg8w1', '667895_w0ofbdzuuir']
let iconfontUrl = `//at.alicdn.com/t/font_$key.css`;
let codeUrl = `${baseUrl}/code`
const env = process.env
if (env.NODE_ENV == 'development') {
baseUrl = ``; // 开发环境地址
} else if (env.NODE_ENV == 'production') {
baseUrl = ``; //生产环境地址
} else if (env.NODE_ENV == 'test') {
baseUrl = ``; //测试环境地址
}
export {
baseUrl,
iconfontUrl,
iconfontVersion,
codeUrl,
env
}
\ No newline at end of file
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
const DIC = {
vaild: [{
label: '否',
value: 'false'
}, {
label: '是',
value: 'true'
}]
}
export const tableOption = {
'border': true,
'index': true,
'indexLabel': '序号',
'stripe': true,
'menuAlign': 'center',
'align': 'center',
'editBtn': false,
'delBtn': false,
'dic': [],
'column': [{
width: 150,
label: '编号',
prop: 'clientId',
align: 'center',
sortable: true,
rules: [{
required: true,
message: '请输入clientId',
trigger: 'blur'
}]
}, {
width: 300,
label: '密钥',
prop: 'clientSecret',
align: 'center',
sortable: true,
rules: [{
required: true,
message: '请输入clientSecret',
trigger: 'blur'
}]
}, {
label: '域',
prop: 'scope',
align: 'center',
width: 150,
rules: [{
required: true,
message: '请输入scope',
trigger: 'blur'
}]
}, {
label: '授权模式',
prop: 'authorizedGrantTypes',
align: 'center',
width: 150,
hide: true,
rules: [{
required: true,
message: '请输入授权模式',
trigger: 'blur'
}]
}, {
label: '回调地址',
prop: 'webServerRedirectUri',
align: 'center',
width: 150,
hide: true
}, {
label: '权限',
prop: 'authorities',
align: 'center',
width: 150,
hide: true
}, {
label: '请求令牌',
prop: 'accessTokenValidity',
align: 'center',
width: 150,
hide: true
}, {
label: '刷新令牌',
prop: 'refreshTokenValidity',
align: 'center',
width: 150,
hide: true
}, {
label: '扩展信息',
prop: 'additionalInformation',
align: 'center',
width: 150,
hide: true
}, {
label: '自动放行',
prop: 'autoapprove',
align: 'center',
type: 'radio',
dicData: DIC.vaild,
width: 150,
rules: [{
required: true,
message: '请选择是否放行',
trigger: 'blur'
}]
}, {
label: '资源ID',
prop: 'resourceIds',
align: 'center',
width: 150
}]
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
export const tableData = [{
username: 'lengleng',
name: 'lengleng',
number: 12,
type: '0',
stars: 'https://gitee.com/log4j/pig/badge/star.svg?theme=white',
git: 'https://gitee.com/log4j/pig',
address: 'https://gitee.com/log4j',
info: 'Pig是基于Spring Cloud、OAuth2.0,使用Vue前后分离的开发平台,支持账号、 短信、 SSO等多种登录。 '
}, {
username: 'smallwei',
name: 'smallwei',
number: 20,
type: '1',
stars: 'https://gitee.com/smallweigit/avue/badge/star.svg?theme=white',
git: 'https://gitee.com/smallweigit/avue',
address: 'https://gitee.com/smallweigit',
info: 'Avue是一个后台集成解决方案,它基于 Vue.js 和 element。 使用了最新的前端技术栈,支持权限验证,第三方网站嵌套等功能。'
}]
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
export const tableOption = {
'border': true,
'index': true,
'indexLabel': '序号',
'stripe': true,
'menuAlign': 'center',
'align': 'center',
'refreshBtn': false,
'showClomnuBtn': false,
'searchSize': 'mini',
'editBtn': false,
'delBtn': false,
'dic': [],
'column': [{
width: 150,
label: '数据值',
prop: 'value',
rules: [{
required: true,
message: '请输入数据值',
trigger: 'blur'
}]
}, {
label: '标签名',
prop: 'label',
rules: [{
required: true,
message: '请输入标签名',
trigger: 'blur'
}]
}, {
label: '类型',
prop: 'type',
'search': true,
rules: [{
required: true,
message: '请输入字典类型',
trigger: 'blur'
}]
}, {
label: '描述',
prop: 'description',
rules: [{
required: true,
message: '请输入字典描述',
trigger: 'blur'
}]
}, {
label: '排序',
prop: 'sort',
rules: [{
required: true,
message: '请输入排序',
trigger: 'blur'
}]
}, {
label: '备注信息',
prop: 'remarks'
}]
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
export const tableOption = {
'border': true,
'index': true,
'stripe': true,
'menuAlign': 'center',
'align': 'center',
'addBtn': false,
'editBtn': false,
'delBtn': false,
'column': [{
label: '表名称',
prop: 'tableName',
align: 'center',
search: true
}, {
label: '表注释',
prop: 'tableComment',
align: 'center'
}, {
label: '索引',
prop: 'engine',
align: 'center'
}, {
type: 'datetime',
valueFormat: 'timestamp',
format: 'yyyy-MM-dd hh:mm:ss',
label: '创建时间',
prop: 'createTime',
align: 'center'
}]
}
export const formOption = {
submitText: '生成',
column: [
{
label: '表名称',
prop: 'tableName',
disabled: true
}, {
label: '包名',
prop: 'packageName',
placeholder: '可为空,加载系统默认配置'
}, {
label: '作者',
prop: 'author',
placeholder: '可为空,加载系统默认配置'
}, {
label: '模块',
prop: 'moduleName',
placeholder: '可为空,加载系统默认配置'
}, {
label: '表前缀',
prop: 'tablePrefix',
placeholder: '可为空,加载系统默认配置'
}, {
label: '注释',
prop: 'comments',
placeholder: '可为空,加载表备注'
}
]
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
export const tableOption = {
'border': true,
'index': true,
'indexLabel': '序号',
'stripe': true,
'menuAlign': 'center',
'menuWidth': 150,
'align': 'center',
'refreshBtn': true,
'showClomnuBtn': false,
'searchSize': 'mini',
'addBtn': false,
'editBtn': false,
'delBtn': false,
'dicUrl': '/admin/dict/type/log_type',
props: {
label: 'label',
value: 'value'
},
'column': [{
label: '类型',
prop: 'type',
type: 'select',
dicData: 'log_type',
search: true
}, {
label: '请求接口',
prop: 'requestUri'
}, {
label: 'IP地址',
prop: 'remoteAddr'
}, {
label: '请求方式',
prop: 'method'
}, {
label: '客户端',
prop: 'serviceId'
}, {
label: '请求时间',
prop: 'time'
}, {
label: '创建时间',
prop: 'createTime',
type: 'datetime',
format: 'yyyy-MM-dd HH:mm',
valueFormat: 'yyyy-MM-dd HH:mm:ss'
}]
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
export const tableOption = {
'border': true,
'index': true,
'expand': true,
'stripe': true,
'selection': true,
'page': false,
'menuAlign': 'center',
'defaultSort': {
prop: 'username',
order: 'descending'
},
'align': 'center',
'dic': [],
'column': [{
'label': '用户名',
'prop': 'username',
'span': 24,
'solt': true,
'sortable': true,
'width': 120,
'rules': [{
'required': true,
'message': '请输入用户名',
'trigger': 'blur'
}]
}, {
'label': '类型',
'prop': 'type',
'width': 80,
'type': 'select',
'sortable': true,
'dicData': [{
'label': '后端',
'value': '0'
}, {
'label': '前端',
'value': '1'
}]
}, {
'label': 'stars',
'width': '150',
'prop': 'stars',
'sortable': true,
'solt': true
}, {
'label': '码云',
'solt': true,
'span': 24,
'prop': 'address',
'type': 'textarea',
'overHidden': true
}, {
'label': '项目介绍',
'width': '300',
'prop': 'info',
'editDisabled': true,
'type': 'textarea',
'span': 24,
'maxRow': 4,
'minRow': 4,
'overHidden': true
}]
}
\ No newline at end of file
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
const DIC = {
state: [{
label: '准备中',
value: 'TASK_STAGING'
},
{
label: '执行中',
value: 'TASK_RUNNING'
}, {
label: '已经完成',
value: 'TASK_FINISHED'
}
]
}
export const tableOption = {
"border": true,
"index": true,
"stripe": true,
"menuAlign": "center",
"align": "center",
"editBtn": false,
"delBtn": false,
"addBtn": false,
"dic": [],
"column": [{
label: 'ID',
prop: 'id',
hide: true
},
{
label: '作业名称',
prop: 'jobName',
search: true
},
{
label: '原任务',
prop: 'originalTaskId',
hide: true,
width: 100
},
{
label: '任务ID',
prop: 'taskId',
hide: true
},
{
label: '服务器IP',
prop: 'slaveId'
},
{
label: '资源',
prop: 'source',
hide: true
},
{
label: '执行类型',
prop: 'executionType',
hide: true,
width: 100
},
{
label: '分片项',
prop: 'shardingItem'
},
{
label: '状态',
prop: 'state',
type: 'select',
dicData: DIC.state,
search: true
},
{
label: '创建时间',
prop: 'creationTime'
},
{
label: '消息',
prop: 'message',
width: 100
}
]
}
\ No newline at end of file
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
export const tableOption = {
"border": true,
"index": true,
"stripe": true,
"menuAlign": "center",
"align": "center",
"editBtn": false,
"delBtn": false,
"addBtn": false,
'dicUrl': '/admin/dict/type/social_type',
"column": [{
label: 'ID',
prop: 'id',
hide: true,
addVisdiplay: false,
editDisabled: true
},
{
label: '类型',
prop: 'type',
type: 'select',
dicData: 'social_type',
search: true,
rules: [{
required: true,
message: '请选择类型',
trigger: 'blur'
}]
},
{
label: '描述',
prop: 'remark'
},
{
label: 'appId',
prop: 'appId',
rules: [{
required: true,
message: '请输入appId',
trigger: 'blur'
}]
},
{
label: 'appSecret',
prop: 'appSecret',
rules: [{
required: true,
message: '请输入appSecret',
trigger: 'blur'
}]
},
{
label: '回调地址',
prop: 'redirectUrl',
rules: [{
required: true,
message: '请输入回调地址',
trigger: 'blur'
}]
},
{
valueFormat: 'timestamp',
format: 'yyyy-MM-dd hh:mm:ss',
label: '创建时间',
prop: 'createTime',
align: 'center',
addVisdiplay: false,
editDisabled: true
}
]
}
\ No newline at end of file
export const DIC = {
VAILD: [{
label: '真',
value: 'true',
color: 'green'
}, {
label: '假',
value: 'false',
color: 'red'
}],
SEX: [{
label: '男',
value: 0,
color: 'green'
}, {
label: '女',
value: 1,
color: 'red'
}],
POSTIONDATA: [{
label: '左对齐',
value: 'left'
}, {
label: '居中',
value: 'center'
}, {
label: '右对齐',
value: 'right'
}],
TYPE: [{
label: '一级1',
value: 0,
children: [{
label: '一级1二级1',
value: 2,
}]
}, {
label: '一级2',
value: 1,
children: [{
label: '一级2二级1',
value: 2,
}]
}
],
STATE: [{
label: '有效',
value: 0
}, {
label: '无效',
value: 1
}],
GRADE: [{
label: "管理员",
value: 0
},
{
label: "二级管理员",
value: 1
}
],
VAILDATA: [{
label: "激活",
value: true,
},
{
label: "禁用",
value: false,
}
],
CRUDTYPE: [{
label: "输入框",
value: ''
}, {
label: "选择框",
value: 'select'
},
{
label: "文本框",
value: 'text'
},
{
label: "密码框",
value: 'password'
},
{
label: "树型框",
value: 'tree'
},
{
label: "富文本编辑框",
value: 'ueditor'
},
{
label: "多行文本框",
value: 'textarea'
},
{
label: "单选框",
value: 'radio'
},
{
label: "多选框",
value: 'checkbox'
},
{
label: "数字框",
value: 'number'
},
{
label: "日期框",
value: 'date'
},
{
label: "日期范围框",
value: 'daterange'
},
{
label: "时间范围框",
value: 'datetimerange'
},
{
label: "时间框",
value: 'datetime'
},
{
label: "周",
value: 'week'
},
{
label: "月",
value: 'month'
},
{
label: "年",
value: 'year'
},
{
label: "滑动框",
value: 'silder'
},
{
label: "评价框",
value: 'rate'
},
{
label: "上传框",
value: 'upload'
}
],
UITYPE: [{
value: 'zhinan',
label: '指南',
children: [{
value: 'shejiyuanze',
label: '设计原则',
children: [{
value: 'yizhi',
label: '一致'
}, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}]
}, {
value: 'daohang',
label: '导航',
children: [{
value: 'cexiangdaohang',
label: '侧向导航'
}, {
value: 'dingbudaohang',
label: '顶部导航'
}]
}]
}, {
value: 'zujian',
label: '组件',
children: [{
value: 'basic',
label: 'Basic',
children: [{
value: 'layout',
label: 'Layout 布局'
}, {
value: 'color',
label: 'Color 色彩'
}, {
value: 'typography',
label: 'Typography 字体'
}, {
value: 'icon',
label: 'Icon 图标'
}, {
value: 'button',
label: 'Button 按钮'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio 单选框'
}, {
value: 'checkbox',
label: 'Checkbox 多选框'
}, {
value: 'input',
label: 'Input 输入框'
}, {
value: 'input-number',
label: 'InputNumber 计数器'
}, {
value: 'select',
label: 'Select 选择器'
}, {
value: 'cascader',
label: 'Cascader 级联选择器'
}, {
value: 'switch',
label: 'Switch 开关'
}, {
value: 'slider',
label: 'Slider 滑块'
}, {
value: 'time-picker',
label: 'TimePicker 时间选择器'
}, {
value: 'date-picker',
label: 'DatePicker 日期选择器'
}, {
value: 'datetime-picker',
label: 'DateTimePicker 日期时间选择器'
}, {
value: 'upload',
label: 'Upload 上传'
}, {
value: 'rate',
label: 'Rate 评分'
}, {
value: 'form',
label: 'Form 表单'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table 表格'
}, {
value: 'tag',
label: 'Tag 标签'
}, {
value: 'progress',
label: 'Progress 进度条'
}, {
value: 'tree',
label: 'Tree 树形控件'
}, {
value: 'pagination',
label: 'Pagination 分页'
}, {
value: 'badge',
label: 'Badge 标记'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert 警告'
}, {
value: 'loading',
label: 'Loading 加载'
}, {
value: 'message',
label: 'Message 消息提示'
}, {
value: 'message-box',
label: 'MessageBox 弹框'
}, {
value: 'notification',
label: 'Notification 通知'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu 导航菜单'
}, {
value: 'tabs',
label: 'Tabs 标签页'
}, {
value: 'breadcrumb',
label: 'Breadcrumb 面包屑'
}, {
value: 'dropdown',
label: 'Dropdown 下拉菜单'
}, {
value: 'steps',
label: 'Steps 步骤条'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog 对话框'
}, {
value: 'tooltip',
label: 'Tooltip 文字提示'
}, {
value: 'popover',
label: 'Popover 弹出框'
}, {
value: 'card',
label: 'Card 卡片'
}, {
value: 'carousel',
label: 'Carousel 走马灯'
}, {
value: 'collapse',
label: 'Collapse 折叠面板'
}]
}]
}, {
value: 'ziyuan',
label: '资源',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'jiaohu',
label: '组件交互文档'
}]
}],
PAYTYPE: [{
label: '微信',
value: '0',
}, {
label: '支付宝',
value: '1',
}, {
label: '银行卡',
value: '2',
}],
DATALIST: [{
label: 'SEX',
value: 'SEX',
}, {
label: 'STATE',
value: 'STATE',
}, {
label: 'GRADE',
value: 'GRADE',
}]
}
\ No newline at end of file
export default {
'401': '当前操作没有权限',
'403': '当前操作没有权限',
'404': '资源不存在',
'417': '未绑定登录账号,请使用密码登录后绑定',
'423': '演示环境不能操作,如需了解联系冷冷',
'426': '用户名不存在或密码错误',
'428': '验证码错误,请重新输入',
'429': '请求过频繁',
'479': '演示环境,没有权限操作',
'default': '系统未知错误,请反馈给管理员'
}
\ No newline at end of file
export default {
menu: false,
addBtn: false,
page: false,
border: true,
expand: true,
refreshBtn: false,
headerAlign: 'center',
column: [{
label: '类型',
prop: 'type',
width: 80,
align: 'center',
solt: true,
dicData: [{
label: 'bug',
value: 'error'
}]
}, {
label: '地址',
width: 200,
prop: 'url',
overHidden: true,
}, {
label: '内容',
prop: 'message',
overHidden: true,
}, {
label: '错误堆栈',
prop: 'stack',
hide: true
}, {
label: '时间',
align: 'center',
prop: 'time',
width: 200,
}]
}
\ No newline at end of file
const dicData = [{
label: '开启',
value: 'true'
}, {
label: '关闭',
value: 'false'
}]
export const list = [{
key: 'showTag',
commit: 'SET_SHOWTAG'
}, {
key: 'showTheme',
commit: 'SET_SHOWTHEME'
}, {
key: 'showColor',
commit: 'SET_SHOWCOLOR'
}, {
key: 'showLock',
commit: 'SET_SHOWLOCK'
}, {
key: 'showDebug',
commit: 'SET_SHOWDEBUG'
}, {
key: 'showFullScren',
commit: 'SET_SHOWFULLSCREN'
}, {
key: 'showCollapse',
commit: 'SET_SHOWCOLLAPSE'
}, {
key: 'showSearch',
commit: 'SET_SHOWSEARCH'
}, {
key: 'showMenu',
commit: 'SET_SHOWMENU'
}]
export const option = (safe) => {
const _safe = safe;
return {
submitBtn: false,
column: [{
label: '标签',
prop: 'showTag',
type: 'switch',
span: 24,
dicData: dicData,
click: ({ column }) => {
_safe.set(column.prop);
}
}, {
label: '日志',
prop: 'showDebug',
type: 'switch',
span: 24,
dicData: dicData,
click: ({ column }) => {
_safe.set(column.prop);
}
}, {
label: '主题',
prop: 'showTheme',
type: 'switch',
span: 24,
dicData: dicData,
click: ({ column }) => {
_safe.set(column.prop);
}
}, {
label: '主题色',
prop: 'showColor',
type: 'switch',
span: 24,
dicData: dicData,
click: ({ column }) => {
_safe.set(column.prop);
}
}, {
label: '全屏',
prop: 'showFullScren',
type: 'switch',
span: 24,
dicData: dicData,
click: ({ column }) => {
_safe.set(column.prop);
}
}, {
label: '锁屏',
prop: 'showLock',
type: 'switch',
span: 24,
dicData: dicData,
click: ({ column }) => {
_safe.set(column.prop);
}
}, {
label: '搜索',
prop: 'showSearch',
type: 'switch',
span: 24,
dicData: dicData,
click: ({ column }) => {
_safe.set(column.prop);
}
}, {
label: '缩放',
prop: 'showCollapse',
type: 'switch',
span: 24,
dicData: dicData,
click: ({ column }) => {
_safe.set(column.prop);
}
}, {
label: '顶部菜单',
prop: 'showMenu',
type: 'switch',
span: 24,
dicData: dicData,
click: ({ column }) => {
_safe.set(column.prop);
}
}]
}
}
\ No newline at end of file
export default {
title: "Avue",
logo: "A",
indexTitle: 'avue-cli By smallwei',
whiteList: ["/login", "/404", "/401", "/lock"], //配置无权限可以访问的页面
whiteTagList: ["/login", "/404", "/401", "/lock", ], //配置不添加tags页面 ('/advanced-router/mutative-detail/*'——*为通配符)
lockPage: '/lock',
tokenTime: 6000,
info: {
title: "Avue 通用管理系统快速开发框架",
list: [
'Avue 是一个基于vue+vuex+vue-router快速后台管理模板,采用token交互验证方式。',
'您可以 Avue 为基础,不只限制于vue的页面,你可以嵌入第三方网站,基于iframe框架。',
'Avue 构建简单上手快,最大程度上帮助企业节省时间成本和费用开支。',
]
},
//配置菜单的属性
menu: {
props: {
label: 'label',
path: 'path',
icon: 'icon',
children: 'children'
}
}
}
\ No newline at end of file
FROM nginx
VOLUME /tmp
ENV LANG en_US.UTF-8
ADD ./dist/ /usr/share/nginx/html/
EXPOSE 80
EXPOSE 443
\ No newline at end of file
import Vue from 'vue';
import store from './store'
Vue.config.errorHandler = function(err, vm, info) {
Vue.nextTick(() => {
store.commit('ADD_LOGS', {
type: 'error',
message: err.message,
stack: err.stack,
info
})
if (process.env.NODE_ENV === 'development') {
console.group('>>>>>> 错误信息 >>>>>>')
console.log(info)
console.groupEnd();
console.group('>>>>>> Vue 实例 >>>>>>')
console.log(vm)
console.groupEnd();
console.group('>>>>>> Error >>>>>>')
console.log(err)
console.groupEnd();
}
})
}
\ No newline at end of file
function pluralize(time, label) {
if (time === 1) {
return time + label
}
return time + label + 's'
}
/**
* 日期格式化
*/
export function dateFormat(date) {
let format = 'yyyy-MM-dd hh:mm:ss';
if (date != 'Invalid Date') {
var o = {
"M+": date.getMonth() + 1, //month
"d+": date.getDate(), //day
"h+": date.getHours(), //hour
"m+": date.getMinutes(), //minute
"s+": date.getSeconds(), //second
"q+": Math.floor((date.getMonth() + 3) / 3), //quarter
"S": date.getMilliseconds() //millisecond
}
if (/(y+)/.test(format)) format = format.replace(RegExp.$1,
(date.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(format))
format = format.replace(RegExp.$1,
RegExp.$1.length == 1 ? o[k] :
("00" + o[k]).substr(("" + o[k]).length));
return format;
}
return '';
}
export function timeAgo(time) {
const between = Date.now() / 1000 - Number(time)
if (between < 3600) {
return pluralize(~~(between / 60), ' minute')
} else if (between < 86400) {
return pluralize(~~(between / 3600), ' hour')
} else {
return pluralize(~~(between / 86400), ' day')
}
}
export function parseTime(time, cFormat) {
if (arguments.length === 0) {
return null
}
if ((time + '').length === 10) {
time = +time * 1000
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
date = new Date(parseInt(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() + '分'
}
}
/* 数字 格式化*/
export function nFormatter(num, digits) {
const si = [
{ value: 1E18, symbol: 'E' },
{ value: 1E15, symbol: 'P' },
{ value: 1E12, symbol: 'T' },
{ value: 1E9, symbol: 'G' },
{ value: 1E6, symbol: 'M' },
{ value: 1E3, symbol: 'k' }
]
for (let i = 0; i < si.length; i++) {
if (num >= si[i].value) {
return (num / si[i].value + 0.1).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol
}
}
return num.toString()
}
export function html2Text(val) {
const div = document.createElement('div')
div.innerHTML = val
return div.textContent || div.innerText
}
export function toThousandslsFilter(num) {
return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
}
\ No newline at end of file
import 'babel-polyfill';
import 'classlist-polyfill';
import Vue from 'vue';
import axios from './router/axios';
import VueAxios from 'vue-axios';
import App from './App';
import './permission'; // 权限
import './error'; // 日志
import router from './router/router';
import 'avue-plugin-transfer/packages' //引入avue-plugin-transfer插件
// import 'avue-plugin-ueditor/packages' //引入avue-plugin-ueditor插件(如果要兼容ie自行换掉富文本编辑器,此款插件不兼容ie)
import store from './store';
import {
loadStyle
} from './util/util'
import * as urls from '@/config/env';
import {
iconfontUrl,
iconfontVersion
} from '@/config/env';
import * as filters from './filters' // 全局filter
import './styles/common.scss';
// 引入avue的包
import '@smallwei/avue/lib/index.js';
// 引入avue的样式文件
import '@smallwei/avue/lib/theme-chalk/index.css';
// //源文件包
// import './packages/index.js';
// import './packages/theme-chalk/src/index.scss';
import basicContainer from './components/basic-container/main'
import VueClipboard from 'vue-clipboard2'
// 插件 json 展示
import vueJsonTreeView from 'vue-json-tree-view'
Vue.use(router)
Vue.use(VueClipboard)
Vue.use(vueJsonTreeView)
Vue.use(VueAxios, axios)
Vue.component('basicContainer', basicContainer)
Object.keys(urls).forEach(key => {
Vue.prototype[key] = urls[key];
})
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])
})
iconfontVersion.forEach(ele => {
loadStyle(iconfontUrl.replace('$key', ele));
})
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
\ No newline at end of file
import {
mapGetters
} from "vuex";
const version = require("element-ui/package.json").version; // element-ui version from node_modules
const ORIGINAL_THEME = "#409EFF"; // default color
export default function () {
return {
data() {
return {
themeVal: ORIGINAL_THEME
}
},
created() {
this.themeVal = this.theme;
},
watch: {
themeVal(val, oldVal) {
this.$store.commit("SET_THEME", val);
this.updateTheme(val, oldVal);
}
},
computed: {
...mapGetters(["theme"])
},
methods: {
updateTheme(val, oldVal) {
if (typeof val !== "string") return;
const head = document.getElementsByTagName("head")[0];
const themeCluster = this.getThemeCluster(val.replace("#", ""));
const originalCluster = this.getThemeCluster(oldVal.replace("#", ""));
const getHandler = (variable, id) => {
return () => {
const originalCluster = this.getThemeCluster(
ORIGINAL_THEME.replace("#", "")
);
const newStyle = this.updateStyle(
this[variable],
originalCluster,
themeCluster
);
let styleTag = document.getElementById(id);
if (!styleTag) {
styleTag = document.createElement("style");
styleTag.setAttribute("id", id);
head.appendChild(styleTag);
}
styleTag.innerText = newStyle;
};
};
const chalkHandler = getHandler("chalk", "chalk-style");
if (!this.chalk) {
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`;
this.getCSSString(url, chalkHandler, "chalk");
} else {
chalkHandler();
}
const link = [].slice.call(
document.getElementsByTagName("head")[0].getElementsByTagName("link")
);
for (let i = link.length - 3; i < link.length; i++) {
const style = link[i];
if (style.href.indexOf('app') != -1) {
this.getCSSString(style.href, innerText => {
const originalCluster = this.getThemeCluster(
ORIGINAL_THEME.replace("#", "")
);
const newStyle = this.updateStyle(
innerText,
originalCluster,
themeCluster
);
let styleTag = document.getElementById(i);
if (!styleTag) {
styleTag = document.createElement("style");
styleTag.id = i;
styleTag.innerText = newStyle;
head.appendChild(styleTag);
}
});
}
}
const styles = [].slice
.call(document.querySelectorAll("style"))
.filter(style => {
const text = style.innerText;
return (
new RegExp(oldVal, "i").test(text) && !/Chalk Variables/.test(text)
);
});
styles.forEach(style => {
const {
innerText
} = style;
if (typeof innerText !== "string") return;
style.innerText = this.updateStyle(
innerText,
originalCluster,
themeCluster
);
});
},
updateStyle(style, oldCluster, newCluster) {
let newStyle = style;
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, "ig"), newCluster[index]);
});
return newStyle;
},
getCSSString(url, callback, variable) {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
if (variable) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, "");
}
callback(xhr.responseText);
}
};
xhr.open("GET", url);
xhr.send();
},
getThemeCluster(theme) {
const tintColor = (color, tint) => {
let red = parseInt(color.slice(0, 2), 16);
let green = parseInt(color.slice(2, 4), 16);
let blue = parseInt(color.slice(4, 6), 16);
if (tint === 0) {
// when primary color is in its rgb space
return [red, green, blue].join(",");
} else {
red += Math.round(tint * (255 - red));
green += Math.round(tint * (255 - green));
blue += Math.round(tint * (255 - blue));
red = red.toString(16);
green = green.toString(16);
blue = blue.toString(16);
return `#${red}${green}${blue}`;
}
};
const shadeColor = (color, shade) => {
let red = parseInt(color.slice(0, 2), 16);
let green = parseInt(color.slice(2, 4), 16);
let blue = parseInt(color.slice(4, 6), 16);
red = Math.round((1 - shade) * red);
green = Math.round((1 - shade) * green);
blue = Math.round((1 - shade) * blue);
red = red.toString(16);
green = green.toString(16);
blue = blue.toString(16);
return `#${red}${green}${blue}`;
};
const clusters = [theme];
for (let i = 0; i <= 9; i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))));
}
clusters.push(shadeColor(theme, 0.1));
return clusters;
}
}
}
}
<template>
<div class="avue-contail"
:class="{'avue--collapse':isCollapse}">
<div class="avue-header">
<!-- 顶部导航栏 -->
<top />
</div>
<div class="avue-layout">
<div class="avue-left">
<!-- 左侧导航栏 -->
<sidebar />
</div>
<div class="avue-main">
<!-- 顶部标签卡 -->
<tags />
<!-- 主体视图层 -->
<el-scrollbar style="height:100%">
<keep-alive>
<router-view class="avue-view"
v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view class="avue-view"
v-if="!$route.meta.keepAlive" />
</el-scrollbar>
</div>
</div>
<!-- <el-footer class="avue-footer">
<img src="/svg/logo.svg"
alt=""
class="logo">
<p class="copyright">© 2018 Avue designed by smallwei</p>
</el-footer> -->
<div class="avue-shade"
@click="showCollapse"></div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import tags from './tags'
import top from './top/'
import sidebar from './sidebar/'
import admin from '@/util/admin';
import { validatenull } from '@/util/validate';
import { calcDate } from '@/util/date.js';
import { getStore } from '@/util/store.js';
export default {
components: {
top,
tags,
sidebar
},
name: 'index',
data () {
return {
//刷新token锁
refreshLock: false,
//刷新token的时间
refreshTime: '',
}
},
created () {
//实时检测刷新token
// this.refreshToken();
},
mounted () {
this.init();
},
computed: mapGetters(['isLock', 'isCollapse', 'website']),
props: [],
methods: {
showCollapse () {
this.$store.commit("SET_COLLAPSE");
},
// 屏幕检测
init () {
this.$store.commit('SET_SCREEN', admin.getScreen());
window.onresize = () => {
setTimeout(() => {
this.$store.commit('SET_SCREEN', admin.getScreen());
}, 0);
}
},
// 实时检测刷新token
refreshToken () {
this.refreshTime = setInterval(() => {
const token = getStore({
name: 'token',
debug: true,
});
const date = calcDate(token.datetime, new Date().getTime());
if (validatenull(date)) return;
if (!(date.seconds >= this.website.tokenTime) && !this.refreshLock) {
this.refreshLock = true;
this.$store
.dispatch('RefeshToken')
.then(() => {
clearInterval(this.refreshTime);
})
.catch(() => {
this.refreshLock = false;
});
}
}, 3000);
},
}
}
</script>
\ No newline at end of file
<template>
<router-view></router-view>
</template>
<template>
<div class="avue-logo">
<transition name="fade">
<span v-if="keyCollapse"
class="avue-logo_subtitle"
key="0">
{{website.logo}}
</span>
</transition>
<transition-group name="fade">
<template v-if="!keyCollapse">
<span class="avue-logo_title"
key="1">{{website.indexTitle}} </span>
</template>
</transition-group>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "logo",
data () {
return {};
},
created () {
},
computed: {
...mapGetters(["website", 'keyCollapse'])
},
methods: {}
};
</script>
<style lang="scss">
.fade-leave-active {
transition: opacity 0.2s;
}
.fade-enter-active {
transition: opacity 2.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.avue-logo {
position: fixed;
top: 0;
left: 0;
width: 220px;
height: 50px;
line-height: 50px;
background-color: #20222a;
font-size: 20px;
overflow: hidden;
box-sizing: border-box;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.15);
color: rgba(255, 255, 255, 0.8);
z-index: 1024;
&_title {
display: block;
text-align: center;
font-weight: 300;
font-size: 16px;
}
&_subtitle {
display: block;
text-align: center;
font-size: 18px;
font-weight: bold;
color: #fff;
}
}
</style>
\ No newline at end of file
export default {
propsDefault: {
label: 'label',
path: 'path',
icon: 'icon',
children: 'children'
}
}
\ No newline at end of file
<template>
<div class="avue-sidebar">
<logo></logo>
<el-scrollbar style="height:100%">
<el-menu unique-opened
:default-active="nowTagValue"
mode="vertical"
:show-timeout="200"
background-color="#20222a"
text-color="rgba(255,255,255,0.7)"
:collapse="keyCollapse">
<sidebar-item :menu="menu"
:screen="screen"
:props="website.menu.props"
:collapse="keyCollapse"></sidebar-item>
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import logo from '../logo';
import sidebarItem from './sidebarItem'
export default {
name: 'sidebar',
components: { sidebarItem, logo },
data () {
return {}
},
created () {
console.log(this.menu);
this.$store.dispatch("GetMenu").then(data => {
if (data.length === 0) return
this.$router.addRoutes(this.$router.$avueRouter.formatRoutes(data, true))
});
},
computed: {
...mapGetters(['website', 'menu', 'tag', 'keyCollapse', 'screen']),
nowTagValue: function () { return this.$router.$avueRouter.getValue(this.$route) }
},
mounted () { },
methods: {}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div class="menu-wrapper">
<template v-for="(item,index) in menu">
<el-menu-item v-if="validatenull(item[childrenKey])"
:index="filterPath(item[pathKey],index)"
@click="open(item)"
:key="item[labelKey]">
<i :class="item[iconKey]"></i>
<span slot="title">{{item[labelKey]}}</span>
</el-menu-item>
<el-submenu v-else
:index="filterPath(item[labelKey],index)"
:key="item[labelKey]">
<template slot="title">
<i :class="item[iconKey]"></i>
<span slot="title"
:class="{'el-menu--display':collapse}">{{item[labelKey]}}</span>
</template>
<template v-for="(child,cindex) in item[childrenKey]">
<el-menu-item :class="{'siderbar-active':nowTagValue==child[pathKey]}"
:index="filterPath(child[pathKey],cindex)"
@click="open(child)"
v-if="validatenull(child[childrenKey])"
:key="child[labelKey]">
<i :class="child[iconKey]"></i>
<span slot="title">{{child[labelKey]}}</span>
</el-menu-item>
<sidebar-item v-else
:menu="[child]"
:key="cindex"
:props="props"
:screen="screen"
:collapse="collapse"></sidebar-item>
</template>
</el-submenu>
</template>
</div>
</template>
<script>
import { validatenull } from '@/util/validate';
import config from './config.js'
export default {
name: 'sidebarItem',
data () {
return {
config: config
}
},
props: {
menu: {
type: Array
},
screen: {
type: Number
},
props: {
type: Object,
default: () => { return {} }
},
collapse: {
type: Boolean
}
},
created () {
},
mounted () { },
computed: {
labelKey () { return this.props.label || this.config.propsDefault.label },
pathKey () { return this.props.path || this.config.propsDefault.path },
iconKey () { return this.props.icon || this.config.propsDefault.icon },
childrenKey () { return this.props.children || this.config.propsDefault.children },
nowTagValue () { return this.$router.$avueRouter.getValue(this.$route) }
},
methods: {
validatenull (val) {
return validatenull(val);
},
filterPath (path, index) {
return path == null ? index + '' : path
},
open (item) {
if (this.screen <= 1) this.$store.commit("SET_COLLAPSE");
this.$router.push({
path: this.$router.$avueRouter.getPath({
name: item[this.labelKey],
src: item[this.pathKey]
}),
query: item.query
})
}
}
}
</script>
<style lang="scss" scoped>
//刷新激活状态
.siderbar-active {
i,
span {
color: #409eff;
}
}
</style>
<template>
<div class="avue-tags"
v-if="showTag">
<!-- tag盒子 -->
<div class="tags-box"
ref="tagBox">
<el-tabs v-model="active"
type="card"
:closable="tagLen!==1"
@tab-click="openTag"
@edit="menuTag">
<el-tab-pane :key="item.value"
v-for="item in tagList"
:label="item.label"
:name="item.value">
</el-tab-pane>
</el-tabs>
<el-dropdown class="tags-menu pull-right">
<el-button type="primary"
size="mini">
更多
<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="closeOthersTags">关闭其他</el-dropdown-item>
<el-dropdown-item @click.native="closeAllTags">关闭全部</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</template>
<script>
import { mapGetters, mapState } from 'vuex'
import { isObjectValueEqual } from '@/util/util';
export default {
name: 'tags',
data () {
return {
active: '',
}
},
created () { },
mounted () {
this.setActive();
},
watch: {
tag () {
this.setActive();
}
},
computed: {
...mapGetters(['tagWel', 'tagList', 'tag']),
...mapState({
showTag: state => state.common.showTag,
}),
tagLen () {
return this.tagList.length || 0;
}
},
methods: {
//激活当前选项
setActive () {
this.active = this.tag.value;
},
menuTag (value, action) {
if (action === 'remove') {
let { tag, key } = this.findTag(value);
this.$store.commit('DEL_TAG', tag)
if (tag.value === this.tag.value) {
tag = this.tagList[key === 0 ? key : key - 1] //如果关闭本标签让前推一个
this.openTag(tag)
}
}
},
openTag (item) {
let tag;
if (item.name) {
tag = this.findTag(item.name).tag;
} else {
tag = item;
}
this.$router.push({
path: this.$router.$avueRouter.getPath({
name: tag.label,
src: tag.value
}),
query: tag.query
})
},
isObjectValueEqual (a, b) {
return isObjectValueEqual(a, b)
},
closeOthersTags () {
this.$store.commit('DEL_TAG_OTHER')
},
findTag (value) {
let tag, key;
this.tagList.map((item, index) => {
if (item.value === value) {
tag = item;
key = index;
}
});
return { tag: tag, key: key };
},
closeAllTags () {
this.$store.commit('DEL_ALL_TAG')
this.$router.push({
path: this.$router.$avueRouter.getPath({
src: this.tagWel.value
}),
query: this.tagWel.query
})
},
}
}
</script>
<template>
<div class="avue-top">
<div class="top-bar__left">
<div class="avue-breadcrumb"
v-if="showCollapse">
<i class="icon-navicon avue-breadcrumb_collapse"
:class="[{ 'avue-breadcrumb_collapse--right': isCollapse }]"
@click="setCollapse"></i>
</div>
</div>
<h1 class="top-bar__title">
<div class="top-bar__item top-bar__item--show"
v-if="showMenu">
<top-menu></top-menu>
</div>
<span class="top-bar__item"
v-if="showSearch">
<top-search></top-search>
</span>
</h1>
<div class="top-bar__right">
<el-tooltip v-if="showColor"
effect="dark"
content="主题色"
placement="bottom">
<div class="top-bar__item">
<top-color></top-color>
</div>
</el-tooltip>
<el-tooltip v-if="showDebug"
effect="dark"
:content="logsFlag?'没有错误日志':`${logsLen}条错误日志`"
placement="bottom">
<div class="top-bar__item">
<top-logs></top-logs>
</div>
</el-tooltip>
<el-tooltip v-if="showLock"
effect="dark"
content="锁屏"
placement="bottom">
<div class="top-bar__item">
<top-lock></top-lock>
</div>
</el-tooltip>
<el-tooltip v-if="showTheme"
effect="dark"
content="特色主题"
placement="bottom">
<div class="top-bar__item top-bar__item--show">
<top-theme></top-theme>
</div>
</el-tooltip>
<el-tooltip v-if="showFullScren"
effect="dark"
:content="isFullScren?'退出全屏':'全屏'"
placement="bottom">
<div class="top-bar__item">
<i :class="isFullScren?'icon-tuichuquanping':'icon-quanping'"
@click="handleScreen"></i>
</div>
</el-tooltip>
<el-tooltip effect="dark"
content="用户头像"
placement="bottom">
<img class="top-bar__img"
:src="userInfo.avatar">
</el-tooltip>
<el-dropdown>
<span class="el-dropdown-link">
{{userInfo.username}}
<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<router-link to="/">首页</router-link>
</el-dropdown-item>
<el-dropdown-item>
<router-link to="/info/index">个人信息</router-link>
</el-dropdown-item>
<el-dropdown-item>
<a href="https://gitee.com/smallweigit/avue"
target="_blank">码云地址</a>
</el-dropdown-item>
<el-dropdown-item>
<a href="https://github.com/nmxiaowei/avue"
target="_blank">github</a>
</el-dropdown-item>
<el-dropdown-item @click.native="logout"
divided>退出系统</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<top-setting></top-setting>
</div>
</div>
</template>
<script>
import { mapGetters, mapState } from "vuex";
import { fullscreenToggel, listenfullscreen } from "@/util/util";
import topLock from "./top-lock";
import topMenu from "./top-menu";
import topSearch from './top-search';
import topBreadcrumb from "./top-breadcrumb";
import topColor from "./top-color";
import topTheme from "./top-theme";
import topLogs from "./top-logs";
import topSetting from "./top-setting";
export default {
components: { topLock, topMenu, topSearch, topBreadcrumb, topColor, topTheme, topLogs, topSetting },
name: "top",
data () {
return {
};
},
filters: {},
created () { },
mounted () {
listenfullscreen(this.setScreen);
},
computed: {
...mapState({
showDebug: state => state.common.showDebug,
showColor: state => state.common.showColor,
showTheme: state => state.common.showTheme,
showLock: state => state.common.showLock,
showFullScren: state => state.common.showFullScren,
showCollapse: state => state.common.showCollapse,
showSearch: state => state.common.showSearch,
showMenu: state => state.common.showMenu
}),
...mapGetters([
"userInfo",
"isFullScren",
"tagWel",
"tagList",
"isCollapse",
"tag",
"logsLen",
"logsFlag"
]),
},
methods: {
handleScreen () {
fullscreenToggel();
},
setCollapse () {
this.$store.commit("SET_COLLAPSE");
},
setScreen () {
this.$store.commit("SET_FULLSCREN");
},
logout () {
this.$confirm("是否退出系统, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$store.dispatch("LogOut").then(() => {
this.$router.push({ path: "/login" });
});
});
}
}
};
</script>
<style lang="scss" scoped>
</style>
<template>
<el-breadcrumb separator="/"
class="avue-breadcrumb-list">
<template v-for="(item,index) in tagCurrent">
<el-breadcrumb-item :to="{ path: item.value }"
:key="index">{{item.label}}</el-breadcrumb-item>
</template>
</el-breadcrumb>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "breadcrumb",
data () {
return {};
},
created () { },
mounted () { },
watch: {},
computed: {
...mapGetters(["tagCurrent"])
},
methods: {}
};
</script>
<style lang="scss" scoped>
</style>
<template>
<el-color-picker size="small"
class="theme-picker"
popper-class="theme-picker-dropdown"
v-model="themeVal"></el-color-picker>
</template>
<script>
import color from "@/mixins/color";
export default {
name: "topColor",
mixins: [color()],
data () {
return {
chalk: ""
};
}
};
</script>
<style>
.theme-picker .el-color-picker__trigger {
vertical-align: middle;
}
.theme-picker-dropdown .el-color-dropdown__link-btn {
display: none;
}
</style>
<template>
<span>
<i class="icon-bofangqi-suoping"
@click="handleLock"></i>
<el-dialog title="设置锁屏密码"
:visible.sync="box"
width="30%"
append-to-body>
<el-form :model="form"
ref="form"
label-width="80px">
<el-form-item label="锁屏密码"
prop="passwd"
:rules="[{ required: true, message: '锁屏密码不能为空'}]">
<el-input v-model="form.passwd"
placeholder="请输入锁屏密码"></el-input>
</el-form-item>
</el-form>
<span slot="footer"
class="dialog-footer">
<el-button type="primary"
@click="handleSetLock">确 定</el-button>
</span>
</el-dialog>
</span>
</template>
<script>
import { validatenull } from "@/util/validate";
import { mapGetters } from "vuex";
export default {
name: "top-lock",
data () {
return {
box: false,
form: {
passwd: ""
}
};
},
created () { },
mounted () { },
computed: {
...mapGetters(["lockPasswd"])
},
props: [],
methods: {
handleSetLock () {
this.$refs["form"].validate(valid => {
if (valid) {
this.$store.commit("SET_LOCK_PASSWD", this.form.passwd);
this.handleLock();
}
});
},
handleLock () {
if (validatenull(this.lockPasswd)) {
this.box = true;
return;
}
this.$store.commit("SET_LOCK");
setTimeout(() => {
this.$router.push({ path: "/lock" });
}, 100);
}
},
components: {}
};
</script>
<style lang="scss" scoped>
</style>
<template>
<span @click="logsFlag?'':handleOpen()">
<el-badge :value="logsFlag?'':logsLen">
<i class="icon-bug"></i>
</el-badge>
<el-dialog title="日志"
fullscreen
:visible.sync="box"
width="100%"
append-to-body>
<logs></logs>
</el-dialog>
</span>
</template>
<script>
import { mapGetters } from "vuex";
import logs from '@/page/logs/index'
export default {
name: "top-logs",
components: { logs },
data () {
return {
box: false
};
},
created () {
},
mounted () { },
computed: {
...mapGetters(["logsFlag", "logsLen"]),
},
props: [],
methods: {
handleOpen () {
this.box = true;
}
}
};
</script>
<style lang="scss" scoped>
</style>
<template>
<div class="top-menu">
<el-menu :default-active="activeIndex"
mode="horizontal"
text-color="#333">
<template v-for="(item,index) in items">
<el-menu-item :index="item.parentId+''"
@click.native="openMenu(item)"
:key="index">
<template slot="title">
<i :class="item.icon"></i>
</template>
</el-menu-item>
</template>
</el-menu>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "top-menu",
data () {
return {
activeIndex: "0",
items: [
{
label: "首页",
href: "/wel/index",
icon: 'el-icon-menu',
parentId: 0
},
{
label: '文档',
href: 'https://www.kancloud.cn/lengleng/pig-guide/627970',
icon: 'el-icon-document',
parentId: 1
},
{
label: 'crud实例',
href: '/crud/index',
icon: 'el-icon-setting',
parentId: 2
}
]
};
},
created () { },
computed: {
...mapGetters(["tagCurrent", "menu"])
},
methods: {
openMenu (item) {
this.$store.dispatch("GetMenu", item.parentId).then(() => {
let itemActive,
childItemActive = 0;
if (item.href) {
itemActive = item;
} else {
if (this.menu[childItemActive].length == 0) {
itemActive = this.menu[childItemActive];
} else {
itemActive = this.menu[childItemActive].children[childItemActive];
}
}
this.$router.push({
path: this.$router.$avueRouter.getPath({
name: itemActive.label,
src: itemActive.href
})
});
});
}
}
};
</script>
\ No newline at end of file
<template>
<el-autocomplete class="top-search"
popper-class="my-autocomplete"
v-model="value"
:fetch-suggestions="querySearch"
placeholder="请输入搜索内容"
@select="handleSelect">
<template slot-scope="{ item }">
<i :class="[item[iconKey],'icon']"></i>
<div class="name">{{ item[labelKey] }}</div>
<p class="addr">{{ item[pathKey] }}</p>
</template>
</el-autocomplete>
</template>
<script>
import config from '../sidebar/config.js'
import { mapGetters } from "vuex";
export default {
data () {
return {
config: config,
value: '',
menuList: [],
}
},
created () {
this.getMenuList();
},
watch: {
menu () {
this.getMenuList();
}
},
computed: {
labelKey () { return this.website.menu.props.label || this.config.propsDefault.label },
pathKey () { return this.website.menu.props.path || this.config.propsDefault.path },
iconKey () { return this.website.menu.props.icon || this.config.propsDefault.icon },
childrenKey () { return this.website.menu.props.children || this.config.propsDefault.children },
...mapGetters(['menu', 'website'])
},
methods: {
getMenuList () {
const findMenu = (list) => {
for (let i = 0; i < list.length; i++) {
const ele = Object.assign({}, list[i]);
if (ele[this.childrenKey]) findMenu(ele[this.childrenKey]);
delete ele[this.childrenKey];
this.menuList.push(ele);
}
}
this.menuList = [];
findMenu(this.menu);
},
querySearch (queryString, cb) {
var restaurants = this.menuList;
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
// 调用 callback 返回建议列表的数据
cb(results);
},
createFilter (queryString) {
return (restaurant) => {
return (restaurant.label.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
};
},
handleSelect (item) {
this.value = '';
this.$router.push({
path: this.$router.$avueRouter.getPath({
name: item[this.labelKey],
src: item[this.pathKey]
}),
query: item.query
})
},
}
}
</script>
<style lang="scss">
.my-autocomplete {
li {
line-height: normal;
padding: 7px;
.icon {
margin-right: 5px;
display: inline-block;
vertical-align: middle;
}
.name {
display: inline-block;
text-overflow: ellipsis;
overflow: hidden;
vertical-align: middle;
}
.addr {
padding-top: 5px;
width: 100%;
font-size: 12px;
color: #b4b4b4;
}
.highlighted .addr {
color: #ddd;
}
}
}
</style>
\ No newline at end of file
<template>
<span class="setting">
<div class="setting__shade"
:class="{'setting__shade--show':isShade}"
@click="close"></div>
<i class="el-icon-more setting__icon"
@click="open"></i>
<div class="setting__content"
:class="{'setting__content--show':box}">
<div class="setting__header">版权信息</div>
<div class="setting__body setting__about">
<p>当前版本:avue-cli v2.x </p>
<p>基于框架:avue v2.x</p>
<a href="https://avue.top/#/component/avue2.x"
target="_blank">
<el-button type="primary">
获取源码
</el-button>
</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://pig4cloud.com"
target="_blank">
<el-button type="primary">
查看详情
</el-button>
</a>
</div>
<div class="setting__header">设置
<small>(滑动鼠标下面还有更多设置)</small>
</div>
<el-scrollbar style="height:500px">
<div class="setting__body setting__form">
<avue-form v-model="form"
:option="option"></avue-form>
</div>
</el-scrollbar>
</div>
</span>
</template>
<script>
import { mapState, mapGetters } from 'vuex'
import { validatenull } from '@/util/validate'
import { option, list } from '@/const/setting/'
export default {
data () {
return {
box: false,
form: {},
list: list,
option: option(this)
}
},
computed: {
...mapGetters(['isShade']),
...mapState({
showTag: state => state.common.showTag,
showDebug: state => state.common.showDebug,
showLock: state => state.common.showLock,
showColor: state => state.common.showColor,
showFullScren: state => state.common.showFullScren,
showCollapse: state => state.common.showCollapse,
showSearch: state => state.common.showSearch,
showMenu: state => state.common.showMenu,
showTheme: state => state.common.showTheme
})
},
created () {
this.init();
},
methods: {
close () {
this.box = false;
this.$store.commit('SET_SHADE', false);
},
set (key) {
const ele = this.find(key);
this.$store.commit(ele.commit, eval(this.form[ele.key]));
},
find (key) {
return this.list.filter(ele => ele.key === key)[0]
},
init () {
this.list.forEach(ele => {
this.form[ele.key] = validatenull(this[ele.key]) ? 'true' : this[ele.key] + '';
this.set(ele.key);
})
},
open () {
this.box = true;
this.$store.commit('SET_SHADE', true);
}
}
}
</script>
<style lang="scss" scoped>
.setting {
margin-left: 10px;
&__icon {
transform: rotate(90deg);
}
&__header {
height: 42px;
line-height: 42px;
padding: 0 15px;
border-bottom: 1px solid #f6f6f6;
color: #333;
border-radius: 2px 2px 0 0;
font-size: 14px;
small {
margin-left: 8px;
color: #999;
}
}
&__body {
padding: 10px 15px;
line-height: 24px;
}
&__about {
font-size: 14px;
line-height: 30px;
}
&__shade {
position: fixed;
display: none;
width: 100%;
height: 100%;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.3);
z-index: 2048;
&--show {
display: block;
}
}
&__form {
width: 230px;
margin: 0 auto;
}
&__content {
box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.1);
transition: all 0.3s;
position: fixed;
width: 320px;
height: 100%;
right: -450px;
top: 0;
z-index: 2048;
background-color: #fff;
&--show {
right: 0;
}
}
}
</style>
<template>
<div>
<el-dialog title="选择"
:visible.sync="box"
width="50%">
<el-radio-group v-model="text"
class="list">
<el-row :span="24">
<el-col v-for="(item,index) in list"
:key="index"
:md="4"
:xs="12"
:sm="4">
<el-radio :label="item.value">{{item.name}}</el-radio>
</el-col>
</el-row>
</el-radio-group>
</el-dialog>
<span>
<i class="el-icon-view"
@click="open"></i>
</span>
</div>
</template>
<script>
import { setTheme } from '@/util/util'
import { mapGetters } from 'vuex';
export default {
data () {
return {
box: false,
text: '',
list: [
{
name: '默认主题',
value: '',
}, {
name: '炫彩主题',
value: 'theme-star'
}, {
name: '黑色主题',
value: 'theme-black'
}, {
name: '渐变主题',
value: 'theme-gradual'
}
]
}
},
watch: {
text: function (val) {
this.$store.commit('SET_THEME_NAME', val);
setTheme(val);
}
},
computed: {
...mapGetters(["themeName"])
},
mounted () {
this.text = this.themeName;
if (!this.text) {
this.text = '';
}
},
methods: {
open () {
this.box = true;
}
}
}
</script>
<style lang="scss" scoped>
.list {
width: 100%;
}
</style>
<template>
<div class="lock-container pull-height">
<div class="lock-form animated bounceInDown">
<div class="animated"
:class="{'shake':passwdError,'bounceOut':pass}">
<h3 class="title">{{userInfo.username}}</h3>
<el-input placeholder="请输入登录密码"
type="password"
class="input-with-select animated"
v-model="passwd"
@keyup.enter.native="handleLogin">
<el-button slot="append"
icon="icon-bofangqi-suoping"
@click="handleLogin"></el-button>
<el-button slot="append"
icon="icon-tuichu"
@click="handleLogout"></el-button>
</el-input>
</div>
</div>
</div>
</template>
<script>
import { mapGetters, mapState } from "vuex";
export default {
name: "lock",
data () {
return {
passwd: "",
passwdError: false,
pass: false
};
},
created () { },
mounted () { },
computed: {
...mapState({
userInfo: state => state.user.userInfo
}),
...mapGetters(["tag", "lockPasswd"])
},
props: [],
methods: {
handleLogout () {
this.$confirm("是否退出系统, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$store.dispatch("LogOut").then(() => {
this.$router.push({ path: "/login" });
});
});
},
handleLogin () {
if (this.passwd != this.lockPasswd) {
this.passwd = "";
this.$message({
message: "解锁密码错误,请重新输入",
type: "error"
});
this.passwdError = true;
setTimeout(() => {
this.passwdError = false;
}, 1000);
return;
}
this.pass = true;
setTimeout(() => {
this.$store.commit("CLEAR_LOCK");
this.$router.push({ path: this.$router.$avueRouter.getPath({ src: this.tag.value }) });
}, 1000);
}
},
components: {}
};
</script>
<style lang="scss">
.lock-container {
display: flex;
align-items: center;
justify-content: center;
position: relative;
.title {
margin-bottom: 8px;
color: #333;
}
}
.lock-container::before {
z-index: -999;
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-image: url('/img/login.png');
background-size: cover;
}
.lock-form {
width: 300px;
}
</style>
\ No newline at end of file
<template>
<div></div>
</template>
<script>
import request from '@/router/axios'
import { mapGetters } from 'vuex'
export default {
name: 'authredirect',
computed: {
...mapGetters(['tagWel'])
},
created () {
const params = this.$route.query
const state = params.state
const code = params.code
const type = params.type
if (type === 'BIND') {
request({
url: '/admin/social/bind',
method: 'post',
params: { state, code }
}).then(() => {
this.$alert('社交账号绑定成功', '成功', {
confirmButtonText: '确定',
callback: action => {
window.close()
}
})
})
} else {
window.close()
window.opener.location.href = `${window.location.origin}/#/login?state=${state}&code=${code}`
}
}
}
</script>
<style>
</style>
<template>
<el-form class="login-form"
status-icon
:rules="loginRules"
ref="loginForm"
:model="loginForm"
label-width="0">
<el-form-item prop="phone">
<el-input size="small"
@keyup.enter.native="handleLogin"
v-model="loginForm.phone"
auto-complete="off"
placeholder="请输入手机号码">
<i slot="prefix"
class="icon-shouji"></i>
</el-input>
</el-form-item>
<el-form-item prop="code">
<el-input size="small"
@keyup.enter.native="handleLogin"
v-model="loginForm.code"
auto-complete="off"
placeholder="请输入验证码">
<i slot="prefix"
class="icon-yanzhengma"
style="margin-top:6px;"></i>
<template slot="append">
<span @click="handleSend"
class="msg-text"
:class="[{display:msgKey}]">{{msgText}}</span>
</template>
</el-input>
</el-form-item>
<el-form-item>
<el-button size="small"
type="primary"
@click.native.prevent="handleLogin"
class="login-submit">登录</el-button>
</el-form-item>
</el-form>
</template>
<script>
const MSGINIT = "发送验证码",
// MSGERROR = "验证码发送失败",
MSGSCUCCESS = "${time}秒后重发",
MSGTIME = 60;
import { isvalidatemobile } from "@/util/validate";
import { mapGetters } from "vuex";
export default {
name: "codelogin",
data () {
const validatePhone = (rule, value, callback) => {
if (isvalidatemobile(value)[0]) {
callback(new Error(isvalidatemobile(value)[1]));
} else {
callback();
}
};
const validateCode = (rule, value, callback) => {
if (value.length != 4) {
callback(new Error("请输入4位数的验证码"));
} else {
callback();
}
};
return {
msgText: MSGINIT,
msgTime: MSGTIME,
msgKey: false,
loginForm: {
phone: "17547400800",
code: ""
},
loginRules: {
phone: [{ required: true, trigger: "blur", validator: validatePhone }],
code: [{ required: true, trigger: "blur", validator: validateCode }]
}
};
},
created () { },
mounted () { },
computed: {
...mapGetters(["tagWel"])
},
props: [],
methods: {
handleSend () {
if (this.msgKey) return;
this.msgText = MSGSCUCCESS.replace("${time}", this.msgTime);
this.msgKey = true;
const time = setInterval(() => {
this.msgTime--;
this.msgText = MSGSCUCCESS.replace("${time}", this.msgTime);
if (this.msgTime == 0) {
this.msgTime = MSGTIME;
this.msgText = MSGINIT;
this.msgKey = false;
clearInterval(time);
}
}, 1000);
},
handleLogin () {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.$store.dispatch("LoginByPhone", this.loginForm).then(() => {
this.$router.push({ path: this.tagWel.value });
});
}
});
}
}
};
</script>
<style>
.msg-text {
display: block;
width: 60px;
font-size: 12px;
text-align: center;
cursor: pointer;
}
.msg-text.display {
color: #ccc;
}
</style>
<template>
<div class="login-container pull-height"
@keyup.enter.native="handleLogin">
<div class="login-logo animated fadeIn">
<img src="/svg/logo.svg"
alt="">
</div>
<div class="login-weaper">
<div class="login-left animated fadeInLeft">
<div class="login-info">
<h2 class="login-info-title">{{website.info.title}}</h2>
<ul class="login-info-list">
<li class="login-info-item"
v-for="(item,index) in website.info.list"
:key="index">
<i class="el-icon-check"></i>&nbsp;{{item}}
</li>
</ul>
<el-button type="primary"
size="small"
class="login-index">首页</el-button>
</div>
</div>
<div class="login-border animated fadeInRight">
<div class="login-main">
<h4 class="login-title">登录 {{website.title}}</h4>
<userLogin v-if="activeName==='user'"></userLogin>
<codeLogin v-else-if="activeName==='code'"></codeLogin>
<thirdLogin v-else-if="activeName==='third'"></thirdLogin>
</div>
<div class="login-menu">
<a href="#"
@click.stop="activeName='user'">账号密码</a>
<a href="#"
@click.stop="activeName='code'">手机号登录</a>
<a href="#"
@click.stop="activeName='third'">第三方登录</a>
</div>
</div>
</div>
</div>
</template>
<script>
import userLogin from "./userlogin";
import codeLogin from "./codelogin";
import thirdLogin from "./thirdlogin";
import topColor from "../index/top/top-color";
import color from "@/mixins/color";
import { mapGetters } from "vuex";
import { validatenull } from '@/util/validate'
export default {
name: "login",
mixins: [color()],
components: {
topColor,
userLogin,
codeLogin,
thirdLogin
},
data () {
return {
activeName: "user"
};
},
watch: {
$route () {
const params = this.$route.query
this.socialForm.state = params.state
this.socialForm.code = params.code
if (!validatenull(this.socialForm.state)) {
const loading = this.$loading({
lock: true,
text: `登录中,请稍后。。。`,
spinner: 'el-icon-loading'
})
setTimeout(() => {
loading.close()
}, 2000)
this.handleSocialLogin()
}
}
},
created () { },
mounted () { },
computed: {
...mapGetters(["website"])
},
props: [],
methods: {}
};
</script>
<style lang="scss">
.login-container {
position: relative;
width: 100%;
margin: 0 auto;
}
.login-weaper {
position: absolute;
top: 50%;
left: 0;
width: 100%;
height: 500px;
margin-top: -200px;
}
.login-container::before {
z-index: -1024;
content: "";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-image: url("/img/login.png");
background-size: cover;
}
.login-left {
float: left;
width: 50%;
position: relative;
}
.login-logo {
position: absolute;
top: 0;
left: 0;
padding-top: 50px;
font-size: 24px;
color: #333;
}
.login-info {
padding-left: 140px;
}
.login-info-title {
line-height: 90px;
color: rgb(52, 58, 64);
}
.login-info-item {
font-size: 14px;
line-height: 2.5;
color: rgb(33, 37, 41);
}
.login-border {
width: 50%;
float: left;
box-sizing: border-box;
}
.login-main {
margin: 0 auto;
width: 50%;
box-sizing: border-box;
}
.login-main > h3 {
margin-bottom: 20px;
}
.login-main > p {
color: #76838f;
}
.login-title {
margin-bottom: 40px;
font-weight: 500;
font-size: 22px;
text-align: center;
letter-spacing: 4px;
}
.login-menu {
width: 100%;
text-align: center;
a {
color: rgb(153, 153, 153);
font-size: 12px;
margin: 0px 8px;
}
}
.login-index {
margin-top: 40px;
width: 180px;
height: 48px;
text-align: center;
border-radius: 50px;
background: transparent;
color: #333;
font-size: 16px;
border: 1px solid rgb(152, 22, 244);
}
.login-submit {
display: block;
margin: 40px auto 10px auto;
width: 200px;
height: 48px;
font-size: 14px;
text-align: center;
border-radius: 50px;
border: 0px;
box-shadow: rgba(152, 22, 244, 0.19) 0px 5px 10px 2px;
}
.login-form {
margin: 10px 0;
i {
color: #999;
}
.el-form-item__content {
width: 100%;
}
.el-form-item {
margin-bottom: 12px;
}
.el-input {
input {
padding-bottom: 10px;
text-indent: 5px;
background: transparent;
border: none;
border-radius: 0;
color: #333;
border-bottom: 1px solid rgb(235, 237, 242);
}
.el-input__prefix {
i {
padding: 0 5px;
font-size: 16px !important;
}
}
}
}
.login-code {
display: flex;
align-items: center;
justify-content: space-around;
margin: 0 0 0 10px;
}
.login-code-img {
margin-top: 2px;
width: 100px;
height: 38px;
background-color: #fdfdfd;
border: 1px solid #f0f0f0;
color: #333;
font-size: 14px;
font-weight: bold;
letter-spacing: 5px;
line-height: 38px;
text-indent: 5px;
text-align: center;
}
</style>
\ No newline at end of file
<template>
<div class="social-container">
<div class="box"
@click="handleClick('wechat')">
<span class="container"
:style="{backgroundColor:'#6ba2d6'}">
<i icon-class="wechat"
class="iconfont icon-weixin"></i>
</span>
<p class="title">微信</p>
</div>
<div class="box"
@click="handleClick('tencent')">
<span class="container"
:style="{backgroundColor:'#8dc349'}">
<i icon-class="qq"
class="iconfont icon-qq"></i>
</span>
<p class="title">QQ</p>
</div>
</div>
</template>
<script>
import { openWindow } from '@/util/util'
export default {
name: 'social-signin',
methods: {
handleClick (thirdpart) {
let appid, client_id, redirect_uri, url
redirect_uri = encodeURIComponent(window.location.origin + '/#/authredirect')
if (thirdpart === 'wechat') {
appid = 'wxd1678d3f83b1d83a'
url = 'https://open.weixin.qq.com/connect/qrconnect?appid=' + appid + '&redirect_uri=' + redirect_uri + '&state=' + appid + '&response_type=code&scope=snsapi_login#wechat_redirect'
} else if (thirdpart === 'tencent') {
client_id = '101322838'
url = 'https://graph.qq.com/oauth2.0/authorize?response_type=code&state=' + appid + '&client_id=' + client_id + '&redirect_uri=' + redirect_uri
}
openWindow(url, thirdpart, 540, 540)
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.social-container {
margin: 20px 0;
display: flex;
align-items: center;
justify-content: space-around;
.box {
cursor: pointer;
}
.iconfont {
color: #fff;
font-size: 30px;
}
.container {
$height: 50px;
display: inline-block;
width: $height;
height: $height;
line-height: $height;
text-align: center;
border-radius: 4px;
margin-bottom: 10px;
}
.title {
text-align: center;
}
}
</style>
<template>
<el-form class="login-form"
status-icon
:rules="loginRules"
ref="loginForm"
:model="loginForm"
label-width="0">
<el-form-item prop="username">
<el-input size="small"
@keyup.enter.native="handleLogin"
v-model="loginForm.username"
auto-complete="off"
placeholder="请输入用户名">
<i slot="prefix"
class="icon-yonghu"></i>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input size="small"
@keyup.enter.native="handleLogin"
:type="passwordType"
v-model="loginForm.password"
auto-complete="off"
placeholder="请输入密码">
<i class="el-icon-view el-input__icon"
slot="suffix"
@click="showPassword"></i>
<i slot="prefix"
class="icon-mima"></i>
</el-input>
</el-form-item>
<el-form-item prop="code">
<el-row :span="24">
<el-col :span="16">
<el-input size="small"
@keyup.enter.native="handleLogin"
:maxlength="code.len"
v-model="loginForm.code"
auto-complete="off"
placeholder="请输入验证码">
<i slot="prefix"
class="icon-yanzhengma"></i>
</el-input>
</el-col>
<el-col :span="8">
<div class="login-code">
<span class="login-code-img"
@click="refreshCode"
v-if="code.type == 'text'">{{code.value}}</span>
<img :src="code.src"
class="login-code-img"
@click="refreshCode"
v-else/>
<!-- <i class="icon-shuaxin login-code-icon" @click="refreshCode"></i> -->
</div>
</el-col>
</el-row>
</el-form-item>
<el-checkbox v-model="checked">记住账号</el-checkbox>
<el-form-item>
<el-button type="primary"
size="small"
@click.native.prevent="handleLogin"
class="login-submit">登录</el-button>
</el-form-item>
</el-form>
</template>
<script>
import { randomLenNum } from "@/util/util";
import { mapGetters } from "vuex";
export default {
name: "userlogin",
data () {
return {
loginForm: {
username: "admin",
password: "123456",
code: "",
redomStr: ""
},
checked: false,
code: {
src: "/code",
value: "",
len: 4,
type: "image"
},
loginRules: {
username: [
{ required: true, message: "请输入用户名", trigger: "blur" }
],
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ min: 6, message: "密码长度最少为6位", trigger: "blur" }
],
code: [
{ required: true, message: "请输入验证码", trigger: "blur" },
{ min: 4, max: 4, message: "验证码长度为4位", trigger: "blur" }
]
},
passwordType: "password"
};
},
created () {
this.refreshCode();
},
mounted () { },
computed: {
...mapGetters(["tagWel"])
},
props: [],
methods: {
refreshCode () {
this.loginForm.code = ''
this.loginForm.randomStr = randomLenNum(this.code.len, true)
this.code.type === 'text'
? (this.code.value = randomLenNum(this.code.len))
: (this.code.src = `${this.codeUrl}?randomStr=${this.loginForm.randomStr}`)
},
showPassword () {
this.passwordType == ''
? (this.passwordType = 'password')
: (this.passwordType = '')
},
handleSocialLogin () {
this.$store.dispatch('LoginBySocial', this.socialForm).then(
() => {
this.$router.push({ path: this.tagWel.value });
}
)
},
handleLogin () {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.$store.dispatch("LoginByUsername", this.loginForm).then(() => {
this.$router.push({ path: this.tagWel.value });
}),
() => {
this.refreshCode()
}
}
});
}
}
};
</script>
<style>
</style>
<template>
<basic-container>
<p>请打开浏览器控制台,然后点击下面的按钮</p>
<el-button type="danger"
@click="handleNewError">触发一个错误</el-button>
</basic-container>
</template>
<script>
export default {
methods: {
handleNewError () {
console.log(a) // eslint-disable-line
}
}
}
</script>
\ No newline at end of file
<template>
<avue-crud :data="logsList"
:option="option">
<template slot="menuLeft">
<el-button type="primary"
size="small"
icon="el-icon-upload"
@click="send">上传服务器</el-button>
<el-button type="danger"
size="small"
icon="el-icon-delete"
@click="clear">清空本地日志</el-button>
</template>
<template slot-scope="scope"
slot="type">
<el-tag type="danger"
size="small">{{scope.label}}</el-tag>
</template>
<template slot-scope="props"
slot="expand">
<pre class="code">
{{props.row.stack}}
</pre>
</template>
</avue-crud>
</template>
<script>
import { mapGetters } from "vuex";
import option from '@/const/logs/index'
export default {
name: "errLogs",
data () {
return {
option: option
};
},
created () {
},
mounted () { },
computed: {
...mapGetters(["logsList"])
},
props: [],
methods: {
send () {
this.$confirm('确定上传本地日志到服务器?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$store.dispatch('SendLogs').then(() => {
this.$parent.$parent.box = false;
this.$message({
type: 'success',
message: '发送成功!'
});
});
}).catch(() => {
});
},
clear () {
this.$confirm('确定清空本地日志记录?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$store.commit('CLEAR_LOGS');
console.log(this);
this.$parent.$parent.box = false;
this.$message({
type: 'success',
message: '清空成功!'
});
}).catch(() => {
});
}
}
};
</script>
<style lang="scss" scoped>
.code {
font-size: 12px;
display: block;
font-family: monospace;
white-space: pre;
margin: 1em 0px;
}
</style>
<template>
<div>
<basic-container>
<div slot="header"
class="clearfix">
<span>404错误页面</span>
</div>
<div class="error-box">
<errorPage404 class="error-page"></errorPage404>
<span class="error-text">/404当访问的页面不存在时会跳转到404页面,您可以在浏览器地址栏中修改url为一个不存在的路径,体验一下效果</span>
</div>
</basic-container>
<basic-container>
<div slot="header"
class="clearfix">
<span>403错误页面</span>
</div>
<div class="error-box">
<errorPage403 class="error-page"></errorPage403>
<span class="error-text">/403在当前登录用户不具有执行当前操作的权限时跳转到该页面,您可以在ajax请求方法中判断返回的状态码为403时跳转到该页面</span>
</div>
</basic-container>
<basic-container>
<div slot="header"
class="clearfix">
<span>500错误页面</span>
</div>
<div class="error-box">
<errorPage500 class="error-page"></errorPage500>
<span class="error-text">/500当请求之后出现服务端错误时跳转到该页面,您可以在ajax请求方法中判断返回的状态码为500时跳转到该页面</span>
</div>
</basic-container>
</div>
</template>
<script>
import errorPage404 from "@/components/error-page/404.vue";
import errorPage403 from "@/components/error-page/403.vue";
import errorPage500 from "@/components/error-page/500.vue";
export default {
name: "errPage",
data () {
return {};
},
created () { },
mounted () { },
computed: {},
props: [],
methods: {},
components: { errorPage404, errorPage403, errorPage500 }
};
</script>
<style lang="scss" scoped>
.error-page {
position: absolute;
top: 90px;
left: 150px;
transform: scale(0.4);
}
.error-text {
position: absolute;
top: 20px;
left: 340px;
}
.error-box {
position: relative;
height: 200px;
}
</style>
<template>
<div>
<el-row :span="24">
<el-col :md="7"
:xs="24"
:sm="24">
<basic-container>
<div class="info">
<div class="img-border">
<a href="#">
<div class="img"><img src="https://gitee.com/uploads/61/632261_smallweigit.jpg"></div>
</a><img alt="用户等级"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAMAUExURUxpcf9dfP9aef9be/9dfP9gfv9hf/9kgP9eff+bm/9dff8yWf84XP82XP82XP84Xv9jgv84Xv83XP8xVv9BYv9Ia/89Yf89Y/8uVf9Fav8/Y/9igP9Hav8vV/9lgv8uVf8xW/8uVf9kgv8uVf8vWP9jgv8uWP9Vdf+A//9mhf9jgf9lgv9lgf9kgv9Wdf9lgv9Rcf9Nb/9Ocf9be/8xWP8yWP9AYP9gff9ig/9mgP9ff/85YP81W/8yWf86X/85Y/9aef9ZeP8xWP9AY/9Faf8xWf8zWv89Yf81W/8/ZP9JbP85cf9YeP9EaP9Zd/9FZ/87Yf86X/9Lbf9Xd/8uVv9Kbf8sVv9AZP9DZv9JbP9Ca/9Gaf9Daf9Wd/9Tc/8uVf9Nbf8tVP9Qdf9TdP9TdP9Mbf////9FaP9EZ/9Ja/9Lbf9aef9Wdv9ZeP9Gaf82XP9PcP9bev80Wv9KbP9BZf9AZP9efP86X/89Yv9fff8wV/9ce/9Xd/9Hav9gfv9UdP9Qcf9Vdf8xWP9Sc/83XP81W/83Xf88Yf8yWf87YP8+Yv9Nbv9Rcv9Yd/9Iav9CZv9Mbv8vVv8zWf8/Y/9Tc/9OcP9if/9DZv/+/v9Ob/9hf/85Xv84Xv9jgf8tVf9de/9dfP85X/8+Y/9TdP9Nb/9YeP9Ia/9JbP9Mbf9Haf9Wdf8zWv88YP9Scv+wv/9igP9cev80W/9CZf9BZP91j//3+f/Q2f9DZ//T3P97lf8yWP/r7//6+//W3f9Rcf+ltv9hfv94kf9+lv/g5v/z9f9eff/Q2P95kv+ouf/t8P++yv/m6//d5P/G0f/a4f9ffv+ywf+8yP+2w/+is/9Kbf+jtP+Vqf+fsf+cr/+OpP/S2v+Nov/V3f/5+v9lg//Dzv/j6P/J0//w8//M1v/G0P+Inv+Mof/s8P+/y//X3v+puf/h5v/v8v+5xv+ZrP+vvv/19/+Em//09v/9/f9ohf+4xf+0wv9phf/L1P9yjf+QpP+KoP+Spv+svP+ru/+Yq/TCRPAAAABmdFJOUwD+/lSgTrYEfAEsoxvxOCg/v9xRE+uT+3shf8jR0vPDD3RISCWeLtICOurApoRR2fCpi37GPQjyJyjzeOfL8RL19sckuD/MFejR9wm9cbqe8nveSf3cYs5u9B+2nEem/MRhRqNEwud7RXQAAARfSURBVDjLfZV3WFNXGMZv7aCtdlhnrbbWUUe1Vbv30Nq9996hCaE3hOxAck0gIWElBlISCAYoQhUMWCgCClopIFoVaRG02Kq4tdDSPf2+c26SCxLPn/f+nvd5z3fe8x6GGbyi3lu08J3nHhs3ecnTT17JnG1ddMNbCzhPqkMiTvw4+qNPFI9OWhyRfX6W0czJslMl8eKMz6JrMhVK14TxDw+LXvzEqmVZ5jRZ9qcAo3Lm50q7xvrMs1Fnsuc+kC5dVlTegDbixSuJDWWhtcyWO3rsUPamEcVSKVGWOUol4gyA1yqUdrtVrbZccdngnZ0XFxOLymaOIzbAM1HWlNkK8thLLhXCF+oBTpAai7LSZB7YYAnxrHAVgnKuhU1+ZFSYPf+cFRVE2ViOGwTPGYlE2WW1qgvyLMnypY8H2Tvu/Ioo89NIlXxTEp6GusDCspUpI4PwBVrVCmIDYE4mSy2l08hcqyy022CDoLza9BBlLzdo/aCcjp7NaZyHn3MNetZYbbl5LCtPMT1I4asMBtW+vXsP//QLeoY5SySoXEM9K9K1Wq1kdZ1uDLLT3F6t3zcggnXCbW4Az474lSHPu3vwx+/LTbopCM/0GsBzM34TbUnAQxHMuZV83i5fnqJzzmCY2XMDYENfRaRFbRx6pqmDE9zXvx6/t8hB2Xktw8zxeTeCsp5K96i4bEdpfAnOGVLXdqCpev3ANrYSla9hmPkBt3eHSh/HS7cL8+zbWr/lZFN/LU5D53xhKjPP5wbP+ooYKl0dK8jzms0/bK0/sgHmjMr51zHX+wIIx8VsyiH0b+E8qzZs3wZ4S1KyPKUO4OnMjWBDq/LDCX5B4P5VoTx3NK8D/A81OUGAX2Kuhg0a/HDcxbx0XzDPsV/vPwj4JksSC7DJmT8RYN5GbPoeAjcV8XPuPPp97/6DbZo8FjyjjYlow6ClqWuh0q00z9Jdv7YDXoV5rsRp5L+LG4Tjpnmm0gc4kudDfTt3nWrfaSd5JtOYzswLeA07+DzXEljUgXnOamz9D/A/+TybyOjm+9wbQ3leRxNSCtOo3d3RePzfRlcwzzrn21OZOYFAOM+89HFxYkLn/12AV4XybMLjnj3XC0GCORfjHaTSA11Vf3f/0/lj16logMno6kiQmJmY5+Ad/JJKD/T+dehwd8exPk0ZvbCQOt0MDD/JcwVRLjJ/R2lRTv2JkznVEg2WDNiAaUwJXStUlkqNxnJemq41LquNegblMfTCkjzztzvtWJitlkEV2AosScmQ55uDVYB5RhtGo7lBIN3nckF95VosOI1bePj22zDPxaCM/dwbZOsdSpcGewOzMVJQX4JGkjbzrI80EhQj5PmeWwXF6OdbFPvZ073n557N33qC/QwnePcoYY1C5Ubu56TBlQvaIyL385Ayx2fi/kj9PPq+YR6gp4bt53vvihr2vXpz1hn9PGH82MiP5vsLhP388qSzP7JRHyxa+OGLr46b/Pobr7w29OdpmH8aJmElL+MAAAAASUVORK5CYII="
class="img-v"></div>
<div class="user">
<div class="user-img">
<span style="user-title">smallwei</span>
<div class="user-subtitle">VIP用户</div>
</div>
<div class="user-item">绑定机构:Avue后台模版</div>
<div class="user-item">认证信息:hello 大家好!</div>
</div>
</div>
</basic-container>
</el-col>
<el-col :md="17"
:xs="24"
:sm="24">
<basic-container>
<avue-data-icons :option="easyDataOption2"></avue-data-icons>
</basic-container>
</el-col>
</el-row>
<basic-container>
<avue-data-box :option="easyDataOption"></avue-data-box>
</basic-container>
<basic-container>
<avue-crud :data="data"
:option="tableOption">
<template slot-scope="scope"
slot="username">
<el-tag>{{scope.row.username}}</el-tag>
</template>
<template slot-scope="scope"
slot="stars">
<a :href='scope.row.git'
target="_blank">
<img :src="scope.row.stars"
alt='star' />
</a>
</template>
<template slot-scope="scope"
slot="address">
<a :href="scope.row.git"
target="_blank">{{scope.row.address}}</a>
</template>
</avue-crud>
</basic-container>
</div>
</template>
<script>
export default {
name: "wel",
data () {
return {
tableOption: {
"border": true,
"index": true,
"expand": true,
"stripe": true,
"selection": true,
"page": false,
"menuBtn": true,
"menuWidth": 130,
"menuAlign": "center",
"align": "center",
"dic": ['type'],
"column": [{
"label": "用户名",
"prop": "username",
"width": 120,
"span": 24,
"solt": true,
"sortable": true,
"rules": [{
"required": true,
"message": "请输入用户名",
"trigger": "blur"
}]
},
{
"label": "类型",
"prop": "type",
"width": 80,
"type": "select",
"sortable": true,
"dicData": [{
label: '前端',
value: 0,
}, {
label: '后端',
value: 1,
}]
},
{
"label": "stars",
"width": "150",
"prop": "stars",
"sortable": true,
"solt": true,
},
{
"label": "码云",
"solt": true,
"span": 24,
"prop": "address",
"type": "textarea",
"overHidden": true
}, {
"label": "项目介绍",
"width": "300",
"prop": "info",
"editDisabled": true,
"formHeight": 200,
"type": "ueditor",
"span": 24,
"overHidden": true
},
]
},
data: [{
username: "lengleng",
name: "lengleng",
number: 12,
type: '0',
stars: 'https://gitee.com/log4j/pig/badge/star.svg?theme=white',
git: 'https://gitee.com/log4j/pig',
address: "https://gitee.com/log4j",
info: 'Pig是基于Spring Cloud、OAuth2.0,使用Vue前后分离的开发平台,支持账号、 短信、 SSO等多种登录。 ',
},
{
username: "smallwei",
name: "smallwei",
number: 20,
type: '1',
stars: 'https://gitee.com/smallweigit/avue/badge/star.svg?theme=white',
git: 'https://gitee.com/smallweigit/avue',
address: "https://gitee.com/smallweigit",
info: 'Avue是一个后台集成解决方案,它基于 Vue.js 和 element。 使用了最新的前端技术栈,支持权限验证,第三方网站嵌套等功能。',
}],
easyDataOption2: {
// color: 'rgb(63, 161, 255)',
span: 6,
discount: true,
data: [
{
title: '错误日志',
icon: 'icon-cuowu'
},
{
title: '数据展示',
icon: 'icon-shujuzhanshi2'
},
{
title: '权限管理',
icon: 'icon-jiaoseguanli'
},
{
title: '菜单管理',
icon: 'icon-caidanguanli'
}]
},
easyDataOption: {
data: [
{
title: '错误日志',
count: 12332,
icon: 'icon-cuowu',
color: 'rgb(49, 180, 141)',
},
{
title: '数据展示',
count: 33,
icon: 'icon-shujuzhanshi2',
color: 'rgb(56, 161, 242)',
},
{
title: '权限管理',
count: 2223,
icon: 'icon-jiaoseguanli',
color: 'rgb(117, 56, 199)',
},
]
}
};
},
computed: {
},
created () {
},
methods: {
}
};
</script>
<style scoped="scoped" lang="scss">
.info {
padding: 21px 0;
.img-border {
width: 64px;
height: 65px;
position: relative;
vertical-align: middle;
display: inline-block;
}
.img-v {
position: absolute;
bottom: -2px;
right: -2px;
width: 22px;
height: 22px;
}
.img {
border-radius: 5px;
width: 64px;
height: 64px;
display: inline-block;
overflow: hidden;
img {
display: block;
max-width: none;
height: 64px;
opacity: 1;
width: 64px;
margin-left: 0px;
margin-top: 0px;
}
}
.user {
margin-left: 20px;
display: inline-block;
color: rgb(153, 153, 153);
vertical-align: middle;
}
.user-title {
font-size: 18px;
color: rgb(102, 102, 102);
margin-right: 5px;
display: inline-block;
max-width: 200px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.user-subtitle {
display: inline-block;
width: 40px;
height: 16px;
line-height: 16px;
border-radius: 2px;
padding: 0px 5px;
margin-left: 10px;
font-size: 12px;
text-align: center;
color: rgb(255, 44, 84);
background-color: rgb(255, 242, 244);
white-space: nowrap;
}
.user-item {
font-size: 12px;
line-height: 20px;
}
}
</style>
import router from './router/router'
import store from './store'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { asyncRouterMap } from '@/router/router'
NProgress.configure({ showSpinner: false });
const lockPage = store.getters.website.lockPage; //锁屏页
const whiteList = store.getters.website.whiteList; //不鉴权白名单
const whiteTagList = store.getters.website.whiteTagList; //不加tags白名单
router.addRoutes(asyncRouterMap);
router.beforeEach((to, from, next) => {
NProgress.start()
if (store.getters.access_token) {
if (store.getters.isLock && to.path != lockPage) {
next({ path: lockPage })
} else if (to.path === '/login') {
next({ path: '/' })
} else {
if (store.getters.roles.length === 0) {
store.dispatch('GetUserInfo').then(() => {
next({...to, replace: true })
}).catch(() => {
store.dispatch('FedLogOut').then(() => {
next({ path: '/login' })
})
})
} else {
if (!router.$avueRouter.vaildPath(whiteTagList, to.path)) {
const value = to.query.src ? to.query.src : to.path;
const label = to.query.name ? to.query.name : to.name;
store.commit('ADD_TAG', {
label: label,
value: value,
params: to.params,
query: to.query
});
}
next()
}
}
} else {
if (router.$avueRouter.vaildPath(whiteList, to.path)) {
next()
} else {
next('/login')
}
}
})
router.afterEach(() => {
NProgress.done();
const title = store.getters.tag.label;
router.$avueRouter.setTitle(title);
});
//正则验证路由
\ No newline at end of file
let RouterPlugin = function() {
this.$router = null;
};
RouterPlugin.install = function(router, store) {
this.$router = router;
this.$store = store;
function objToform(obj) {
let result = [];
Object.keys(obj).forEach(ele => {
result.push(`${ele}=${obj[ele]}`);
})
return result.join('&');
}
this.$router.$avueRouter = {
// 设置标题
setTitle: function(title) {
title = title ? `${title}——Avue 通用管理 系统快速开发框架` : 'Avue 通用管理 系统快速开发框架';
document.title = title;
},
closeTag: (value) => {
const tag = value || this.$store.getters.tag;
this.$store.commit('DEL_TAG', tag)
},
//处理路由
getPath: function(params) {
let { src } = params;
let result = src || '/';
if (src.includes("http") || src.includes("https")) {
result = `/myiframe/urlPath?${objToform(params)}`;
}
return result;
},
//正则处理路由
vaildPath: function(list, path) {
let result = false;
list.forEach(ele => {
if (new RegExp("^" + ele + ".*", "g").test(path)) {
result = true
}
})
return result;
},
//设置路由值
getValue: function(route) {
let value = "";
if (route.query.src) {
value = route.query.src;
} else {
value = route.path;
}
return value;
},
//动态路由
formatRoutes: function(aMenu, first) {
const aRouter = []
aMenu.forEach(oMenu => {
const {
path,
component,
name,
icon,
children
} = oMenu
if (component) {
const isChild = children.length !== 0
const oRouter = {
path: path,
component(resolve) {
// 判断是否为首路由
if (first) {
require(['../page/index'], resolve)
return
// 判断是否为多层路由
} else if (isChild && !first) {
require(['../page/index/layout'], resolve)
return
// 判断是否为最终的页面视图
} else {
require([`../${component}.vue`], resolve)
}
},
name: name,
icon: icon,
redirect: (() => {
if (!isChild && first) return `${path}/index`
else return '';
})(),
// 处理是否为一级路由
children: !isChild ? (() => {
if (first) {
return [{
component(resolve) { require([`../${component}.vue`], resolve) },
icon: icon,
name: name,
path: 'index'
}]
}
return [];
})() : (() => {
return this.formatRoutes(children, false)
})()
}
aRouter.push(oRouter)
}
})
return aRouter
}
}
}
export default RouterPlugin;
\ No newline at end of file
/**
*
* http配置
*
*/
// 引入axios以及element ui中的loading和message组件
import axios from 'axios'
import store from '../store'
import { getToken } from '@/util/auth'
import NProgress from 'nprogress' // progress bar
import errorCode from '@/const/errorCode'
import { Message } from 'element-ui'
import 'nprogress/nprogress.css' // progress bar style
axios.defaults.timeout = 30000;
//返回其他状态吗
// axios.defaults.validateStatus = function(status) {
// return status >= 200 && status < 500; // 默认的
// };
//跨域请求,允许保存cookie
axios.defaults.withCredentials = true;
NProgress.configure({ showSpinner: false }) // NProgress Configuration
//HTTPrequest拦截
axios.interceptors.request.use(config => {
NProgress.start() // start progress bar
if (store.getters.access_token) {
config.headers['TENANT_ID'] = '1' // 租户ID
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
}
return config
}, error => {
console.log('err' + error) // for debug
return Promise.reject(error)
})
//HTTPresponse拦截
axios.interceptors.response.use(data => {
NProgress.done();
return data
}, error => {
NProgress.done()
let errMsg = error.toString()
let code = errMsg.substr(errMsg.indexOf('code') + 5)
Message({
message: errorCode[code] || errorCode['default'],
type: 'error'
})
return Promise.reject(new Error(error))
})
export default axios
\ No newline at end of file
import Layout from '@/page/index/'
export default [{
path: '*',
redirect: '/404',
hidden: true
}, {
path: '/login',
name: '登录页',
component: () =>
import ( /* webpackChunkName: "page" */ '@/page/login/index'),
meta: {
keepAlive: true,
}
},
{
path: '/authredirect',
name: '授权页',
component: () =>
import ( /* webpackChunkName: "page" */ '@/page/login/authredirect')
},
{
path: '/lock',
name: '锁屏页',
component: () =>
import ( /* webpackChunkName: "page" */ '@/page/lock/index'),
},
{
path: '/404',
component: () =>
import ( /* webpackChunkName: "page" */ '@/components/error-page/404'),
name: '404'
},
{
path: '/403',
component: () =>
import ( /* webpackChunkName: "page" */ '@/components/error-page/403'),
name: '403'
},
{
path: '/500',
component: () =>
import ( /* webpackChunkName: "page" */ '@/components/error-page/500'),
name: '500'
},
{
path: '/',
name: '主页',
redirect: '/wel'
},
{
path: '/wel',
component: Layout,
redirect: '/wel/index',
children: [{
path: 'index',
name: '首页',
component: () =>
import ( /* webpackChunkName: "page" */ '@/page/wel'),
}]
},
{
path: '/myiframe',
component: Layout,
redirect: '/myiframe',
children: [{
path: ":routerPath",
name: 'iframe',
component: () =>
import ( /* webpackChunkName: "page" */ '@/components/iframe/main'),
props: true
}]
}
]
\ No newline at end of file
import VueRouter from 'vue-router';
import PageRouter from './page/'
import ViewsRouter from './views/'
import AvueRouter from './avue-router';
import Store from '../store/';
let Router = new VueRouter({
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
if (from.meta.keepAlive) {
from.meta.savedPosition = document.body.scrollTop;
}
return {
x: 0,
y: to.meta.savedPosition || 0
}
}
},
routes: [].concat([])
});
AvueRouter.install(Router, Store);
Router.addRoutes(Router.$avueRouter.formatRoutes(Store.state.user.menu, true));
export default Router;
export const asyncRouterMap = [].concat(PageRouter, ViewsRouter)
\ No newline at end of file
import Layout from '@/page/index/'
export default [{
path: '/info',
component: Layout,
redirect: '/info/index',
children: [{
path: 'index',
name: '首页',
component: () =>
import ( /* webpackChunkName: "views" */ '@/views/admin/user/info')
}]
}, {
path: '/crud',
component: Layout,
redirect: '/crud/index',
children: [{
path: 'index',
name: 'CRUD例子',
component: () =>
import ( /* webpackChunkName: "views" */ '@/views/crud/index')
}]
}]
\ No newline at end of file
const getters = {
tag: state => state.tags.tag,
website: state => state.common.website,
userInfo: state => state.user.userInfo,
theme: state => state.common.theme,
themeName: state => state.common.themeName,
isShade: state => state.common.isShade,
isCollapse: state => state.common.isCollapse,
keyCollapse: (state, getters) => getters.screen > 1 ? getters.isCollapse : false,
screen: state => state.common.screen,
isLock: state => state.common.isLock,
isFullScren: state => state.common.isFullScren,
lockPasswd: state => state.common.lockPasswd,
tagList: state => state.tags.tagList,
tagWel: state => state.tags.tagWel,
access_token: state => state.user.access_token,
refresh_token: state => state.user.refresh_token,
roles: state => state.user.roles,
permissions: state => state.user.permissions,
menu: state => state.user.menu,
menuAll: state => state.user.menuAll,
logsList: state => state.logs.logsList,
logsLen: state => state.logs.logsList.length || 0,
logsFlag: (state, getters) => getters.logsLen === 0
}
export default getters
\ No newline at end of file
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import common from './modules/common'
import tags from './modules/tags'
import logs from './modules/logs'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user,
common,
logs,
tags
},
getters,
})
export default store
\ No newline at end of file
import {
setStore,
getStore,
removeStore
} from '@/util/store'
import website from '@/const/website'
const common = {
state: {
isCollapse: false,
isFullScren: false,
isShade: false,
screen: -1,
isLock: getStore({ name: 'isLock' }) || false,
showTag: getStore({ name: 'showTag' }),
showDebug: getStore({ name: 'showDebug' }),
showCollapse: getStore({ name: 'showCollapse' }),
showSearch: getStore({ name: 'showSearch' }),
showLock: getStore({ name: 'showLock' }),
showFullScren: getStore({ name: 'showFullScren' }),
showTheme: getStore({ name: 'showTheme' }),
showColor: getStore({ name: 'showColor' }),
showMenu: getStore({ name: 'showMenu' }),
theme: getStore({ name: 'theme' }) || '#409EFF',
themeName: getStore({ name: 'themeName' }) || '',
lockPasswd: getStore({ name: 'lockPasswd' }) || '',
website: website,
},
actions: {
},
mutations: {
SET_SHADE: (state, active) => {
state.isShade = active;
},
SET_COLLAPSE: (state) => {
state.isCollapse = !state.isCollapse;
},
SET_FULLSCREN: (state) => {
state.isFullScren = !state.isFullScren;
},
SET_SHOWCOLLAPSE: (state, active) => {
state.showCollapse = active;
setStore({
name: 'showCollapse',
content: state.showCollapse
})
},
SET_SHOWTAG: (state, active) => {
state.showTag = active;
setStore({
name: 'showTag',
content: state.showTag
})
},
SET_SHOWMENU: (state, active) => {
state.showMenu = active;
setStore({
name: 'showMenu',
content: state.showMenu
})
},
SET_SHOWLOCK: (state, active) => {
state.showLock = active;
setStore({
name: 'showLock',
content: state.showLock
})
},
SET_SHOWSEARCH: (state, active) => {
state.showSearch = active;
setStore({
name: 'showSearch',
content: state.showSearch
})
},
SET_SHOWFULLSCREN: (state, active) => {
state.showFullScren = active;
setStore({
name: 'showFullScren',
content: state.showFullScren
})
},
SET_SHOWDEBUG: (state, active) => {
state.showDebug = active;
setStore({
name: 'showDebug',
content: state.showDebug
})
},
SET_SHOWTHEME: (state, active) => {
state.showTheme = active;
setStore({
name: 'showTheme',
content: state.showTheme
})
},
SET_SHOWCOLOR: (state, active) => {
state.showColor = active;
setStore({
name: 'showColor',
content: state.showColor
})
},
SET_LOCK: (state) => {
state.isLock = true;
setStore({
name: 'isLock',
content: state.isLock,
type: 'session'
})
},
SET_SCREEN: (state, screen) => {
state.screen = screen;
},
SET_THEME: (state, color) => {
state.theme = color;
setStore({
name: 'theme',
content: state.theme,
})
},
SET_THEME_NAME: (state, themeName) => {
state.themeName = themeName;
setStore({
name: 'themeName',
content: state.themeName,
})
},
SET_LOCK_PASSWD: (state, lockPasswd) => {
state.lockPasswd = lockPasswd;
setStore({
name: 'lockPasswd',
content: state.lockPasswd,
type: 'session'
})
},
CLEAR_LOCK: (state) => {
state.isLock = false;
state.lockPasswd = '';
removeStore({
name: 'lockPasswd'
});
removeStore({
name: 'isLock'
});
},
}
}
export default common
\ No newline at end of file
import { setStore, getStore } from '@/util/store'
import { dateFormat } from '@/filters/'
import { sendLogs } from '@/api/log'
const logs = {
state: {
logsList: getStore({ name: 'logsList' }) || [],
},
actions: {
//发送错误日志
SendLogs({ state, commit }) {
return new Promise((resolve, reject) => {
sendLogs(state.logsList).then(() => {
commit('CLEAR_LOGS');
resolve();
}).catch(error => {
reject(error)
})
})
},
},
mutations: {
ADD_LOGS: (state, { type, message, stack, info }) => {
state.logsList.push(Object.assign({
url: window.location.href,
time: dateFormat(new Date())
}, {
type,
message,
stack,
info: info.toString()
}))
setStore({ name: 'logsList', content: state.logsList })
},
CLEAR_LOGS: (state) => {
state.logsList = [];
setStore({ name: 'logsList', content: state.logsList })
}
}
};
export default logs;
\ No newline at end of file
import { setStore, getStore } from '@/util/store'
import { isObjectValueEqual } from '@/util/util'
const tagObj = {
label: '', //标题名称
value: '', //标题的路径
params: '', //标题的路径参数
query: '', //标题的参数
}
//处理首个标签
function setFistTag(list) {
if (list.length == 1) {
list[0].close = false;
} else {
list.some(a => {
a.close = true
})
}
}
const navs = {
state: {
tagList: getStore({ name: 'tagList' }) || [],
tag: getStore({ name: 'tag' }) || tagObj,
tagWel: {
label: "首页",
value: "/wel/index",
params: {},
query: {},
close: false
}
},
actions: {
},
mutations: {
ADD_TAG: (state, action) => {
state.tag = action;
setStore({ name: 'tag', content: state.tag, type: 'session' })
if (state.tagList.some(ele => isObjectValueEqual(ele, action))) return
state.tagList.push(action)
setFistTag(state.tagList);
setStore({ name: 'tagList', content: state.tagList, type: 'session' })
},
DEL_TAG: (state, action) => {
state.tagList = state.tagList.filter(item => {
if (typeof(action) === 'object') {
let a = Object.assign({}, item);
let b = Object.assign({}, action);
delete a.close;
delete b.__ob__;
return !isObjectValueEqual(a, b)
} else {
return item.value !== action
}
})
setFistTag(state.tagList);
setStore({ name: 'tagList', content: state.tagList, type: 'session' })
},
DEL_ALL_TAG: (state) => {
state.tagList = [state.tagWel];
setStore({ name: 'tagList', content: state.tagList, type: 'session' })
},
DEL_TAG_OTHER: (state) => {
state.tagList = state.tagList.filter(item => item.value === state.tag.value)
setFistTag(state.tagList);
setStore({ name: 'tagList', content: state.tagList, type: 'session' })
},
}
}
export default navs
\ No newline at end of file
import { setToken, removeToken } from '@/util/auth'
import { setStore, getStore } from '@/util/store'
import { logout, loginByUsername, loginBySocial, getUserInfo } from '@/api/login'
import { encryption } from '@/util/util'
import { GetMenu } from '@/api/menu'
function addPath(ele) {
ele.children.forEach(child => {
const isChild = ele.children.length !== 0;
if (isChild) {
if (!child.path.includes('http') && !child.path.includes('https')) {
child.path = `${ele.path}/${child.path?child.path:'index'}`
}
addPath(child);
}
})
}
const user = {
state: {
userInfo: {},
permissions: {},
roles: [],
menu: getStore({
name: 'menu'
}) || [],
menuAll: [],
access_token: getStore({
name: 'access_token'
}) || '',
refresh_token: getStore({
name: 'refresh_token'
}) || ''
},
actions: {
//根据用户名登录
LoginByUsername({ commit }, userInfo) {
const user = encryption({
data: userInfo,
key: 'pigxpigxpigxpigx',
param: ['password']
})
return new Promise((resolve, reject) => {
loginByUsername(user.username, user.password, user.code, user.randomStr).then(response => {
const data = response.data
setToken(data.access_token)
commit('SET_ACCESS_TOKEN', data.access_token)
commit('SET_REFRESH_TOKEN', data.refresh_token)
commit('CLEAR_LOCK')
resolve()
}).catch(error => {
reject(error)
})
})
},
//根据手机号登录
LoginByPhone({ commit }, userInfo) {
return new Promise((resolve) => {
loginByUsername(userInfo.phone, userInfo.code).then(res => {
const data = res.data;
commit('SET_TOKEN', data);
commit('DEL_ALL_TAG');
commit('CLEAR_LOCK');
setToken(data);
resolve();
})
})
},
// 根据OpenId登录
LoginBySocial({ commit }, param) {
return new Promise((resolve, reject) => {
loginBySocial(param.state, param.code).then(response => {
const data = response.data
setToken(data.access_token)
commit('SET_ACCESS_TOKEN', data.access_token)
commit('SET_REFRESH_TOKEN', data.refresh_token)
commit('CLEAR_LOCK')
resolve()
}).catch(error => {
reject(error)
})
})
},
GetUserInfo({ commit }) {
return new Promise((resolve) => {
getUserInfo().then((res) => {
const data = res.data.data;
commit('SET_USERIFNO', data.sysUser);
commit('SET_ROLES', data.roles);
commit('SET_PERMISSIONS', data.permissions)
resolve(data);
})
})
},
//刷新token
RefeshToken({ commit }) {
return new Promise((resolve, reject) => {
logout().then(() => {
commit('SET_TOKEN', new Date().getTime());
setToken();
resolve();
}).catch(error => {
reject(error)
})
})
},
// 登出
LogOut({ commit }) {
return new Promise((resolve, reject) => {
logout().then(() => {
commit('SET_MENU', [])
commit('SET_PERMISSIONS', [])
commit('SET_USER_INFO', {})
commit('SET_ACCESS_TOKEN', '')
commit('SET_REFRESH_TOKEN', '')
commit('SET_ROLES', [])
commit('DEL_ALL_TAG')
commit('CLEAR_LOCK');
removeToken()
resolve()
}).catch(error => {
reject(error)
})
})
},
//注销session
FedLogOut({ commit }) {
return new Promise(resolve => {
commit('SET_MENU', [])
commit('SET_PERMISSIONS', [])
commit('SET_USER_INFO', {})
commit('SET_ACCESS_TOKEN', '')
commit('SET_REFRESH_TOKEN', '')
commit('SET_ROLES', [])
commit('DEL_ALL_TAG')
commit('CLEAR_LOCK');
removeToken()
resolve()
})
},
//获取系统菜单
GetMenu({
commit
}) {
return new Promise(resolve => {
GetMenu().then((res) => {
const data = res.data
data.forEach(ele => {
addPath(ele);
})
commit('SET_MENU', data)
resolve(data)
})
})
}
},
mutations: {
SET_ACCESS_TOKEN: (state, access_token) => {
state.access_token = access_token
setStore({
name: 'access_token',
content: state.access_token,
type: 'session'
})
},
SET_REFRESH_TOKEN: (state, rfToken) => {
state.refresh_token = rfToken
setStore({
name: 'refresh_token',
content: state.refresh_token,
type: 'session'
})
},
SET_USERIFNO: (state, userInfo) => {
state.userInfo = userInfo;
},
SET_MENU: (state, menu) => {
state.menu = menu
setStore({
name: 'menu',
content: state.menu,
type: 'session'
})
},
SET_MENU_ALL: (state, menuAll) => {
state.menuAll = menuAll;
},
SET_ROLES: (state, roles) => {
state.roles = roles;
},
SET_PERMISSIONS: (state, permissions) => {
const list = {}
for (let i = 0; i < permissions.length; i++) {
list[permissions[i]] = true
}
state.permissions = list
}
}
}
export default user
\ No newline at end of file
// 过渡动画 横向渐变
.fade-transverse-leave-active,
.fade-transverse-enter-active {
transition: all .5s;
}
.fade-transverse-enter {
opacity: 0;
transform: translateX(-30px);
}
.fade-transverse-leave-to {
opacity: 0;
transform: translateX(30px);
}
// 过渡动画 缩放渐变
.fade-scale-leave-active,
.fade-scale-enter-active {
transition: all .5s;
}
.fade-scale-enter {
opacity: 0;
transform: scale(1.2);
}
.fade-scale-leave-to {
opacity: 0;
transform: scale(0.8);
}
\ No newline at end of file
// 全局变量
@import './variables.scss';
// ele样式覆盖
@import './element-ui.scss';
// 顶部右侧显示
@import './top.scss';
// 导航标签
@import './tags.scss';
// 工具类函数
@import './mixin.scss';
// 侧面导航栏
@import './sidebar.scss';
// 动画
@import './animate/vue-transition.scss';
//主题
@import './theme/index.scss';
//适配
@import './media.scss';
.h1,
.h2,
.h3,
.h4,
.h5,
.h6,
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 500;
}
@include scrollBar();
body,
div,
dl,
dt,
dd,
ul,
ol,
li,
h1,
h2,
h3,
h4,
h5,
h6,
pre,
form,
fieldset,
input,
p,
blockquote,
th,
td {
margin: 0;
padding: 0;
}
* {
outline: none !important;
}
body {
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
line-height: 2;
}
html,
body {
height: 100%;
}
fieldset,
img {
border: 0;
}
ol,
ul {
list-style: none;
}
em {
font-style: normal;
}
input,
button,
select,
textarea {
outline: none;
}
textarea {
resize: none;
}
//为了使文本段落左右两边对齐
p {
word-wrap: break-word
}
a {
text-decoration: none;
}
i {
display: inline-block;
}
/*a:hover { color: #f60; text-decoration:none; }*/
address,
cite,
code,
em,
th {
font-weight: normal;
font-style: normal;
}
a {
color: inherit;
text-decoration: none;
display: inline-block;
}
/*a:link{color:#009;}*/
/*a:visited{color:#800080;}*/
a:hover,
a:active,
a:focus {
text-decoration: underline;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
.hidden {
display: none;
}
.padding {
padding: 0 !important;
}
.margin {
margin: 0 !important;
}
.pull-right {
float: right !important;
;
}
.pull-left {
float: left !important;
}
.pull-center {
text-align: center;
}
.pull-flex {
display: flex;
}
.pull-overflow {
overflow: hidden;
}
.pull-auto {
height: auto;
overflow: hidden;
}
.pull-height {
height: 100%;
overflow: hidden;
}
.pull-fixed {
position: fixed;
left: 0;
top: 0;
}
.text-white {
color: #fff;
}
.grayMode {
filter: grayscale(100%);
}
\ No newline at end of file
.el-dropdown-menu__item {
font-size: 12px;
line-height: 28px;
}
.el-card.is-always-shadow {
box-shadow: none;
}
.el-scrollbar__view {
height: 100%;
}
.el-menu--horizontal {
border-bottom: none !important;
}
.el-menu {
border-right: none !important;
}
.el-menu--display,
.el-menu--display+.el-submenu__icon-arrow {
display: none;
}
.el-dropdown-menu__item--divided:before,
.el-menu,
.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus,
.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,
.el-menu--horizontal>.el-submenu .el-submenu__title:hover {
background-color: transparent;
}
.el-message__icon,
.el-message__content {
display: inline-block;
}
.el-date-editor .el-range-input,
.el-date-editor .el-range-separator {
height: auto;
overflow: hidden;
}
.el-dialog__wrapper {
z-index: 2048;
}
.el-scrollbar__wrap {
overflow-x: hidden;
}
.el-col {
margin-bottom: 8px;
}
.el-main {
padding: 0 !important;
}
\ No newline at end of file
.avue-left,
.avue-header,
.avue-top,
.avue-logo,
.login-logo,
.avue-main {
transition: all .3s;
}
.avue-contail {
width: 100%;
height: 100%;
background-color: #f2f2f2;
background-size: 100%;
background-repeat: no-repeat;
}
.avue-top {
position: relative;
width: 100%;
height: 50px;
margin: 0 auto;
}
.avue-left {
position: fixed;
left: 0;
top: 0;
width: 220px;
height: 100%;
z-index: 1025;
}
.avue--collapse {
.avue-left,
.avue-logo {
width: 60px;
}
.avue-header {
padding-left: 60px;
}
.avue-main {
width: calc(100% - 60px);
left: 60px;
}
}
.avue-header {
padding-left: 240px;
width: 100%;
background-color: #fff;
box-sizing: border-box;
}
.avue-main {
position: absolute;
left: 220px;
margin-top: 5px;
padding: 0;
padding-bottom: 20px;
width: calc(100% - 220px);
height: calc(100% - 57px);
box-sizing: border-box;
overflow: hidden;
}
.avue-view {
padding-bottom: 22px;
width: 100%;
box-sizing: border-box;
}
.avue-footer {
margin: 0 auto;
padding: 0 22px;
width: 1300px;
display: flex;
align-items: center;
justify-content: space-between;
.logo {
margin-left: -50px;
}
.copyright {
color: #666;
line-height: 1.5;
font-size: 12px;
}
}
.avue-shade {
position: fixed;
display: none;
width: 100%;
height: 100%;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .3);
z-index: 1024;
&--show {
display: block;
}
}
@media screen and (max-width: 992px) {
$width: 220px;
// ele的自适应
.el-dialog,
.el-message-box {
width: 98% !important;
}
//登录页面
.login-left {
display: none !important;
}
.login-logo {
padding-top: 30px !important;
margin-left: -30px;
}
.login-border {
margin: 0 auto;
float: none !important;
width: 86% !important;
}
.login-main {
width: 100% !important;
}
//主框架
.avue-tags {
display: none;
}
.avue-left,
.avue-logo {
left: -$width;
}
.avue-main {
left: 0;
width: 100%;
}
.avue-header {
margin-bottom: 15px;
padding-left: 15px;
}
.top-bar__item {
display: none;
}
.avue-top {
.top-menu {
.el-menu-item {
padding: 0 2px;
}
}
}
.avue--collapse {
.avue-left,
.avue-logo {
width: $width;
left: 0;
}
.avue-main {
left: $width;
width: 100%;
}
.avue-header {
padding: 0;
transform: translate3d(230px, 0, 0);
}
.avue-shade {
display: block;
}
}
}
\ No newline at end of file
@mixin clearfix {
&:after {
content: "";
display: table;
clear: both;
}
}
@mixin scrollBar {
::-webkit-scrollbar-track-piece {
background-color: transparent;
}
::-webkit-scrollbar {
width: 7px;
height: 7px;
background-color: transparent;
}
::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: hsla(220, 4%, 58%, .3);
}
}
@mixin radius($width, $size, $color) {
width: $width;
height: $width;
line-height: $width;
border-radius: $width;
text-align: center;
border-width: $size;
border-style: solid;
border-color: $color;
}
@mixin relative {
position: relative;
width: 100%;
height: 100%;
}
@mixin pct($pct) {
width: #{$pct};
position: relative;
margin: 0 auto;
}
@mixin triangle($width, $height, $color, $direction) {
$width: $width/2;
$color-border-style: $height solid $color;
$transparent-border-style: $width solid transparent;
height: 0;
width: 0;
@if $direction==up {
border-bottom: $color-border-style;
border-left: $transparent-border-style;
border-right: $transparent-border-style;
}
@else if $direction==right {
border-left: $color-border-style;
border-top: $transparent-border-style;
border-bottom: $transparent-border-style;
}
@else if $direction==down {
border-top: $color-border-style;
border-left: $transparent-border-style;
border-right: $transparent-border-style;
}
@else if $direction==left {
border-right: $color-border-style;
border-top: $transparent-border-style;
border-bottom: $transparent-border-style;
}
}
\ No newline at end of file
.avue-sidebar {
padding-top: 60px;
height: 100%;
position: relative;
background-color: #20222a;
transition: width .6s;
box-sizing: border-box;
.el-menu-item,
.el-submenu__title {
font-size: 14px;
height: 56px;
line-height: 56px;
}
.el-menu-item {
&:hover {
background-color: transparent !important;
color: #fff;
span,
i {
color: #fff;
}
}
&.is-active {
background-color: rgba(0, 0, 0, .8) !important;
span,
i {
color: #fff;
}
&:hover {
background-color: rgba(0, 0, 0, .8) !important;
}
&::before {
content: " ";
top: 0;
left: 0;
bottom: 0;
width: 4px;
background: $mainBg;
position: absolute
}
}
}
.el-submenu__title {
&:hover {
i,
span {
color: #fff;
}
background-color:transparent !important;
}
}
.el-submenu .el-menu-item {
height: 50px;
line-height: 50px;
&.is-active {
background-color: rgba(0, 0, 0, .8) !important;
span,
i {
color: #fff
}
&:hover {
background-color: rgba(0, 0, 0, .8) !important;
}
}
&:hover {
background-color: transparent !important;
span,
i {
color: #fff;
}
}
}
}
\ No newline at end of file
.avue-breadcrumb {
&_collapse {
line-height: 55px;
font-size: 30px !important;
&--right {
transform: rotate(90deg);
}
}
}
.avue-tags {
position: relative;
padding: 5px 10px;
margin-bottom: 10px;
box-sizing: border-box;
overflow: hidden;
border-top: 1px solid #f6f6f6;
background-color: #fff;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .05);
.el-tabs--card>.el-tabs__header {
margin: 0;
}
.el-tabs--card>.el-tabs__header .el-tabs__nav,
.el-tabs--card>.el-tabs__header .el-tabs__item,
.el-tabs--card>.el-tabs__header {
border: none;
}
.el-tabs--card>.el-tabs__header .el-tabs__item:first-child {
border-left-width: 1px
}
.el-tabs--card>.el-tabs__header .el-tabs__item {
margin: 0 3px;
height: 30px;
line-height: 30px;
font-size: 13px;
font-weight: normal;
border: 1px solid #eee;
color: #ccc;
border-radius: 3px;
&.is-active {
border: 1px solid #409EFF;
color: #409EFF;
}
}
.el-tabs__nav-prev,
.el-tabs__nav-next {
width: 20px;
line-height: 34px;
font-size: 18x;
text-align: center;
}
.tags-box {
position: relative;
box-sizing: border-box;
padding-right: 106px;
width: 100%;
}
.tags-list {
position: absolute;
padding: 2px 10px;
overflow: visible;
white-space: nowrap;
transition: left .3s ease;
}
.tags-menu {
position: absolute;
top: 0;
right: 0;
padding: 1px 15px;
box-sizing: border-box;
}
}
\ No newline at end of file
.theme-black {
.avue-contail {
background-color: #002253!important;
}
.avue-header,
.tags-container,
.avue-logo {
background-color: transparent;
}
.el-card {
opacity: .9;
}
.top {
.el-dropdown {
color: #ff929a;
i {
color: #ff929a;
}
}
.top-item {
i {
color: #ff929a;
}
}
}
.avue-tabs {
padding: 0 20px !important;
}
.avue-sidebar,
.logo,
.el-menu-item,
.el-submenu__title,
.el-menu {
background-color: transparent !important
}
.logo_subtitle {
color: #ccc !important;
}
.logo_title,
.avue-breadcrumb,
{
color: #ff929a !important;
i {
color: #ff929a;
}
}
.el-menu--horizontal>.el-menu-item.is-active {
color: #ffb870 !important;
border-bottom: none;
}
.el-color-picker__trigger {
border: 1px solid #ff929a !important;
}
.top {
border-bottom: none;
}
.avue-tags {
background-color: transparent;
border: none;
}
.tag-item {
color: #ff929a !important;
border: 1px solid #ff929a!important;
background: hsla(0, 0%, 100%, .05) !important;
.tag-item-icon {
color: #ff929a !important;
}
&.is-active {
color: #ffb870 !important;
border: 1px solid #ffb870 !important;
.tag-item-icon {
color: #ffb870 !important;
}
}
}
.el-menu-item {
i,
span {
color: #ff929a;
}
&:hover {
span,
i {
color: #ffb870 !important;
}
}
&.is-active {
&::before {
background: #ffb870;
}
span,
i {
color: #ffb870 !important;
}
background: hsla(0, 0%, 100%, .05) !important;
&:hover {
color: #ffb870 !important;
background: hsla(0, 0%, 100%, .05) !important;
}
}
}
.el-submenu__title {
i,
span {
color: #ff929a !important;
}
}
.el-submenu .el-menu-item {
&:hover {
span,
i {
color: #ffb870 !important;
}
}
&.is-active {
background: hsla(0, 0%, 100%, .05) !important;
span,
i {
color: #ffb870 !important;
}
&:hover {
background: hsla(0, 0%, 100%, .05) !important;
}
}
}
.el-tabs--card>.el-tabs__header .el-tabs__item {
color: #ff929a;
border: 1px solid #ff929a;
&.is-active {
border: 1px solid #ffb870;
color: #ffb870;
}
}
.tags-container {
border-color: #ff929a;
}
.top-search {
input::-webkit-input-placeholder,
textarea::-webkit-input-placeholder {
/* WebKit browsers */
color: #ff929a;
}
input:-moz-placeholder,
textarea:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: #ff929a;
}
input::-moz-placeholder,
textarea::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: #ff929a;
}
input:-ms-input-placeholder,
textarea:-ms-input-placeholder {
/* Internet Explorer 10+ */
color: #ff929a;
}
}
.top-bar__item {
i {
color: #ff929a;
}
}
}
\ No newline at end of file
.theme-gradual {
.avue-contail {
background: linear-gradient(120deg, #bc00e3, #4efffb) !important;
}
.avue-header,
.tags-container,
.avue-logo {
background-color: transparent;
}
.el-card {
opacity: .9;
}
.top {
.el-dropdown {
color: #fff;
i {
color: #fff;
}
}
.top-item {
i {
color: #fff;
}
}
}
.avue-tabs {
padding: 0 20px !important;
}
.avue-sidebar,
.logo,
.el-menu-item,
.el-submenu__title,
.el-menu {
background-color: transparent !important
}
.logo_subtitle {
color: #ccc !important;
}
.logo_title,
.avue-breadcrumb,
{
color: #fff !important;
i {
color: #fff;
}
}
.el-menu--horizontal>.el-menu-item.is-active {
border-bottom: none;
}
.top {
border-bottom: none;
}
.avue-tags {
background-color: transparent;
border: none;
}
.tag-item {
color: #fff !important;
border: none !important;
background-color: rgba(255, 255, 255, .5) !important;
&.is-active {
color: #fff !important;
border: 1px solid #fff !important;
background: linear-gradient(90deg, hsla(0, 0%, 100%, .28), hsla(0, 0%, 100%, 0)) !important;
.tag-item-icon {
color: #fff !important;
}
}
}
.el-menu-item {
i,
span {
color: #fff;
}
&:hover {
span,
i {
color: #fff !important;
}
}
&.is-active {
&::before {
background: #fff;
}
span,
i {
color: #fff !important;
}
background: linear-gradient(90deg, hsla(0, 0%, 100%, .28), hsla(0, 0%, 100%, 0)) !important;
&:hover {
color: #fff !important;
background: linear-gradient(90deg, hsla(0, 0%, 100%, .28), hsla(0, 0%, 100%, 0)) !important;
}
}
}
.el-submenu__title {
i,
span {
color: #fff !important;
}
}
.el-submenu .el-menu-item {
&:hover {
span,
i {
color: #fff !important;
}
}
&.is-active {
background: linear-gradient(90deg, hsla(0, 0%, 100%, .28), hsla(0, 0%, 100%, 0)) !important;
span,
i {
color: #fff !important;
}
&:hover {
background: linear-gradient(90deg, hsla(0, 0%, 100%, .28), hsla(0, 0%, 100%, 0)) !important;
}
}
}
.top-bar__item {
i {
color: #fff;
}
}
.el-tabs--card>.el-tabs__header .el-tabs__item {
&.is-active {
border: 1px solid #fff;
color: #fff;
}
}
}
\ No newline at end of file
// 炫酷主题
@import './star.scss';
//渐变主题
@import './gradual.scss';
//纯色
@import './black.scss';
\ No newline at end of file
.theme-star {
.avue-contail {
background-image: url("/img/bg/star-squashed.jpg");
background-size: 100% 100%;
}
.avue-header,
.avue-logo,
.tags-container {
background-color: transparent;
}
.el-card {
opacity: .9;
}
.top {
.el-dropdown {
color: #fff;
i {
color: #fff;
}
}
.top-item {
i {
color: #fff;
}
}
}
.avue-tabs {
padding: 0 20px !important;
}
.avue-sidebar,
.logo,
.el-menu-item,
.el-submenu__title,
.el-menu {
background-color: transparent !important
}
.logo_title,
.avue-breadcrumb,
{
color: #fff !important;
i {
color: #fff;
}
}
.el-menu--horizontal>.el-menu-item.is-active {
border-bottom: none;
}
.top {
border-bottom: none;
}
.avue-tags {
background-color: transparent;
border: none;
}
.tag-item {
color: #fff !important;
border: none !important;
background-color: rgba(255, 255, 255, .5);
&.is-active {
color: #fff !important;
border: 1px solid #fff !important;
background-color: rgba(0, 0, 0, .4);
.tag-item-icon {
color: #fff !important;
}
}
}
.el-menu-item {
i,
span {
color: #fff !important;
}
&:hover {
i,
span {
color: #409eff !important;
}
}
&.is-active {
background-color: rgba(0, 0, 0, .4) !important;
&:hover {
background-color: rgba(0, 0, 0, .4) !important;
}
}
}
.el-submenu__title {
i,
span {
color: #fff !important;
}
&:hover {
i,
span {
color: #409eff !important;
}
background-color:transparent !important;
}
}
.el-submenu .el-menu-item {
&.is-active {
background-color: rgba(0, 0, 0, .4) !important;
span,
i {
color: $mainBg !important;
}
&:hover {
background-color: rgba(0, 0, 0, .4) !important;
}
}
}
.top-search {
input::-webkit-input-placeholder,
textarea::-webkit-input-placeholder {
/* WebKit browsers */
color: #fff;
}
input:-moz-placeholder,
textarea:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: #fff;
}
input::-moz-placeholder,
textarea::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: #fff;
}
input:-ms-input-placeholder,
textarea:-ms-input-placeholder {
/* Internet Explorer 10+ */
color: #fff;
}
}
.top-bar__item {
i {
color: #fff;
}
}
}
\ No newline at end of file
.avue-top {
position: relative;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .05);
color: rgba(0, 0, 0, .65);
font-size: 18px;
padding: 0 10px;
box-sizing: border-box;
white-space: nowrap;
}
.top-menu {
box-sizing: border-box;
.el-menu-item {
padding: 0 15px;
height: 50px !important;
line-height: 50px !important;
}
.el-menu--horizontal>.el-menu-item.is-active {
border: 0;
}
}
.top-search {
position: absolute !important;
top: 10px;
left: 20px;
width: 400px !important;
.el-input__inner {
border: none;
background-color: transparent;
}
}
.top-bar__img {
margin: 0 8px 0 5px;
padding: 2px;
width: 30px;
height: 30px;
border-radius: 100%;
box-sizing: border-box;
border: 1px solid #eee;
vertical-align: middle;
}
.top-bar__left,
.top-bar__right {
position: absolute;
top: 0;
}
.top-bar__left {
left: 0;
}
.top-bar__right {
padding: 8px 10px;
right: 0;
}
.top-bar__title {
padding-left: 40px;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: inherit;
font-weight: 400;
}
.top-bar__item {
position: relative;
display: inline-block;
margin-right: 15px;
height: 50px;
&--show {
display: inline-block !important;
}
}
\ No newline at end of file
//main
$mainBg: #409eff;
export default {
getScreen: function() {
var width = window.screen.width;
if (width >= 1200) {
return 3; //大屏幕
} else if (width >= 992) {
return 2; //中屏幕
} else if (width >= 768) {
return 1; //小屏幕
} else {
return 0; //超小屏幕
}
}
}
\ No newline at end of file
import Cookies from 'js-cookie'
const TokenKey = 'x-access-token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
\ No newline at end of file
export const calcDate = (date1, date2) => {
var date3 = date2 - date1;
var days = Math.floor(date3 / (24 * 3600 * 1000))
var leave1 = date3 % (24 * 3600 * 1000) //计算天数后剩余的毫秒数
var hours = Math.floor(leave1 / (3600 * 1000))
var leave2 = leave1 % (3600 * 1000) //计算小时数后剩余的毫秒数
var minutes = Math.floor(leave2 / (60 * 1000))
var leave3 = leave2 % (60 * 1000) //计算分钟数后剩余的毫秒数
var seconds = Math.round(date3 / 1000)
return {
leave1,
leave2,
leave3,
days: days,
hours: hours,
minutes: minutes,
seconds: seconds,
}
}
\ No newline at end of file
import {
validatenull
} from '@/util/validate';
/**
* 存储localStorage
*/
export const setStore = (params) => {
let {
name,
content,
type,
} = params;
let obj = {
dataType: typeof(content),
content: content,
type: type,
datetime: new Date().getTime()
}
if (type) window.sessionStorage.setItem(name, JSON.stringify(obj));
else window.localStorage.setItem(name, JSON.stringify(obj));
}
/**
* 获取localStorage
*/
export const getStore = (params) => {
let {
name,
debug
} = params;
let obj = {},
content;
obj = window.sessionStorage.getItem(name);
if (validatenull(obj)) obj = window.localStorage.getItem(name);
if (validatenull(obj)) return;
obj = JSON.parse(obj);
if (debug) {
return obj;
}
if (obj.dataType == 'string') {
content = obj.content;
} else if (obj.dataType == 'number') {
content = Number(obj.content);
} else if (obj.dataType == 'boolean') {
content = eval(obj.content);
} else if (obj.dataType == 'object') {
content = obj.content;
}
return content;
}
/**
* 删除localStorage
*/
export const removeStore = params => {
let {
name
} = params;
window.localStorage.removeItem(name);
window.sessionStorage.removeItem(name);
}
/**
* 获取全部localStorage
*/
export const getAllStore = (params) => {
let list = [];
let {
type
} = params;
for (let i = 1; i <= window.sessionStorage.length; i++) {
if (type) {
list.push({
name: window.sessionStorage.key(i),
content: getStore({
name: window.sessionStorage.key(i),
type: 'session'
})
})
} else {
list.push(getStore({
name: window.localStorage.key(i),
content: getStore({
name: window.localStorage.key(i),
})
}))
}
}
return list;
}
/**
* 清空全部localStorage
*/
export const clearStore = (params) => {
let {
type
} = params;
if (type) {
window.sessionStorage.clear();
return
}
window.localStorage.clear()
}
\ No newline at end of file
import {
validatenull
} from './validate'
/**
* 设置灰度模式
*/
export const toggleGrayMode = (status) => {
if (status) {
document.body.className = document.body.className + ' grayMode';
} else {
document.body.className = document.body.className.replace(' grayMode', '');
}
};
/**
* 设置主题
*/
export const setTheme = (name) => {
document.body.className = name;
}
/**
*加密处理
*/
export const encryption = (params) => {
let {
data,
type,
param,
key
} = params
const result = JSON.parse(JSON.stringify(data))
if (type === 'Base64') {
param.forEach(ele => {
result[ele] = btoa(result[ele])
})
} else {
param.forEach(ele => {
var data = result[ele]
key = CryptoJS.enc.Latin1.parse(key)
var iv = key
// 加密
var encrypted = CryptoJS.AES.encrypt(
data,
key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
})
result[ele] = encrypted.toString()
})
}
return result
}
/**
* 浏览器判断是否全屏
*/
export const fullscreenToggel = () => {
if (fullscreenEnable()) {
exitFullScreen();
} else {
reqFullScreen();
}
};
/**
* esc监听全屏
*/
export const listenfullscreen = (callback) => {
function listen() {
callback()
}
document.addEventListener("fullscreenchange", function() {
listen();
});
document.addEventListener("mozfullscreenchange", function() {
listen();
});
document.addEventListener("webkitfullscreenchange", function() {
listen();
});
document.addEventListener("msfullscreenchange", function() {
listen();
});
};
/**
* 浏览器判断是否全屏
*/
export const fullscreenEnable = () => {
var isFullscreen = document.fullscreenEnabled ||
window.fullScreen ||
document.mozFullscreenEnabled ||
document.webkitIsFullScreen;
return isFullscreen;
}
/**
* 浏览器全屏
*/
export const reqFullScreen = () => {
if (document.documentElement.requestFullScreen) {
document.documentElement.requestFullScreen();
} else if (document.documentElement.webkitRequestFullScreen) {
document.documentElement.webkitRequestFullScreen();
} else if (document.documentElement.mozRequestFullScreen) {
document.documentElement.mozRequestFullScreen();
}
};
/**
* 浏览器退出全屏
*/
export const exitFullScreen = () => {
if (document.documentElement.requestFullScreen) {
document.exitFullScreen();
} else if (document.documentElement.webkitRequestFullScreen) {
document.webkitCancelFullScreen();
} else if (document.documentElement.mozRequestFullScreen) {
document.mozCancelFullScreen();
}
};
/**
* 递归寻找子类的父类
*/
export const findParent = (menu, id) => {
for (let i = 0; i < menu.length; i++) {
if (menu[i].children.length != 0) {
for (let j = 0; j < menu[i].children.length; j++) {
if (menu[i].children[j].id == id) {
return menu[i];
} else {
if (menu[i].children[j].children.length != 0) {
return findParent(menu[i].children[j].children, id);
}
}
}
}
}
};
/**
* 判断2个对象属性和值是否相等
*/
/**
* 动态插入css
*/
export const loadStyle = url => {
const link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = url;
const head = document.getElementsByTagName('head')[0];
head.appendChild(link);
};
/**
* 判断路由是否相等
*/
export const isObjectValueEqual = (a, b) => {
let result = true;
Object.keys(a).forEach(ele => {
const type = typeof(a[ele]);
if (type === 'string' && a[ele] !== b[ele]) result = false;
else if (type === 'object' && JSON.stringify(a[ele]) !== JSON.stringify(b[ele])) result = false;
})
return result;
}
/**
* 根据字典的value显示label
*/
export const findByvalue = (dic, value) => {
let result = '';
if (validatenull(dic)) return value;
if (typeof(value) == 'string' || typeof(value) == 'number' || typeof(value) == 'boolean') {
let index = 0;
index = findArray(dic, value);
if (index != -1) {
result = dic[index].label;
} else {
result = value;
}
} else if (value instanceof Array) {
result = [];
let index = 0;
value.forEach(ele => {
index = findArray(dic, ele);
if (index != -1) {
result.push(dic[index].label);
} else {
result.push(value);
}
});
result = result.toString();
}
return result;
};
/**
* 根据字典的value查找对应的index
*/
export const findArray = (dic, value) => {
for (let i = 0; i < dic.length; i++) {
if (dic[i].value == value) {
return i;
}
}
return -1;
};
/**
* 生成随机len位数字
*/
export const randomLenNum = (len, date) => {
let random = '';
random = Math.ceil(Math.random() * 100000000000000).toString().substr(0, len ? len : 4);
if (date) random = random + Date.now();
return random;
};
/**
* 打开小窗口
*/
export const openWindow = (url, title, w, h) => {
// Fixes dual-screen position Most browsers Firefox
const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left
const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top
const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width
const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height
const left = ((width / 2) - (w / 2)) + dualScreenLeft
const top = ((height / 2) - (h / 2)) + dualScreenTop
const newWindow = window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left)
// Puts focus on the newWindow
if (window.focus) {
newWindow.focus()
}
}
\ No newline at end of file
/**
* 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)
}
/*验证pad还是pc*/
export const vaildatePc = function() {
const userAgentInfo = navigator.userAgent;
const Agents = ["Android", "iPhone",
"SymbianOS", "Windows Phone",
"iPad", "iPod"
];
let flag = true;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
}
/**
* validate email
* @param email
* @returns {boolean}
*/
export function validateEmail(email) {
const re = /^(([^<>()\\[\]\\.,;:\s@"]+(\.[^<>()\\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return re.test(email)
}
/**
* 判断身份证号码
*/
export function cardid(code) {
let list = [];
let result = true;
let msg = '';
var city = {
11: "北京",
12: "天津",
13: "河北",
14: "山西",
15: "内蒙古",
21: "辽宁",
22: "吉林",
23: "黑龙江 ",
31: "上海",
32: "江苏",
33: "浙江",
34: "安徽",
35: "福建",
36: "江西",
37: "山东",
41: "河南",
42: "湖北 ",
43: "湖南",
44: "广东",
45: "广西",
46: "海南",
50: "重庆",
51: "四川",
52: "贵州",
53: "云南",
54: "西藏 ",
61: "陕西",
62: "甘肃",
63: "青海",
64: "宁夏",
65: "新疆",
71: "台湾",
81: "香港",
82: "澳门",
91: "国外 "
};
if (!validatenull(code)) {
if (code.length == 18) {
if (!code || !/(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(code)) {
msg = "证件号码格式错误";
} else if (!city[code.substr(0, 2)]) {
msg = "地址编码错误";
} else {
//18位身份证需要验证最后一位校验位
code = code.split('');
//∑(ai×Wi)(mod 11)
//加权因子
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
//校验位
var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2, 'x'];
var sum = 0;
var ai = 0;
var wi = 0;
for (var i = 0; i < 17; i++) {
ai = code[i];
wi = factor[i];
sum += ai * wi;
}
if (parity[sum % 11] != code[17]) {
msg = "证件号码校验位错误";
} else {
result = false;
}
}
} else {
msg = "证件号码长度不为18位";
}
} else {
msg = "证件号码不能为空";
}
list.push(result);
list.push(msg);
return list;
}
/**
* 判断手机号码是否正确
*/
export function isvalidatemobile(phone) {
let list = [];
let result = true;
let msg = '';
var isPhone = /^0\d{2,3}-?\d{7,8}$/;
//增加134 减少|1349[0-9]{7},增加181,增加145,增加17[678]
if (!validatenull(phone)) {
if (phone.length == 11) {
if (isPhone.test(phone)) {
msg = '手机号码格式不正确';
} else {
result = false;
}
} else {
msg = '手机号码长度不为11位';
}
} else {
msg = '手机号码不能为空';
}
list.push(result);
list.push(msg);
return list;
}
/**
* 判断姓名是否正确
*/
export function validatename(name) {
var regName = /^[\u4e00-\u9fa5]{2,4}$/;
if (!regName.test(name)) return false;
return true;
}
/**
* 判断是否为整数
*/
export function validatenum(num, type) {
let regName = /[^\d.]/g;
if (type == 1) {
if (!regName.test(num)) return false;
} else if (type == 2) {
regName = /[^\d]/g;
if (!regName.test(num)) return false;
}
return true;
}
/**
* 判断是否为小数
*/
export function validatenumord(num, type) {
let regName = /[^\d.]/g;
if (type == 1) {
if (!regName.test(num)) return false;
} else if (type == 2) {
regName = /[^\d.]/g;
if (!regName.test(num)) return false;
}
return true;
}
/**
* 判断是否为空
*/
export function validatenull(val) {
if (typeof val == 'boolean') {
return false;
}
if (typeof val == 'number') {
return false;
}
if (val instanceof Array) {
if (val.length == 0) return true;
} else if (val instanceof Object) {
if (JSON.stringify(val) === '{}') return true;
} else {
if (val == 'null' || val == null || val == 'undefined' || val == undefined || val == '') return true;
return false;
}
return false;
}
\ No newline at end of file
/* eslint-disable */
/* Blob.js
* A Blob implementation.
* 2014-05-27
*
* By Eli Grey, http://eligrey.com
* By Devin Samarin, https://github.com/eboyjr
* License: X11/MIT
* See LICENSE.md
*/
/*global self, unescape */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
(function (view) {
"use strict";
view.URL = view.URL || view.webkitURL;
if (view.Blob && view.URL) {
try {
new Blob;
return;
} catch (e) { }
}
// Internally we use a BlobBuilder implementation to base Blob off of
// in order to support older browsers that only have BlobBuilder
var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function (view) {
var
get_class = function (object) {
return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
}
, FakeBlobBuilder = function BlobBuilder() {
this.data = [];
}
, FakeBlob = function Blob(data, type, encoding) {
this.data = data;
this.size = data.length;
this.type = type;
this.encoding = encoding;
}
, FBB_proto = FakeBlobBuilder.prototype
, FB_proto = FakeBlob.prototype
, FileReaderSync = view.FileReaderSync
, FileException = function (type) {
this.code = this[this.name = type];
}
, file_ex_codes = (
"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
).split(" ")
, file_ex_code = file_ex_codes.length
, real_URL = view.URL || view.webkitURL || view
, real_create_object_URL = real_URL.createObjectURL
, real_revoke_object_URL = real_URL.revokeObjectURL
, URL = real_URL
, btoa = view.btoa
, atob = view.atob
, ArrayBuffer = view.ArrayBuffer
, Uint8Array = view.Uint8Array
;
FakeBlob.fake = FB_proto.fake = true;
while (file_ex_code--) {
FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
}
if (!real_URL.createObjectURL) {
URL = view.URL = {};
}
URL.createObjectURL = function (blob) {
var
type = blob.type
, data_URI_header
;
if (type === null) {
type = "application/octet-stream";
}
if (blob instanceof FakeBlob) {
data_URI_header = "data:" + type;
if (blob.encoding === "base64") {
return data_URI_header + ";base64," + blob.data;
} else if (blob.encoding === "URI") {
return data_URI_header + "," + decodeURIComponent(blob.data);
} if (btoa) {
return data_URI_header + ";base64," + btoa(blob.data);
} else {
return data_URI_header + "," + encodeURIComponent(blob.data);
}
} else if (real_create_object_URL) {
return real_create_object_URL.call(real_URL, blob);
}
};
URL.revokeObjectURL = function (object_URL) {
if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
real_revoke_object_URL.call(real_URL, object_URL);
}
};
FBB_proto.append = function (data/*, endings*/) {
var bb = this.data;
// decode data to a binary string
if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
var
str = ""
, buf = new Uint8Array(data)
, i = 0
, buf_len = buf.length
;
for (; i < buf_len; i++) {
str += String.fromCharCode(buf[i]);
}
bb.push(str);
} else if (get_class(data) === "Blob" || get_class(data) === "File") {
if (FileReaderSync) {
var fr = new FileReaderSync;
bb.push(fr.readAsBinaryString(data));
} else {
// async FileReader won't work as BlobBuilder is sync
throw new FileException("NOT_READABLE_ERR");
}
} else if (data instanceof FakeBlob) {
if (data.encoding === "base64" && atob) {
bb.push(atob(data.data));
} else if (data.encoding === "URI") {
bb.push(decodeURIComponent(data.data));
} else if (data.encoding === "raw") {
bb.push(data.data);
}
} else {
if (typeof data !== "string") {
data += ""; // convert unsupported types to strings
}
// decode UTF-16 to binary string
bb.push(unescape(encodeURIComponent(data)));
}
};
FBB_proto.getBlob = function (type) {
if (!arguments.length) {
type = null;
}
return new FakeBlob(this.data.join(""), type, "raw");
};
FBB_proto.toString = function () {
return "[object BlobBuilder]";
};
FB_proto.slice = function (start, end, type) {
var args = arguments.length;
if (args < 3) {
type = null;
}
return new FakeBlob(
this.data.slice(start, args > 1 ? end : this.data.length)
, type
, this.encoding
);
};
FB_proto.toString = function () {
return "[object Blob]";
};
FB_proto.close = function () {
this.size = this.data.length = 0;
};
return FakeBlobBuilder;
}(view));
view.Blob = function Blob(blobParts, options) {
var type = options ? (options.type || "") : "";
var builder = new BlobBuilder();
if (blobParts) {
for (var i = 0, len = blobParts.length; i < len; i++) {
builder.append(blobParts[i]);
}
}
return builder.getBlob(type);
};
}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this));
\ No newline at end of file
/* eslint-disable */
require('script-loader!file-saver');
require('script-loader!@/vendor/Blob');
import XLSX from 'xlsx'
function generateArray(table) {
var out = [];
var rows = table.querySelectorAll('tr');
var ranges = [];
for (var R = 0; R < rows.length; ++R) {
var outRow = [];
var row = rows[R];
var columns = row.querySelectorAll('td');
for (var C = 0; C < columns.length; ++C) {
var cell = columns[C];
var colspan = cell.getAttribute('colspan');
var rowspan = cell.getAttribute('rowspan');
var cellValue = cell.innerText;
if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
//Skip ranges
ranges.forEach(function (range) {
if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
}
});
//Handle Row Span
if (rowspan || colspan) {
rowspan = rowspan || 1;
colspan = colspan || 1;
ranges.push({ s: { r: R, c: outRow.length }, e: { r: R + rowspan - 1, c: outRow.length + colspan - 1 } });
}
;
//Handle Value
outRow.push(cellValue !== "" ? cellValue : null);
//Handle Colspan
if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
}
out.push(outRow);
}
return [out, ranges];
};
function datenum(v, date1904) {
if (date1904) v += 1462;
var epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}
function sheet_from_array_of_arrays(data, opts) {
var ws = {};
var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } };
for (var R = 0; R != data.length; ++R) {
for (var C = 0; C != data[R].length; ++C) {
if (range.s.r > R) range.s.r = R;
if (range.s.c > C) range.s.c = C;
if (range.e.r < R) range.e.r = R;
if (range.e.c < C) range.e.c = C;
var cell = { v: data[R][C] };
if (cell.v == null) continue;
var cell_ref = XLSX.utils.encode_cell({ c: C, r: R });
if (typeof cell.v === 'number') cell.t = 'n';
else if (typeof cell.v === 'boolean') cell.t = 'b';
else if (cell.v instanceof Date) {
cell.t = 'n';
cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
}
else cell.t = 's';
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
}
function Workbook() {
if (!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
export function export_table_to_excel(id) {
var theTable = document.getElementById(id);
var oo = generateArray(theTable);
var ranges = oo[1];
/* original data */
var data = oo[0];
var ws_name = "SheetJS";
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
/* add ranges to worksheet */
// ws['!cols'] = ['apple', 'banan'];
ws['!merges'] = ranges;
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' });
saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), "test.xlsx")
}
export function export_json_to_excel(th, jsonData, defaultTitle) {
/* original data */
var data = jsonData;
data.unshift(th);
var ws_name = "SheetJS";
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
/*设置worksheet每列的最大宽度*/
const colWidth = data.map(row => row.map(val => {
/*先判断是否为null/undefined*/
if (val == null) {
return { 'wch': 10 };
}
/*再判断是否为中文*/
else if (val.toString().charCodeAt(0) > 255) {
return { 'wch': val.toString().length * 2 };
} else {
return { 'wch': val.toString().length };
}
}))
/*以第一行为初始值*/
let result = colWidth[0];
for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; j < colWidth[i].length; j++) {
if (result[j]['wch'] < colWidth[i][j]['wch']) {
result[j]['wch'] = colWidth[i][j]['wch'];
}
}
}
ws['!cols'] = result;
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' });
var title = defaultTitle || 'excel-list'
saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), title + ".xlsx")
}
\ No newline at end of file
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container pull-auto">
<basic-container>
<avue-crud ref="crud"
:page="page"
:data="tableData"
:table-loading="tableLoading"
:option="tableOption"
@current-change="currentChange"
@refresh-change="refreshChange"
@size-change="sizeChange"
@row-update="handleUpdate"
@row-save="handleSave"
@row-del="rowDel">
<template slot-scope="scope"
slot="menu">
<el-button type="primary"
v-if="permissions.sys_client_edit"
icon="el-icon-check"
size="mini"
plain
@click="handleEdit(scope.row,scope.index)">编辑</el-button>
<el-button type="danger"
v-if="permissions.sys_client_del"
icon="el-icon-delete"
size="mini"
plain
@click="handleDel(scope.row,scope.index)">删除</el-button>
</template>
</avue-crud>
</basic-container>
</div>
</template>
<script>
import { fetchList, addObj, putObj, delObj } from '@/api/client'
import { tableOption } from '@/const/crud/client'
import { mapGetters } from 'vuex'
export default {
name: 'client',
data() {
return {
tableData: [],
page: {
total: 0, // 总页数
currentPage: 1, // 当前页数
pageSize: 20 // 每页显示多少条
},
tableLoading: false,
tableOption: tableOption
}
},
created() {
this.getList()
},
mounted: function() { },
computed: {
...mapGetters(['permissions'])
},
methods: {
getList() {
this.tableLoading = true
fetchList({
page: this.page.currentPage,
limit: this.page.pageSize
}).then(response => {
this.tableData = response.data.records
this.page.total = response.data.total
this.tableLoading = false
})
},
currentChange(val) {
this.page.currentPage = val
this.getList()
},
sizeChange(val) {
this.page.pageSize = val
this.getList()
},
/**
* @title 打开新增窗口
* @detail 调用crud的handleadd方法即可
*
**/
handleAdd: function() {
this.$refs.crud.rowAdd()
},
handleEdit(row, index) {
this.$refs.crud.rowEdit(row, index)
},
handleDel(row, index) {
this.$refs.crud.rowDel(row, index)
},
rowDel: function(row, index) {
var _this = this
this.$confirm('是否确认删除ID为' + row.clientId, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(function() {
return delObj(row.clientId)
})
.then(data => {
_this.tableData.splice(index, 1)
_this.$message({
showClose: true,
message: '删除成功',
type: 'success'
})
})
.catch(function(err) { })
},
/**
* @title 数据更新
* @param row 为当前的数据
* @param index 为当前更新数据的行数
* @param done 为表单关闭函数
*
**/
handleUpdate: function(row, index, done) {
putObj(row).then(data => {
this.tableData.splice(index, 1, Object.assign({}, row))
this.$message({
showClose: true,
message: '修改成功',
type: 'success'
})
done()
})
},
/**
* @title 数据添加
* @param row 为当前的数据
* @param done 为表单关闭函数
*
**/
handleSave: function(row, done) {
addObj(row).then(data => {
this.tableData.push(Object.assign({}, row))
this.$message({
showClose: true,
message: '添加成功',
type: 'success'
})
done()
})
},
/**
* 刷新回调
*/
refreshChange() {
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
</style>
`<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container calendar-list-container">
<basic-container>
<div class="filter-container">
<el-button-group>
<el-button type="primary"
v-if="deptManager_btn_add"
icon="plus"
@click="handlerAdd">添加</el-button>
<el-button type="primary"
v-if="deptManager_btn_edit"
icon="edit"
@click="handlerEdit">编辑</el-button>
<el-button type="primary"
v-if="deptManager_btn_del"
icon="delete"
@click="handleDelete">删除</el-button>
</el-button-group>
</div>
<el-row>
<el-col :span="8"
style='margin-top:15px;'>
<el-tree class="filter-tree"
:data="treeData"
node-key="id"
highlight-current
:props="defaultProps"
:filter-node-method="filterNode"
@node-click="getNodeData"
default-expand-all>
</el-tree>
</el-col>
<el-col :span="16"
style='margin-top:15px;'>
<el-card class="box-card">
<el-form :label-position="labelPosition"
label-width="80px"
:model="form"
ref="form">
<el-form-item label="父级节点"
prop="parentId">
<el-input v-model="form.parentId"
:disabled="formEdit"
placeholder="请输入父级节点"></el-input>
</el-form-item>
<el-form-item label="节点编号"
prop="parentId"
v-if="formEdit">
<el-input v-model="form.deptId"
:disabled="formEdit"
placeholder="节点编号"></el-input>
</el-form-item>
<el-form-item label="部门名称"
prop="name">
<el-input v-model="form.name"
:disabled="formEdit"
placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="排序"
prop="orderNum">
<el-input v-model="form.orderNum"
:disabled="formEdit"
placeholder="请输入排序"></el-input>
</el-form-item>
<el-form-item v-if="formStatus == 'update'">
<el-button type="primary"
@click="update">更新</el-button>
<el-button @click="onCancel">取消</el-button>
</el-form-item>
<el-form-item v-if="formStatus == 'create'">
<el-button type="primary"
@click="create">保存</el-button>
<el-button @click="onCancel">取消</el-button>
</el-form-item>
</el-form>
</el-card>
</el-col>
</el-row>
</basic-container>
</div>
</template>
<script>
import { fetchTree, getObj, addObj, delObj, putObj } from '@/api/dept'
import { mapGetters } from 'vuex'
export default {
name: 'menu',
data() {
return {
list: null,
total: null,
formEdit: true,
formAdd: true,
formStatus: '',
showElement: false,
typeOptions: ['0', '1'],
methodOptions: ['GET', 'POST', 'PUT', 'DELETE'],
listQuery: {
name: undefined
},
treeData: [],
defaultProps: {
children: 'children',
label: 'name'
},
labelPosition: 'right',
form: {
name: undefined,
orderNum: undefined,
parentId: undefined,
deptId: undefined
},
currentId: 0,
deptManager_btn_add: false,
deptManager_btn_edit: false,
deptManager_btn_del: false
}
},
filters: {
typeFilter(type) {
const typeMap = {
0: '菜单',
1: '按钮'
}
return typeMap[type]
}
},
created() {
this.getList()
this.deptManager_btn_add = this.permissions['sys_dept_add']
this.deptManager_btn_edit = this.permissions['sys_dept_edit']
this.deptManager_btn_del = this.permissions['sys_dept_del']
},
computed: {
...mapGetters([
'elements',
'permissions'
])
},
methods: {
getList() {
fetchTree(this.listQuery).then(response => {
this.treeData = response.data
})
},
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
getNodeData(data) {
if (!this.formEdit) {
this.formStatus = 'update'
}
getObj(data.id).then(response => {
this.form = response.data
})
this.currentId = data.id
this.showElement = true
},
handlerEdit() {
if (this.form.deptId) {
this.formEdit = false
this.formStatus = 'update'
}
},
handlerAdd() {
this.resetForm()
this.formEdit = false
this.formStatus = 'create'
},
handleDelete() {
this.$confirm('此操作将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delObj(this.currentId).then(() => {
this.getList()
this.resetForm()
this.onCancel()
this.$notify({
title: '成功',
message: '删除成功',
type: 'success',
duration: 2000
})
})
})
},
update() {
putObj(this.form).then(() => {
this.getList()
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
})
},
create() {
addObj(this.form).then(() => {
this.getList()
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000
})
})
},
onCancel() {
this.formEdit = true
this.formStatus = ''
},
resetForm() {
this.form = {
permission: undefined,
name: undefined,
menuId: undefined,
parentId: this.currentId,
url: undefined,
icon: undefined,
sort: undefined,
component: undefined,
type: undefined,
method: undefined
}
}
}
}
</script>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container pull-auto">
<basic-container>
<avue-crud ref="crud"
:page="page"
:data="tableData"
:table-loading="tableLoading"
:option="tableOption"
@current-change="currentChange"
@size-change="sizeChange"
@row-update="handleUpdate"
@row-save="handleSave"
@search-change="searchChange"
@row-del="rowDel">
<template slot-scope="scope"
slot="menu">
<el-button type="primary"
v-if="permissions.sys_dict_edit"
icon="el-icon-check"
size="mini"
plain
@click="handleEdit(scope.row,scope.index)">编辑</el-button>
<el-button type="danger"
v-if="permissions.sys_dict_del"
icon="el-icon-delete"
size="mini"
plain
@click="handleDel(scope.row,scope.index)">删除</el-button>
</template>
</avue-crud>
</basic-container>
</div>
</template>
<script>
import { fetchList, addObj, putObj, delObj } from '@/api/dict'
import { tableOption } from '@/const/crud/dict'
import { mapGetters } from 'vuex'
export default {
name: 'dict',
data () {
return {
tableData: [],
page: {
total: 0, // 总页数
currentPage: 1, // 当前页数
pageSize: 20 // 每页显示多少条
},
listQuery: {
page: 1,
limit: 20,
type: undefined
},
tableLoading: false,
tableOption: tableOption
}
},
created () {
this.getList()
},
mounted: function () { },
computed: {
...mapGetters(['permissions'])
},
methods: {
getList () {
this.tableLoading = true
this.listQuery.orderByField = 'create_time'
this.listQuery.isAsc = false
fetchList(this.listQuery).then(response => {
this.tableData = response.data.records
this.page.total = response.data.total
this.tableLoading = false
})
},
currentChange (val) {
this.listQuery.page = val
this.getList()
},
sizeChange (val) {
this.listQuery.limit = val
this.getList()
},
/**
* @title 打开新增窗口
* @detail 调用crud的handleadd方法即可
*
**/
handleAdd: function () {
this.$refs.crud.rowAdd()
},
handleEdit (row, index) {
this.$refs.crud.rowEdit(row, index)
},
handleDel (row, index) {
this.$refs.crud.rowDel(row, index)
},
rowDel: function (row, index) {
var _this = this
this.$confirm('是否确认删除标签名为"' + row.label + '",数据类型为"' + row.type + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(function () {
return delObj(row)
})
.then(() => {
this.getList()
_this.$message({
showClose: true,
message: '删除成功',
type: 'success'
})
})
.catch(function () { })
},
/**
* @title 数据更新
* @param row 为当前的数据
* @param index 为当前更新数据的行数
* @param done 为表单关闭函数
*
**/
handleUpdate: function (row, index, done) {
putObj(row).then(() => {
this.tableData.splice(index, 1, Object.assign({}, row))
this.$message({
showClose: true,
message: '修改成功',
type: 'success'
})
done()
})
},
/**
* @title 数据添加
* @param row 为当前的数据
* @param done 为表单关闭函数
*
**/
handleSave: function (row, done) {
addObj(row).then(data => {
this.tableData.push(Object.assign({}, row))
this.$message({
showClose: true,
message: '添加成功',
type: 'success'
})
done()
})
},
searchChange (form) {
this.listQuery.type = form.type
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
</style>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container pull-auto">
<basic-container>
<avue-crud ref="crud"
:page="page"
:data="tableData"
:table-loading="tableLoading"
:option="tableOption"
@current-change="currentChange"
@refresh-change="refreshChange"
@size-change="sizeChange"
@search-change="searchChange">
<template slot-scope="scope"
slot="menu">
<el-button type="primary"
v-if="permissions.sys_client_del"
icon="el-icon-check"
size="mini"
plain
@click="handleDown(scope.row,scope.index)">生成</el-button>
</template>
</avue-crud>
<el-dialog title="生成配置"
:visible.sync="box"
width="50%"
lock-scroll>
<div class="pull-auto">
<avue-form :option="formOption"
ref="formData"
v-model="formData"
@submit="gen()"
>
</avue-form>
</div>
</el-dialog>
</basic-container>
</div>
</template>
<script>
import { fetchList, handleDown } from '@/api/gen'
import { tableOption, formOption } from '@/const/crud/gen'
import { mapGetters } from 'vuex'
export default {
name: 'client',
data() {
return {
tableData: [],
formData: {},
box: false,
page: {
total: 0, // 总页数
currentPage: 1, // 当前页数
pageSize: 20 // 每页显示多少条
},
listQuery: {
page: 1,
limit: 20,
tableName: undefined
},
tableLoading: false,
tableOption: tableOption,
formOption: formOption
}
},
created() {
this.getList()
},
mounted: function() { },
computed: {
...mapGetters(['permissions'])
},
methods: {
getList() {
this.tableLoading = true
fetchList(this.listQuery).then(response => {
this.tableData = response.data.records
this.page.total = response.data.total
this.tableLoading = false
})
},
currentChange(val) {
this.page.currentPage = val
this.listQuery.page = val
this.getList()
},
sizeChange(val) {
this.page.pageSize = val
this.listQuery.limit = val
this.getList()
},
handleDown: function(row, index) {
this.formData.tableName = row.tableName
this.box = true
},
/**
* 刷新回调
*/
refreshChange() {
this.getList()
},
searchChange(form) {
this.listQuery.tableName = form.tableName
this.getList()
},
gen(form) {
console.log(this.formData)
handleDown(this.formData).then(response => {
this.box = true
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container pull-auto">
<basic-container>
<avue-crud ref="crud"
:page="page"
:data="tableData"
:table-loading="tableLoading"
:option="tableOption"
@current-change="currentChange"
@size-change="sizeChange"
@search-change="searchChange"
@refresh-change="refreshChange"
@row-del="rowDel">
<template slot-scope="scope"
slot="menu">
<el-button type="danger"
v-if="permissions.sys_log_del"
icon="el-icon-delete"
size="mini"
plain
@click="handleDel(scope.row,scope.index)">删除</el-button>
</template>
</avue-crud>
</basic-container>
</div>
</template>
<script>
import { fetchList, delObj } from '@/api/log'
import { tableOption } from '@/const/crud/log'
import { mapGetters } from 'vuex'
export default {
name: 'log',
data() {
return {
tableData: [],
page: {
total: 0, // 总页数
currentPage: 1, // 当前页数
pageSize: 20 // 每页显示多少条
},
listQuery: {
page: 1,
limit: 20,
type: undefined
},
tableLoading: false,
tableOption: tableOption
}
},
created() {
this.getList()
},
mounted: function() { },
computed: {
...mapGetters(['permissions'])
},
methods: {
getList() {
this.tableLoading = true
this.listQuery.orderByField = 'create_time'
this.listQuery.isAsc = false
fetchList(this.listQuery).then(response => {
this.tableData = response.data.records
this.page.total = response.data.total
this.tableLoading = false
})
},
currentChange(val) {
this.listQuery.page = val
this.getList()
},
sizeChange(val) {
this.listQuery.limit = val
this.getList()
},
handleDel(row, index) {
this.$refs.crud.rowDel(row, index)
},
rowDel: function(row, index) {
var _this = this
this.$confirm('是否确认删除ID为"' + row.id + '"的日志?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(function() {
return delObj(row.id)
})
.then(data => {
this.getList()
_this.$message({
showClose: true,
message: '删除成功',
type: 'success'
})
})
.catch(function(err) { })
},
/**
* 搜索回调
*/
searchChange(form) {
this.listQuery.type = form.type
this.getList()
},
/**
* 刷新回调
*/
refreshChange() {
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
</style>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container calendar-list-container">
<basic-container>
<div class="filter-container">
<el-button-group>
<el-button type="primary"
v-if="menuManager_btn_add"
icon="plus"
@click="handlerAdd">添加</el-button>
<el-button type="primary"
v-if="menuManager_btn_edit"
icon="edit"
@click="handlerEdit">编辑</el-button>
<el-button type="primary"
v-if="menuManager_btn_del"
icon="delete"
@click="handleDelete">删除</el-button>
</el-button-group>
</div>
<el-row>
<el-col :span="8"
style='margin-top:15px;'>
<el-tree class="filter-tree"
node-key="id"
highlight-current
:data="treeData"
:default-expanded-keys="aExpandedKeys"
:filter-node-method="filterNode"
:props="defaultProps"
@node-click="getNodeData"
@node-expand="nodeExpand"
@node-collapse="nodeCollapse">
</el-tree>
</el-col>
<el-col :span="16"
style='margin-top:15px;'>
<el-card class="box-card">
<el-form :label-position="labelPosition"
label-width="80px"
:model="form"
ref="form">
<el-form-item label="父级节点"
prop="parentId">
<el-input v-model="form.parentId"
:disabled="true"
placeholder="请输入父级节点"></el-input>
</el-form-item>
<el-form-item label="节点ID"
prop="menuId">
<el-input v-model="form.menuId"
:disabled="formEdit"
placeholder="请输入节点ID"></el-input>
</el-form-item>
<el-form-item label="标题"
prop="name">
<el-input v-model="form.name"
:disabled="formEdit"
placeholder="请输入标题"></el-input>
</el-form-item>
<el-form-item label="权限标识"
prop="permission">
<el-input v-model="form.permission"
:disabled="formEdit"
placeholder="请输入权限标识"></el-input>
</el-form-item>
<el-form-item label="图标"
prop="icon">
<el-input v-model="form.icon"
:disabled="formEdit"
placeholder="请输入图标"></el-input>
</el-form-item>
<el-form-item label="类型"
prop="type">
<el-select class="filter-item"
v-model="form.type"
:disabled="formEdit"
placeholder="请输入资源请求类型">
<el-option v-for="item in typeOptions"
:key="item"
:label="item | typeFilter"
:value="item"> </el-option>
</el-select>
</el-form-item>
<el-form-item label="排序"
prop="sort">
<el-input v-model="form.sort"
:disabled="formEdit"
placeholder="请输入排序"></el-input>
</el-form-item>
<el-form-item label="前端组件"
prop="component">
<el-input v-model="form.component"
:disabled="formEdit"
placeholder="请输入描述"></el-input>
</el-form-item>
<el-form-item label="前端地址"
prop="component">
<el-input v-model="form.path"
:disabled="formEdit"
placeholder="iframe嵌套地址"></el-input>
</el-form-item>
<el-form-item v-if="formStatus == 'update'">
<el-button type="primary"
@click="update">更新</el-button>
<el-button @click="onCancel">取消</el-button>
</el-form-item>
<el-form-item v-if="formStatus == 'create'">
<el-button type="primary"
@click="create">保存</el-button>
<el-button @click="onCancel">取消</el-button>
</el-form-item>
</el-form>
</el-card>
</el-col>
</el-row>
</basic-container>
</div>
</template>
<script>
import { addObj, delObj, fetchTree, getObj, putObj } from '@/api/menu'
import { mapGetters } from 'vuex'
export default {
name: 'menu',
data () {
return {
list: null,
total: null,
formEdit: true,
formAdd: true,
formStatus: '',
showElement: false,
typeOptions: ['0', '1'],
methodOptions: ['GET', 'POST', 'PUT', 'DELETE'],
listQuery: {
name: undefined
},
treeData: [],
oExpandedKey: {
// key (from tree id) : expandedOrNot boolean
},
oTreeNodeChildren: {
// id1 : [children] (from tree node id1)
// id2 : [children] (from tree node id2)
},
aExpandedKeys: [],
defaultProps: {
children: 'children',
label: 'name'
},
labelPosition: 'right',
form: {
permission: undefined,
name: undefined,
menuId: undefined,
parentId: undefined,
icon: undefined,
sort: undefined,
component: undefined,
type: undefined,
path: undefined
},
currentId: -1,
menuManager_btn_add: false,
menuManager_btn_edit: false,
menuManager_btn_del: false
}
},
filters: {
typeFilter (type) {
const typeMap = {
0: '菜单',
1: '按钮'
}
return typeMap[type]
}
},
created () {
this.getList()
this.menuManager_btn_add = this.permissions['sys_menu_add']
this.menuManager_btn_edit = this.permissions['sys_menu_edit']
this.menuManager_btn_del = this.permissions['sys_menu_del']
},
computed: {
...mapGetters([
'elements',
'permissions'
])
},
methods: {
getList () {
fetchTree(this.listQuery).then(response => {
this.treeData = response.data
})
},
filterNode (value, data) {
// console.log(value);
if (!value) return true
return data.label.indexOf(value) !== -1
},
nodeExpand (data) {
let aChildren = data.children
if (aChildren.length > 0) {
this.oExpandedKey[data.id] = true
this.oTreeNodeChildren[data.id] = aChildren
}
this.setExpandedKeys()
},
nodeCollapse (data) {
this.oExpandedKey[data.id] = false
// 如果有子节点
this.treeRecursion(this.oTreeNodeChildren[data.id], (oNode) => {
this.oExpandedKey[oNode.id] = false
});
this.setExpandedKeys()
},
setExpandedKeys () {
let oTemp = this.oExpandedKey
this.aExpandedKeys = []
for (let sKey in oTemp) {
if (oTemp[sKey]) {
this.aExpandedKeys.push(parseInt(sKey));
}
}
},
treeRecursion (aChildren, fnCallback) {
if (aChildren) {
for (let i = 0; i < aChildren.length; ++i) {
let oNode = aChildren[i]
fnCallback && fnCallback(oNode)
this.treeRecursion(oNode.children, fnCallback)
}
}
},
getNodeData (data) {
if (!this.formEdit) {
this.formStatus = 'update'
}
getObj(data.id).then(response => {
this.form = response.data
})
this.currentId = data.id
this.showElement = true
},
handlerEdit () {
if (this.form.menuId) {
this.formEdit = false
this.formStatus = 'update'
}
},
handlerAdd () {
this.resetForm()
this.formEdit = false
this.formStatus = 'create'
},
handleDelete () {
this.$confirm('此操作将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delObj(this.currentId).then(() => {
this.getList()
this.resetForm()
this.onCancel()
this.$notify({
title: '成功',
message: '删除成功',
type: 'success',
duration: 2000
})
})
})
},
update () {
putObj(this.form).then(() => {
this.getList()
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
})
},
create () {
addObj(this.form).then(() => {
this.getList()
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000
})
})
},
onCancel () {
this.formEdit = true
this.formStatus = ''
},
resetForm () {
this.form = {
permission: undefined,
name: undefined,
menuId: undefined,
parentId: this.currentId,
icon: undefined,
sort: undefined,
component: undefined,
type: undefined,
path: undefined
}
}
}
}
</script>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container calendar-list-container">
<basic-container>
<div class="filter-container">
<el-button class="filter-item"
style="margin-left: 10px;"
@click="handleCreate"
type="primary"
icon="edit"
v-if="roleManager_btn_add">添加
</el-button>
</div>
<el-table :key='tableKey'
:data="list"
v-loading="listLoading"
element-loading-text="给我一点时间"
border
fit
highlight-current-row
style="width: 99%">
<el-table-column align="center"
label="序号">
<template slot-scope="scope">
<span>{{scope.row.roleId}}</span>
</template>
</el-table-column>
<el-table-column label="角色名称">
<template slot-scope="scope">
<span>{{scope.row.roleName}}</span>
</template>
</el-table-column>
<el-table-column align="center"
label="角色标识">
<template slot-scope="scope">
<span>{{scope.row.roleCode}}</span>
</template>
</el-table-column>
<el-table-column align="center"
label="角色描述">
<template slot-scope="scope">
<span>{{scope.row.roleDesc }}</span>
</template>
</el-table-column>
<el-table-column align="center"
label="所属部门">
<template slot-scope="scope">
<span>{{scope.row.deptName }}</span>
</template>
</el-table-column>
<el-table-column align="center"
label="创建时间">
<template slot-scope="scope">
<span>{{scope.row.createTime | parseTime('{y}-{m}-{d} {h}:{i}')}}</span>
</template>
</el-table-column>
<el-table-column label="操作"
width="220">
<template slot-scope="scope">
<el-button size="mini"
type="success"
v-if="roleManager_btn_edit"
@click="handleUpdate(scope.row)">编辑
</el-button>
<el-button size="mini"
type="danger"
v-if="roleManager_btn_del"
@click="handleDelete(scope.row)">删除
</el-button>
<el-button size="mini"
type="info"
plain
@click="handlePermission(scope.row)"
v-if="roleManager_btn_perm">权限
</el-button>
</template>
</el-table-column>
</el-table>
<div v-show="!listLoading"
class="pagination-container">
<el-pagination @size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="listQuery.page"
:page-sizes="[10,20,30, 50]"
:page-size="listQuery.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</basic-container>
<el-dialog :title="textMap[dialogStatus]"
:visible.sync="dialogFormVisible">
<el-form :model="form"
:rules="rules"
ref="form"
label-width="100px">
<el-form-item label="角色名称"
prop="roleName">
<el-input v-model="form.roleName"
placeholder="角色名称"></el-input>
</el-form-item>
<el-form-item label="角色标识"
prop="roleCode">
<el-input v-model="form.roleCode"
placeholder="角色标识"></el-input>
</el-form-item>
<el-form-item label="描述"
prop="roleDesc">
<el-input v-model="form.roleDesc"
placeholder="描述"></el-input>
</el-form-item>
<el-form-item label="所属部门"
prop="roleDept">
<el-input v-model="form.deptName"
placeholder="选择部门"
@focus="handleDept()"
readonly></el-input>
<el-input type="hidden"
v-model="form.roleDeptId"></el-input>
</el-form-item>
</el-form>
<div slot="footer"
class="dialog-footer">
<el-button @click="cancel('form')"> </el-button>
<el-button v-if="dialogStatus=='create'"
type="primary"
@click="create('form')"> </el-button>
<el-button v-else
type="primary"
@click="update('form')"> </el-button>
</div>
</el-dialog>
<el-dialog :title="textMap[dialogStatus]"
:visible.sync="dialogDeptVisible">
<el-tree class="filter-tree"
:data="treeDeptData"
:default-checked-keys="checkedKeys"
node-key="id"
highlight-current
ref="deptTree"
@node-click="getNodeData"
:props="defaultProps"
:filter-node-method="filterNode"
default-expand-all>
</el-tree>
</el-dialog>
<el-dialog :title="textMap[dialogStatus]"
:visible.sync="dialogPermissionVisible">
<el-tree class="filter-tree"
:data="treeData"
:default-checked-keys="checkedKeys"
:check-strictly="false"
node-key="id"
highlight-current
:props="defaultProps"
show-checkbox
ref="menuTree"
:filter-node-method="filterNode"
default-expand-all>
</el-tree>
<div slot="footer"
class="dialog-footer">
<el-button type="primary"
@click="updatePermession(roleId, roleCode)"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
fetchList,
getObj,
addObj,
putObj,
delObj,
permissionUpd,
fetchRoleTree,
fetchDeptTree
} from '@/api/role'
import { fetchTree } from '@/api/menu'
import { mapGetters } from 'vuex'
export default {
name: 'table_role',
data () {
return {
treeData: [],
treeDeptData: [],
checkedKeys: [],
defaultProps: {
children: 'children',
label: 'name'
},
menuIds: '',
list: null,
total: null,
listLoading: true,
listQuery: {
page: 1,
limit: 20
},
form: {
roleName: undefined,
roleCode: undefined,
roleDesc: undefined,
deptName: undefined,
roleDeptId: undefined
},
roleId: undefined,
roleCode: undefined,
rules: {
roleName: [
{
required: true,
message: '角色名称',
trigger: 'blur'
},
{
min: 3,
max: 20,
message: '长度在 3 到 20 个字符',
trigger: 'blur'
}
],
roleCode: [
{
required: true,
message: '角色标识',
trigger: 'blur'
},
{
min: 3,
max: 20,
message: '长度在 3 到 20 个字符',
trigger: 'blur'
}
],
roleDesc: [
{
required: true,
message: '角色标识',
trigger: 'blur'
},
{
min: 3,
max: 20,
message: '长度在 3 到 20 个字符',
trigger: 'blur'
}
]
},
statusOptions: ['0', '1'],
rolesOptions: undefined,
dialogFormVisible: false,
dialogDeptVisible: false,
dialogPermissionVisible: false,
dialogStatus: '',
textMap: {
update: '编辑',
create: '创建',
permission: '分配权限'
},
tableKey: 0,
roleManager_btn_add: false,
roleManager_btn_edit: false,
roleManager_btn_del: false,
roleManager_btn_perm: false
}
},
created () {
this.getList()
this.roleManager_btn_add = this.permissions['sys_role_add']
this.roleManager_btn_edit = this.permissions['sys_role_edit']
this.roleManager_btn_del = this.permissions['sys_role_del']
this.roleManager_btn_perm = this.permissions['sys_role_perm']
},
computed: {
...mapGetters(['elements', 'permissions'])
},
methods: {
getList () {
this.listLoading = true
fetchList(this.listQuery).then(response => {
this.list = response.data.records
this.total = response.data.total
this.listLoading = false
})
},
handleSizeChange (val) {
this.listQuery.limit = val
this.getList()
},
handleCurrentChange (val) {
this.listQuery.page = val
this.getList()
},
handleCreate () {
this.resetTemp()
this.dialogStatus = 'create'
this.dialogFormVisible = true
},
handleUpdate (row) {
getObj(row.roleId).then(response => {
this.form = response.data
this.form.deptName = row.deptName
this.form.roleDeptId = row.roleDeptId
this.dialogFormVisible = true
this.dialogStatus = 'update'
})
},
handlePermission (row) {
fetchRoleTree(row.roleCode)
.then(response => {
this.checkedKeys = response.data
return fetchTree()
})
.then(response => {
this.treeData = response.data
// 解析出所有的太监节点
this.checkedKeys = this.resolveAllEunuchNodeId(this.treeData, this.checkedKeys, [])
this.dialogStatus = 'permission'
this.dialogPermissionVisible = true
this.roleId = row.roleId
this.roleCode = row.roleCode
})
},
/**
* 解析出所有的太监节点id
* @param json 待解析的json串
* @param idArr 原始节点数组
* @param temp 临时存放节点id的数组
* @return 太监节点id数组
*/
resolveAllEunuchNodeId (json, idArr, temp) {
for (let i = 0; i < json.length; i++) {
const item = json[i]
// 存在子节点,递归遍历;不存在子节点,将json的id添加到临时数组中
if (item.children && item.children.length !== 0) {
this.resolveAllEunuchNodeId(item.children, idArr, temp)
} else {
temp.push(idArr.filter(id => id === item.id))
}
}
return temp
},
handleDept () {
fetchDeptTree().then(response => {
this.treeDeptData = response.data
this.dialogDeptVisible = true
})
},
filterNode (value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
getNodeData (data) {
this.dialogDeptVisible = false
this.form.roleDeptId = data.id
this.form.deptName = data.name
console.log(data)
},
handleDelete (row) {
delObj(row.roleId).then(response => {
this.dialogFormVisible = false
this.getList()
this.$notify({
title: '成功',
message: '删除成功',
type: 'success',
duration: 2000
})
})
},
create (formName) {
const set = this.$refs
set[formName].validate(valid => {
if (valid) {
addObj(this.form).then(() => {
this.dialogFormVisible = false
this.getList()
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000
})
})
} else {
return false
}
})
},
cancel (formName) {
this.dialogFormVisible = false
this.$refs[formName].resetFields()
},
update (formName) {
const set = this.$refs
set[formName].validate(valid => {
if (valid) {
this.dialogFormVisible = false
putObj(this.form).then(() => {
this.dialogFormVisible = false
this.getList()
this.$notify({
title: '成功',
message: '修改成功',
type: 'success',
duration: 2000
})
})
} else {
return false
}
})
},
updatePermession (roleId, roleCode) {
this.menuIds = ''
this.menuIds = this.$refs.menuTree.getCheckedKeys().join(',').concat(',').concat(this.$refs.menuTree.getHalfCheckedKeys().join(','))
permissionUpd(roleId, this.menuIds).then(() => {
this.dialogPermissionVisible = false
fetchTree()
.then(response => {
this.treeData = response.data
return fetchRoleTree(roleCode)
})
.then(response => {
this.checkedKeys = response.data
this.$notify({
title: '成功',
message: '修改成功',
type: 'success',
duration: 2000
})
})
})
},
resetTemp () {
this.form = {
id: undefined,
roleName: undefined,
roleCode: undefined,
roleDesc: undefined
}
}
}
}
</script>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container pull-auto">
<basic-container>
<avue-crud ref="crud"
:page="page"
:data="tableData"
:table-loading="tableLoading"
:option="tableOption"
@current-change="currentChange"
@refresh-change="refreshChange"
@size-change="sizeChange"
@search-change="searchChange"
@row-update="handleUpdate"
@row-save="handleSave"
@row-del="rowDel">
<template slot="menuLeft">
<el-button type="primary"
@click="handleAdd"
size="small"
v-if="permissions.generator_syssocialdetails_add">新 增</el-button>
<br /><br />
</template>
<template slot-scope="scope"
slot="menu">
<el-button type="primary"
v-if="permissions.generator_syssocialdetails_edit"
icon="el-icon-check"
size="small"
plain
@click="handleEdit(scope.row,scope.index)">编辑</el-button>
<el-button type="danger"
v-if="permissions.generator_syssocialdetails_del"
icon="el-icon-delete"
size="small"
plain
@click="handleDel(scope.row,scope.index)">删除</el-button>
</template>
</avue-crud>
</basic-container>
</div>
</template>
<script>
import { fetchList, getObj, addObj, putObj, delObj } from '@/api/syssocialdetails'
import { tableOption } from '@/const/crud/syssocialdetails'
import { mapGetters } from 'vuex'
export default {
name: 'syssocialdetails',
data () {
return {
tableData: [],
page: {
total: 0, // 总页数
currentPage: 1, // 当前页数
pageSize: 20 // 每页显示多少条
},
listQuery: {
page: 1,
limit: 20,
type: undefined
},
tableLoading: false,
tableOption: tableOption
}
},
created () {
this.getList()
},
mounted: function () { },
computed: {
...mapGetters(['permissions'])
},
methods: {
getList () {
this.tableLoading = true
fetchList(this.listQuery).then(response => {
this.tableData = response.data.records
this.page.total = response.data.total
this.tableLoading = false
})
},
currentChange (val) {
this.page.currentPage = val
this.listQuery.page = val
this.getList()
},
sizeChange (val) {
this.page.pageSize = val
this.listQuery.limit = val
this.getList()
},
/**
* @title 打开新增窗口
* @detail 调用crud的handleadd方法即可
*
**/
handleAdd: function () {
this.$refs.crud.rowAdd()
},
handleEdit (row, index) {
this.$refs.crud.rowEdit(row, index)
},
handleDel (row, index) {
this.$refs.crud.rowDel(row, index)
},
rowDel: function (row, index) {
var _this = this
this.$confirm('是否确认删除ID为' + row.id, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(function () {
return delObj(row.clientId)
})
.then(data => {
_this.tableData.splice(index, 1)
_this.$message({
showClose: true,
message: '删除成功',
type: 'success'
})
})
.catch(function (err) { })
},
/**
* @title 数据更新
* @param row 为当前的数据
* @param index 为当前更新数据的行数
* @param done 为表单关闭函数
*
**/
handleUpdate: function (row, index, done) {
putObj(row).then(data => {
this.tableData.splice(index, 1, Object.assign({}, row))
this.$message({
showClose: true,
message: '修改成功',
type: 'success'
})
done()
})
},
/**
* @title 数据添加
* @param row 为当前的数据
* @param done 为表单关闭函数
*
**/
handleSave: function (row, done) {
addObj(row).then(() => {
this.tableData.push(Object.assign({}, row))
this.$message({
showClose: true,
message: '添加成功',
type: 'success'
})
done()
})
},
/**
* 刷新回调
*/
refreshChange () {
this.getList()
},
/**
* 搜索回调
*/
searchChange (form) {
this.listQuery.type = form.type
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
</style>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container pull-auto">
<basic-container>
<avue-crud :data="data" :option="option"/>
</basic-container>
</div>
</template>
<script>
import request from '@/router/axios'
export default {
data() {
return {
obj: {},
data: [],
option: {
menu: false,
page: false,
addBtn: false,
align: 'center',
menuAlign: 'center',
column: [
{
label: '属性名称',
prop: 'key'
},
{
label: '属性值',
prop: 'value'
}
]
}
}
},
created() {
request({
url: '/tx/admin/avueSetting',
method: 'get'
}).then((resp) => {
this.data = resp.data
console.log(resp.data)
})
}
}
</script>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container pull-auto">
<basic-container>
<avue-crud :data="data" :option="option"/>
</basic-container>
</div>
</template>
<script>
import request from '@/router/axios'
export default {
data() {
return {
obj: {},
data: [],
option: {
menu: false,
page: false,
addBtn: false,
align: 'center',
menuAlign: 'center',
column: [
{
label: '模块名称',
prop: 'model'
},
{
label: '唯一标示',
prop: 'uniqueKey'
},
{
label: '模块地址',
prop: 'ipAddress'
},
{
label: '管道名称',
prop: 'channelName'
}
]
}
}
},
created() {
request({
url: '/tx/admin/onlines',
method: 'get'
}).then((resp) => {
this.data = resp.data
})
}
}
</script>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container calendar-list-container">
<basic-container>
<div class="filter-container">
<el-input @keyup.enter.native="handleFilter"
style="width: 200px;"
class="filter-item"
placeholder="用户名"
v-model="listQuery.username">
</el-input>
<el-button class="filter-item"
type="primary"
icon="search"
@click="handleFilter">搜索</el-button>
<el-button v-if="sys_user_add"
class="filter-item"
style="margin-left: 10px;"
@click="handleCreate"
type="primary"
icon="edit">添加</el-button>
</div>
<el-table :key='tableKey'
:data="list"
v-loading="listLoading"
element-loading-text="给我一点时间"
border
fit
highlight-current-row
style="width: 99%">
<el-table-column align="center"
label="序号">
<template slot-scope="scope">
<span>{{scope.row.userId}}</span>
</template>
</el-table-column>
<el-table-column align="center"
label="用户名">
<template slot-scope="scope">
<span>
<img v-if="scope.row.avatar"
class="user-avatar"
style="width: 20px; height: 20px; border-radius: 50%;"
:src="scope.row.avatar+'?imageView2/1/w/20/h/20'"> {{scope.row.username}}
</span>
</template>
</el-table-column>
<el-table-column align="center"
label="所属部门"
show-overflow-tooltip>
<template slot-scope="scope">
<span>{{scope.row.deptName}} </span>
</template>
</el-table-column>
<el-table-column align="center"
label="角色">
<template slot-scope="scope">
<span v-for="(role,index) in scope.row.roleList"
:key="index">{{role.roleDesc}} </span>
</template>
</el-table-column>
<el-table-column align="center"
label="创建时间">
<template slot-scope="scope">
<span>{{scope.row.createTime | parseTime('{y}-{m}-{d} {h}:{i}')}}</span>
</template>
</el-table-column>
<el-table-column align="center"
class-name="status-col"
label="状态">
<template slot-scope="scope">
<el-tag>{{scope.row.delFlag | statusFilter}}</el-tag>
</template>
</el-table-column>
<el-table-column align="center"
label="操作"
width="200">
<template slot-scope="scope">
<el-button v-if="sys_user_edit"
size="small"
type="success"
@click="handleUpdate(scope.row)">编辑
</el-button>
<el-button v-if="sys_user_del"
size="small"
type="danger"
@click="deletes(scope.row)">删除
</el-button>
</template>
</el-table-column>
</el-table>
<div v-show="!listLoading"
class="pagination-container">
<el-pagination @size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="listQuery.page"
:page-sizes="[10,20,30, 50]"
:page-size="listQuery.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</basic-container>
<el-dialog :title="textMap[dialogStatus]"
:visible.sync="dialogDeptVisible">
<el-tree class="filter-tree"
:data="treeDeptData"
:default-checked-keys="checkedKeys"
check-strictly
node-key="id"
highlight-current
ref="deptTree"
:props="defaultProps"
@node-click="getNodeData"
default-expand-all>
</el-tree>
</el-dialog>
<el-dialog :title="textMap[dialogStatus]"
:visible.sync="dialogFormVisible">
<el-form :model="form"
:rules="rules"
ref="form"
label-width="100px">
<el-form-item label="用户名"
prop="username">
<el-input v-model="form.username"
placeholder="请输用户名"></el-input>
</el-form-item>
<el-form-item v-if="dialogStatus == 'create'"
label="密码"
placeholder="请输入密码"
prop="newpassword1">
<el-input type="password"
v-model="form.newpassword1"></el-input>
</el-form-item>
<el-form-item label="所属部门"
prop="deptName">
<el-input v-model="form.deptName"
placeholder="选择部门"
@focus="handleDept()"
readonly></el-input>
<input type="hidden"
v-model="form.deptId" />
</el-form-item>
<el-form-item label="角色"
prop="role">
<el-select class="filter-item"
v-model="role"
placeholder="请选择"
multiple>
<el-option v-for="item in rolesOptions"
:key="item.roleId"
:label="item.roleDesc"
:value="item.roleId"
:disabled="isDisabled[item.delFlag]">
<span style="float: left">{{ item.roleDesc }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.roleCode }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="状态"
v-if="dialogStatus == 'update' && sys_user_del "
prop="delFlag">
<el-select class="filter-item"
v-model="form.delFlag"
placeholder="请选择">
<el-option v-for="item in statusOptions"
:key="item"
:label="item | statusFilter"
:value="item"> </el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer"
class="dialog-footer">
<el-button @click="cancel('form')"> </el-button>
<el-button v-if="dialogStatus=='create'"
type="primary"
@click="create('form')"> </el-button>
<el-button v-else
type="primary"
@click="update('form')"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { fetchList, getObj, addObj, putObj, delObj } from "@/api/user";
import { deptRoleList, fetchDeptTree } from "@/api/role";
// import { parseTime } from '@/utils'
import { mapGetters } from "vuex";
import ElRadioGroup from "element-ui/packages/radio/src/radio-group";
import ElOption from "element-ui/packages/select/src/option";
export default {
components: {
ElOption,
ElRadioGroup
},
name: "table_user",
data () {
return {
treeDeptData: [],
checkedKeys: [],
defaultProps: {
children: "children",
label: "name"
},
list: null,
total: null,
listLoading: true,
listQuery: {
page: 1,
limit: 20
},
role: [],
form: {
username: undefined,
newpassword1: undefined,
delFlag: undefined,
deptId: undefined,
},
rules: {
username: [
{
required: true,
message: "请输入账户",
trigger: "blur"
},
{
min: 3,
max: 20,
message: "长度在 3 到 20 个字符",
trigger: "blur"
}
],
newpassword1: [
{
required: true,
message: "请输入密码",
trigger: "blur"
},
{
min: 6,
max: 20,
message: "长度在 6 到 20 个字符",
trigger: "blur"
}
],
deptId: [
{
required: true,
message: "请选择部门",
trigger: "blur"
}
],
role: [
{
required: true,
message: "请选择角色",
trigger: "blur"
}
]
},
statusOptions: ["0", "1"],
rolesOptions: [],
dialogFormVisible: false,
dialogDeptVisible: false,
userAdd: false,
userUpd: false,
userDel: false,
dialogStatus: "",
textMap: {
update: "编辑",
create: "创建"
},
isDisabled: {
0: false,
1: true
},
tableKey: 0
};
},
computed: {
...mapGetters(["permissions"])
},
filters: {
statusFilter (status) {
const statusMap = {
0: "有效",
1: "无效",
9: "锁定"
};
return statusMap[status];
}
},
created () {
this.getList();
this.sys_user_add = this.permissions["sys_user_add"];
this.sys_user_edit = this.permissions["sys_user_edit"];
this.sys_user_del = this.permissions["sys_user_del"];
},
methods: {
getList () {
this.listLoading = true;
this.listQuery.isAsc = false;
fetchList(this.listQuery).then(response => {
this.list = response.data.records;
this.total = response.data.total;
this.listLoading = false;
});
},
getNodeData (data) {
this.dialogDeptVisible = false;
this.form.deptId = data.id;
this.form.deptName = data.name;
deptRoleList(data.id).then(response => {
this.rolesOptions = response.data;
});
},
handleDept () {
fetchDeptTree().then(response => {
this.treeDeptData = response.data;
this.dialogDeptVisible = true;
});
},
handleFilter () {
this.listQuery.page = 1;
this.getList();
},
handleSizeChange (val) {
this.listQuery.limit = val;
this.getList();
},
handleCurrentChange (val) {
this.listQuery.page = val;
this.getList();
},
handleCreate () {
this.resetTemp();
this.dialogStatus = "create";
this.dialogFormVisible = true;
},
handleUpdate (row) {
getObj(row.userId).then(response => {
this.form = response.data;
this.dialogFormVisible = true;
this.dialogStatus = "update";
this.role = [];
for (var i = 0; i < row.roleList.length; i++) {
this.role[i] = row.roleList[i].roleId;
}
deptRoleList(response.data.deptId).then(response => {
this.rolesOptions = response.data;
});
});
},
create (formName) {
const set = this.$refs;
this.form.role = this.role;
set[formName].validate(valid => {
if (valid) {
addObj(this.form).then(() => {
this.dialogFormVisible = false;
this.getList();
this.$notify({
title: "成功",
message: "创建成功",
type: "success",
duration: 2000
});
});
} else {
return false;
}
});
},
cancel (formName) {
this.dialogFormVisible = false;
this.$refs[formName].resetFields();
},
update (formName) {
const set = this.$refs;
this.form.role = this.role;
set[formName].validate(valid => {
if (valid) {
this.dialogFormVisible = false;
this.form.password = undefined;
putObj(this.form).then(() => {
this.dialogFormVisible = false;
this.getList();
this.$notify({
title: "成功",
message: "修改成功",
type: "success",
duration: 2000
});
});
} else {
return false;
}
});
},
deletes (row) {
this.$confirm(
"此操作将永久删除该用户(用户名:" + row.username + "), 是否继续?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
).then(() => {
delObj(row.userId)
.then(() => {
this.getList();
this.$notify({
title: "成功",
message: "删除成功",
type: "success",
duration: 2000
});
})
.cache(() => {
this.$notify({
title: "失败",
message: "删除失败",
type: "error",
duration: 2000
});
});
});
},
resetTemp () {
this.form = {
id: undefined,
username: "",
password: "",
role: [],
delFlag: "",
deptId: ""
};
}
}
};
</script>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container calendar-list-container">
<basic-container>
<el-row>
<el-col :span="12">
<div class="grid-content bg-purple">
<el-form :model="ruleForm2"
:rules="rules2"
ref="ruleForm2"
label-width="100px"
class="demo-ruleForm">
<el-form-item label="用户名"
prop="username">
<el-input type="text"
:value="userInfo.username"
disabled></el-input>
</el-form-item>
<el-form-item label="原密码"
prop="password">
<el-input type="password"
v-model="ruleForm2.password"
auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="密码"
prop="newpassword1">
<el-input type="password"
v-model="ruleForm2.newpassword1"
auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="确认密码"
prop="newpassword2">
<el-input type="password"
v-model="ruleForm2.newpassword2"
auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="社交登录"
prop="social">
<a href="#"
style="color: blue"
@click="handleClick('wechat')">绑定微信</a>
</el-form-item>
<el-form-item>
<el-button type="primary"
@click="submitForm('ruleForm2')">提交</el-button>
<el-button @click="resetForm('ruleForm2')">重置</el-button>
</el-form-item>
</el-form>
</div>
</el-col>
</el-row>
</basic-container>
</div>
</template>
<script>
import { openWindow } from '@/util/util'
import { mapState } from 'vuex'
import { getToken } from '@/util/auth'
import ElFormItem from 'element-ui/packages/form/src/form-item.vue'
import request from '@/router/axios'
export default {
components: {
ElFormItem
},
data () {
var validatePass = (rule, value, callback) => {
if (this.ruleForm2.password !== '') {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== this.ruleForm2.newpassword1) {
callback(new Error('两次输入密码不一致!'))
} else {
callback()
}
} else {
callback()
}
}
return {
fileList: [],
show: false,
headers: {
Authorization: 'Bearer ' + getToken()
},
ruleForm2: {
password: '',
newpassword1: '',
newpassword2: ''
},
rules2: {
password: [{ required: true, min: 6, message: '原密码不能为空且不少于6位', trigger: 'change' }],
newpassword1: [{ required: true, min: 6, message: '新密码不能为空且不少于6位', trigger: 'change' }],
newpassword2: [{ required: true, validator: validatePass, trigger: 'blur' }]
}
}
},
created () {
},
computed: {
...mapState({
userInfo: state => state.user.userInfo
})
},
methods: {
submitForm (formName) {
this.$refs[formName].validate(valid => {
if (valid) {
request({
url: '/admin/user/editInfo',
method: 'put',
data: this.ruleForm2
}).then(response => {
if (response.data.data) {
this.$notify({
title: '成功',
message: '修改成功',
type: 'success',
duration: 2000
})
// 修改密码之后强制重新登录
if (this.ruleForm2.newpassword1 !== '') {
this.$store.dispatch('LogOut').then(() => {
location.reload() // 为了重新实例化vue-router对象 避免bug
})
} else {
this.$router.push({ path: '/' })
}
} else {
this.$notify({
title: '失败',
message: response.data.msg,
type: 'error',
duration: 2000
})
}
})
.catch(() => {
this.$notify({
title: '失败',
message: '修改失败',
type: 'error',
duration: 2000
})
})
} else {
return false
}
})
},
resetForm (formName) {
console.log(formName)
this.$refs[formName].resetFields()
},
toggleShow () {
this.show = !this.show
},
/**
* upload success
*
* [param] jsonData 服务器返回数据,已进行json转码
* [param] field
*/
cropUploadSuccess (jsonData) {
this.$store.commit('SET_AVATAR', jsonData.filename)
},
handleClick (thirdpart) {
let appid, client_id, redirect_uri, url
redirect_uri = encodeURIComponent(window.location.origin + '/#/authredirect?type=BIND')
if (thirdpart === 'wechat') {
appid = 'wxd1678d3f83b1d83a'
url = 'https://open.weixin.qq.com/connect/qrconnect?appid=' + appid + '&redirect_uri=' + redirect_uri + '&state=' + appid + '&response_type=code&scope=snsapi_login#wechat_redirect'
} else if (thirdpart === 'tencent') {
client_id = '101322838'
url = 'https://graph.qq.com/oauth2.0/authorize?response_type=code&state=' + appid + '&client_id=' + client_id + '&redirect_uri=' + redirect_uri
}
openWindow(url, thirdpart, 540, 540)
}
}
}
</script>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container pull-auto">
<basic-container>
<avue-crud ref="crud"
:data="tableData"
:option="tableOption"
@row-update="handleUpdate"
@row-save="handleSave"
@row-del="handleDel">
<template slot-scope="props"
slot="expand">
<el-form label-position="left"
inline
class="demo-table-expand">
<el-form-item label="姓名">
<span>{{ props.row.name }}</span>
</el-form-item>
<el-form-item label="用户名">
<span>{{ props.row.username }}</span>
</el-form-item>
<el-form-item label="地址">
<a :href="props.row.address"
target="_blank">{{props.row.address}}</a>
</el-form-item>
<el-form-item label="项目地址">
<a :href="props.row.git"
target="_blank">{{props.row.git}}</a>
</el-form-item>
<el-form-item label="stars">
<a :href='props.row.address'
target="_blank">
<img :src="props.row.stars"
alt='star' />
</a>
</el-form-item>
</el-form>
</template>
<template slot-scope="scope"
slot="username">
<el-tag>{{scope.row.username}}</el-tag>
</template>
<template slot-scope="scope"
slot="stars">
<a :href='scope.row.git'
target="_blank">
<img :src="scope.row.stars"
alt='star' />
</a>
</template>
<template slot-scope="scope"
slot="address">
<a :href="scope.row.git"
target="_blank">{{scope.row.address}}</a>
</template>
</avue-crud>
</basic-container>
</div>
</template>
<script>
import { tableOption } from '@/const/crud/option'
import { tableData } from '@/const/crud/data'
export default {
name: 'crud',
data () {
return {
tableData: tableData,
tableOption: tableOption
}
},
mounted: function () { },
methods: {
handleDel: function (row, index) {
var _this = this
this.$confirm('是否确认删除序号为' + row.username, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(function () {
_this.tableData.splice(index, 1)
_this.$message({
showClose: true,
message: '删除成功',
type: 'success'
})
})
.catch(function (err) { })
},
/**
* @title 数据更新
* @param row 为当前的数据
* @param index 为当前更新数据的行数
* @param done 为表单关闭函数
*
**/
handleUpdate: function (row, index, done) {
this.tableData.splice(index, 1, Object.assign({}, row))
this.$message({
showClose: true,
message: '修改成功',
type: 'success'
})
done()
},
/**
* @title 数据添加
* @param row 为当前的数据
* @param done 为表单关闭函数
*
**/
handleSave: function (row, done) {
this.tableData.push(Object.assign({}, row))
this.$message({
showClose: true,
message: '添加成功',
type: 'success'
})
done()
}
}
}
</script>
<style lang="scss" scoped>
.demo-table-expand {
font-size: 0;
}
.demo-table-expand label {
width: 90px;
color: #99a9bf;
}
.demo-table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
width: 50%;
}
</style>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="app-container pull-auto">
<basic-container>
<avue-crud ref="crud"
:page="page"
:data="tableData"
:table-loading="tableLoading"
:option="tableOption"
@current-change="currentChange"
@refresh-change="refreshChange"
@size-change="sizeChange"
@search-change="searchChange"
@row-update="handleUpdate"
@row-save="handleSave"
@row-del="rowDel">
<template slot-scope="scope"
slot="menu">
<el-button type="danger"
v-if="permissions.daemon_statustracelog_del"
icon="el-icon-delete"
size="small"
plain
@click="handleDel(scope.row,scope.index)">删除</el-button>
</template>
</avue-crud>
</basic-container>
</div>
</template>
<script>
import { fetchList, addObj, putObj, delObj } from '@/api/statustracelog'
import { tableOption } from '@/const/crud/statustracelog'
import { mapGetters } from 'vuex'
export default {
name: 'statustracelog',
data () {
return {
tableData: [],
page: {
total: 0, // 总页数
currentPage: 1, // 当前页数
pageSize: 20 // 每页显示多少条
},
listQuery: {
page: 1,
limit: 20,
job_name: undefined,
state: undefined
},
tableLoading: false,
tableOption: tableOption
}
},
created () {
this.getList()
},
mounted: function () { },
computed: {
...mapGetters(['permissions'])
},
methods: {
getList () {
this.tableLoading = true
fetchList(this.listQuery).then(response => {
this.tableData = response.data.records
this.page.total = response.data.total
this.tableLoading = false
})
},
currentChange (val) {
this.page.currentPage = val
this.listQuery.page = val
this.getList()
},
sizeChange (val) {
this.page.pageSize = val
this.listQuery.limit = val
this.getList()
},
/**
* @title 打开新增窗口
* @detail 调用crud的handleadd方法即可
*
**/
handleAdd: function () {
this.$refs.crud.rowAdd()
},
handleEdit (row, index) {
this.$refs.crud.rowEdit(row, index)
},
handleDel (row, index) {
this.$refs.crud.rowDel(row, index)
},
rowDel: function (row, index) {
var _this = this
this.$confirm('是否确认删除ID为' + row.clientId, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(function () {
return delObj(row.clientId)
})
.then(() => {
_this.tableData.splice(index, 1)
_this.$message({
showClose: true,
message: '删除成功',
type: 'success'
})
})
.catch(function () { })
},
/**
* @title 数据更新
* @param row 为当前的数据
* @param index 为当前更新数据的行数
* @param done 为表单关闭函数
*
**/
handleUpdate: function (row, index, done) {
putObj(row).then(() => {
this.tableData.splice(index, 1, Object.assign({}, row))
this.$message({
showClose: true,
message: '修改成功',
type: 'success'
})
done()
})
},
/**
* @title 数据添加
* @param row 为当前的数据
* @param done 为表单关闭函数
*
**/
handleSave: function (row, done) {
addObj(row).then(() => {
this.tableData.push(Object.assign({}, row))
this.$message({
showClose: true,
message: '添加成功',
type: 'success'
})
done()
})
},
searchChange (form) {
this.listQuery.job_name = form.job_name
this.listQuery.state = form.state
this.getList()
},
/**
* 刷新回调
*/
refreshChange () {
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
</style>
<!--
- Copyright (c) 2018-2025, lengleng All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the pig4cloud.com developer nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- Author: lengleng (wangiegie@gmail.com)
-->
<template>
<div class="dashboard-container">
<basic-container>
<div class="dashboard-text">欢迎登录</div>
<div class="dashboard-text">用户名:{{name}}</div>
<div class="dashboard-text">角色名:
<span v-for='role in roles'
:key='role'>{{role}}</span>
</div>
</basic-container>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "dashboard",
computed: {
...mapGetters(["name", "roles"])
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.dashboard {
&-container {
margin: 30px;
}
&-text {
font-size: 30px;
line-height: 46px;
}
}
</style>
module.exports = {
plugins: [
'cypress'
],
env: {
mocha: true,
'cypress/globals': true
},
rules: {
strict: 'off'
}
}
// https://docs.cypress.io/guides/guides/plugins-guide.html
module.exports = (on, config) => {
return Object.assign({}, config, {
fixturesFolder: 'tests/e2e/fixtures',
integrationFolder: 'tests/e2e/specs',
screenshotsFolder: 'tests/e2e/screenshots',
videosFolder: 'tests/e2e/videos',
supportFile: 'tests/e2e/support/index.js'
})
}
// https://docs.cypress.io/api/introduction/api.html
describe('My First Test', () => {
it('Visits the app root url', () => {
cy.visit('/')
cy.contains('h1', 'Welcome to Your Vue.js App')
})
})
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
module.exports = {
env: {
mocha: true
},
rules: {
'import/no-extraneous-dependencies': 'off'
}
}
\ No newline at end of file
import { expect } from 'chai'
import { shallowMount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message'
const wrapper = shallowMount(HelloWorld, {
propsData: { msg }
})
expect(wrapper.text()).to.include(msg)
})
})
const url = 'http://pigx.pigx.top'
module.exports = {
lintOnSave: true,
productionSourceMap: false,
chainWebpack: (config) => {
config.externals({
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios',
'element-ui': 'ELEMENT',
})
},
transpileDependencies: ['avue-plugin-transfer', 'avue-plugin-ueditor'],
//配置转发代理
devServer: {
proxy: {
'/auth': {
target: url,
ws: true,
pathRewrite: {
'^/auth': '/auth'
}
},
'/admin': {
target: url,
ws: true,
pathRewrite: {
'^/admin': '/admin'
}
},
'/code': {
target: url,
ws: true,
pathRewrite: {
'^/code': '/code'
}
},
'/gen': {
target: url,
ws: true,
pathRewrite: {
'^/gen': '/gen'
}
},
'/daemon': {
target: url,
ws: true,
pathRewrite: {
'^/daemon': '/daemon'
}
},
'/tx': {
target: url,
ws: true,
pathRewrite: {
'^/tx': '/tx'
}
},
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment