Ver Código Fonte

登录,找回密码

luyanan 6 anos atrás
pai
commit
48391e728f
34 arquivos alterados com 923 adições e 528 exclusões
  1. 2 3
      build/webpack.dev.conf.js
  2. 8 2
      build/webpack.prod.conf.js
  3. 2 2
      config/index.js
  4. 1 2
      config/prod.env.js
  5. 0 41
      src/api/article.js
  6. 26 9
      src/api/login.js
  7. 5 0
      src/api/pictureVc.js
  8. 1 2
      src/main.js
  9. 46 39
      src/permission.js
  10. 57 34
      src/router/index.js
  11. 5 1
      src/store/getters.js
  12. 4 0
      src/store/index.js
  13. 17 0
      src/store/modules/errorLog.js
  14. 62 0
      src/store/modules/permission.js
  15. 28 15
      src/store/modules/user.js
  16. 162 0
      src/styles/loginform.scss
  17. 8 0
      src/utils/index.js
  18. 26 0
      src/utils/permission.js
  19. 72 44
      src/utils/request.js
  20. 0 0
      src/views/bridgesConsole/bridgeDetail/components/BInfoDialog01.vue
  21. 0 0
      src/views/bridgesConsole/bridgeDetail/components/BInfoDialog02.vue
  22. 0 0
      src/views/bridgesConsole/bridgeDetail/components/BInfoDialog03.vue
  23. 0 0
      src/views/bridgesConsole/bridgeDetail/components/BInfoDialog04.vue
  24. 0 0
      src/views/bridgesConsole/bridgeDetail/components/LineChart.vue
  25. 0 0
      src/views/bridgesConsole/bridgeDetail/components/updateLoginPwd.vue
  26. 0 0
      src/views/bridgesConsole/bridgeDetail/components/updatePersonInfo.vue
  27. 0 0
      src/views/bridgesConsole/bridgeDetail/index.vue
  28. 3 3
      src/views/dashboard/admin/index.vue
  29. 3 3
      src/views/dashboard/index.vue
  30. 85 46
      src/views/dashboard/other/index.vue
  31. 244 164
      src/views/findPwd/index.vue
  32. 2 1
      src/views/layout/components/Sidebar/index.vue
  33. 10 0
      src/views/login/authredirect.vue
  34. 44 117
      src/views/login/index.vue

+ 2 - 3
build/webpack.dev.conf.js

54
      filename: 'index.html',
54
      filename: 'index.html',
55
      template: 'index.html',
55
      template: 'index.html',
56
      inject: true,
56
      inject: true,
57
      favicon: resolve('favicon.ico'),
58
      title: 'vue-element-admin'
59
    }),
57
      favicon: resolve('favicon.ico')
58
    })
60
  ]
59
  ]
61
})
60
})
62
61

+ 8 - 2
build/webpack.prod.conf.js

68
      template: 'index.html',
68
      template: 'index.html',
69
      inject: true,
69
      inject: true,
70
      favicon: resolve('favicon.ico'),
70
      favicon: resolve('favicon.ico'),
71
      title: 'vue-element-admin',
72
      minify: {
71
      minify: {
73
        removeComments: true,
72
        removeComments: true,
74
        collapseWhitespace: true,
73
        collapseWhitespace: true,
112
      children: true,
111
      children: true,
113
      minChunks: 3
112
      minChunks: 3
114
    }),
113
    }),
115
114
    // split echarts into its own file
115
    new webpack.optimize.CommonsChunkPlugin({
116
      async: 'echarts',
117
      minChunks(module) {
118
        var context = module.context;
119
        return context && (context.indexOf('echarts') >= 0 || context.indexOf('zrender') >= 0);
120
      }
121
    }),
116
    // copy custom static assets
122
    // copy custom static assets
117
    new CopyWebpackPlugin([
123
    new CopyWebpackPlugin([
118
      {
124
      {

+ 2 - 2
config/index.js

61
     * then assetsPublicPath should be set to "/bar/".
61
     * then assetsPublicPath should be set to "/bar/".
62
     * In most cases please use '/' !!!
62
     * In most cases please use '/' !!!
63
     */
63
     */
64
    assetsPublicPath: '/vueAdmin-template/', // If you are deployed on the root path, please use '/'
64
    assetsPublicPath: '/', // If you are deployed on the root path, please use '/'
65
65
66
    /**
66
    /**
67
     * Source Maps
67
     * Source Maps
68
     */
68
     */
69
69
70
    productionSourceMap: false,
70
    productionSourceMap: true,
71
    // https://webpack.js.org/configuration/devtool/#production
71
    // https://webpack.js.org/configuration/devtool/#production
72
    devtool: '#source-map',
72
    devtool: '#source-map',
73
73

+ 1 - 2
config/prod.env.js

1
'use strict'
1
'use strict'
2
module.exports = {
2
module.exports = {
3
  NODE_ENV: '"production"',
4
  BASE_API: '"https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin"',
3
  NODE_ENV: '"production"'
5
}
4
}

+ 0 - 41
src/api/article.js

1
import request from '@/utils/request'
2
3
export function fetchList(query) {
4
  return request({
5
    url: '/article/list',
6
    method: 'get',
7
    params: query
8
  })
9
}
10
11
export function fetchArticle(id) {
12
  return request({
13
    url: '/article/detail',
14
    method: 'get',
15
    params: { id }
16
  })
17
}
18
19
export function fetchPv(pv) {
20
  return request({
21
    url: '/article/pv',
22
    method: 'get',
23
    params: { pv }
24
  })
25
}
26
27
export function createArticle(data) {
28
  return request({
29
    url: '/article/create',
30
    method: 'post',
31
    data
32
  })
33
}
34
35
export function updateArticle(data) {
36
  return request({
37
    url: '/article/update',
38
    method: 'post',
39
    data
40
  })
41
}

+ 26 - 9
src/api/login.js

1
import request from '@/utils/request'
1
import request from '@/utils/request'
2
2
3
export function login(username, password) {
3
export function login(account, pw, vc) {
4
  return request({
4
  return request({
5
    url: '/user/login',
5
    url: '/ajax/sys/login',
6
    method: 'post',
6
    method: 'post',
7
    data: {
7
    data: {
8
      username,
9
      password
8
      account,
9
      pw,
10
      vc
10
    }
11
    }
11
  })
12
  })
12
}
13
}
13
14
14
export function getInfo(token) {
15
export function getInfo(params) {
15
  return request({
16
  return request({
16
    url: '/user/info',
17
    url: '/ajax/sys/user',
17
    method: 'get',
18
    method: 'get',
18
    params: { token }
19
    params
19
  })
20
  })
20
}
21
}
21
22
22
export function logout() {
23
export function logout() {
24
  // return request({
25
  //   url: '/user/logout',
26
  //   method: 'post'
27
  // })
28
}
29
30
export function isReg(params) {
31
  return request({
32
    url: '/ajax/sys/check',
33
    method: 'get',
34
    params
35
  })
36
}
37
38
export function getMsgPhone(params) {
23
  return request({
39
  return request({
24
    url: '/user/logout',
25
    method: 'post'
40
    url: '/ajax/sys/resetPwMobile',
41
    method: 'get',
42
    params
26
  })
43
  })
27
}
44
}

+ 5 - 0
src/api/pictureVc.js

1
import { comUrl } from '@/utils/index'
2
3
export function getPictureVC(flag) {
4
  return comUrl + '/ajax/PictureVC?' + new Date().getTime() + '&flag=' + flag
5
}

+ 1 - 2
src/main.js

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
8
7
9
import '@/styles/index.scss' // global css
8
import '@/styles/index.scss' // global css
10
9
15
import '@/icons' // icon
14
import '@/icons' // icon
16
import '@/permission' // permission control
15
import '@/permission' // permission control
17
16
18
Vue.use(ElementUI, { locale })
17
Vue.use(ElementUI)
19
18
20
Vue.config.productionTip = false
19
Vue.config.productionTip = false
21
20

+ 46 - 39
src/permission.js

1
import router from './router'
2
import store from './store'
3
import NProgress from 'nprogress' // Progress 进度条
4
import 'nprogress/nprogress.css'// Progress 进度条样式
5
import { Message } from 'element-ui'
6
import { getToken } from '@/utils/auth' // 验权
1
// import router from './router'
2
// import store from './store'
3
// import NProgress from 'nprogress' // Progress 进度条
4
// import 'nprogress/nprogress.css'// Progress 进度条样式
5
// import { Message } from 'element-ui'
6
// import { getToken } from '@/utils/auth' // 验权
7
7
8
const whiteList = ['/login'] // 不重定向白名单
9
router.beforeEach((to, from, next) => {
10
  NProgress.start()
11
  if (getToken()) {
12
    if (to.path === '/login') {
13
      next({ path: '/' })
14
      NProgress.done() // if current page is dashboard will not trigger	afterEach hook, so manually handle it
15
    } else {
16
      if (store.getters.roles.length === 0) {
17
        store.dispatch('GetInfo').then(res => { // 拉取用户信息
18
          next()
19
        }).catch((err) => {
20
          store.dispatch('FedLogOut').then(() => {
21
            Message.error(err || 'Verification failed, please login again')
22
            next({ path: '/' })
23
          })
24
        })
25
      } else {
26
        next()
27
      }
28
    }
29
  } else {
30
    if (whiteList.indexOf(to.path) !== -1) {
31
      next()
32
    } else {
33
      next('/login')
34
      NProgress.done()
35
    }
36
  }
37
})
8
// NProgress.configure({ showSpinner: false })// NProgress Configuration
38
9
39
router.afterEach(() => {
40
  NProgress.done() // 结束Progress
41
})
10
// const whiteList = ['/login', '/authredirect'] // 不重定向白名单
11
// router.beforeEach((to, from, next) => {
12
//   NProgress.start()
13
//   if (getToken()) {
14
//     if (to.path === '/login') {
15
//       // next({ path: '/' })
16
//       NProgress.done() // if current page is dashboard will not trigger	afterEach hook, so manually handle it
17
//     } else {
18
//       if (store.getters.roles.length === 0) {
19
//         store.dispatch('GetUserInfo').then(res => { // 拉取用户信息
20
//           next()
21
//           // const roles = res.data.roles // note: roles must be a array! such as: ['editor','develop']
22
//           // store.dispatch('GenerateRoutes', { roles }).then(() => { // 根据roles权限生成可访问的路由表
23
//           //   router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
24
//           //   next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
25
//           // })
26
//         }).catch((err) => {
27
//           store.dispatch('FedLogOut').then(() => {
28
//             Message.error(err || 'Verification failed, please login again')
29
//             next({ path: '/' })
30
//           })
31
//         })
32
//       } else {
33
//         next()
34
//       }
35
//     }
36
//   } else {
37
//     if (whiteList.indexOf(to.path) !== -1) {
38
//       next()
39
//     } else {
40
//       // next('/login')
41
//       NProgress.done()
42
//     }
43
//   }
44
// })
45
46
// router.afterEach(() => {
47
//   NProgress.done() // 结束Progress
48
// })

+ 57 - 34
src/router/index.js

8
8
9
/* Layout */
9
/* Layout */
10
import Layout from '../views/layout/Layout'
10
import Layout from '../views/layout/Layout'
11
import LayoutC from '../views/layout/LayoutC'
11
// import LayoutC from '../views/layout/LayoutC'
12
13
/** note: submenu only apppear when children.length>=1
14
*   detail see  https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
15
**/
12
16
13
/**
17
/**
14
* hidden: true                   if `hidden:true` will not show in the sidebar(default is false)
18
* hidden: true                   if `hidden:true` will not show in the sidebar(default is false)
18
* redirect: noredirect           if `redirect:noredirect` will no redirct in the breadcrumb
22
* redirect: noredirect           if `redirect:noredirect` will no redirct in the breadcrumb
19
* name:'router-name'             the name is used by <keep-alive> (must set!!!)
23
* name:'router-name'             the name is used by <keep-alive> (must set!!!)
20
* meta : {
24
* meta : {
25
    roles: ['admin','editor']     will control the page roles (you can set multiple roles)
21
    title: 'title'               the name show in submenu and breadcrumb (recommend set)
26
    title: 'title'               the name show in submenu and breadcrumb (recommend set)
22
    icon: 'svg-name'             the icon show in the sidebar,
27
    icon: 'svg-name'             the icon show in the sidebar,
28
    noCache: true                if true ,the page will no be cached(default is false)
23
  }
29
  }
24
**/
30
**/
31
32
// 所有权限通用路由表
33
// 如首页和登录页和一些不用权限的公用页面
34
25
export const constantRouterMap = [
35
export const constantRouterMap = [
26
  { path: '/login', component: () => import('@/views/login/index'), hidden: true },
36
  { path: '/login', component: () => import('@/views/login/index'), hidden: true },
27
  { path: '/findPwd', component: () => import('@/views/findPwd/index'), hidden: true },
37
  { path: '/findPwd', component: () => import('@/views/findPwd/index'), hidden: true },
28
  { path: '/404', component: () => import('@/views/404'), hidden: true },
38
  { path: '/404', component: () => import('@/views/404'), hidden: true },
29
39
30
  {
31
    path: '/bridgesConsole',
32
    component: LayoutC,
33
    redirect: '/bridgesConsole/birdgeLists',
34
    hidden: true,
35
    children: [
36
      {
37
        path: 'birdgeLists',
38
        name: 'bridgeLists',
39
        component: () => import('@/views/bridgesConsole/birdgeLists/index')
40
      },
41
      {
42
        path: 'dashboardC',
43
        name: 'dashboardC',
44
        component: () => import('@/views/bridgesConsole/dashboardC/index')
45
      }
46
    ]
47
  },
48
49
  {
40
  {
50
    path: '/',
41
    path: '/',
51
    component: Layout,
42
    component: Layout,
52
    redirect: '/dashboard',
43
    redirect: '/dashboard',
53
    name: 'Dashboard',
54
    hidden: true,
44
    hidden: true,
55
    children: [{
45
    children: [{
56
      path: 'dashboard',
46
      path: 'dashboard',
57
      component: () => import('@/views/dashboard/index')
47
      component: () => import('@/views/dashboard/index'),
48
      name: 'dashboard',
49
      meta: { title: '主页', noCache: true }
58
    }]
50
    }]
59
     meta: { title: '主页', noCache: true },
51
  }
52
]
53
54
// 实例化vue的时候只挂载constantRouter
55
56
export default new Router({
57
  // mode: 'history', //后端支持可开
58
  scrollBehavior: () => ({ y: 0 }),
59
  routes: constantRouterMap
60
})
61
62
// 异步挂载的路由
63
// 动态需要根据权限加载的路由表
64
65
export const asyncRouterMap = [
60
  {
66
  {
61
    path: '/peoplesManage',
67
    path: '/peoplesManage',
62
    component: Layout,
68
    component: Layout,
63
    redirect: '/peoplesManage/infoManage',
69
    redirect: '/peoplesManage/infoManage/index',
64
    name: 'peoplesManage',
70
    name: 'peoplesManage',
65
    meta: { title: '用户系统管理', icon: 'peoples' },
71
    meta: {
72
      title: '用户系统管理',
73
      icon: 'peoples',
74
      roles: ['admin']
75
    },
66
    alwaysShow: true,
76
    alwaysShow: true,
67
    children: [
77
    children: [
68
      {
78
      {
76
  {
86
  {
77
    path: '/baseInfoManage',
87
    path: '/baseInfoManage',
78
    component: Layout,
88
    component: Layout,
79
    redirect: '/baseInfoManage/bridgesInfo',
89
    redirect: '/baseInfoManage/bridgesInfo/index',
80
    name: 'BaseInfoManage',
90
    name: 'BaseInfoManage',
81
    meta: { title: '基础信息管理', icon: 'list' },
91
    meta: {
92
      title: '基础信息管理',
93
      icon: 'list',
94
      roles: ['admin']
95
    },
82
    children: [
96
    children: [
83
      {
97
      {
84
        path: 'bridgesInfo',
98
        path: 'bridgesInfo',
107
    ]
121
    ]
108
  },
122
  },
109
123
124
  {
125
    path: '/bridgesConsole',
126
    component: Layout,
127
    redirect: '/bridgesConsole/bridgeDetail',
128
    meta: {
129
      roles: ['other']
130
    },
131
    children: [
132
      {
133
        path: 'bridgeDetail',
134
        name: 'bridgeDetail',
135
        component: () => import('@/views/bridgesConsole/bridgeDetail/index')
136
      }
137
    ]
138
  },
139
110
  { path: '*', redirect: '/404', hidden: true }
140
  { path: '*', redirect: '/404', hidden: true }
111
]
141
]
112
113
export default new Router({
114
  // mode: 'history', //后端支持可开
115
  scrollBehavior: () => ({ y: 0 }),
116
  routes: constantRouterMap
117
})
118

+ 5 - 1
src/store/getters.js

4
  token: state => state.user.token,
4
  token: state => state.user.token,
5
  avatar: state => state.user.avatar,
5
  avatar: state => state.user.avatar,
6
  name: state => state.user.name,
6
  name: state => state.user.name,
7
  roles: state => state.user.roles
7
  status: state => state.user.status,
8
  roles: state => state.user.roles,
9
  permission_routers: state => state.permission.routers,
10
  addRouters: state => state.permission.addRouters,
11
  errorLogs: state => state.errorLog.logs
8
}
12
}
9
export default getters
13
export default getters

+ 4 - 0
src/store/index.js

1
import Vue from 'vue'
1
import Vue from 'vue'
2
import Vuex from 'vuex'
2
import Vuex from 'vuex'
3
import app from './modules/app'
3
import app from './modules/app'
4
import errorLog from './modules/errorLog'
5
import permission from './modules/permission'
4
import user from './modules/user'
6
import user from './modules/user'
5
import getters from './getters'
7
import getters from './getters'
6
8
9
const store = new Vuex.Store({
11
const store = new Vuex.Store({
10
  modules: {
12
  modules: {
11
    app,
13
    app,
14
    errorLog,
15
    permission,
12
    user
16
    user
13
  },
17
  },
14
  getters
18
  getters

+ 17 - 0
src/store/modules/errorLog.js

1
const errorLog = {
2
  state: {
3
    logs: []
4
  },
5
  mutations: {
6
    ADD_ERROR_LOG: (state, log) => {
7
      state.logs.push(log)
8
    }
9
  },
10
  actions: {
11
    addErrorLog({ commit }, log) {
12
      commit('ADD_ERROR_LOG', log)
13
    }
14
  }
15
}
16
17
export default errorLog

+ 62 - 0
src/store/modules/permission.js

1
import { asyncRouterMap, constantRouterMap } from '@/router'
2
3
/**
4
 * 通过meta.role判断是否与当前用户权限匹配
5
 * @param roles
6
 * @param route
7
 */
8
function hasPermission(roles, route) {
9
  if (route.meta && route.meta.roles) {
10
    return roles.some(role => route.meta.roles.indexOf(role) >= 0)
11
  } else {
12
    return true
13
  }
14
}
15
16
/**
17
 * 递归过滤异步路由表,返回符合用户角色权限的路由表
18
 * @param asyncRouterMap
19
 * @param roles
20
 */
21
function filterAsyncRouter(asyncRouterMap, roles) {
22
  const accessedRouters = asyncRouterMap.filter(route => {
23
    if (hasPermission(roles, route)) {
24
      if (route.children && route.children.length) {
25
        route.children = filterAsyncRouter(route.children, roles)
26
      }
27
      return true
28
    }
29
    return false
30
  })
31
  return accessedRouters
32
}
33
34
const permission = {
35
  state: {
36
    routers: constantRouterMap,
37
    addRouters: []
38
  },
39
  mutations: {
40
    SET_ROUTERS: (state, routers) => {
41
      state.addRouters = routers
42
      state.routers = constantRouterMap.concat(routers)
43
    }
44
  },
45
  actions: {
46
    GenerateRoutes({ commit }, data) {
47
      return new Promise(resolve => {
48
        const { roles } = data
49
        let accessedRouters
50
        if (roles.indexOf('admin') >= 0) {
51
          accessedRouters = asyncRouterMap
52
        } else {
53
          accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
54
        }
55
        commit('SET_ROUTERS', accessedRouters)
56
        resolve()
57
      })
58
    }
59
  }
60
}
61
62
export default permission

+ 28 - 15
src/store/modules/user.js

3
3
4
const user = {
4
const user = {
5
  state: {
5
  state: {
6
    user: '',
7
    status: '',
8
    code: '',
6
    token: getToken(),
9
    token: getToken(),
7
    name: '',
10
    name: '',
8
    avatar: '',
11
    avatar: '',
10
  },
13
  },
11
14
12
  mutations: {
15
  mutations: {
16
    SET_CODE: (state, code) => {
17
      state.code = code
18
    },
19
    SET_STATUS: (state, status) => {
20
      state.status = status
21
    },
13
    SET_TOKEN: (state, token) => {
22
    SET_TOKEN: (state, token) => {
14
      state.token = token
23
      state.token = token
15
    },
24
    },
25
  },
34
  },
26
35
27
  actions: {
36
  actions: {
28
    // 登录
29
    Login({ commit }, userInfo) {
37
    // 用户名登录
38
    LoginByUsername({ commit }, userInfo) {
30
      const username = userInfo.username.trim()
39
      const username = userInfo.username.trim()
31
      return new Promise((resolve, reject) => {
40
      return new Promise((resolve, reject) => {
32
        login(username, userInfo.password).then(response => {
33
          const data = response.data
34
          setToken(data.token)
35
          commit('SET_TOKEN', data.token)
41
        login(username, userInfo.password, vc).then(response => {
42
          // const data = response.data
43
          // commit('SET_TOKEN', data.token)
44
          setToken(response.data.token)
36
          resolve()
45
          resolve()
37
        }).catch(error => {
46
        }).catch(error => {
38
          reject(error)
47
          reject(error)
41
    },
50
    },
42
51
43
    // 获取用户信息
52
    // 获取用户信息
44
    GetInfo({ commit, state }) {
53
    GetUserInfo({ commit, state }) {
45
      return new Promise((resolve, reject) => {
54
      return new Promise((resolve, reject) => {
46
        getInfo(state.token).then(response => {
47
          const data = response.data
48
          if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
49
            commit('SET_ROLES', data.roles)
50
          } else {
51
            reject('getInfo: roles must be a non-null array !')
55
        getInfo().then(response => {
56
          if (response.success) {
57
            console.log(response)
52
          }
58
          }
53
          commit('SET_NAME', data.name)
54
          commit('SET_AVATAR', data.avatar)
59
          // if (!response.data) { // 由于mockjs 不支持自定义状态码只能这样hack
60
          //   reject('error')
61
          // }
62
          // const data = response.data
63
          // if (data.type) { // 验证返回的roles是否是一个非空数组
64
          //   commit('SET_ROLES', data.type)
65
          // }
66
          // commit('SET_NAME', data.name)
67
          // commit('SET_AVATAR', data.avatar)
55
          resolve(response)
68
          resolve(response)
56
        }).catch(error => {
69
        }).catch(error => {
57
          reject(error)
70
          reject(error)

+ 162 - 0
src/styles/loginform.scss

1
$bg:#2d3a4b;
2
$dark_gray:#889aa4;
3
$light_gray:#eee;
4
$light_black:#555;
5
6
.login-container {
7
  position: fixed;
8
  height: 100%;
9
  width: 100%;
10
  background-color: $bg;
11
  .logo-wrapper {
12
    display:block;
13
    position:absolute;
14
    top:30px;
15
    left:30px;
16
    height:30px;
17
    width:320px;
18
    background-image: url('/static/touchwave.png');
19
    background-size: 320px 30px;
20
  }
21
  .form-wrapper{
22
    width:100%;
23
    height:100%;
24
    display:flex;
25
    justify-content: center;
26
    align-items: center;
27
    .form-contain {
28
      width:420px;
29
      padding:30px 20px;
30
      .form-title {
31
        font-size: 22px;
32
        line-height: 36px;
33
        color:$light_gray;
34
        text-align:center;
35
        margin-bottom:40px;
36
      }
37
      .el-button--primary{
38
        width:100%;
39
      }
40
    }
41
  }
42
43
  .step-wrapper{
44
    margin-bottom:30px;
45
    .el-step__head.is-process{
46
      color: $light_black;
47
      border-color: $light_gray;
48
    }
49
    .el-step__title.is-process{
50
      color: $light_gray;
51
    }
52
    .el-step__description.is-process{
53
      color: $light_gray;
54
    }
55
    .el-step__icon{
56
      width:40px;
57
      height:40px;
58
      .el-step__icon-inner{
59
        font-size:16px;
60
      }
61
    }
62
  }
63
  .step-contain{
64
    .importTip{
65
      font-size: 18px;
66
      margin: 10px 0;
67
    }
68
    .mainTip{
69
      color:$light_gray;
70
    }
71
    .smallTip{
72
      color:$light_gray;
73
      line-height:16px;
74
      font-size:13px;
75
    }
76
  }
77
  .login-form {
78
    position: absolute;
79
    left: 0;
80
    right: 0;
81
    width: 520px;
82
    padding: 50px 35px 15px 35px;
83
    margin: 120px auto;
84
  }
85
  .el-input {
86
    display: inline-block;
87
    height: 47px;
88
    width: 85%;
89
    input {
90
      background: transparent;
91
      border: 0px;
92
      -webkit-appearance: none;
93
      border-radius: 0px;
94
      padding: 12px 5px 12px 15px;
95
      color: $light_gray;
96
      height: 47px;
97
      &:-webkit-autofill {
98
        -webkit-box-shadow: 0 0 0px 1000px $bg inset !important;
99
        -webkit-text-fill-color: #fff !important;
100
      }
101
    }
102
  }
103
  .el-form-item {
104
    border: 1px solid rgba(255, 255, 255, 0.1);
105
    background: rgba(0, 0, 0, 0.1);
106
    border-radius: 5px;
107
    color: #454545;
108
  }
109
  .el-form-find {
110
    border: none;
111
    background: none;
112
    margin-top: -20px;
113
  }
114
  .code-btn{
115
    width: 92%;
116
    .el-input-group__append{
117
      padding: 0;
118
      overflow: hidden;
119
      position: absolute;
120
      right: 0;
121
      top: 0;
122
      width: 140px;
123
      img{
124
        width: 140px;
125
        height:42px;
126
        cursor: pointer;
127
      }
128
      .el-button{
129
        width: 100%;
130
        margin:0;
131
        padding:15px 20px;
132
      }
133
    }
134
  }
135
  .svg-container {
136
    padding: 6px 5px 6px 15px;
137
    color: $dark_gray;
138
    vertical-align: middle;
139
    width: 30px;
140
    display: inline-block;
141
    &_login {
142
      font-size: 20px;
143
    }
144
  }
145
  .title {
146
    font-size: 26px;
147
    font-weight: 400;
148
    color: $light_gray;
149
    margin: 0px auto 40px auto;
150
    text-align: center;
151
    font-weight: bold;
152
  }
153
  .show-pwd {
154
    position: absolute;
155
    right: 10px;
156
    top: 7px;
157
    font-size: 16px;
158
    color: $dark_gray;
159
    cursor: pointer;
160
    user-select: none;
161
  }
162
}

+ 8 - 0
src/utils/index.js

1
/**
1
/**
2
 * Created by jiachenpan on 16/11/18.
2
 * Created by jiachenpan on 16/11/18.
3
 */
3
 */
4
export const comUrl = 'http://localhost:90'
4
5
5
export function parseTime(time, cFormat) {
6
export function parseTime(time, cFormat) {
6
  if (arguments.length === 0) {
7
  if (arguments.length === 0) {
57
  }
58
  }
58
}
59
}
59
60
61
export function param2Obj(url) {
62
  const search = url.split('?')[1]
63
  if (!search) {
64
    return {}
65
  }
66
  return JSON.parse('{"' + decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}')
67
}
60
export function debounce(func, wait, immediate) {
68
export function debounce(func, wait, immediate) {
61
  let timeout, args, context, timestamp, result
69
  let timeout, args, context, timestamp, result
62
70

+ 26 - 0
src/utils/permission.js

1
import store from '@/store'
2
3
/**
4
 * @param {Array} value
5
 * @returns {Boolean}
6
 * @example see @/views/permission/directive.vue
7
 */
8
export default function checkPermission(value) {
9
  if (value && value instanceof Array && value.length > 0) {
10
    const roles = store.getters && store.getters.roles
11
    const permissionRoles = value
12
13
    const hasPermission = roles.some(role => {
14
      return permissionRoles.includes(role)
15
    })
16
17
    if (!hasPermission) {
18
      return false
19
    }
20
    return true
21
  } else {
22
    console.error(`need roles! Like v-permission="['admin','editor']"`)
23
    return false
24
  }
25
}
26

+ 72 - 44
src/utils/request.js

1
import axios from 'axios'
1
import axios from 'axios'
2
import { Message, MessageBox } from 'element-ui'
3
import store from '../store'
4
import { getToken } from '@/utils/auth'
2
import qs from 'qs'
3
import { comUrl } from '@/utils/index'
4
// import { Message } from 'element-ui'
5
// import store from '@/store'
6
// import { getToken } from '@/utils/auth'
5
7
6
// 创建axios实例
8
// 创建axios实例
7
const service = axios.create({
9
const service = axios.create({
8
  baseURL: process.env.BASE_API, // api的base_url
9
  timeout: 5000 // 请求超时时间
10
  baseURL: comUrl // api的base_url
11
  // timeout: 5000 // 请求超时时间
10
})
12
})
11
13
12
// request拦截器
14
// request拦截器
13
service.interceptors.request.use(config => {
15
service.interceptors.request.use(config => {
14
  if (store.getters.token) {
15
    config.headers['X-Token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
16
  // 配置config
17
  config.headers.Accept = 'application/json'
18
  if (config.method === 'post') {
19
    // if (config.url !== http.sample.list && config.url !== http.manage.kit.save) {
20
    config.data = qs.stringify(config.data)
21
    // 处理后后台无需添加RequestBody
22
    config.headers['Content-Type'] = 'application/x-www-form-urlencoded charset=UTF-8'
23
    // }
16
  }
24
  }
25
  // if (store.getters.token) {
26
  //   config.headers['X-Token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
27
  // }
17
  return config
28
  return config
18
}, error => {
29
}, error => {
19
  // Do something with request error
30
  // Do something with request error
22
})
33
})
23
34
24
// respone拦截器
35
// respone拦截器
25
service.interceptors.response.use(
26
  response => {
27
  /**
28
  * code为非20000是抛错 可结合自己业务进行修改
29
  */
30
    const res = response.data
31
    if (res.code !== 20000) {
32
      Message({
33
        message: res.message,
34
        type: 'error',
35
        duration: 5 * 1000
36
      })
36
service.interceptors.response.use(response => {
37
  // response => {
38
  // /**
39
  // * code为非20000是抛错 可结合自己业务进行修改
40
  // */
41
  //   const res = response.data
42
  //   if (res.code !== 20000) {
43
  //     Message({
44
  //       message: res.message,
45
  //       type: 'error',
46
  //       duration: 5 * 1000
47
  //     })
37
48
38
      // 50008:非法的token; 50012:其他客户端登录了;  50014:Token 过期了;
39
      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
40
        MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
41
          confirmButtonText: '重新登录',
42
          cancelButtonText: '取消',
43
          type: 'warning'
44
        }).then(() => {
45
          store.dispatch('FedLogOut').then(() => {
46
            location.reload()// 为了重新实例化vue-router对象 避免bug
47
          })
48
        })
49
      }
50
      return Promise.reject('error')
49
  //     // 50008:非法的token 50012:其他客户端登录了  50014:Token 过期了
50
  //     if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
51
  //       MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
52
  //         confirmButtonText: '重新登录',
53
  //         cancelButtonText: '取消',
54
  //         type: 'warning'
55
  //       }).then(() => {
56
  //         store.dispatch('FedLogOut').then(() => {
57
  //           location.reload()// 为了重新实例化vue-router对象 避免bug
58
  //         })
59
  //       })
60
  //     }
61
  //     return Promise.reject('error')
62
  //   } else {
63
  //     return response.data
64
  //   }
65
  // },
66
  let data = response.data
67
  const status = response.status
68
  if (status === 200) {
69
    if (response.data === undefined) {
70
      // 解决IE9数据问题
71
      data = response.request.responseText
51
    } else {
72
    } else {
52
      return response.data
73
      data = response.data
53
    }
74
    }
54
  },
55
  error => {
56
    console.log('err' + error)// for debug
57
    Message({
58
      message: error.message,
59
      type: 'error',
60
      duration: 5 * 1000
61
    })
62
    return Promise.reject(error)
75
    if (!(data instanceof Object)) {
76
      // 判断data不是Object时,解析成Object
77
      // data = JSON.parse(data)
78
    }
79
    return data
80
  } else {
81
    // 业务异常
82
    console.log(response)
83
    return Promise.resolve(response)
63
  }
84
  }
64
)
85
}, error => {
86
  // 系统异常(后期统一处理)
87
  console.log(error)
88
  return Promise.reject(error)
89
})
65
90
66
export default service
91
export default {
92
  service,
93
  comUrl
94
}

src/views/bridgesConsole/dashboardC/components/BInfoDialog01.vue → src/views/bridgesConsole/bridgeDetail/components/BInfoDialog01.vue


src/views/bridgesConsole/dashboardC/components/BInfoDialog02.vue → src/views/bridgesConsole/bridgeDetail/components/BInfoDialog02.vue


src/views/bridgesConsole/dashboardC/components/BInfoDialog03.vue → src/views/bridgesConsole/bridgeDetail/components/BInfoDialog03.vue


src/views/bridgesConsole/dashboardC/components/BInfoDialog04.vue → src/views/bridgesConsole/bridgeDetail/components/BInfoDialog04.vue


src/views/bridgesConsole/dashboardC/components/LineChart.vue → src/views/bridgesConsole/bridgeDetail/components/LineChart.vue


src/views/bridgesConsole/dashboardC/components/updateLoginPwd.vue → src/views/bridgesConsole/bridgeDetail/components/updateLoginPwd.vue


src/views/bridgesConsole/dashboardC/components/updatePersonInfo.vue → src/views/bridgesConsole/bridgeDetail/components/updatePersonInfo.vue


src/views/bridgesConsole/dashboardC/index.vue → src/views/bridgesConsole/bridgeDetail/index.vue


+ 3 - 3
src/views/dashboard/admin/index.vue

1
<template>
1
<template>
2
  <div class="dashboard-editor-container">
2
  <div class="dashboard-editor-container">
3
4
    <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
3
  超级管理员,欢迎您
4
   <!--  <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
5
      <line-chart :chart-data="lineChartData"></line-chart>
5
      <line-chart :chart-data="lineChartData"></line-chart>
6
    </el-row>
6
    </el-row> -->
7
7
8
   <!--  <el-row :gutter="32">
8
   <!--  <el-row :gutter="32">
9
      <el-col :xs="24" :sm="24" :lg="8">
9
      <el-col :xs="24" :sm="24" :lg="8">

+ 3 - 3
src/views/dashboard/index.vue

23
    ])
23
    ])
24
  },
24
  },
25
  created() {
25
  created() {
26
    if (!this.roles.includes('admin')) {
27
      this.currentRole = 'otherDashboard'
28
    }
26
    // if (this.roles !== 1) {
27
    //   this.currentRole = 'otherDashboard'
28
    // }
29
  }
29
  }
30
}
30
}
31
</script>
31
</script>

+ 85 - 46
src/views/dashboard/other/index.vue

1
<template>
1
<template>
2
  <div class="dashboard-editor-container">
2
  <div class="dashboard-editor-container">
3
    <div class=" clearfix">
4
      <pan-thumb style="float: left" :image="avatar"> Your roles:
5
        <span class="pan-info-roles" :key='item' v-for="item in roles">{{item}}</span>
6
      </pan-thumb>
7
      <div class="info-container">
8
        <span class="display_name">{{name}}</span>
9
        <span style="font-size:20px;padding-top:20px;display:inline-block;">Editor's Dashboard</span>
10
      </div>
11
    </div>
12
    <div>
13
      <img class="emptyGif" :src="emptyGif">
3
    <el-row class="panel-group" :gutter="40">
4
      <el-col :xs="24" :sm="12" :lg="6" class="card-panel-col" v-for="item in [0,1,2,3,4]" :key="item.id" @click.native="goToDashboardC">
5
        <div class='card-panel'>
6
          <div class="card-panel-icon-wrapper">
7
            <div class="card-image" style="background-image: url(/static/touchwave.png);"></div>
8
          </div>
9
          <div class="card-panel-description">
10
            <div class="card-panel-text">桥梁名称 <span>山东青岛跨海大桥A段</span></div>
11
            <div class="card-panel-text">未读报警 10条</div>
12
          </div>
13
        </div>
14
      </el-col>
15
    </el-row>
16
    <div class="pagination-container">
17
      <el-pagination
18
        background
19
        @size-change="handleSizeChange"
20
        @current-change="handleCurrentChange"
21
        :current-page.sync="currentPage"
22
        :page-size="4"
23
        layout="prev, pager, next, jumper"
24
        :total="10">
25
      </el-pagination>
14
    </div>
26
    </div>
15
  </div>
27
  </div>
16
</template>
28
</template>
17
29
18
<script>
30
<script>
19
import { mapGetters } from 'vuex'
20
import PanThumb from '@/components/PanThumb'
21
31
22
export default {
32
export default {
23
  name: 'dashboard-editor',
24
  components: { PanThumb },
25
  data() {
33
  data() {
26
    return {
34
    return {
27
      emptyGif: 'https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3'
35
      currentPage: 1
28
    }
36
    }
29
  },
37
  },
30
  computed: {
31
    ...mapGetters([
32
      'name',
33
      'avatar',
34
      'roles'
35
    ])
38
  components: {
39
40
  },
41
  methods: {
42
    goToDashboardC() {
43
      this.$router.push({ path: '/bridgesConsole' })
44
    },
45
    handleSizeChange(val) {
46
      console.log(`每页 ${val} 条`)
47
    },
48
    handleCurrentChange(val) {
49
      console.log(`当前页: ${val}`)
50
    }
36
  }
51
  }
37
}
52
}
38
</script>
53
</script>
39
54
40
<style rel="stylesheet/scss" lang="scss" scoped>
55
<style rel="stylesheet/scss" lang="scss" scoped>
41
  .emptyGif {
42
    display: block;
43
    width: 45%;
44
    margin: 0 auto;
45
  }
46
47
  .dashboard-editor-container {
48
    background-color: #e3e3e3;
49
    min-height: 100vh;
50
    padding: 50px 60px 0px;
51
    .pan-info-roles {
52
      font-size: 12px;
53
      font-weight: 700;
54
      color: #333;
55
      display: block;
56
.dashboard-editor-container{
57
  padding: 32px;
58
  .panel-group {
59
    margin-top: 18px;
60
    .card-panel-col{
61
      margin-bottom: 32px;
56
    }
62
    }
57
    .info-container {
63
    .card-panel {
64
      cursor: pointer;
65
      padding: 15px;
66
      font-size: 12px;
58
      position: relative;
67
      position: relative;
59
      margin-left: 190px;
60
      height: 150px;
61
      line-height: 200px;
62
      .display_name {
68
      overflow: hidden;
69
      color: #666;
70
      background: #fff;
71
      box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
72
      border-color: rgba(0, 0, 0, .05);
73
      &:hover {
74
        .card-panel-icon-wrapper {
75
          color: #fff;
76
        }
77
      }
78
      .card-panel-icon-wrapper {
79
        margin: 10px 0;
80
        transition: all 0.38s ease-out;
81
        border-radius: 6px;
82
      }
83
      .card-image{
84
        width: 100%;
85
        max-width: 280px;
86
        margin: auto;
87
        height: 160px;
88
        border: 1px solid #d0d0d0;
89
        background-position: center;
90
        background-size: cover;
91
      }
92
      .card-panel-icon {
63
        font-size: 48px;
93
        font-size: 48px;
64
        line-height: 48px;
65
        color: #212121;
66
        position: absolute;
67
        top: 25px;
94
      }
95
      .card-panel-description {
96
        font-weight: bold;
97
        margin-top:12px;
98
        .card-panel-text {
99
          line-height: 24px;
100
          color: rgba(0, 0, 0, 0.45);
101
          font-size: 16px;
102
        }
103
        .card-panel-num {
104
          font-size: 20px;
105
        }
68
      }
106
      }
69
    }
107
    }
70
  }
108
  }
109
}
71
</style>
110
</style>

+ 244 - 164
src/views/findPwd/index.vue

1
<template>
1
<template>
2
  <div class="login-container">
2
  <div class="login-container">
3
    <el-form class="login-form" autoComplete="on" :model="loginForm" :rules="loginRules" ref="loginForm" label-position="left">
4
      <h3 class="title">vue-element-admin</h3>
5
      <el-form-item prop="username">
6
        <span class="svg-container svg-container_login">
7
          <svg-icon icon-class="user" />
8
        </span>
9
        <el-input name="username" type="text" v-model="loginForm.username" autoComplete="on" placeholder="username" />
10
      </el-form-item>
11
      <el-form-item prop="password">
12
        <span class="svg-container">
13
          <svg-icon icon-class="password"></svg-icon>
14
        </span>
15
        <el-input name="password" :type="pwdType" @keyup.enter.native="handleLogin" v-model="loginForm.password" autoComplete="on"
16
          placeholder="password"></el-input>
17
          <span class="show-pwd" @click="showPwd"><svg-icon icon-class="eye" /></span>
18
      </el-form-item>
19
      <el-form-item>
20
        <el-button type="primary" style="width:100%;" :loading="loading" @click.native.prevent="handleLogin">
21
          Sign in
22
        </el-button>
23
      </el-form-item>
24
      <div class="tips">
25
        <span style="margin-right:20px;">username: admin</span>
26
        <span> password: admin</span>
3
    <div class="logo-wrapper"></div>
4
    <div class="form-wrapper">
5
      <div class="form-contain">
6
        <p class="form-title">找回密码</p>
7
        <div class="step-wrapper">
8
          <el-steps :active="stepVal" finish-status="success" align-center>
9
            <el-step title="输入手机号"></el-step>
10
            <el-step title="重置密码"></el-step>
11
          </el-steps>
12
        </div>
13
14
        <div class="step-contain">
15
          <el-form v-show="stepFisrt" :model="ruleForm" :rules="rules" ref="ruleForm" class="demo-ruleForm">
16
            <el-form-item prop="phoneNum">
17
              <el-input v-model="ruleForm.phoneNum" placeholder="请输入您的手机号码"></el-input>
18
            </el-form-item>
19
            <el-form-item prop="msgVC">
20
              <el-input v-model="ruleForm.msgVC" placeholder="请输入短信验证码" class="code-btn" style="width:100%">
21
                <el-button slot="append" :disabled="phoneCodeBol" @click="clickMsgVcLogin">
22
                  <span v-if="sendMsgDisabled">{{seconds + '秒后获取'}}</span>
23
                  <span v-if="!sendMsgDisabled">获取验证码</span>
24
                </el-button>
25
             </el-input>
26
            </el-form-item>
27
            <el-form-item>
28
              <el-button type="primary" :disabled="isDisabl" @click="nextStep('ruleForm')">下一步</el-button>
29
            </el-form-item>
30
            <el-form-item class="el-form-find">
31
              <el-button type="text" @click="goLogin">又想起来了</el-button>
32
            </el-form-item>
33
          </el-form>
34
          <el-form v-show="stepThird" :model="ruleForm2" :rules="rules2" ref="ruleForm2" class="demo-ruleForm">
35
            <el-form-item prop="pass">
36
              <el-input type="password" v-model="ruleForm2.pass" placeholder="请设置您的新密码" auto-complete="off"></el-input>
37
            </el-form-item>
38
            <el-form-item prop="checkPass">
39
              <el-input type="password" v-model="ruleForm2.checkPass" placeholder="请再次输入密码确认" auto-complete="off"></el-input>
40
            </el-form-item>
41
            <el-form-item>
42
              <el-button type="primary" :disabled="isDisabl" @click="resetPwd('ruleForm2')">重置密码</el-button>
43
            </el-form-item>
44
          </el-form>
45
        </div>
27
      </div>
46
      </div>
28
    </el-form>
47
    </div>
29
  </div>
48
  </div>
30
</template>
49
</template>
31
50
32
<script>
51
<script>
33
import { isvalidUsername } from '@/utils/validate'
52
  import { isReg, getMsgPhone } from '@/api/login'
53
  import '@/styles/loginform.scss'
34
54
35
export default {
36
  name: 'login',
37
  data() {
38
    const validateUsername = (rule, value, callback) => {
39
      if (!isvalidUsername(value)) {
40
        callback(new Error('请输入正确的用户名'))
41
      } else {
42
        callback()
55
  export default {
56
    data() {
57
      var validPhone = (rule, value, callback) => {
58
        const reg = /^1[3|4|5|7|8][0-9]\d{8}$/
59
        if (!value) {
60
          callback(new Error('请输入你的手机号码'))
61
        } else if (!reg.test(value)) {
62
          callback(new Error('请输入正确的手机号码'))
63
        } else {
64
          callback()
65
        }
43
      }
66
      }
44
    }
45
    const validatePass = (rule, value, callback) => {
46
      if (value.length < 5) {
47
        callback(new Error('密码不能小于5位'))
48
      } else {
49
        callback()
67
      var validatePass = (rule, value, callback) => {
68
        if (value === '') {
69
          callback(new Error('请设置您的新密码'))
70
        } else if (value.length < 6 || value.length > 24) {
71
          callback(new Error('密码由6-24个字符组成,区分大小写'))
72
        } else {
73
          if (this.ruleForm2.checkPass !== '') {
74
            this.$refs.ruleForm2.validateField('checkPass')
75
          }
76
          callback()
77
        }
50
      }
78
      }
51
    }
52
    return {
53
      loginForm: {
54
        username: 'admin',
55
        password: 'admin'
56
      },
57
      loginRules: {
58
        username: [{ required: true, trigger: 'blur', validator: validateUsername }],
59
        password: [{ required: true, trigger: 'blur', validator: validatePass }]
60
      },
61
      loading: false,
62
      pwdType: 'password'
63
    }
64
  },
65
  methods: {
66
    showPwd() {
67
      if (this.pwdType === 'password') {
68
        this.pwdType = ''
69
      } else {
70
        this.pwdType = 'password'
79
      var validatePass2 = (rule, value, callback) => {
80
        if (value === '') {
81
          callback(new Error('请再次输入密码确认'))
82
        } else if (value !== this.ruleForm2.pass) {
83
          callback(new Error('两次输入密码不一致,请重新输入!'))
84
        } else {
85
          callback()
86
        }
87
      }
88
      return {
89
        phoneCodeBol: false,
90
        sendMsgDisabled: false,
91
        seconds: 60,
92
        platId: '',
93
        resetStepNum: '',
94
        resetCode: '',
95
        stepVal: 0,
96
        stepFisrt: true,
97
        stepThird: false,
98
        isDisabl: false,
99
        ruleForm: {
100
          phoneNum: '',
101
          msgVC: ''
102
        },
103
        rules: {
104
          phoneNum: [
105
            { required: true, validator: validPhone, trigger: 'blur' }
106
          ],
107
          msgVC: [
108
            { required: true, message: '请输入短信验证码', trigger: 'blur' }
109
          ]
110
        },
111
        ruleForm2: {
112
          pass: '',
113
          checkPass: ''
114
        },
115
        rules2: {
116
          pass: [
117
            { validator: validatePass, trigger: 'blur' }
118
          ],
119
          checkPass: [
120
            { validator: validatePass2, trigger: 'blur' }
121
          ]
122
        }
123
      }
124
    },
125
    created() {
126
      // this.platId = Cookies.get('platId')
127
      // this.resetStepNum = util.urlParse('step')
128
      // this.resetCode = util.urlParse('sc')
129
      if (this.resetStepNum === '2') {
130
        this.stepFisrt = false
131
        this.stepThird = true
132
        this.stepVal = 2
71
      }
133
      }
72
    },
134
    },
73
    handleLogin() {
74
      this.$refs.loginForm.validate(valid => {
75
        if (valid) {
76
          this.loading = true
77
          this.$store.dispatch('Login', this.loginForm).then(() => {
78
            this.loading = false
79
            this.$router.push({ path: '/' })
80
          }).catch(() => {
81
            this.loading = false
135
    methods: {
136
      nextStep(formName) {
137
        this.$refs[formName].validate((valid) => {
138
          if (valid) {
139
            // this.$axios.post(httpUrl.hQuery.sign.reqResetPw, {
140
            //   id: this.platId,
141
            //   mail: this.ruleForm.mail,
142
            //   url: httpUrl.platUrl + '/#/findPwd?step=2&sc'
143
            // }).then(res => {
144
            //   console.log(res)
145
            //   if (res.success) {
146
            //     this.stepFisrt = false
147
            //     this.stepVal = 1
148
            //   } else {
149
            //     let errorCode = [{
150
            //       code: -600001,
151
            //       msg: '用户不存在'
152
            //     }, {
153
            //       code: -600002,
154
            //       msg: '发送邮箱错误'
155
            //     }]
156
            //     for (let i = 0 i < errorCode.length i++) {
157
            //       if (res.code === errorCode[i].code) {
158
            //         this.$message.error(errorCode[i].msg)
159
            //         return
160
            //       }
161
            //     }
162
            //   }
163
            // })
164
          } else {
165
            return false
166
          }
167
        })
168
      },
169
      userRegisterOk() {
170
        isReg(this.ruleForm.phoneNum).then(res => {
171
          if (res.success) {
172
            if (res.data === true) {
173
              this.$message({
174
                message: '该账号不存在,请检查后重试',
175
                type: 'warning'
176
              })
177
            }
178
          }
179
        })
180
      },
181
      getPhoneLogin() {
182
        getMsgPhone(this.ruleForm.phoneNum, true).then((res) => {
183
          if (res.success) {
184
            this.phoneResBackLogin = res.data
185
          }
186
        })
187
      },
188
      clickMsgVcLogin() {
189
        const reg = /^1[3|4|5|7|8][0-9]\d{8}$/
190
        if (!this.ruleForm.phoneNum) {
191
          this.$message({
192
            message: '请输入你的手机号码',
193
            type: 'warning'
194
          })
195
        } else if (!reg.test(this.ruleForm.phoneNum)) {
196
          this.$message({
197
            message: '请输入正确的手机号码',
198
            type: 'warning'
82
          })
199
          })
83
        } else {
200
        } else {
84
          console.log('error submit!!')
85
          return false
201
          this.userRegisterOk()
202
          const me = this
203
          me.sendMsgDisabled = true
204
          me.phoneCodeBol = true
205
          const interval = window.setInterval(function() {
206
            if ((me.seconds--) <= 0) {
207
              me.seconds = 60
208
              me.sendMsgDisabled = false
209
              me.phoneCodeBol = false
210
              window.clearInterval(interval)
211
            }
212
          }, 1000)
86
        }
213
        }
87
      })
88
    }
89
  }
90
}
91
</script>
92
93
<style rel="stylesheet/scss" lang="scss">
94
$bg:#2d3a4b;
95
$light_gray:#eee;
96
97
/* reset element-ui css */
98
.login-container {
99
  .el-input {
100
    display: inline-block;
101
    height: 47px;
102
    width: 85%;
103
    input {
104
      background: transparent;
105
      border: 0px;
106
      -webkit-appearance: none;
107
      border-radius: 0px;
108
      padding: 12px 5px 12px 15px;
109
      color: $light_gray;
110
      height: 47px;
111
      &:-webkit-autofill {
112
        -webkit-box-shadow: 0 0 0px 1000px $bg inset !important;
113
        -webkit-text-fill-color: #fff !important;
114
      }
115
    }
116
  }
117
  .el-form-item {
118
    border: 1px solid rgba(255, 255, 255, 0.1);
119
    background: rgba(0, 0, 0, 0.1);
120
    border-radius: 5px;
121
    color: #454545;
122
  }
123
}
124
125
</style>
126
127
<style rel="stylesheet/scss" lang="scss" scoped>
128
$bg:#2d3a4b;
129
$dark_gray:#889aa4;
130
$light_gray:#eee;
131
.login-container {
132
  position: fixed;
133
  height: 100%;
134
  width: 100%;
135
  background-color: $bg;
136
  .login-form {
137
    position: absolute;
138
    left: 0;
139
    right: 0;
140
    width: 520px;
141
    padding: 35px 35px 15px 35px;
142
    margin: 120px auto;
143
  }
144
  .tips {
145
    font-size: 14px;
146
    color: #fff;
147
    margin-bottom: 10px;
148
    span {
149
      &:first-of-type {
150
        margin-right: 16px;
214
      },
215
      resetPwd(formName) {
216
        this.$refs[formName].validate((valid) => {
217
          if (valid) {
218
            // this.$axios.post(httpUrl.hQuery.sign.resetpw, {
219
            //   code: this.resetCode,
220
            //   pw: this.ruleForm2.pass
221
            // }).then(res => {
222
            //   console.log(res)
223
            //   if (res.success) {
224
            //     this.$alert('您可以使用新密码登录您的账户了', '恭喜您,您的密码重置成功!', {
225
            //       confirmButtonText: '重新登录',
226
            //       type: 'success',
227
            //       center: true,
228
            //       callback: action => {
229
            //         if (action === 'confirm') {
230
            //           this.$router.push({path: '/loginPlat'})
231
            //         }
232
            //       }
233
            //     })
234
            //   } else {
235
            //     if (res.code === -600001) {
236
            //       this.$alert('小提示:邮件内的链接有效时长为10分钟', '很抱歉,当前的链接已失效。', {
237
            //         confirmButtonText: '重新找回密码',
238
            //         type: 'warning',
239
            //         center: true,
240
            //         callback: action => {
241
            //           if (action === 'confirm') {
242
            //             this.stepFisrt = true
243
            //             this.stepThird = false
244
            //             this.stepVal = 0
245
            //           }
246
            //         }
247
            //       })
248
            //       return
249
            //     }
250
            //   }
251
            // })
252
          } else {
253
            return false
254
          }
255
        })
256
      },
257
      goLogin() {
258
        this.$router.push({ path: '/login' })
151
      }
259
      }
152
    }
260
    }
153
  }
261
  }
154
  .svg-container {
155
    padding: 6px 5px 6px 15px;
156
    color: $dark_gray;
157
    vertical-align: middle;
158
    width: 30px;
159
    display: inline-block;
160
    &_login {
161
      font-size: 20px;
162
    }
163
  }
164
  .title {
165
    font-size: 26px;
166
    font-weight: 400;
167
    color: $light_gray;
168
    margin: 0px auto 40px auto;
169
    text-align: center;
170
    font-weight: bold;
171
  }
172
  .show-pwd {
173
    position: absolute;
174
    right: 10px;
175
    top: 7px;
176
    font-size: 16px;
177
    color: $dark_gray;
178
    cursor: pointer;
179
    user-select: none;
180
  }
181
}
182
</style>
262
</script>

+ 2 - 1
src/views/layout/components/Sidebar/index.vue

9
      text-color="#bfcbd9"
9
      text-color="#bfcbd9"
10
      active-text-color="#409EFF"
10
      active-text-color="#409EFF"
11
    >
11
    >
12
      <sidebar-item v-for="route in routes" :key="route.name" :item="route" :base-path="route.path"></sidebar-item>
12
      <sidebar-item v-for="route in permission_routers" :key="route.name" :item="route" :base-path="route.path"></sidebar-item>
13
    </el-menu>
13
    </el-menu>
14
  </el-scrollbar>
14
  </el-scrollbar>
15
</template>
15
</template>
22
  components: { SidebarItem },
22
  components: { SidebarItem },
23
  computed: {
23
  computed: {
24
    ...mapGetters([
24
    ...mapGetters([
25
      'permission_routers',
25
      'sidebar'
26
      'sidebar'
26
    ]),
27
    ]),
27
    routes() {
28
    routes() {

+ 10 - 0
src/views/login/authredirect.vue

1
<script>
2
  export default {
3
    name: 'authredirect',
4
    created() {
5
      const hash = window.location.search.slice(1)
6
      window.opener.location.href = window.location.origin + '/login#' + hash
7
      window.close()
8
    }
9
  }
10
</script>

+ 44 - 117
src/views/login/index.vue

1
<template>
1
<template>
2
  <div class="login-container">
2
  <div class="login-container">
3
    <div class="logo-wrapper"></div>
3
    <el-form class="login-form" autoComplete="on" :model="loginForm" :rules="loginRules" ref="loginForm" label-position="left">
4
    <el-form class="login-form" autoComplete="on" :model="loginForm" :rules="loginRules" ref="loginForm" label-position="left">
4
      <h3 class="title">vue-element-admin</h3>
5
      <h3 class="title">登录</h3>
5
      <el-form-item prop="username">
6
      <el-form-item prop="username">
6
        <span class="svg-container svg-container_login">
7
        <span class="svg-container svg-container_login">
7
          <svg-icon icon-class="user" />
8
          <svg-icon icon-class="user" />
8
        </span>
9
        </span>
9
        <el-input name="username" type="text" v-model="loginForm.username" autoComplete="on" placeholder="username" />
10
        <el-input name="username" type="text" v-model="loginForm.username" autoComplete="on" placeholder="请输入手机号" />
10
      </el-form-item>
11
      </el-form-item>
11
      <el-form-item prop="password">
12
      <el-form-item prop="password">
12
        <span class="svg-container">
13
        <span class="svg-container">
13
          <svg-icon icon-class="password"></svg-icon>
14
          <svg-icon icon-class="password"></svg-icon>
14
        </span>
15
        </span>
15
        <el-input name="password" :type="pwdType" @keyup.enter.native="handleLogin" v-model="loginForm.password" autoComplete="on"
16
        <el-input name="password" :type="pwdType" @keyup.enter.native="handleLogin" v-model="loginForm.password" autoComplete="on"
16
          placeholder="password"></el-input>
17
          placeholder="请输入登录密码"></el-input>
17
          <span class="show-pwd" @click="showPwd"><svg-icon icon-class="eye" /></span>
18
          <span class="show-pwd" @click="showPwd"><svg-icon icon-class="eye" /></span>
18
      </el-form-item>
19
      </el-form-item>
20
      <el-form-item prop="imgVerifyCode">
21
        <span class="svg-container">
22
          <svg-icon icon-class="password"></svg-icon>
23
        </span>
24
        <el-input v-model="loginForm.imgVerifyCode" placeholder="请输入图形验证码" class="code-btn">
25
        <img slot="append" :src="imgVcUrl" @click="changeImgVc" /></el-input>
26
      </el-form-item>
19
      <el-form-item>
27
      <el-form-item>
20
        <el-button type="primary" style="width:100%;" :loading="loading" @click.native.prevent="handleLogin">
21
          Sign in
22
        </el-button>
28
        <el-button type="primary" style="width:100%;" :loading="loading" @click.native.prevent="handleLogin">登录</el-button>
29
      </el-form-item>
30
      <el-form-item class="el-form-find">
31
        <el-button type="text" @click.native.prevent="goBackPwd">忘记密码?</el-button>
23
      </el-form-item>
32
      </el-form-item>
24
      <div class="tips">
25
        <span style="margin-right:20px;">username: admin</span>
26
        <span> password: admin</span>
27
      </div>
28
    </el-form>
33
    </el-form>
29
  </div>
34
  </div>
30
</template>
35
</template>
31
36
32
<script>
37
<script>
33
import { isvalidUsername } from '@/utils/validate'
38
// import { isvalidUsername } from '@/utils/validate'
39
import { getPictureVC } from '@/api/pictureVc'
40
import '@/styles/loginform.scss'
34
41
35
export default {
42
export default {
36
  name: 'login',
43
  name: 'login',
37
  data() {
44
  data() {
38
    const validateUsername = (rule, value, callback) => {
39
      if (!isvalidUsername(value)) {
40
        callback(new Error('请输入正确的用户名'))
41
      } else {
42
        callback()
43
      }
44
    }
45
    const validatePass = (rule, value, callback) => {
46
      if (value.length < 5) {
47
        callback(new Error('密码不能小于5位'))
45
    var validPhone = (rule, value, callback) => {
46
      const reg = /^1[3|4|5|7|8][0-9]\d{8}$/
47
      if (!value) {
48
        callback(new Error('请输入你的手机号码'))
49
      } else if (!reg.test(value)) {
50
        callback(new Error('请输入正确的手机号码'))
48
      } else {
51
      } else {
49
        callback()
52
        callback()
50
      }
53
      }
51
    }
54
    }
52
    return {
55
    return {
56
      imgVerifyCode: '',
57
      imgVcUrl: '',
53
      loginForm: {
58
      loginForm: {
54
        username: 'admin',
55
        password: 'admin'
59
        username: '',
60
        password: ''
56
      },
61
      },
57
      loginRules: {
62
      loginRules: {
58
        username: [{ required: true, trigger: 'blur', validator: validateUsername }],
59
        password: [{ required: true, trigger: 'blur', validator: validatePass }]
63
        username: [{ required: true, trigger: 'blur', validator: validPhone }],
64
        password: [
65
          { required: true, message: '请输入登录密码', trigger: 'blur' },
66
          { min: 6, max: 24, message: '密码由6-24个字符组成,区分大小写', trigger: 'blur' }
67
        ],
68
        imgVerifyCode: [{ required: true, message: '请输入图形验证码', trigger: 'blur' }]
60
      },
69
      },
61
      loading: false,
70
      loading: false,
62
      pwdType: 'password'
71
      pwdType: 'password'
63
    }
72
    }
64
  },
73
  },
74
  created() {
75
    this.changeImgVc()
76
  },
65
  methods: {
77
  methods: {
66
    showPwd() {
78
    showPwd() {
67
      if (this.pwdType === 'password') {
79
      if (this.pwdType === 'password') {
74
      this.$refs.loginForm.validate(valid => {
86
      this.$refs.loginForm.validate(valid => {
75
        if (valid) {
87
        if (valid) {
76
          this.loading = true
88
          this.loading = true
77
          this.$store.dispatch('Login', this.loginForm).then(() => {
89
          this.$store.dispatch('LoginByUsername', this.loginForm).then(() => {
78
            this.loading = false
90
            this.loading = false
79
            this.$router.push({ path: '/' })
91
            this.$router.push({ path: '/' })
80
          }).catch(() => {
92
          }).catch(() => {
85
          return false
97
          return false
86
        }
98
        }
87
      })
99
      })
100
    },
101
    goBackPwd() {
102
      this.$router.push({ path: '/findPwd' })
103
    },
104
    changeImgVc() {
105
      this.imgVcUrl = getPictureVC('PIC_LOGIN')
88
    }
106
    }
89
  }
107
  }
90
}
108
}
91
</script>
109
</script>
92
93
<style rel="stylesheet/scss" lang="scss">
94
$bg:#2d3a4b;
95
$light_gray:#eee;
96
97
/* reset element-ui css */
98
.login-container {
99
  .el-input {
100
    display: inline-block;
101
    height: 47px;
102
    width: 85%;
103
    input {
104
      background: transparent;
105
      border: 0px;
106
      -webkit-appearance: none;
107
      border-radius: 0px;
108
      padding: 12px 5px 12px 15px;
109
      color: $light_gray;
110
      height: 47px;
111
      &:-webkit-autofill {
112
        -webkit-box-shadow: 0 0 0px 1000px $bg inset !important;
113
        -webkit-text-fill-color: #fff !important;
114
      }
115
    }
116
  }
117
  .el-form-item {
118
    border: 1px solid rgba(255, 255, 255, 0.1);
119
    background: rgba(0, 0, 0, 0.1);
120
    border-radius: 5px;
121
    color: #454545;
122
  }
123
}
124
125
</style>
126
127
<style rel="stylesheet/scss" lang="scss" scoped>
128
$bg:#2d3a4b;
129
$dark_gray:#889aa4;
130
$light_gray:#eee;
131
.login-container {
132
  position: fixed;
133
  height: 100%;
134
  width: 100%;
135
  background-color: $bg;
136
  .login-form {
137
    position: absolute;
138
    left: 0;
139
    right: 0;
140
    width: 520px;
141
    padding: 35px 35px 15px 35px;
142
    margin: 120px auto;
143
  }
144
  .tips {
145
    font-size: 14px;
146
    color: #fff;
147
    margin-bottom: 10px;
148
    span {
149
      &:first-of-type {
150
        margin-right: 16px;
151
      }
152
    }
153
  }
154
  .svg-container {
155
    padding: 6px 5px 6px 15px;
156
    color: $dark_gray;
157
    vertical-align: middle;
158
    width: 30px;
159
    display: inline-block;
160
    &_login {
161
      font-size: 20px;
162
    }
163
  }
164
  .title {
165
    font-size: 26px;
166
    font-weight: 400;
167
    color: $light_gray;
168
    margin: 0px auto 40px auto;
169
    text-align: center;
170
    font-weight: bold;
171
  }
172
  .show-pwd {
173
    position: absolute;
174
    right: 10px;
175
    top: 7px;
176
    font-size: 16px;
177
    color: $dark_gray;
178
    cursor: pointer;
179
    user-select: none;
180
  }
181
}
182
</style>