diff --git a/src/router/index.ts b/src/router/index.ts index 14289c1..ccf2040 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,5 +1,6 @@ import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router' -import type { MenuInfo } from '@/api/auth' +import { useUserStore } from '@/stores/user' +//import type { MenuInfo } from '@/api/auth' // 动态导入所有页面组件 const modules = import.meta.glob('/src/views/**/*.vue') @@ -34,7 +35,7 @@ const routes: RouteRecordRaw[] = [ component: () => import('@/views/dashboard/index.vue'), meta: { title: '首页', icon: 'HomeOutline' } }, - + // 个人中心 { path: 'profile', @@ -216,11 +217,16 @@ const routes: RouteRecordRaw[] = [ } ] }, + // { + // path: '/:pathMatch(.*)', + // name: 'NotFound', + // component: () => import('@/views/error/404.vue'), + // meta: { title: '404', requiresAuth: false } + // } { - path: '/:pathMatch(.*)*', - name: 'NotFound', + path: '/:pathMatch(.*)', component: () => import('@/views/error/404.vue'), - meta: { title: '404', requiresAuth: false } + // meta: { title: '404', requiresAuth: false } } ] @@ -232,47 +238,34 @@ const router = createRouter({ // 已添加的动态路由 const addedRouteNames = new Set() -// 动态路由是否已初始化 -let dynamicRoutesInitialized = false + /** * 根据菜单动态添加新路由(只添加静态路由中没有的) */ -export function addDynamicRoutes(menus: MenuInfo[]) { - console.log('[动态路由] 开始处理菜单:', menus) - - // 获取 Layout 路由的现有子路由路径 - const getLayoutChildPaths = () => { - const layoutRoute = router.getRoutes().find(r => r.name === 'Layout') - if (layoutRoute && layoutRoute.children) { - return new Set(layoutRoute.children.map(c => c.path)) - } - return new Set() - } - - const addRoutes = (menuList: MenuInfo[]) => { +export function addDynamicRoutes(menus: any) { //MenuInfo[] + //console.log('[动态路由] 开始处理菜单:', menus) + const addRoutes = (menuList: any) => { //MenuInfo[] for (const menu of menuList) { // 只处理菜单类型(type=2),且有 path if (menu.type === 2 && menu.path) { const routeName = 'Dynamic-' + menu.id - - // 规范化路径,去掉开头的 / + + // 检查是否已经有同路径的静态路由 + const existingRoutes = router.getRoutes() const menuPath = menu.path.startsWith('/') ? menu.path.slice(1) : menu.path - - // 检查是否已经有同路径的路由(检查 Layout 的子路由) - const layoutChildPaths = getLayoutChildPaths() - const pathExists = layoutChildPaths.has(menuPath) || layoutChildPaths.has('/' + menuPath) - + const pathExists = existingRoutes.some(r => r.path === '/' + menuPath || r.path === menuPath) + if (pathExists) { - console.log(`[动态路由] 跳过(已存在): ${menuPath}`) + // console.log(`[动态路由] 跳过(已存在): ${menuPath}`) continue } - + if (addedRouteNames.has(routeName)) { - console.log(`[动态路由] 跳过(已添加): ${menuPath}`) + //console.log(`[动态路由] 跳过(已添加): ${menuPath}`) continue } - + // 判断是否是外链菜单 if (menu.isFrame === 1 && menu.component) { // 外链菜单,使用 iframe 组件 @@ -292,36 +285,11 @@ export function addDynamicRoutes(menus: MenuInfo[]) { } else if (menu.component) { // 普通菜单,加载组件 const componentName = menu.component.startsWith('/') ? menu.component.slice(1) : menu.component - - // 组件路径映射表(解决菜单component与实际文件路径不匹配的问题) - const componentMapping: Record = { - 'biz/toolUsage': 'biz/tool/usage/index', - 'biz/toolUsage/index': 'biz/tool/usage/index', - 'biz/tool/usage': 'biz/tool/usage/index', - } - - // 查找映射关系 - const mappedComponent = componentMapping[componentName] || componentName - - // 尝试多种路径加载组件 - let component = null - const possiblePaths = [ - `/src/views/${mappedComponent}.vue`, - `/src/views/${mappedComponent}/index.vue`, - `/src/views/${componentName}.vue`, - `/src/views/${componentName}/index.vue`, - ] - - for (const path of possiblePaths) { - if (modules[path]) { - component = modules[path] - console.log(`[动态路由] 找到组件: ${path}`) - break - } - } - - console.log(`[动态路由] 处理: path=${menuPath}, componentName=${componentName}, mappedComponent=${mappedComponent}, 组件存在=${!!component}`) - + const componentPath = `/src/views/${componentName}.vue` + const component = modules[componentPath] + + //console.log(`[动态路由] 处理: path=${menuPath}, component=${componentPath}, 组件存在=${!!component}`) + if (component) { router.addRoute('Layout', { path: menuPath, @@ -334,23 +302,22 @@ export function addDynamicRoutes(menus: MenuInfo[]) { } }) addedRouteNames.add(routeName) - console.log(`[动态路由] ✓ 添加成功: ${menuPath}`) + //console.log(`[动态路由] ✓ 添加成功: ${menuPath}`) } else { - console.warn(`[动态路由] ✗ 组件不存在: ${componentName}`) + //console.warn(`[动态路由] ✗ 组件不存在: ${componentPath}`) } } } - + // 递归处理子菜单 if (menu.children && menu.children.length > 0) { addRoutes(menu.children) } } } - + addRoutes(menus) - dynamicRoutesInitialized = true - console.log('[动态路由] 当前所有路由:', router.getRoutes().map(r => r.path)) + //console.log('[动态路由] 当前所有路由:', router.getRoutes().map(r => r.path)) } /** @@ -363,16 +330,15 @@ export function resetRouter() { } }) addedRouteNames.clear() - dynamicRoutesInitialized = false } + // 路由守卫 router.beforeEach(async (to, _from, next) => { - const { useUserStore } = await import('@/stores/user') + console.log('路由测试'); const userStore = useUserStore() - document.title = `${to.meta.title || ''} - mes Admin` - + //document.title = `${to.meta.title || ''} - CSY Admin` if (to.meta.requiresAuth === false) { next() return @@ -383,25 +349,47 @@ router.beforeEach(async (to, _from, next) => { return } - if (!userStore.user || !dynamicRoutesInitialized) { + + if (userStore.init) { try { - if (!userStore.user) { - await userStore.getInfo() - } + + await userStore.getInfo() // 添加动态路由(只添加新的,不影响已有的) addDynamicRoutes(userStore.menus) - console.log('[路由守卫] 动态路由已添加,重新导航到:', to.path) + userStore.setinit(false) + // userStore.init = false next({ ...to, replace: true }) - return + //return } catch (error) { - console.error('[路由守卫] 获取用户信息失败:', error) userStore.logout() + //userStore.init = false + userStore.setinit(true) next({ name: 'Login' }) - return + //return } + }else{ + next() } - next() + // if (!userStore.user) { + // try { + // await userStore.getInfo() + // // 添加动态路由(只添加新的,不影响已有的) + // addDynamicRoutes(userStore.menus) + // next({ ...to, replace: true }) + // return + // } catch (error) { + // userStore.logout() + // next({ name: 'Login' }) + // return + // } + // } + + // if (to.meta.requiresAuth === false) { + // next() + // return + // } + }) export default router diff --git a/src/stores/user.ts b/src/stores/user.ts index 3b28199..17c10b9 100644 --- a/src/stores/user.ts +++ b/src/stores/user.ts @@ -1,6 +1,7 @@ import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { authApi, type LoginParams, type UserInfo, type MenuInfo } from '@/api/auth' +import router, { resetRouter } from '@/router' export const useUserStore = defineStore('user', () => { // 状态 @@ -10,11 +11,21 @@ export const useUserStore = defineStore('user', () => { const permissions = ref([]) const menus = ref([]) + const init = ref(true) + // 计算属性 const isLogin = computed(() => !!token.value) const nickname = computed(() => user.value?.nickname || user.value?.username || '') const avatar = computed(() => user.value?.avatar || '') - + + const postNames = computed(() => user.value?.postNames || '') + + const userid = computed(() => user.value?.id || '') + + function setinit(v:any) { + init.value = v + } + // 登录 async function login(params: LoginParams) { const res = await authApi.login(params) @@ -45,6 +56,11 @@ export const useUserStore = defineStore('user', () => { permissions.value = [] menus.value = [] + init.value = true + + // 重置路由 + resetRouter() + // 只有之前有 token 时才发送 logout 请求 if (hadToken) { try { @@ -54,9 +70,6 @@ export const useUserStore = defineStore('user', () => { } } - // 动态导入 router 避免循环依赖 - const { default: router, resetRouter } = await import('@/router') - resetRouter() router.push('/login') } @@ -82,6 +95,10 @@ export const useUserStore = defineStore('user', () => { isLogin, nickname, avatar, + init, + postNames, + userid, + setinit, login, getInfo, logout, @@ -90,7 +107,7 @@ export const useUserStore = defineStore('user', () => { } }, { persist: { - key: 'mes-user', + key: 'mars-user', paths: ['token'] } })