jtoms 4 years ago
parent
commit
3957aaaaae

+ 1 - 1
src/layout/components/Navbar.vue

@@ -11,7 +11,7 @@
     <div class="right-menu">
       <el-dropdown class="right-container" trigger="click">
         <a>
-          {{ oauthInfo.nickName }}
+          {{ oauthInfo && oauthInfo.nickName }}
           <i class="el-icon-caret-bottom"/>
         </a>
 

+ 2 - 2
src/layout/components/Sidebar/Logo.vue

@@ -24,8 +24,8 @@ export default {
   },
   data() {
     return {
-      title: 'Vue Admin Template',
-      logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png'
+      title: '开放平台',
+      logo: undefined
     }
   }
 }

+ 7 - 6
src/layout/components/Sidebar/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div :class="{'has-logo':showLogo}">
-    <logo v-if="showLogo" :collapse="isCollapse" />
+    <logo v-if="showLogo" :collapse="isCollapse"/>
     <el-scrollbar wrap-class="scrollbar-wrapper">
       <el-menu
         :default-active="activeMenu"
@@ -12,7 +12,7 @@
         :collapse-transition="false"
         mode="vertical"
       >
-        <sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" />
+        <sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path"/>
       </el-menu>
     </el-scrollbar>
   </div>
@@ -28,11 +28,12 @@ export default {
   components: { SidebarItem, Logo },
   computed: {
     ...mapGetters([
-      'sidebar'
+      'sidebar',
+      'routes'
     ]),
-    routes() {
-      return this.$router.options.routes
-    },
+    // routes() {
+    //   return this.$router.options.routes
+    // },
     activeMenu() {
       const route = this.$route
       const { meta, path } = route

+ 2 - 12
src/main.js

@@ -15,18 +15,8 @@ import router from './router'
 import '@/icons' // icon
 import '@/permission' // permission control
 
-/**
- * If you don't want to use mock-server
- * you want to use MockJs for mock api
- * you can execute: mockXHR()
- *
- * Currently MockJs will be used in the production environment,
- * please remove it before going online ! ! !
- */
-// if (process.env.NODE_ENV === 'production') {
-//   const { mockXHR } = require('../mock')
-//   mockXHR()
-// }
+import PermissionDirective from '@/permission/directive/index.js' // 权限判断指令
+Vue.use(PermissionDirective)
 
 // set ElementUI lang to EN
 Vue.use(ElementUI, { locale })

+ 8 - 4
src/permission.js

@@ -26,13 +26,17 @@ router.beforeEach(async(to, from, next) => {
       next({ path: '/' })
       NProgress.done()
     } else {
-      const hasOauthInfo = store.getters.oauthInfo
-      if (hasOauthInfo) {
+      const oauthInfo = store.getters.oauthInfo
+      if (oauthInfo && oauthInfo.authorities && oauthInfo.authorities.length > 0) {
         next()
       } else {
         try {
-          await store.dispatch('user/getInfo')
-          next()
+          const { authorities } = await store.dispatch('user/getInfo')
+          const accessRoutes = await store.dispatch('permission/generateRoutes', authorities)
+
+          router.addRoutes(accessRoutes)
+          console.log('toto,to,to', to)
+          next({ ...to, replace: true })
         } catch (error) {
           // remove token and go to login page to re-login
           await store.dispatch('user/resetToken')

+ 14 - 0
src/permission/directive/index.js

@@ -0,0 +1,14 @@
+import permission from './permission'
+import Vue from 'vue'
+
+const install = function(Vue) {
+  Vue.directive('permission', permission)
+}
+
+if (window.Vue) {
+  window['permission'] = permission
+  Vue.use(install) // eslint-disable-line
+}
+
+permission.install = install
+export default permission

+ 32 - 0
src/permission/directive/permission.js

@@ -0,0 +1,32 @@
+import store from '@/store'
+
+function checkPermission(el, binding) {
+  const { value } = binding
+  const oauthInfo = store.getters && store.getters.oauthInfo
+  const authorities = oauthInfo.authorities || []
+
+  if (value && value instanceof Array) {
+    if (value.length > 0) {
+      const permissionRoles = value
+
+      const hasPermission = authorities.some(role => {
+        return permissionRoles.includes(role)
+      })
+
+      if (!hasPermission) {
+        el.parentNode && el.parentNode.removeChild(el)
+      }
+    }
+  } else {
+    throw new Error(`need roles! Like v-permission="['admin','editor']"`)
+  }
+}
+
+export default {
+  inserted(el, binding) {
+    checkPermission(el, binding)
+  },
+  update(el, binding) {
+    checkPermission(el, binding)
+  }
+}

+ 4 - 84
src/router/index.js

@@ -53,7 +53,10 @@ export const constantRoutes = [
         meta: { title: '首页', icon: 'dashboard', affix: true }
       }
     ]
-  },
+  }
+]
+
+export const asyncRoutes = [
   {
     path: '/interface',
     component: Layout,
@@ -121,89 +124,6 @@ export const constantRoutes = [
       }
     ]
   },
-
-  // {
-  //   path: '/form',
-  //   component: Layout,
-  //   children: [
-  //     {
-  //       path: 'index',
-  //       name: 'Form',
-  //       component: () => import('@/views/form/index'),
-  //       meta: { title: 'Form', icon: 'form' }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: '/nested',
-  //   component: Layout,
-  //   redirect: '/nested/menu1',
-  //   name: 'Nested',
-  //   meta: {
-  //     title: 'Nested',
-  //     icon: 'nested'
-  //   },
-  //   children: [
-  //     {
-  //       path: 'menu1',
-  //       component: () => import('@/views/nested/menu1/index'), // Parent router-view
-  //       name: 'Menu1',
-  //       meta: { title: 'Menu1' },
-  //       children: [
-  //         {
-  //           path: 'menu1-1',
-  //           component: () => import('@/views/nested/menu1/menu1-1'),
-  //           name: 'Menu1-1',
-  //           meta: { title: 'Menu1-1' }
-  //         },
-  //         {
-  //           path: 'menu1-2',
-  //           component: () => import('@/views/nested/menu1/menu1-2'),
-  //           name: 'Menu1-2',
-  //           meta: { title: 'Menu1-2' },
-  //           children: [
-  //             {
-  //               path: 'menu1-2-1',
-  //               component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
-  //               name: 'Menu1-2-1',
-  //               meta: { title: 'Menu1-2-1' }
-  //             },
-  //             {
-  //               path: 'menu1-2-2',
-  //               component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
-  //               name: 'Menu1-2-2',
-  //               meta: { title: 'Menu1-2-2' }
-  //             }
-  //           ]
-  //         },
-  //         {
-  //           path: 'menu1-3',
-  //           component: () => import('@/views/nested/menu1/menu1-3'),
-  //           name: 'Menu1-3',
-  //           meta: { title: 'Menu1-3' }
-  //         }
-  //       ]
-  //     },
-  //     {
-  //       path: 'menu2',
-  //       component: () => import('@/views/nested/menu2/index'),
-  //       meta: { title: 'menu2' }
-  //     }
-  //   ]
-  // },
-
-  // {
-  //   path: 'external-link',
-  //   component: Layout,
-  //   children: [
-  //     {
-  //       path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
-  //       meta: { title: 'External Link', icon: 'link' }
-  //     }
-  //   ]
-  // },
-
   // 404 page must be placed at the end !!!
   { path: '*', redirect: '/404', hidden: true }
 ]

+ 3 - 3
src/settings.js

@@ -1,16 +1,16 @@
 module.exports = {
 
-  title: 'Vue Admin Template',
+  title: '开放平台',
 
   /**
    * @type {boolean} true | false
    * @description Whether fix the header
    */
-  fixedHeader: false,
+  fixedHeader: true,
 
   /**
    * @type {boolean} true | false
    * @description Whether show the logo in sidebar
    */
-  sidebarLogo: false
+  sidebarLogo: true
 }

+ 2 - 1
src/store/getters.js

@@ -1,6 +1,7 @@
 const getters = {
   sidebar: state => state.app.sidebar,
   device: state => state.app.device,
-  oauthInfo: state => state.user.oauthInfo
+  oauthInfo: state => state.user.oauthInfo,
+  routes: state => state.permission.routes
 }
 export default getters

+ 3 - 1
src/store/index.js

@@ -4,6 +4,7 @@ import getters from './getters'
 import app from './modules/app'
 import settings from './modules/settings'
 import user from './modules/user'
+import permission from './modules/permission'
 
 Vue.use(Vuex)
 
@@ -11,7 +12,8 @@ const store = new Vuex.Store({
   modules: {
     app,
     settings,
-    user
+    user,
+    permission
   },
   getters
 })

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

@@ -0,0 +1,64 @@
+import { asyncRoutes, constantRoutes } from '@/router'
+
+/**
+ * Use meta.role to determine if the current user has permission
+ * @param authorities
+ * @param route
+ */
+function hasPermission(authorities, route) {
+  if (route.meta && route.meta.authorities) {
+    return authorities.some(authority => route.meta.authorities.includes(authority))
+  } else {
+    return true
+  }
+}
+
+/**
+ * Filter asynchronous routing tables by recursion
+ * @param routes asyncRoutes
+ * @param authorities
+ */
+export function filterAsyncRoutes(routes, authorities) {
+  const res = []
+
+  routes.forEach(route => {
+    const tmp = { ...route }
+    if (hasPermission(authorities, tmp)) {
+      if (tmp.children) {
+        tmp.children = filterAsyncRoutes(tmp.children, authorities)
+      }
+      res.push(tmp)
+    }
+  })
+
+  return res
+}
+
+const state = {
+  routes: [],
+  addRoutes: []
+}
+
+const mutations = {
+  SET_ROUTES: (state, routes) => {
+    state.addRoutes = routes
+    state.routes = constantRoutes.concat(routes)
+  }
+}
+
+const actions = {
+  generateRoutes({ commit }, authorities) {
+    return new Promise(resolve => {
+      const accessedRoutes = filterAsyncRoutes(asyncRoutes, authorities)
+      commit('SET_ROUTES', accessedRoutes)
+      resolve(accessedRoutes)
+    })
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}

+ 6 - 8
src/store/modules/user.js

@@ -3,7 +3,7 @@ import { resetRouter } from '@/router'
 
 const getDefaultState = () => {
   return {
-    oauthInfo: undefined,
+    oauthInfo: undefined
   }
 }
 
@@ -16,7 +16,7 @@ const mutations = {
 
   SET_OAUTH_INFO: (state, oauthInfo) => {
     state.oauthInfo = oauthInfo
-  },
+  }
 }
 
 const actions = {
@@ -25,9 +25,7 @@ const actions = {
     const { captcha, username, password, token } = params
     return new Promise((resolve, reject) => {
       login({ loginAccount: username.trim(), loginPassword: password, captcha, token }).then(data => {
-        console.log(data);
-        commit('SET_OAUTH_INFO', data)
-        localStorage.setItem("x-access-token", data.accessToken || '');
+        localStorage.setItem('x-access-token', data.accessToken || '')
         resolve()
       }).catch(error => {
         reject(error)
@@ -43,7 +41,7 @@ const actions = {
           reject('获取用户信息失败,请重新登录')
         }
         commit('SET_OAUTH_INFO', data)
-        localStorage.setItem("x-access-token", data.accessToken || '');
+        localStorage.setItem('x-access-token', data.accessToken || '')
         resolve(data)
       }).catch(error => {
         reject(error)
@@ -55,7 +53,7 @@ const actions = {
   logout({ commit, state }) {
     return new Promise((resolve, reject) => {
       loginOut().then(() => {
-        localStorage.removeItem("x-access-token");
+        localStorage.removeItem('x-access-token')
         resetRouter()
         commit('RESET_STATE')
         resolve()
@@ -68,7 +66,7 @@ const actions = {
   // remove token
   resetToken({ commit }) {
     return new Promise(resolve => {
-      localStorage.removeItem("x-access-token");
+      localStorage.removeItem('x-access-token')
       resolve()
     })
   }

+ 1 - 1
src/views/404.vue

@@ -14,7 +14,7 @@
         </div>
         <div class="bullshit__headline">{{ message }}</div>
         <div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div>
-        <a href="" class="bullshit__return-home">Back to home</a>
+        <a href="/" class="bullshit__return-home">Back to home</a>
       </div>
     </div>
   </div>

+ 2 - 2
src/views/login/index.vue

@@ -81,8 +81,8 @@ export default {
   data() {
     return {
       loginForm: {
-        username: '',
-        password: '',
+        username: '18888888888',
+        password: 'a111111',
         captcha: ''
       },
       loading: false,

+ 1 - 1
src/views/user/info/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="app-container">
     <el-row class="action-bar-container" type="flex" justify="end">
-      <el-button type="primary" size="small" @click.native="$refs.dialogForm.open({})">新建</el-button>
+      <el-button v-permission="['oauth.user.find']" type="primary" size="small" @click.native="$refs.dialogForm.open({})">新建</el-button>
     </el-row>
     <el-table
       v-loading="isLoading"