Commit a795fa7b14f6cb93eb6b5c2a8da425ed8ca6625d

Authored by Adam
1 parent cf56a6c30f
Exists in master

auto commit the code by alias command

1 .DS_Store 1 .DS_Store
2 node_modules/ 2 node_modules/
3 dist/ 3 dist/
4 npm-debug.log* 4 npm-debug.log*
5 yarn-debug.log* 5 yarn-debug.log*
6 yarn-error.log* 6 yarn-error.log*
7 package-lock.json 7 package-lock.json
8 tests/**/coverage/ 8 tests/**/coverage/
9 9
10 # Editor directories and files 10 # Editor directories and files
11 .idea 11 .idea
12 .vscode 12 .vscode
13 *.suo 13 *.suo
14 *.ntvs* 14 *.ntvs*
15 *.njsproj 15 *.njsproj
16 *.sln 16 *.sln
17 yarn.lock
1 { 1 {
2 "name": "vue-admin-template", 2 "name": "yp-plan",
3 "version": "4.2.1", 3 "version": "4.2.1",
4 "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint", 4 "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
5 "author": "Pan <panfree23@gmail.com>", 5 "author": "XYT==admin@xiuyetang.com",
6 "license": "MIT", 6 "license": "MIT",
7 "scripts": { 7 "scripts": {
8 "dev": "vue-cli-service serve", 8 "dev": "vue-cli-service serve",
9 "build:prod": "vue-cli-service build", 9 "build:prod": "vue-cli-service build",
10 "build:stage": "vue-cli-service build --mode staging", 10 "build:stage": "vue-cli-service build --mode staging",
11 "preview": "node build/index.js --preview", 11 "preview": "node build/index.js --preview",
12 "lint": "eslint --ext .js,.vue src", 12 "lint": "eslint --ext .js,.vue src",
13 "test:unit": "jest --clearCache && vue-cli-service test:unit", 13 "test:unit": "jest --clearCache && vue-cli-service test:unit",
14 "test:ci": "npm run lint && npm run test:unit", 14 "test:ci": "npm run lint && npm run test:unit",
15 "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml" 15 "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
16 }, 16 },
17 "dependencies": { 17 "dependencies": {
18 "axios": "0.18.1", 18 "axios": "0.18.1",
19 "echarts": "^4.7.0",
19 "element-ui": "2.13.0", 20 "element-ui": "2.13.0",
20 "js-cookie": "2.2.0", 21 "js-cookie": "2.2.0",
21 "normalize.css": "7.0.0", 22 "normalize.css": "7.0.0",
22 "nprogress": "0.2.0", 23 "nprogress": "0.2.0",
23 "path-to-regexp": "2.4.0", 24 "path-to-regexp": "2.4.0",
25 "plop": "^2.6.0",
24 "vue": "2.6.10", 26 "vue": "2.6.10",
25 "vue-router": "3.0.6", 27 "vue-router": "3.0.6",
26 "vuex": "3.1.0" 28 "vuex": "3.1.0"
27 }, 29 },
28 "devDependencies": { 30 "devDependencies": {
29 "@babel/core": "7.0.0", 31 "@babel/core": "7.0.0",
30 "@babel/register": "7.0.0", 32 "@babel/register": "7.0.0",
31 "@vue/cli-plugin-babel": "3.6.0", 33 "@vue/cli-plugin-babel": "3.6.0",
32 "@vue/cli-plugin-eslint": "^3.9.1", 34 "@vue/cli-plugin-eslint": "^3.9.1",
33 "@vue/cli-plugin-unit-jest": "3.6.3", 35 "@vue/cli-plugin-unit-jest": "3.6.3",
34 "@vue/cli-service": "3.6.0", 36 "@vue/cli-service": "3.6.0",
35 "@vue/test-utils": "1.0.0-beta.29", 37 "@vue/test-utils": "1.0.0-beta.29",
36 "autoprefixer": "^9.5.1", 38 "autoprefixer": "^9.5.1",
37 "babel-core": "7.0.0-bridge.0", 39 "babel-core": "7.0.0-bridge.0",
38 "babel-eslint": "10.0.1", 40 "babel-eslint": "10.0.1",
39 "babel-jest": "23.6.0", 41 "babel-jest": "23.6.0",
40 "chalk": "2.4.2", 42 "chalk": "2.4.2",
41 "connect": "3.6.6", 43 "connect": "3.6.6",
42 "eslint": "5.15.3", 44 "eslint": "5.15.3",
43 "eslint-plugin-vue": "5.2.2", 45 "eslint-plugin-vue": "5.2.2",
44 "html-webpack-plugin": "3.2.0", 46 "html-webpack-plugin": "3.2.0",
45 "mockjs": "1.0.1-beta3", 47 "mockjs": "1.0.1-beta3",
46 "node-sass": "^4.9.0", 48 "node-sass": "^4.9.0",
47 "runjs": "^4.3.2", 49 "runjs": "^4.3.2",
48 "sass-loader": "^7.1.0", 50 "sass-loader": "^7.1.0",
49 "script-ext-html-webpack-plugin": "2.1.3", 51 "script-ext-html-webpack-plugin": "2.1.3",
50 "script-loader": "0.7.2", 52 "script-loader": "0.7.2",
51 "serve-static": "^1.13.2", 53 "serve-static": "^1.13.2",
52 "svg-sprite-loader": "4.1.3", 54 "svg-sprite-loader": "4.1.3",
53 "svgo": "1.2.2", 55 "svgo": "1.2.2",
54 "vue-template-compiler": "2.6.10" 56 "vue-template-compiler": "2.6.10"
55 }, 57 },
56 "engines": { 58 "engines": {
57 "node": ">=8.9", 59 "node": ">=8.9",
58 "npm": ">= 3.0.0" 60 "npm": ">= 3.0.0"
59 }, 61 },
60 "browserslist": [ 62 "browserslist": [
61 "> 1%", 63 "> 1%",
62 "last 2 versions" 64 "last 2 versions"
63 ] 65 ]
64 } 66 }
65 67
1 <template> 1 <template>
2 <div id="app"> 2 <div id="app">
3 <router-view /> 3 <router-view />
4 </div> 4 </div>
5
5 </template> 6 </template>
6 7
7 <script> 8 <script>
8 export default { 9 export default {
9 name: 'App' 10 name: 'App'
10 } 11 }
11 </script> 12 </script>
12 13
1 import request from '@/utils/request' 1 import request from '@/utils/request'
2 2
3 export function login(data) { 3 export function login(data) {
4 console.log('login....', data)
4 return request({ 5 return request({
5 url: '/vue-admin-template/user/login', 6 url: '/vue-admin-template/user/login',
6 method: 'post', 7 method: 'post',
7 data 8 data
8 }) 9 })
9 } 10 }
10 11
11 export function getInfo(token) { 12 export function getInfo(token) {
13 console.log('getInfo....', token)
12 return request({ 14 return request({
13 url: '/vue-admin-template/user/info', 15 url: '/vue-admin-template/user/info',
14 method: 'get', 16 method: 'get',
15 params: { token } 17 params: { token }
16 }) 18 })
17 } 19 }
18 20
19 export function logout() { 21 export function logout() {
22 console.log('logout....')
20 return request({ 23 return request({
21 url: '/vue-admin-template/user/logout', 24 url: '/vue-admin-template/user/logout',
22 method: 'post' 25 method: 'post'
23 }) 26 })
24 } 27 }
25 28
src/layout/components/AppMain.vue
1 <template> 1 <template>
2 <section class="app-main"> 2 <section class="app-main">
3 <transition name="fade-transform" mode="out-in"> 3 <transition name="fade-transform" mode="out-in">
4 <router-view :key="key" /> 4 <router-view :key="key" />
5 </transition> 5 </transition>
6 </section> 6 </section>
7 </template> 7 </template>
8 8
9 <script> 9 <script>
10 export default { 10 export default {
11 name: 'AppMain', 11 name: 'AppMain',
12 computed: { 12 computed: {
13 // key() {
14 // return this.$route.name !== undefined? this.$route.name + +new Date(): this.$route + +new Date()
15 // }
13 key() { 16 key() {
14 return this.$route.path 17 return this.$route.path
15 } 18 }
16 } 19 }
17 } 20 }
18 </script> 21 </script>
19 22
20 <style scoped> 23 <style scoped>
21 .app-main { 24 .app-main {
22 /*50 = navbar */ 25 /*50 = navbar */
23 min-height: calc(100vh - 50px); 26 min-height: calc(100vh - 50px);
24 width: 100%; 27 width: 100%;
25 position: relative; 28 position: relative;
26 overflow: hidden; 29 overflow: hidden;
27 } 30 }
28 .fixed-header+.app-main { 31 .fixed-header+.app-main {
29 padding-top: 50px; 32 padding-top: 50px;
30 } 33 }
31 </style> 34 </style>
32 35
33 <style lang="scss"> 36 <style lang="scss">
34 // fix css style bug in open el-dialog 37 // fix css style bug in open el-dialog
35 .el-popup-parent--hidden { 38 .el-popup-parent--hidden {
36 .fixed-header { 39 .fixed-header {
37 padding-right: 15px; 40 padding-right: 15px;
38 } 41 }
39 } 42 }
40 </style> 43 </style>
41 44
src/layout/components/Navbar.vue
1 <template> 1 <template>
2 <div class="navbar"> 2 <div class="navbar">
3 <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> 3 <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
4 4
5 <breadcrumb class="breadcrumb-container" /> 5 <breadcrumb class="breadcrumb-container" />
6 6
7 <div class="right-menu"> 7 <div class="right-menu">
8 语言设置
8 <el-dropdown class="avatar-container" trigger="click"> 9 <el-dropdown class="avatar-container" trigger="click">
9 <div class="avatar-wrapper"> 10 <div class="avatar-wrapper">
10 <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar"> 11 <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">
11 <i class="el-icon-caret-bottom" /> 12 <i class="el-icon-caret-bottom" />
12 </div> 13 </div>
13 <el-dropdown-menu slot="dropdown" class="user-dropdown"> 14 <el-dropdown-menu slot="dropdown" class="user-dropdown">
14 <router-link to="/"> 15 <router-link to="/">
15 <el-dropdown-item> 16 <el-dropdown-item>
16 Home 17 Home
17 </el-dropdown-item> 18 </el-dropdown-item>
18 </router-link> 19 </router-link>
19 <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/"> 20 <router-link to="/seting">
21 <el-dropdown-item>
22 个人设置
23 </el-dropdown-item>
24 </router-link>
25 <!-- <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/">
20 <el-dropdown-item>Github</el-dropdown-item> 26 <el-dropdown-item>Github</el-dropdown-item>
21 </a> 27 </a> -->
22 <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/"> 28 <!-- <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">
23 <el-dropdown-item>Docs</el-dropdown-item> 29 <el-dropdown-item>Docs</el-dropdown-item>
24 </a> 30 </a> -->
25 <el-dropdown-item divided @click.native="logout"> 31 <el-dropdown-item divided @click.native="logout">
26 <span style="display:block;">Log Out</span> 32 <span style="display:block;">退出系统</span>
27 </el-dropdown-item> 33 </el-dropdown-item>
28 </el-dropdown-menu> 34 </el-dropdown-menu>
29 </el-dropdown> 35 </el-dropdown>
30 </div> 36 </div>
31 </div> 37 </div>
32 </template> 38 </template>
33 39
34 <script> 40 <script>
35 import { mapGetters } from 'vuex' 41 import { mapGetters } from 'vuex'
36 import Breadcrumb from '@/components/Breadcrumb' 42 import Breadcrumb from '@/components/Breadcrumb'
37 import Hamburger from '@/components/Hamburger' 43 import Hamburger from '@/components/Hamburger'
38 44
39 export default { 45 export default {
40 components: { 46 components: {
41 Breadcrumb, 47 Breadcrumb,
42 Hamburger 48 Hamburger
43 }, 49 },
44 computed: { 50 computed: {
45 ...mapGetters([ 51 ...mapGetters([
46 'sidebar', 52 'sidebar',
47 'avatar' 53 'avatar'
48 ]) 54 ])
49 }, 55 },
50 methods: { 56 methods: {
51 toggleSideBar() { 57 toggleSideBar() {
52 this.$store.dispatch('app/toggleSideBar') 58 this.$store.dispatch('app/toggleSideBar')
53 }, 59 },
54 async logout() { 60 async logout() {
55 await this.$store.dispatch('user/logout') 61 await this.$store.dispatch('user/logout')
56 this.$router.push(`/login?redirect=${this.$route.fullPath}`) 62 this.$router.push(`/login?redirect=${this.$route.fullPath}`)
57 } 63 }
58 } 64 }
59 } 65 }
60 </script> 66 </script>
61 67
62 <style lang="scss" scoped> 68 <style lang="scss" scoped>
63 .navbar { 69 .navbar {
64 height: 50px; 70 height: 50px;
65 overflow: hidden; 71 overflow: hidden;
66 position: relative; 72 position: relative;
67 background: #fff; 73 background: #fff;
68 box-shadow: 0 1px 4px rgba(0,21,41,.08); 74 box-shadow: 0 1px 4px rgba(0,21,41,.08);
69 75
70 .hamburger-container { 76 .hamburger-container {
71 line-height: 46px; 77 line-height: 46px;
72 height: 100%; 78 height: 100%;
73 float: left; 79 float: left;
74 cursor: pointer; 80 cursor: pointer;
75 transition: background .3s; 81 transition: background .3s;
76 -webkit-tap-highlight-color:transparent; 82 -webkit-tap-highlight-color:transparent;
77 83
78 &:hover { 84 &:hover {
79 background: rgba(0, 0, 0, .025) 85 background: rgba(0, 0, 0, .025)
80 } 86 }
81 } 87 }
82 88
83 .breadcrumb-container { 89 .breadcrumb-container {
84 float: left; 90 float: left;
85 } 91 }
86 92
87 .right-menu { 93 .right-menu {
88 float: right; 94 float: right;
89 height: 100%; 95 height: 100%;
90 line-height: 50px; 96 line-height: 50px;
91 97
92 &:focus { 98 &:focus {
93 outline: none; 99 outline: none;
94 } 100 }
95 101
96 .right-menu-item { 102 .right-menu-item {
97 display: inline-block; 103 display: inline-block;
98 padding: 0 8px; 104 padding: 0 8px;
99 height: 100%; 105 height: 100%;
100 font-size: 18px; 106 font-size: 18px;
101 color: #5a5e66; 107 color: #5a5e66;
102 vertical-align: text-bottom; 108 vertical-align: text-bottom;
103 109
104 &.hover-effect { 110 &.hover-effect {
105 cursor: pointer; 111 cursor: pointer;
106 transition: background .3s; 112 transition: background .3s;
107 113
108 &:hover { 114 &:hover {
109 background: rgba(0, 0, 0, .025) 115 background: rgba(0, 0, 0, .025)
110 } 116 }
111 } 117 }
112 } 118 }
113 119
114 .avatar-container { 120 .avatar-container {
115 margin-right: 30px; 121 margin-right: 30px;
116 122
117 .avatar-wrapper { 123 .avatar-wrapper {
118 margin-top: 5px; 124 margin-top: 5px;
119 position: relative; 125 position: relative;
120 126
121 .user-avatar { 127 .user-avatar {
122 cursor: pointer; 128 cursor: pointer;
123 width: 40px; 129 width: 40px;
124 height: 40px; 130 height: 40px;
125 border-radius: 10px; 131 border-radius: 10px;
126 } 132 }
127 133
128 .el-icon-caret-bottom { 134 .el-icon-caret-bottom {
129 cursor: pointer; 135 cursor: pointer;
130 position: absolute; 136 position: absolute;
131 right: -20px; 137 right: -20px;
132 top: 25px; 138 top: 25px;
133 font-size: 12px; 139 font-size: 12px;
134 } 140 }
135 } 141 }
136 } 142 }
137 } 143 }
138 } 144 }
139 </style> 145 </style>
140 146
src/layout/components/Sidebar/Logo.vue
1 <template> 1 <template>
2 <div class="sidebar-logo-container" :class="{'collapse':collapse}"> 2 <div class="sidebar-logo-container" :class="{'collapse':collapse}">
3 <transition name="sidebarLogoFade"> 3 <transition name="sidebarLogoFade">
4 <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/"> 4 <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
5 <img v-if="logo" :src="logo" class="sidebar-logo"> 5 <img v-if="logo" :src="logo" class="sidebar-logo">
6 <h1 v-else class="sidebar-title">{{ title }} </h1> 6 <h1 v-else class="sidebar-title">{{ title }} </h1>
7 </router-link> 7 </router-link>
8 <router-link v-else key="expand" class="sidebar-logo-link" to="/"> 8 <router-link v-else key="expand" class="sidebar-logo-link" to="/">
9 <img v-if="logo" :src="logo" class="sidebar-logo"> 9 <img v-if="logo" :src="logo" class="sidebar-logo">
10 <h1 class="sidebar-title">{{ title }} </h1> 10 <h1 class="sidebar-title">{{ title }} </h1>
11 </router-link> 11 </router-link>
12 </transition> 12 </transition>
13 </div> 13 </div>
14 </template> 14 </template>
15 15
16 <script> 16 <script>
17 export default { 17 export default {
18 name: 'SidebarLogo', 18 name: 'SidebarLogo',
19 props: { 19 props: {
20 collapse: { 20 collapse: {
21 type: Boolean, 21 type: Boolean,
22 required: true 22 required: true
23 } 23 }
24 }, 24 },
25 data() { 25 data() {
26 return { 26 return {
27 title: 'Vue Admin Template', 27 title: '鱼皮出海',
28 logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png' 28 logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png'
29 } 29 }
30 } 30 }
31 } 31 }
32 </script> 32 </script>
33 33
34 <style lang="scss" scoped> 34 <style lang="scss" scoped>
35 .sidebarLogoFade-enter-active { 35 .sidebarLogoFade-enter-active {
36 transition: opacity 1.5s; 36 transition: opacity 1.5s;
37 } 37 }
38 38
39 .sidebarLogoFade-enter, 39 .sidebarLogoFade-enter,
40 .sidebarLogoFade-leave-to { 40 .sidebarLogoFade-leave-to {
41 opacity: 0; 41 opacity: 0;
42 } 42 }
43 43
44 .sidebar-logo-container { 44 .sidebar-logo-container {
45 position: relative; 45 position: relative;
46 width: 100%; 46 width: 100%;
47 height: 50px; 47 height: 50px;
48 line-height: 50px; 48 line-height: 50px;
49 background: #2b2f3a; 49 background: #2b2f3a;
50 text-align: center; 50 text-align: center;
51 overflow: hidden; 51 overflow: hidden;
52 52
53 & .sidebar-logo-link { 53 & .sidebar-logo-link {
54 height: 100%; 54 height: 100%;
55 width: 100%; 55 width: 100%;
56 56
57 & .sidebar-logo { 57 & .sidebar-logo {
58 width: 32px; 58 width: 32px;
59 height: 32px; 59 height: 32px;
60 vertical-align: middle; 60 vertical-align: middle;
61 margin-right: 12px; 61 margin-right: 12px;
62 } 62 }
63 63
64 & .sidebar-title { 64 & .sidebar-title {
65 display: inline-block; 65 display: inline-block;
66 margin: 0; 66 margin: 0;
67 color: #fff; 67 color: #fff;
68 font-weight: 600; 68 font-weight: 600;
69 line-height: 50px; 69 line-height: 50px;
70 font-size: 14px; 70 font-size: 14px;
71 font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif; 71 font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
72 vertical-align: middle; 72 vertical-align: middle;
73 } 73 }
74 } 74 }
75 75
76 &.collapse { 76 &.collapse {
77 .sidebar-logo { 77 .sidebar-logo {
78 margin-right: 0px; 78 margin-right: 0px;
79 } 79 }
80 } 80 }
81 } 81 }
82 </style> 82 </style>
83 83
1 import Vue from 'vue' 1 import Vue from 'vue'
2 2
3 import 'normalize.css/normalize.css' // A modern alternative to CSS resets 3 import 'normalize.css/normalize.css' // A modern alternative to CSS resets
4 4
5 import ElementUI from 'element-ui' 5 import ElementUI from 'element-ui'
6 import 'element-ui/lib/theme-chalk/index.css' 6 import 'element-ui/lib/theme-chalk/index.css'
7 import locale from 'element-ui/lib/locale/lang/en' // lang i18n 7 import locale from 'element-ui/lib/locale/lang/en' // lang i18n
8 // import local_zh from 'element-ui/lib/locale/lang/zh-CN' // 在node_module里面
8 9
9 import '@/styles/index.scss' // global css 10 import '@/styles/index.scss' // global css
10 11
11 import App from './App' 12 import App from './App'
12 import store from './store' 13 import store from './store'
13 import router from './router' 14 import router from './router'
14 15
15 import '@/icons' // icon 16 import '@/icons' // icon
16 import '@/permission' // permission control 17 import '@/permission' // permission control
17 18
18 /** 19 /**
19 * If you don't want to use mock-server 20 * If you don't want to use mock-server
20 * you want to use MockJs for mock api 21 * you want to use MockJs for mock api
21 * you can execute: mockXHR() 22 * you can execute: mockXHR()
22 * 23 *
23 * Currently MockJs will be used in the production environment, 24 * Currently MockJs will be used in the production environment,
24 * please remove it before going online ! ! ! 25 * please remove it before going online ! ! !
25 */ 26 */
26 if (process.env.NODE_ENV === 'production') { 27 if (process.env.NODE_ENV === 'production') {
27 const { mockXHR } = require('../mock') 28 const { mockXHR } = require('../mock')
28 mockXHR() 29 mockXHR()
29 } 30 }
30 31
31 // set ElementUI lang to EN 32 // set ElementUI lang to EN
32 Vue.use(ElementUI, { locale }) 33 Vue.use(ElementUI, { locale })
33 // 如果想要中文版 element-ui,按如下方式声明 34 // 如果想要中文版 element-ui,按如下方式声明
34 // Vue.use(ElementUI) 35 // Vue.use(ElementUI, {local_zh})
35 36
36 Vue.config.productionTip = false 37 Vue.config.productionTip = false
37 38
38 new Vue({ 39 new Vue({
39 el: '#app', 40 el: '#app',
40 router, 41 router,
41 store, 42 store,
42 render: h => h(App) 43 render: h => h(App)
43 }) 44 })
44 45
src/router/index.js
1 import Vue from 'vue' 1 import Vue from 'vue'
2 import Router from 'vue-router' 2 import Router from 'vue-router'
3 3
4 Vue.use(Router) 4 Vue.use(Router)
5 5
6 /* Layout */ 6 /* Layout */
7 import Layout from '@/layout' 7 import Layout from '@/layout'
8 8
9 /** 9 /**
10 * Note: sub-menu only appear when route children.length >= 1 10 * Note: sub-menu only appear when route children.length >= 1
11 * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html 11 * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
12 * 12 *
13 * hidden: true if set true, item will not show in the sidebar(default is false) 13 * hidden: true if set true, item will not show in the sidebar(default is false)
14 * alwaysShow: true if set true, will always show the root menu 14 * alwaysShow: true if set true, will always show the root menu
15 * if not set alwaysShow, when item has more than one children route, 15 * if not set alwaysShow, when item has more than one children route,
16 * it will becomes nested mode, otherwise not show the root menu 16 * it will becomes nested mode, otherwise not show the root menu
17 * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb 17 * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb
18 * name:'router-name' the name is used by <keep-alive> (must set!!!) 18 * name:'router-name' the name is used by <keep-alive> (must set!!!)
19 * meta : { 19 * meta : {
20 roles: ['admin','editor'] control the page roles (you can set multiple roles) 20 roles: ['admin','editor'] control the page roles (you can set multiple roles)
21 title: 'title' the name show in sidebar and breadcrumb (recommend set) 21 title: 'title' the name show in sidebar and breadcrumb (recommend set)
22 icon: 'svg-name' the icon show in the sidebar 22 icon: 'svg-name' the icon show in the sidebar
23 breadcrumb: false if set false, the item will hidden in breadcrumb(default is true) 23 breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
24 activeMenu: '/example/list' if set path, the sidebar will highlight the path you set 24 activeMenu: '/example/list' if set path, the sidebar will highlight the path you set
25 } 25 }
26 */ 26 */
27 27
28 /** 28 /**
29 * constantRoutes 29 * constantRoutes
30 * a base page that does not have permission requirements 30 * a base page that does not have permission requirements
31 * all roles can be accessed 31 * all roles can be accessed
32 */ 32 */
33 export const constantRoutes = [ 33 export const constantRoutes = [
34 { 34 {
35 path: '/login', 35 path: '/login',
36 component: () => import('@/views/login/index'), 36 component: () => import('@/views/login/index'),
37 hidden: true 37 hidden: true
38 }, 38 },
39 39
40 { 40 {
41 path: '/404', 41 path: '/404',
42 component: () => import('@/views/404'), 42 component: () => import('@/views/404'),
43 hidden: true 43 hidden: true
44 }, 44 },
45 45
46 { 46 {
47 path: '/', 47 path: '/',
48 component: Layout, 48 component: Layout,
49 redirect: '/dashboard', 49 redirect: '/dashboard',
50 children: [{ 50 children: [{
51 path: 'dashboard', 51 path: 'dashboard',
52 name: 'Dashboard', 52 name: 'Dashboard',
53 component: () => import('@/views/dashboard/index'), 53 component: () => import('@/views/dashboard/index'),
54 meta: { title: 'Dashboard', icon: 'dashboard' } 54 meta: { title: '标题-------dashboard', icon: 'dashboard' }
55 }] 55 }]
56 }, 56 },
57 57
58 { 58 {
59 path: '/example', 59 path: '/example',
60 component: Layout, 60 component: Layout,
61 redirect: '/example/table', 61 redirect: '/example/table',
62 name: 'Example', 62 name: 'Example',
63 meta: { title: 'Example', icon: 'example' }, 63 meta: { title: 'Example', icon: 'example' },
64 children: [ 64 children: [
65 { 65 {
66 path: 'table', 66 path: 'table',
67 name: 'Table', 67 name: 'Table',
68 component: () => import('@/views/table/index'), 68 component: () => import('@/views/table/index'),
69 meta: { title: 'Table', icon: 'table' } 69 meta: { title: 'Table', icon: 'table' }
70 }, 70 },
71 { 71 {
72 path: 'tree', 72 path: 'tree',
73 name: 'Tree', 73 name: 'Tree',
74 component: () => import('@/views/tree/index'), 74 component: () => import('@/views/tree/index'),
75 meta: { title: 'Tree', icon: 'tree' } 75 meta: { title: 'Tree', icon: 'tree' }
76 } 76 }
77 ] 77 ]
78 }, 78 },
79 79
80 { 80 {
81 path: '/form', 81 path: '/form',
82 component: Layout, 82 component: Layout,
83 children: [ 83 children: [
84 { 84 {
85 path: 'index', 85 path: 'index',
86 name: 'Form', 86 name: 'Form',
87 component: () => import('@/views/form/index'), 87 component: () => import('@/views/form/index'),
88 meta: { title: 'Form', icon: 'form' } 88 meta: { title: 'Form', icon: 'form' }
89 } 89 }
90 ] 90 ]
91 } 91 }
92 ] 92 ]
93 93
94 /** 94 /**
95 * asyncRoutes 95 * asyncRoutes
96 * the routes that need to be dynamically loaded based on user roles 96 * the routes that need to be dynamically loaded based on user roles
97 */ 97 */
98 export const asyncRoutes = [ 98 export const asyncRoutes = [
99 { 99 {
100 path: '/nested', 100 path: '/nested',
101 component: Layout, 101 component: Layout,
102 redirect: '/nested/menu1', 102 redirect: '/nested/menu1',
103 name: 'Nested', 103 name: 'Nested',
104 meta: { 104 meta: {
105 title: 'Nested', 105 title: 'Nested',
106 icon: 'nested' 106 icon: 'nested'
107 }, 107 },
108 children: [ 108 children: [
109 { 109 {
110 path: 'menu1', 110 path: 'menu1',
111 component: () => import('@/views/nested/menu1/index'), // Parent router-view 111 component: () => import('@/views/nested/menu1/index'), // Parent router-view
112 name: 'Menu1', 112 name: 'Menu1',
113 meta: { title: 'Menu1' }, 113 meta: { title: 'Menu1' },
114 children: [ 114 children: [
115 { 115 {
116 path: 'menu1-1', 116 path: 'menu1-1',
117 component: () => import('@/views/nested/menu1/menu1-1'), 117 component: () => import('@/views/nested/menu1/menu1-1'),
118 name: 'Menu1-1', 118 name: 'Menu1-1',
119 meta: { title: 'Menu1-1' } 119 meta: { title: 'Menu1-1' }
120 }, 120 },
121 { 121 {
122 path: 'menu1-2', 122 path: 'menu1-2',
123 component: () => import('@/views/nested/menu1/menu1-2'), 123 component: () => import('@/views/nested/menu1/menu1-2'),
124 name: 'Menu1-2', 124 name: 'Menu1-2',
125 meta: { title: 'Menu1-2' }, 125 meta: { title: 'Menu1-2' },
126 children: [ 126 children: [
127 { 127 {
128 path: 'menu1-2-1', 128 path: 'menu1-2-1',
129 component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'), 129 component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
130 name: 'Menu1-2-1', 130 name: 'Menu1-2-1',
131 meta: { title: 'Menu1-2-1' } 131 meta: { title: 'Menu1-2-1' }
132 }, 132 },
133 { 133 {
134 path: 'menu1-2-2', 134 path: 'menu1-2-2',
135 component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'), 135 component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
136 name: 'Menu1-2-2', 136 name: 'Menu1-2-2',
137 meta: { title: 'Menu1-2-2' } 137 meta: { title: 'Menu1-2-2' }
138 } 138 }
139 ] 139 ]
140 }, 140 },
141 { 141 {
142 path: 'menu1-3', 142 path: 'menu1-3',
143 component: () => import('@/views/nested/menu1/menu1-3'), 143 component: () => import('@/views/nested/menu1/menu1-3'),
144 name: 'Menu1-3', 144 name: 'Menu1-3',
145 meta: { title: 'Menu1-3' } 145 meta: { title: 'Menu1-3' }
146 } 146 }
147 ] 147 ]
148 }, 148 },
149 { 149 {
150 path: 'menu2', 150 path: 'menu2',
151 component: () => import('@/views/nested/menu2/index'), 151 component: () => import('@/views/nested/menu2/index'),
152 meta: { title: 'menu2' } 152 meta: { title: 'menu2' }
153 } 153 }
154 ] 154 ]
155 }, 155 },
156 156
157 { 157 {
158 path: 'external-link', 158 path: 'external-link',
159 component: Layout, 159 component: Layout,
160 children: [ 160 children: [
161 { 161 {
162 path: 'https://panjiachen.github.io/vue-element-admin-site/#/', 162 path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
163 meta: { title: 'External Link', icon: 'link' } 163 meta: { title: 'External Link', icon: 'link' }
164 } 164 }
165 ] 165 ]
166 }, 166 },
167
168 // 404 page must be placed at the end !!! 167 // 404 page must be placed at the end !!!
169 { path: '*', redirect: '/404', hidden: true } 168 {
169 path: '*',
170 redirect: '/404'
171 }
170 ] 172 ]
171 173
172 const createRouter = () => new Router({ 174 const createRouter = () => new Router({
173 // mode: 'history', // require service support 175 // mode: 'history', // require service support
174 scrollBehavior: () => ({ y: 0 }), 176 scrollBehavior: () => ({ y: 0 }),
175 routes: constantRoutes 177 routes: constantRoutes
176 }) 178 })
177 179
178 const router = createRouter() 180 const router = createRouter()
179 181
180 // Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465 182 // Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
181 export function resetRouter() { 183 export function resetRouter() {
182 const newRouter = createRouter() 184 const newRouter = createRouter()
183 router.matcher = newRouter.matcher // reset router 185 router.matcher = newRouter.matcher // reset router
184 } 186 }
185 187
186 export default router 188 export default router
1 module.exports = { 1 module.exports = {
2 2
3 title: 'Vue Admin Template', 3 title: '鱼皮出海',
4 4
5 /** 5 /**
6 * @type {boolean} true | false 6 * @type {boolean} true | false
7 * @description Whether fix the header 7 * @description Whether fix the header
8 */ 8 */
9 fixedHeader: false, 9 fixedHeader: true,
10 10
11 /** 11 /**
12 * @type {boolean} true | false 12 * @type {boolean} true | false
13 * @description Whether show the logo in sidebar 13 * @description Whether show the logo in sidebar
14 */ 14 */
15 sidebarLogo: false 15 sidebarLogo:true
16 } 16 }
17 17
src/utils/request.js
1 import axios from 'axios' 1 import axios from 'axios'
2 import { MessageBox, Message } from 'element-ui' 2 import { MessageBox, Message } from 'element-ui'
3 import store from '@/store' 3 import store from '@/store'
4 import { getToken } from '@/utils/auth' 4 import { getToken } from '@/utils/auth'
5 5
6 // create an axios instance 6 // create an axios instance
7 // 创建axios实例
7 const service = axios.create({ 8 const service = axios.create({
8 baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url 9 baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
9 // withCredentials: true, // send cookies when cross-domain requests 10 // withCredentials: true, // send cookies when cross-domain requests
10 timeout: 5000 // request timeout 11 timeout: 5000 // request timeout
11 }) 12 })
12 13
13 // request interceptor 14 // request interceptor
15 // request拦截器
14 service.interceptors.request.use( 16 service.interceptors.request.use(
15 config => { 17 config => {
16 // do something before request is sent 18 // do something before request is sent
17 19 console.log('do something before request is sent')
18 if (store.getters.token) { 20 if (store.getters.token) {
21 console.log('[X-Token] is a custom headers key')
19 // let each request carry token 22 // let each request carry token
20 // ['X-Token'] is a custom headers key 23 // ['X-Token'] is a custom headers key
21 // please modify it according to the actual situation 24 // please modify it according to the actual situation
22 config.headers['X-Token'] = getToken() 25 config.headers['X-Token'] = getToken()
23 } 26 }
24 return config 27 return config
25 }, 28 },
26 error => { 29 error => {
30 console.log('do something with request error')
27 // do something with request error 31 // do something with request error
28 console.log(error) // for debug 32 console.log(error) // for debug
29 return Promise.reject(error) 33 return Promise.reject(error)
30 } 34 }
31 ) 35 )
32 36
33 // response interceptor 37 // response interceptor
38 // respone拦截器
34 service.interceptors.response.use( 39 service.interceptors.response.use(
35 /** 40 /**
36 * If you want to get http information such as headers or status 41 * If you want to get http information such as headers or status
37 * Please return response => response 42 * Please return response => response
38 */ 43 */
39 44
40 /** 45 /**
41 * Determine the request status by custom code 46 * Determine the request status by custom code
42 * Here is just an example 47 * Here is just an example
43 * You can also judge the status by HTTP Status Code 48 * You can also judge the status by HTTP Status Code
44 */ 49 */
45 response => { 50 response => {
46 const res = response.data 51 const res = response.data
47 52 /**
53 * 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页
54 * 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中
55 */
56 console.log('if the custom code is not 20000, it is judged as an error.')
48 // if the custom code is not 20000, it is judged as an error. 57 // if the custom code is not 20000, it is judged as an error.
49 if (res.code !== 20000) { 58 if (res.code !== 20000) {
50 Message({ 59 Message({
51 message: res.message || 'Error', 60 message: res.message || 'Error',
52 type: 'error', 61 type: 'error',
53 duration: 5 * 1000 62 duration: 5 * 1000
54 }) 63 })
55 64
56 // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; 65 // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
66 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
57 if (res.code === 50008 || res.code === 50012 || res.code === 50014) { 67 if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
58 // to re-login 68 // to re-login
59 MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { 69 // MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
60 confirmButtonText: 'Re-Login', 70 MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
61 cancelButtonText: 'Cancel', 71 // confirmButtonText: 'Re-Login',
72 confirmButtonText: '重新登录',
73 // cancelButtonText: 'Cancel',
74 cancelButtonText: '取消',
62 type: 'warning' 75 type: 'warning'
63 }).then(() => { 76 }).then(() => {
64 store.dispatch('user/resetToken').then(() => { 77 store.dispatch('user/resetToken').then(() => {
65 location.reload() 78 location.reload()// 为了重新实例化vue-router对象 避免bug
66 }) 79 })
67 }) 80 })
68 } 81 }
69 return Promise.reject(new Error(res.message || 'Error')) 82 return Promise.reject(new Error(res.message || 'Error'))
70 } else { 83 } else {
71 return res 84 return res
72 } 85 }
73 }, 86 },
74 error => { 87 error => {
75 console.log('err' + error) // for debug 88 console.log('err' + error) // for debug
76 Message({ 89 Message({
77 message: error.message, 90 message: error.message,
78 type: 'error', 91 type: 'error',
79 duration: 5 * 1000 92 duration: 5 * 1000
80 }) 93 })
81 return Promise.reject(error) 94 return Promise.reject(error)
82 } 95 }
83 ) 96 )
84 97
85 export default service 98 export default service
86 99
src/views/dashboard/index.vue
1 <template> 1 <template>
2 <div class="dashboard-container"> 2 <div class="dashboard-container">
3 <div class="dashboard-text">name: {{ name }}</div> 3 <div class="dashboard-text">用户名: {{ name }}</div>
4 <div class="dashboard-text">roles: <span v-for="role in roles" :key="role">{{ role }}</span></div> 4 <div class="dashboard-text">角色: <span v-for="role in roles" :key="role">{{ role }}</span></div>
5 </div> 5 </div>
6 </template> 6 </template>
7 7
8
9
8 <script> 10 <script>
9 import { mapGetters } from 'vuex' 11 import { mapGetters } from 'vuex'
12 import ElementUI from 'element-ui'
10 13
11 export default { 14 export default {
12 name: 'Dashboard', 15 name: 'Dashboard',
13 computed: { 16 computed: {
14 ...mapGetters([ 17 ...mapGetters([
15 'name', 18 'name',
16 'roles' 19 'roles'
17 ]) 20 ])
18 } 21 }
19 } 22 }
20 </script> 23 </script>
21 24
22 <style lang="scss" scoped> 25 <style lang="scss" scoped>
23 .dashboard { 26 .dashboard {
24 &-container { 27 &-container {
25 margin: 30px; 28 margin: 30px;
26 } 29 }
27 &-text { 30 &-text {
28 font-size: 30px; 31 font-size: 30px;
29 line-height: 46px; 32 line-height: 46px;
30 } 33 }
31 } 34 }
32 </style> 35 </style>
33 36
src/views/login/index.vue
1 <template> 1 <template>
2 <div class="login-container"> 2 <div class="login-container">
3 <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left"> 3 <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
4 4
5 <div class="title-container"> 5 <div class="title-container">
6 <h3 class="title">Login Form</h3> 6 <h3 class="title">Login Form</h3>
7 </div> 7 </div>
8 8
9 <el-form-item prop="username"> 9 <el-form-item prop="username">
10 <span class="svg-container"> 10 <span class="svg-container">
11 <svg-icon icon-class="user" /> 11 <svg-icon icon-class="user" />
12 </span> 12 </span>
13 <el-input 13 <el-input
14 ref="username" 14 ref="username"
15 v-model="loginForm.username" 15 v-model="loginForm.username"
16 placeholder="Username" 16 placeholder="Username"
17 name="username" 17 name="username"
18 type="text" 18 type="text"
19 tabindex="1" 19 tabindex="1"
20 auto-complete="on" 20 auto-complete="on"
21 /> 21 />
22 </el-form-item> 22 </el-form-item>
23 23
24 <el-form-item prop="password"> 24 <el-form-item prop="password">
25 <span class="svg-container"> 25 <span class="svg-container">
26 <svg-icon icon-class="password" /> 26 <svg-icon icon-class="password" />
27 </span> 27 </span>
28 <el-input 28 <el-input
29 :key="passwordType" 29 :key="passwordType"
30 ref="password" 30 ref="password"
31 v-model="loginForm.password" 31 v-model="loginForm.password"
32 :type="passwordType" 32 :type="passwordType"
33 placeholder="Password" 33 placeholder="Password"
34 name="password" 34 name="password"
35 tabindex="2" 35 tabindex="2"
36 auto-complete="on" 36 auto-complete="on"
37 @keyup.enter.native="handleLogin" 37 @keyup.enter.native="handleLogin"
38 /> 38 />
39 <span class="show-pwd" @click="showPwd"> 39 <span class="show-pwd" @click="showPwd">
40 <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" /> 40 <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
41 </span> 41 </span>
42 </el-form-item> 42 </el-form-item>
43 43 <!-- <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">reg</el-button> -->
44 <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button> 44 <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button>
45 45
46 <div class="tips"> 46 <div class="tips">
47 <span style="margin-right:20px;">username: admin</span> 47 <span style="margin-right:20px;">username: admin</span>
48 <span> password: any</span> 48 <span> password: any</span>
49 </div> 49 </div>
50 50
51 </el-form> 51 </el-form>
52 </div> 52 </div>
53 </template> 53 </template>
54 54
55 <script> 55 <script>
56 import { validUsername } from '@/utils/validate' 56 import { validUsername } from '@/utils/validate'
57 57
58 export default { 58 export default {
59 name: 'Login', 59 name: 'Login',
60 data() { 60 data() {
61 const validateUsername = (rule, value, callback) => { 61 const validateUsername = (rule, value, callback) => {
62 if (!validUsername(value)) { 62 if (!validUsername(value)) {
63 callback(new Error('Please enter the correct user name')) 63 callback(new Error('Please enter the correct user name'))
64 } else { 64 } else {
65 callback() 65 callback()
66 } 66 }
67 } 67 }
68 const validatePassword = (rule, value, callback) => { 68 const validatePassword = (rule, value, callback) => {
69 if (value.length < 6) { 69 if (value.length < 6) {
70 callback(new Error('The password can not be less than 6 digits')) 70 callback(new Error('The password can not be less than 6 digits'))
71 } else { 71 } else {
72 callback() 72 callback()
73 } 73 }
74 } 74 }
75 return { 75 return {
76 loginForm: { 76 loginForm: {
77 username: 'admin', 77 username: 'admin',
78 password: '111111' 78 password: '111111'
79 }, 79 },
80 loginRules: { 80 loginRules: {
81 username: [{ required: true, trigger: 'blur', validator: validateUsername }], 81 username: [{ required: true, trigger: 'blur', validator: validateUsername }],
82 password: [{ required: true, trigger: 'blur', validator: validatePassword }] 82 password: [{ required: true, trigger: 'blur', validator: validatePassword }]
83 }, 83 },
84 loading: false, 84 loading: false,
85 passwordType: 'password', 85 passwordType: 'password',
86 redirect: undefined 86 redirect: undefined
87 } 87 }
88 }, 88 },
89 watch: { 89 watch: {
90 $route: { 90 $route: {
91 handler: function(route) { 91 handler: function(route) {
92 this.redirect = route.query && route.query.redirect 92 this.redirect = route.query && route.query.redirect
93 }, 93 },
94 immediate: true 94 immediate: true
95 } 95 }
96 }, 96 },
97 methods: { 97 methods: {
98 showPwd() { 98 showPwd() {
99 if (this.passwordType === 'password') { 99 if (this.passwordType === 'password') {
100 this.passwordType = '' 100 this.passwordType = ''
101 } else { 101 } else {
102 this.passwordType = 'password' 102 this.passwordType = 'password'
103 } 103 }
104 this.$nextTick(() => { 104 this.$nextTick(() => {
105 this.$refs.password.focus() 105 this.$refs.password.focus()
106 }) 106 })
107 }, 107 },
108 handleLogin() { 108 handleLogin() {
109 this.$refs.loginForm.validate(valid => { 109 this.$refs.loginForm.validate(valid => {
110 if (valid) { 110 if (valid) {
111 this.loading = true 111 this.loading = true
112 this.$store.dispatch('user/login', this.loginForm).then(() => { 112 this.$store.dispatch('user/login', this.loginForm).then(() => {
113 this.$router.push({ path: this.redirect || '/' }) 113 this.$router.push({ path: this.redirect || '/' })
114 this.loading = false 114 this.loading = false
115 }).catch(() => { 115 }).catch(() => {
116 this.loading = false 116 this.loading = false
117 }) 117 })
118 } else { 118 } else {
119 console.log('error submit!!') 119 console.log('error submit!!')
120 return false 120 return false
121 } 121 }
122 }) 122 })
123 } 123 }
124 } 124 }
125 } 125 }
126 </script> 126 </script>
127 127
128 <style lang="scss"> 128 <style lang="scss">
129 /* 修复input 背景不协调 和光标变色 */ 129 /* 修复input 背景不协调 和光标变色 */
130 /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */ 130 /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
131 131
132 $bg:#283443; 132 $bg:#283443;
133 $light_gray:#fff; 133 $light_gray:#fff;
134 $cursor: #fff; 134 $cursor: #fff;
135 135
136 @supports (-webkit-mask: none) and (not (cater-color: $cursor)) { 136 @supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
137 .login-container .el-input input { 137 .login-container .el-input input {
138 color: $cursor; 138 color: $cursor;
139 } 139 }
140 } 140 }
141 141
142 /* reset element-ui css */ 142 /* reset element-ui css */
143 .login-container { 143 .login-container {
144 .el-input { 144 .el-input {
145 display: inline-block; 145 display: inline-block;
146 height: 47px; 146 height: 47px;
147 width: 85%; 147 width: 85%;
148 148
149 input { 149 input {
150 background: transparent; 150 background: transparent;
151 border: 0px; 151 border: 0px;
152 -webkit-appearance: none; 152 -webkit-appearance: none;
153 border-radius: 0px; 153 border-radius: 0px;
154 padding: 12px 5px 12px 15px; 154 padding: 12px 5px 12px 15px;
155 color: $light_gray; 155 color: $light_gray;
156 height: 47px; 156 height: 47px;
157 caret-color: $cursor; 157 caret-color: $cursor;
158 158
159 &:-webkit-autofill { 159 &:-webkit-autofill {
160 box-shadow: 0 0 0px 1000px $bg inset !important; 160 box-shadow: 0 0 0px 1000px $bg inset !important;
161 -webkit-text-fill-color: $cursor !important; 161 -webkit-text-fill-color: $cursor !important;
162 } 162 }
163 } 163 }
164 } 164 }
165 165
166 .el-form-item { 166 .el-form-item {
167 border: 1px solid rgba(255, 255, 255, 0.1); 167 border: 1px solid rgba(255, 255, 255, 0.1);
168 background: rgba(0, 0, 0, 0.1); 168 background: rgba(0, 0, 0, 0.1);
169 border-radius: 5px; 169 border-radius: 5px;
170 color: #454545; 170 color: #454545;
171 } 171 }
172 } 172 }
173 </style> 173 </style>
174 174
175 <style lang="scss" scoped> 175 <style lang="scss" scoped>
176 $bg:#2d3a4b; 176 $bg:#2d3a4b;
177 $dark_gray:#889aa4; 177 $dark_gray:#889aa4;
178 $light_gray:#eee; 178 $light_gray:#eee;
179 179
180 .login-container { 180 .login-container {
181 min-height: 100%; 181 min-height: 100%;
182 width: 100%; 182 width: 100%;
183 background-color: $bg; 183 background-color: $bg;
184 overflow: hidden; 184 overflow: hidden;
185 185
186 .login-form { 186 .login-form {
187 position: relative; 187 position: relative;
188 width: 520px; 188 width: 520px;
189 max-width: 100%; 189 max-width: 100%;
190 padding: 160px 35px 0; 190 padding: 160px 35px 0;
191 margin: 0 auto; 191 margin: 0 auto;
192 overflow: hidden; 192 overflow: hidden;
193 } 193 }
194 194
195 .tips { 195 .tips {
196 font-size: 14px; 196 font-size: 14px;
197 color: #fff; 197 color: #fff;
198 margin-bottom: 10px; 198 margin-bottom: 10px;
199 199
200 span { 200 span {
201 &:first-of-type { 201 &:first-of-type {
202 margin-right: 16px; 202 margin-right: 16px;
203 } 203 }
204 } 204 }
205 } 205 }
206 206
207 .svg-container { 207 .svg-container {
208 padding: 6px 5px 6px 15px; 208 padding: 6px 5px 6px 15px;
209 color: $dark_gray; 209 color: $dark_gray;
210 vertical-align: middle; 210 vertical-align: middle;
211 width: 30px; 211 width: 30px;
212 display: inline-block; 212 display: inline-block;
213 } 213 }
214 214
215 .title-container { 215 .title-container {
216 position: relative; 216 position: relative;
217 217
218 .title { 218 .title {
219 font-size: 26px; 219 font-size: 26px;
220 color: $light_gray; 220 color: $light_gray;
221 margin: 0px auto 40px auto; 221 margin: 0px auto 40px auto;
222 text-align: center; 222 text-align: center;
223 font-weight: bold; 223 font-weight: bold;
224 } 224 }
225 } 225 }
226 226
227 .show-pwd { 227 .show-pwd {
228 position: absolute; 228 position: absolute;
229 right: 10px; 229 right: 10px;
230 top: 7px; 230 top: 7px;
231 font-size: 16px; 231 font-size: 16px;
232 color: $dark_gray; 232 color: $dark_gray;
233 cursor: pointer; 233 cursor: pointer;
234 user-select: none; 234 user-select: none;
235 } 235 }
236 } 236 }
237 </style> 237 </style>
238 238