Explorar el Código

#13568 & Permission enhancement

vbea hace 2 años
padre
commit
95e354f10a

+ 3 - 0
Strides-Admin/src/http/api/user.js

@@ -14,6 +14,9 @@ const user = {
   },
   updatePassword(data) {
     return post(MODULE_NAME + "update-pwd", data)
+  },
+  refreshAuthMenu() {
+    return get(MODULE_NAME + "resources")
   }
 }
 

+ 1 - 5
Strides-Admin/src/layout/components/Sidebar/index.vue

@@ -38,11 +38,7 @@ import permission from '@/utils/permission'
 export default {
   components: { SidebarItem, Logo },
   created() {
-    this.authRoutesList = getAuthRoutes()
-    if (!this.permission_routes.length) {
-      this.$store.commit('permission/SET_ROUTES', this.authRoutesList);
-    }
-    //this.selectedItemIndex = this.activeMenu
+    
   },
   data() {
     return {

+ 36 - 49
Strides-Admin/src/router/permission.js

@@ -11,26 +11,10 @@ NProgress.configure({ showSpinner: false }) // NProgress Configuration
 
 const whiteList = ['/login', '/redirect', '/404'] // no redirect whitelist
 
-router.beforeEach(async(to, from, next) => {
-  // start progress bar
-  NProgress.start()
-
-  // set page title
-  document.title = getPageTitle(to.meta.title)
-
-  // determine whether the user has logged in
-  const hasToken = getToken()
-  //console.log("权限控制", to, from);
-  const routes = store.getters.resources
-  if (routes.length == 0) {
-    let rs = getAuthRoutes();
-    if (rs && rs.length) {
-      store.commit("user/SET_RESOURCES", rs);
-      routes.push(...rs);
-    }
-  }
-  //console.log("路由", routes);
+function handleRoute(to, routes, next) {
   let validPath = !permission.enable_404;
+  let hasToken = getToken()
+  
   if (!validPath && to.path && routes.length) {
     for (let _route of routes) {
       if (to.path == _route[permission.RESOURCE_KEY] || (to.meta && to.meta.activeMenu == _route[permission.RESOURCE_KEY])) {
@@ -40,46 +24,19 @@ router.beforeEach(async(to, from, next) => {
     }
   }
   if (hasToken) {
-    //console.log("权限通过", validPath);
+    //console.log("已登录", validPath);
     if (to.path === '/login') {
       // if is logged in, redirect to the home page
       next({ path: '/redirect' })
       NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
-    } else if (!validPath && whiteList.indexOf(to.path) == -1) {
+    } else if (!validPath) {
       next({ path: '/404' })
       NProgress.done()
     } else {
       next();
-      /* 下列逻辑不用,启用自定义权限控制
-      const hasRoles = store.getters.roles && store.getters.roles.length > 0
-      if (hasRoles) {
-        next()
-      } else {
-        try {
-          // get user info
-          // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
-          const { roles } = await store.dispatch('user/getInfo')
-
-          // generate accessible routes map based on roles
-          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
-
-          // dynamically add accessible routes
-          router.addRoutes(accessRoutes)
-
-          // hack method to ensure that addRoutes is complete
-          // set the replace: true, so the navigation will not leave a history record
-          next({ ...to, replace: true })
-        } catch (error) {
-          // remove token and go to login page to re-login
-          await store.dispatch('user/resetToken')
-          Message.error(error || 'Has Error')
-          next(`/login?redirect=${to.path}`)
-          NProgress.done()
-        }
-      }*/
     }
   } else {
-    //console.log("权限未通过", to.path, hasToken);
+    //console.log("未登录", to.path, hasToken);
     /* has no token*/
     if (whiteList.indexOf(to.path) !== -1) {
       // in the free login whitelist, go directly
@@ -91,6 +48,36 @@ router.beforeEach(async(to, from, next) => {
       NProgress.done()
     }
   }
+}
+
+router.beforeEach(async(to, from, next) => {
+  // start progress bar
+  NProgress.start()
+
+  // set page title
+  document.title = getPageTitle(to.meta.title)
+  if (whiteList.indexOf(to.path) >= 0) {
+    next();
+  } else {
+    // determine whether the user has logged in
+    //console.log("权限控制", to, from);
+    const routes = store.getters.resources
+    if (routes.length == 0) {
+      getAuthRoutes(rs => {
+        if (rs && rs.length) {
+          store.commit("user/SET_RESOURCES", rs);
+          store.commit('permission/SET_ROUTES', rs);
+          routes.push(...rs);
+          handleRoute(to, routes, next);
+        } else {
+          next({ path: '/404' })
+          NProgress.done()
+        }
+      });
+    } else {
+      handleRoute(to, routes, next);
+    }
+  }
 })
 
 router.afterEach(() => {

+ 6 - 1
Strides-Admin/src/settings.js

@@ -42,7 +42,12 @@ module.exports = {
    * @description Whether show the logo in sidebar
    */
   sidebarLogo: true,
-
+  /**
+   * 是否启用在线校验路由
+   * - true 每次刷新都将获取最新的路由权限
+   * - false 每次刷新获取本地缓存的路由权限
+   */
+  enableOnlineAuth: true,
   /**
    * @type {string | array} 'production' | ['production', 'development']
    * @description Need show err logs component.

+ 0 - 1
Strides-Admin/src/store/modules/permission.js

@@ -1,5 +1,4 @@
 import { asyncRoutes, resetRouter, constantRoutes } from '@/router'
-import { getAuthRoutes } from '@/utils/auth'
 import permission from '@/utils/permission'
 
 /**

+ 37 - 6
Strides-Admin/src/utils/auth.js

@@ -1,6 +1,6 @@
 import Cookies from 'js-cookie'
 import { Base64 } from 'js-base64';
-import settings from '@/settings'
+import settings from '@/settings';
 
 const TokenKey = settings.projectName + '-TOKEN'
 const AuthRoutesKey = settings.projectName + '-ApacheResource'
@@ -20,12 +20,28 @@ export function removeToken() {
   return Cookies.remove(TokenKey)
 }
 
-export function getAuthRoutes() {
+export function getAuthRoutes(back) {
+  if (settings.enableOnlineAuth) {
+    const apiUser = require('../http/api/user').default;
+    apiUser.refreshAuthMenu().then(res => {
+      if (res.data) {
+        setAuthRoutes(res.data)
+        back(res.data)
+      }
+    }).catch(err => {
+      back(getAuthRoutesLocale())
+    })
+  } else {
+    back(getAuthRoutesLocale())
+  }
+}
+
+export function getAuthRoutesLocale() {
   const value = localStorage.getItem(AuthRoutesKey)
   if (value) {
     return JSON.parse(Base64.decode(value))
   }
-  return ''
+  return []
 }
 
 export function removeAuthRoutes() {
@@ -41,7 +57,12 @@ export function setAuthRoutes(routes) {
 }
 
 export function getRoleName() {
-  return Base64.decode(localStorage.getItem(RoleName))
+  const name = localStorage.getItem(RoleName)
+  if (name) {
+    return Base64.decode(name)
+  } else {
+    return "";
+  }
 }
 
 export function setRoleName(roleName) {
@@ -53,7 +74,12 @@ export function setUserName(name) {
 }
 
 export function getUserName() {
-  return Base64.decode(localStorage.getItem(UserName))
+  const name = localStorage.getItem(UserName)
+  if (name) {
+    return Base64.decode(name)
+  } else {
+    return "";
+  }
 }
 
 export function setEmail(email) {
@@ -61,5 +87,10 @@ export function setEmail(email) {
 }
 
 export function getEmail() {
-  return Base64.decode(localStorage.getItem(EmailName))
+  const name = localStorage.getItem(EmailName)
+  if (name) {
+    return Base64.decode(name)
+  } else {
+    return "";
+  }
 }

+ 10 - 3
Strides-Admin/src/views/redirect/index.vue

@@ -5,7 +5,7 @@
 <script>
 import store from '@/store'
 import permission from '@/utils/permission.js'
-import { getAuthRoutes } from '@/utils/auth.js'
+import { getToken, getAuthRoutesLocale } from '@/utils/auth.js'
 export default {
   data() {
     return {
@@ -13,12 +13,19 @@ export default {
     }
   },
   created() {
-    this.checkPermission()
+    let hasToken = getToken()
+    if (hasToken) {
+      this.checkPermission()
+    } else {
+      this.$router.push({
+        path: "/login"
+      })
+    }
   },
   methods: {
     checkPermission() {
       let path = '/dashboard'
-      const routes = getAuthRoutes();
+      const routes = getAuthRoutesLocale();
       if (routes.length > 0) {
         let validPath = false;
         for (let _route of routes) {

+ 45 - 21
Strides-Admin/src/views/user/views/ListMember.vue

@@ -4,7 +4,7 @@
     class="user-sub-item-table no-border">
     <el-table-column
       label="Card No:"
-      min-width="90px">
+      min-width="120px">
       <template slot-scope="{row}">
         <el-input
           class="item-input"
@@ -13,7 +13,7 @@
     </el-table-column>
     <el-table-column
       label="Group:"
-      min-width="90">
+      min-width="120">
       <template slot-scope="{row}">
         <el-select
           class="item-input"
@@ -28,7 +28,7 @@
     </el-table-column>
     <el-table-column
       label="Card Photo:"
-      min-width="90">
+      min-width="120">
       <template slot-scope="{$index,row}">
         <el-upload
           v-if="isEdit"
@@ -42,13 +42,21 @@
           :before-upload="e => beforeUpload(e, $index)">
           <div
             v-loading="loading.upload && $index == loading.index"
-            class="uploader-image">
+            class="uploader-image"
+            v-if="row.cardFront">
             <el-image
               class="uploader-image"
-              v-if="row.cardFront"
-              :src="getImageSrc(row.cardFront)"/>
-            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+              :src="getImageSrc(row.cardFront)"
+              :preview-src-list="previewSrcList(row.cardFront)"
+              @click.stop=""/>
+            <i
+              title="Click to upload image"
+              class="uploader-edit el-icon-edit-outline"></i>
           </div>
+          <i
+            v-else
+            title="Click to upload image"
+            class="avatar-uploader-icon el-icon-plus"></i>
         </el-upload>
         <div class="card-uploader" v-else-if="row.cardFront">
           <el-image
@@ -60,7 +68,7 @@
     </el-table-column>
     <el-table-column
       label="Status:"
-      min-width="80">
+      min-width="100">
       <template slot-scope="{$index,row}">
         <div class="flexc" v-loading="loading.action && $index == loading.index">
           <span>{{row.membershipStatus}}</span>
@@ -77,7 +85,7 @@
     </el-table-column>
     <el-table-column
       label="Action:"
-      min-width="100px">
+      min-width="120px">
       <template slot-scope="{$index,row}">
         <div v-loading="loading.subt">
           <img
@@ -162,13 +170,6 @@ export default {
         accessToken: getToken(),
         photoSubDir: "MEMBERSHIP",
       }
-    },
-    previewSrcList(path) {
-      const imageSrc = []
-      if (path) {
-        imageSrc.push(baseURL + path)
-      }
-      return imageSrc
     }
   },
   mounted() {
@@ -181,6 +182,13 @@ export default {
     getImageSrc(path) {
       return baseURL + path
     },
+    previewSrcList(path) {
+      const imageSrc = []
+      if (path) {
+        imageSrc.push(baseURL + path)
+      }
+      return imageSrc
+    },
     getGroupOptions() {
       api.getGroupByType(this.isFleet ? "FLEET" : "MEMBER").then(res => {
         if (res.data) {
@@ -338,12 +346,28 @@ export default {
     padding: 5px 0;
   }
   .uploader-image {
-    width: 120px;
-    height: 80px;
+    width: 135px;
+    height: 90px;
+    border-radius: 6px;
     text-align: left;
+    position: relative;
   }
   .uploader-image >>> img {
     object-fit: cover;
+    cursor: zoom-in;
+  }
+  .uploader-edit {
+    right: 4px;
+    bottom: 4px;
+    color: #fff;
+    padding: 5px;
+    display: none;
+    border-radius: 30px;
+    position: absolute;
+    background-color: rgba(1,1,1,.4);
+  }
+  .uploader-image:hover .uploader-edit {
+    display: block;
   }
   .avatar-uploader-icon {
     border: 1px dashed #d9d9d9;
@@ -351,9 +375,9 @@ export default {
     cursor: pointer;
     font-size: 28px;
     color: #8c939d;
-    width: 80px;
-    height: 80px;
-    line-height: 80px;
+    width: 90px;
+    height: 90px;
+    line-height: 90px;
     text-align: center;
   }
   .action-approve {