chore: improve route management

This commit is contained in:
chansee97 2025-09-08 22:31:38 +08:00
parent 1b28285b04
commit df11b5a97c
5 changed files with 31 additions and 25 deletions

2
.env
View File

@ -8,7 +8,7 @@ VITE_APP_NAME = Nova - Admin
VITE_ROUTE_MODE = web VITE_ROUTE_MODE = web
# 路由加载模式 static dynamic # 路由加载模式 static dynamic
VITE_ROUTE_LOAD_MODE = static VITE_ROUTE_LOAD_MODE = dynamic
# 设置登陆后跳转地址 # 设置登陆后跳转地址
VITE_HOME_PATH = /home VITE_HOME_PATH = /home

View File

@ -8,7 +8,7 @@ import IconUser from '~icons/icon-park-outline/user'
const { t } = useI18n() const { t } = useI18n()
const { userInfo, logout } = useAuthStore() const authStore = useAuthStore()
const router = useRouter() const router = useRouter()
const options = computed(() => { const options = computed(() => {
@ -56,7 +56,7 @@ function handleSelect(key: string | number) {
positiveText: t('common.confirm'), positiveText: t('common.confirm'),
negativeText: t('common.cancel'), negativeText: t('common.cancel'),
onPositiveClick: () => { onPositiveClick: () => {
logout() authStore.logout()
}, },
}) })
} }
@ -72,6 +72,10 @@ function handleSelect(key: string | number) {
if (key === 'docs') if (key === 'docs')
window.open('https://nova-admin-docs.pages.dev/') window.open('https://nova-admin-docs.pages.dev/')
} }
const avatarUrl = computed(() => {
return authStore.userInfo?.avatar || `https://api.dicebear.com/9.x/adventurer-neutral/svg?seed=${authStore.userInfo?.username}`
})
</script> </script>
<template> <template>
@ -83,7 +87,7 @@ function handleSelect(key: string | number) {
<n-avatar <n-avatar
round round
class="cursor-pointer" class="cursor-pointer"
:src="userInfo?.avatar || `https://api.dicebear.com/9.x/adventurer-neutral/svg?seed=${userInfo!.username}`" :src="avatarUrl"
> >
<template #fallback> <template #fallback>
<div class="wh-full flex-center"> <div class="wh-full flex-center">

View File

@ -5,7 +5,7 @@ import { useRouteStore } from './router'
import { useTabStore } from './tab' import { useTabStore } from './tab'
interface AuthStatus { interface AuthStatus {
userInfo: Entity.User userInfo: Partial<Entity.User>
roles: string[] roles: string[]
permissions: string[] permissions: string[]
} }
@ -38,14 +38,12 @@ export const useAuthStore = defineStore('auth-store', {
// 重置当前存储库 // 重置当前存储库
this.$reset() this.$reset()
// 重定向到登录页 // 重定向到登录页
if (route.meta.requiresAuth) { router.push({
router.push({ name: 'login',
name: 'login', query: {
query: { redirect: route.fullPath,
redirect: route.fullPath, },
}, })
})
}
}, },
clearAuthStorage() { clearAuthStorage() {
local.remove('accessToken') local.remove('accessToken')
@ -65,13 +63,7 @@ export const useAuthStore = defineStore('auth-store', {
const { data } = await fetchLogin(loginData) const { data } = await fetchLogin(loginData)
// 处理登录信息 // 处理登录信息
try { await this.handleLoginInfo(data)
await this.handleLoginInfo(data)
}
catch (error) {
console.error('Failed to handle login info:', error)
throw error
}
// 更新用户信息 // 更新用户信息
await this.updataUserInfo() await this.updataUserInfo()

View File

@ -82,6 +82,7 @@ export function createMenus(userRoutes: Entity.Menu[]): MenuOption[] {
// render the returned routing table as a sidebar // render the returned routing table as a sidebar
function transformAuthRoutesToMenus(userRoutes: Entity.Menu[]) { function transformAuthRoutesToMenus(userRoutes: Entity.Menu[]) {
const routes = clone(userRoutes)
const homeRoute: Entity.Menu = { const homeRoute: Entity.Menu = {
id: 9999999999999, id: 9999999999999,
parentId: 0, parentId: 0,
@ -91,8 +92,8 @@ function transformAuthRoutesToMenus(userRoutes: Entity.Menu[]) {
menuVisible: true, menuVisible: true,
menuType: 'page', menuType: 'page',
} }
userRoutes.unshift(homeRoute) routes.unshift(homeRoute)
return userRoutes return routes
// filter menus that do not need to be displayed // filter menus that do not need to be displayed
.filter(route => route.menuVisible !== false) .filter(route => route.menuVisible !== false)
// Sort the menu according to the order size // Sort the menu according to the order size

View File

@ -11,6 +11,7 @@ interface RoutesStatus {
rowRoutes: Entity.Menu[] rowRoutes: Entity.Menu[]
activeMenu: string | null activeMenu: string | null
cacheRoutes: string[] cacheRoutes: string[]
dynamicRouteNames: string[]
} }
export const useRouteStore = defineStore('route-store', { export const useRouteStore = defineStore('route-store', {
state: (): RoutesStatus => { state: (): RoutesStatus => {
@ -20,6 +21,7 @@ export const useRouteStore = defineStore('route-store', {
menus: [], menus: [],
rowRoutes: [], rowRoutes: [],
cacheRoutes: [], cacheRoutes: [],
dynamicRouteNames: [],
} }
}, },
actions: { actions: {
@ -28,8 +30,14 @@ export const useRouteStore = defineStore('route-store', {
this.$reset() this.$reset()
}, },
resetRoutes() { resetRoutes() {
if (router.hasRoute('appRoot')) // Remove only dynamically added routes, preserve built-in routes
router.removeRoute('appRoot') this.dynamicRouteNames.forEach((routeName) => {
if (router.hasRoute(routeName)) {
router.removeRoute(routeName)
}
})
// Clear the dynamic route names array
this.dynamicRouteNames = []
}, },
// set the currently highlighted menu key // set the currently highlighted menu key
setActiveMenu(key: string) { setActiveMenu(key: string) {
@ -68,9 +76,10 @@ export const useRouteStore = defineStore('route-store', {
// Generate actual route and insert // Generate actual route and insert
const routes = createRoutes(rowRoutes) const routes = createRoutes(rowRoutes)
// Add each route as a child of appRoot // Add each route as a child of appRoot and track their names
routes.forEach((route) => { routes.forEach((route) => {
router.addRoute('appRoot', route as any) router.addRoute('appRoot', route as any)
this.dynamicRouteNames.push(route.name)
}) })
// Generate side menu // Generate side menu