Răsfoiți Sursa

取消首页,登录成功自动进入第一个有权限的菜单

wukai 2 luni în urmă
părinte
comite
a89444468d

+ 11 - 6
src/components/Breadcrumb/index.vue

@@ -2,7 +2,8 @@
   <el-breadcrumb class="app-breadcrumb" separator="/">
     <transition-group name="breadcrumb">
       <el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
-        <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span>
+        <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1"
+              class="no-redirect">{{ item.meta.title }}</span>
         <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
       </el-breadcrumb-item>
     </transition-group>
@@ -33,11 +34,12 @@ function getBreadcrumb() {
     matched = route.matched.filter((item) => item.meta && item.meta.title)
   }
   // 判断是否为首页
-  if (!isDashboard(matched[0])) {
-    matched = [{ path: "/index", meta: { title: "首页" } }].concat(matched)
-  }
+  // if (!isDashboard(matched[0])) {
+  //   matched = [{path: "/index", meta: {title: "首页"}}].concat(matched)
+  // }
   levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
 }
+
 function findPathNum(str, char = "/") {
   let index = str.indexOf(char)
   let num = 0
@@ -47,6 +49,7 @@ function findPathNum(str, char = "/") {
   }
   return num
 }
+
 function getMatched(pathList, routeList, matched) {
   let data = routeList.find(item => item.path == pathList[0] || (item.name += '').toLowerCase() == pathList[0])
   if (data) {
@@ -57,6 +60,7 @@ function getMatched(pathList, routeList, matched) {
     }
   }
 }
+
 function isDashboard(route) {
   const name = route && route.name
   if (!name) {
@@ -64,8 +68,9 @@ function isDashboard(route) {
   }
   return name.trim() === 'Index'
 }
+
 function handleLink(item) {
-  const { redirect, path } = item
+  const {redirect, path} = item
   if (redirect) {
     router.push(redirect)
     return
@@ -95,4 +100,4 @@ getBreadcrumb()
     cursor: text;
   }
 }
-</style>
+</style>

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

@@ -67,6 +67,8 @@ import RuoYiDoc from '@/components/RuoYi/Doc'
 import useAppStore from '@/store/modules/app'
 import useUserStore from '@/store/modules/user'
 import useSettingsStore from '@/store/modules/settings'
+import usePermissionStore from '@/store/modules/permission'
+const indexPage = computed(() => usePermissionStore().indexPage);
 
 const appStore = useAppStore()
 const userStore = useUserStore()
@@ -96,7 +98,8 @@ function logout() {
     type: 'warning'
   }).then(() => {
     userStore.logOut().then(() => {
-      location.href = '/twin/index';
+      location.href = indexPage.value;
+      // location.href = '/twin/index';
     })
   }).catch(() => { });
 }

+ 58 - 50
src/permission.js

@@ -1,69 +1,77 @@
 import router from './router'
-import { ElMessage } from 'element-plus'
+import {ElMessage} from 'element-plus'
 import NProgress from 'nprogress'
 import 'nprogress/nprogress.css'
-import { getToken } from '@/utils/auth'
-import { isHttp, isPathMatch } from '@/utils/validate'
-import { isRelogin } from '@/utils/request'
+import {getToken} from '@/utils/auth'
+import {isHttp, isPathMatch} from '@/utils/validate'
+import {isRelogin} from '@/utils/request'
 import useUserStore from '@/store/modules/user'
 import useSettingsStore from '@/store/modules/settings'
 import usePermissionStore from '@/store/modules/permission'
 
-NProgress.configure({ showSpinner: false })
+NProgress.configure({showSpinner: false})
 
-const whiteList = ['/login', '/register','/sso']
+const whiteList = ['/login', '/register', '/sso']
 
 const isWhiteList = (path) => {
-  return whiteList.some(pattern => isPathMatch(pattern, path))
+    return whiteList.some(pattern => isPathMatch(pattern, path))
 }
 
 router.beforeEach((to, from, next) => {
-  NProgress.start()
-  if (getToken()) {
-    to.meta.title && useSettingsStore().setTitle(to.meta.title)
-    /* has token*/
-    if (to.path === '/login') {
-      next({ path: '/' })
-      NProgress.done()
-    } else if (isWhiteList(to.path)) {
-      next()
-    } else {
-      if (useUserStore().roles.length === 0) {
-        isRelogin.show = true
-        // 判断当前用户是否已拉取完user_info信息
-        useUserStore().getInfo().then(() => {
-          isRelogin.show = false
-          usePermissionStore().generateRoutes().then(accessRoutes => {
-            // 根据roles权限生成可访问的路由表
-            accessRoutes.forEach(route => {
-              if (!isHttp(route.path)) {
-                router.addRoute(route) // 动态添加可访问路由表
-              }
-            })
-            next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
-          })
-        }).catch(err => {
-          useUserStore().logOut().then(() => {
-            ElMessage.error(err)
-            next({ path: '/' })
-          })
-        })
-      } else {
-        next()
-      }
-    }
-  } else {
-    // 没有token
-    if (isWhiteList(to.path)) {
-      // 在免登录白名单,直接进入
-      next()
+    NProgress.start()
+    if (getToken()) {
+        to.meta.title && useSettingsStore().setTitle(to.meta.title)
+        /* has token*/
+        if (to.path === '/login') {
+            next({path: '/'})
+            NProgress.done()
+        } else if (isWhiteList(to.path)) {
+            next()
+        } else {
+            if (useUserStore().roles.length === 0) {
+                isRelogin.show = true
+                // 判断当前用户是否已拉取完user_info信息
+                useUserStore().getInfo().then(() => {
+                    isRelogin.show = false
+                    usePermissionStore().generateRoutes().then(accessRoutes => {
+                        // 根据roles权限生成可访问的路由表
+                        accessRoutes.forEach(route => {
+                            if (!isHttp(route.path)) {
+                                router.addRoute(route) // 动态添加可访问路由表
+                            }
+                        })
+                        if (to.fullPath == '/') {
+                            let pathIndex = '';
+                            pathIndex = accessRoutes[0].path + "/" + accessRoutes[0].children[0].path
+                            next({path: pathIndex, replace: true}); // hack方法 确保addRoutes已完成
+
+                        } else {
+                            next({...to, replace: true}); // hack方法 确保addRoutes已完成
+                        }
+
+                    })
+                }).catch(err => {
+                    useUserStore().logOut().then(() => {
+                        ElMessage.error(err)
+                        next({path: '/'})
+                    })
+                })
+            } else {
+                next()
+            }
+        }
     } else {
-      next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
-      NProgress.done()
+        // 没有token
+        if (isWhiteList(to.path)) {
+            // 在免登录白名单,直接进入
+            next()
+        } else {
+            next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
+            NProgress.done()
+        }
     }
-  }
 })
 
 router.afterEach(() => {
-  NProgress.done()
+    NProgress.done()
 })

+ 13 - 13
src/router/index.js

@@ -62,19 +62,19 @@ export const constantRoutes = [
     component: () => import('@/views/error/401'),
     hidden: true
   },
-  {
-    path: '',
-    component: Layout,
-    redirect: '/index',
-    children: [
-      {
-        path: '/index',
-        component: () => import('@/views/index'),
-        name: 'Index',
-        meta: { title: '默认', icon: 'dashboard', affix: false }
-      }
-    ]
-  },
+  // {
+  //   path: '',
+  //   component: Layout,
+  //   redirect: '/index',
+  //   children: [
+  //     {
+  //       path: '/index',
+  //       component: () => import('@/views/index'),
+  //       name: 'Index',
+  //       meta: { title: '默认', icon: 'dashboard', affix: false }
+  //     }
+  //   ]
+  // },
   {
     path: '/user',
     component: Layout,

+ 127 - 116
src/store/modules/permission.js

@@ -1,6 +1,6 @@
 import auth from '@/plugins/auth'
-import router, { constantRoutes, dynamicRoutes } from '@/router'
-import { getRouters } from '@/api/menu'
+import router, {constantRoutes, dynamicRoutes} from '@/router'
+import {getRouters} from '@/api/menu'
 import Layout from '@/layout/index'
 import ParentView from '@/components/ParentView'
 import InnerLink from '@/layout/components/InnerLink'
@@ -9,134 +9,145 @@ import InnerLink from '@/layout/components/InnerLink'
 const modules = import.meta.glob('./../../views/**/*.vue')
 
 const usePermissionStore = defineStore(
-  'permission',
-  {
-    state: () => ({
-      routes: [],
-      addRoutes: [],
-      defaultRoutes: [],
-      topbarRouters: [],
-      sidebarRouters: []
-    }),
-    actions: {
-      setRoutes(routes) {
-        this.addRoutes = routes
-        this.routes = constantRoutes.concat(routes)
-      },
-      setDefaultRoutes(routes) {
-        this.defaultRoutes = constantRoutes.concat(routes)
-      },
-      setTopbarRoutes(routes) {
-        this.topbarRouters = routes
-      },
-      setSidebarRouters(routes) {
-        this.sidebarRouters = routes
-      },
-      generateRoutes(roles) {
-        return new Promise(resolve => {
-          // 向后端请求路由数据
-          getRouters().then(res => {
-            const sdata = JSON.parse(JSON.stringify(res.data))
-            const rdata = JSON.parse(JSON.stringify(res.data))
-            const defaultData = JSON.parse(JSON.stringify(res.data))
-            const sidebarRoutes = filterAsyncRouter(sdata)
-            const rewriteRoutes = filterAsyncRouter(rdata, false, true)
-            const defaultRoutes = filterAsyncRouter(defaultData)
-            const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
-            asyncRoutes.forEach(route => { router.addRoute(route) })
-            this.setRoutes(rewriteRoutes)
-            this.setSidebarRouters(constantRoutes.concat(sidebarRoutes))
-            this.setDefaultRoutes(sidebarRoutes)
-            this.setTopbarRoutes(defaultRoutes)
-            resolve(rewriteRoutes)
-          })
-        })
-      }
-    }
-  })
+    'permission',
+    {
+        state: () => ({
+            routes: [],
+            addRoutes: [],
+            defaultRoutes: [],
+            topbarRouters: [],
+            sidebarRouters: [],
+            indexPage: ''
+        }),
+        actions: {
+            setIndexPage(page) {
+                this.indexPage = page;
+            },
+            setRoutes(routes) {
+                this.addRoutes = routes
+                this.routes = constantRoutes.concat(routes)
+            },
+            setDefaultRoutes(routes) {
+                this.defaultRoutes = constantRoutes.concat(routes)
+            },
+            setTopbarRoutes(routes) {
+                this.topbarRouters = routes
+            },
+            setSidebarRouters(routes) {
+                this.sidebarRouters = routes
+            },
+            generateRoutes(roles) {
+                return new Promise(resolve => {
+                    // 向后端请求路由数据
+                    getRouters().then(res => {
+                        if (res.data.length && res.data[0].children && res.data[0].children.length > 0) {
+                            res.data[0].children[0].meta.affix = true;
+                            const indexPage = res.data[0].path + "/" + res.data[0].children[0].path
+                            this.setIndexPage(indexPage);
+                        }
+                        const sdata = JSON.parse(JSON.stringify(res.data));
+                        const rdata = JSON.parse(JSON.stringify(res.data))
+                        const defaultData = JSON.parse(JSON.stringify(res.data))
+                        const sidebarRoutes = filterAsyncRouter(sdata)
+                        const rewriteRoutes = filterAsyncRouter(rdata, false, true)
+                        const defaultRoutes = filterAsyncRouter(defaultData)
+                        const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
+                        asyncRoutes.forEach(route => {
+                            router.addRoute(route)
+                        })
+                        this.setRoutes(rewriteRoutes)
+                        this.setSidebarRouters(constantRoutes.concat(sidebarRoutes))
+                        this.setDefaultRoutes(sidebarRoutes)
+                        this.setTopbarRoutes(defaultRoutes)
+                        resolve(rewriteRoutes)
+                    })
+                })
+            }
+        }
+    })
 
 // 遍历后台传来的路由字符串,转换为组件对象
 function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
-  return asyncRouterMap.filter(route => {
-    if (type && route.children) {
-      route.children = filterChildren(route.children)
-    }
-    if (route.component) {
-      // Layout ParentView 组件特殊处理
-      if (route.component === 'Layout') {
-        route.component = Layout
-      } else if (route.component === 'ParentView') {
-        route.component = ParentView
-      } else if (route.component === 'InnerLink') {
-        route.component = InnerLink
-      } else {
-        route.component = loadView(route.component)
-      }
-    }
-    if (route.children != null && route.children && route.children.length) {
-      route.children = filterAsyncRouter(route.children, route, type)
-    } else {
-      delete route['children']
-      delete route['redirect']
-    }
-    return true
-  })
+    return asyncRouterMap.filter(route => {
+        if (type && route.children) {
+            route.children = filterChildren(route.children)
+        }
+        if (route.component) {
+            // Layout ParentView 组件特殊处理
+            if (route.component === 'Layout') {
+                route.component = Layout
+            } else if (route.component === 'ParentView') {
+                route.component = ParentView
+            } else if (route.component === 'InnerLink') {
+                route.component = InnerLink
+            } else {
+                route.component = loadView(route.component)
+            }
+        }
+        if (route.children != null && route.children && route.children.length) {
+            route.children = filterAsyncRouter(route.children, route, type)
+        } else {
+            delete route['children']
+            delete route['redirect']
+        }
+        return true
+    })
 }
 
 function filterChildren(childrenMap, lastRouter = false) {
-  var children = []
-  childrenMap.forEach((el, index) => {
-    if (el.children && el.children.length) {
-      if (el.component === 'ParentView' && !lastRouter) {
-        el.children.forEach(c => {
-          c.path = el.path + '/' + c.path
-          if (c.children && c.children.length) {
-            children = children.concat(filterChildren(c.children, c))
-            return
-          }
-          children.push(c)
-        })
-        return
-      }
-    }
-    if (lastRouter) {
-      el.path = lastRouter.path + '/' + el.path
-      if (el.children && el.children.length) {
-        children = children.concat(filterChildren(el.children, el))
-        return
-      }
-    }
-    children = children.concat(el)
-  })
-  return children
+    var children = []
+    childrenMap.forEach((el, index) => {
+        if (el.children && el.children.length) {
+            if (el.component === 'ParentView' && !lastRouter) {
+                el.children.forEach(c => {
+                    c.path = el.path + '/' + c.path
+                    if (c.children && c.children.length) {
+                        children = children.concat(filterChildren(c.children, c))
+                        return
+                    }
+                    children.push(c)
+                })
+                return
+            }
+        }
+        if (lastRouter) {
+            el.path = lastRouter.path + '/' + el.path
+            if (el.children && el.children.length) {
+                children = children.concat(filterChildren(el.children, el))
+                return
+            }
+        }
+        children = children.concat(el)
+    })
+    return children
 }
 
 // 动态路由遍历,验证是否具备权限
 export function filterDynamicRoutes(routes) {
-  const res = []
-  routes.forEach(route => {
-    if (route.permissions) {
-      if (auth.hasPermiOr(route.permissions)) {
-        res.push(route)
-      }
-    } else if (route.roles) {
-      if (auth.hasRoleOr(route.roles)) {
-        res.push(route)
-      }
-    }
-  })
-  return res
+    const res = []
+    routes.forEach(route => {
+        if (route.permissions) {
+            if (auth.hasPermiOr(route.permissions)) {
+                res.push(route)
+            }
+        } else if (route.roles) {
+            if (auth.hasRoleOr(route.roles)) {
+                res.push(route)
+            }
+        }
+    })
+    return res
 }
 
 export const loadView = (view) => {
-  let res;
-  for (const path in modules) {
-    const dir = path.split('views/')[1].split('.vue')[0];
-    if (dir === view) {
-      res = () => modules[path]();
+    let res;
+    for (const path in modules) {
+        const dir = path.split('views/')[1].split('.vue')[0];
+        if (dir === view) {
+            res = () => modules[path]();
+        }
     }
-  }
-  return res;
+    return res;
 }
 
 export default usePermissionStore

+ 5 - 1
src/utils/request.js

@@ -6,6 +6,9 @@ import { tansParams, blobValidate } from '@/utils/ruoyi'
 import cache from '@/plugins/cache'
 import { saveAs } from 'file-saver'
 import useUserStore from '@/store/modules/user'
+import usePermissionStore from '@/store/modules/permission'
+
+const indexPage = computed(() => usePermissionStore().indexPage);
 
 let downloadLoadingInstance;
 // 是否显示重新登录
@@ -87,7 +90,8 @@ service.interceptors.response.use(res => {
         ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
           isRelogin.show = false;
           useUserStore().logOut().then(() => {
-            location.href = '/twin/index';
+            location.href = indexPage.value;
+            // location.href = '/twin/index';
           })
       }).catch(() => {
         isRelogin.show = false;

+ 3 - 1
src/views/error/404.vue

@@ -17,7 +17,7 @@
         <div class="bullshit__info">
           对不起,您正在寻找的页面不存在。尝试检查URL的错误,然后按浏览器上的刷新按钮或尝试在我们的应用程序中找到其他内容。
         </div>
-        <router-link to="/index" class="bullshit__return-home">
+        <router-link :to="indexPage" class="bullshit__return-home">
           返回首页
         </router-link>
       </div>
@@ -26,6 +26,8 @@
 </template>
 
 <script setup>
+import usePermissionStore from '@/store/modules/permission'
+const indexPage = computed(() => usePermissionStore().indexPage);
 let message = computed(() => {
   return '找不到网页!'
 })