Files
urbanLifeline/urbanLifelineWeb/packages/platform/src/router/index.ts
2026-01-08 16:40:02 +08:00

175 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import { loadRoutesFromStorage } from './dynamicRoute'
// 同步检查 token用于非异步场景
function hasTokenSync(): boolean {
try {
const token = localStorage.getItem('token')
return !!token
} catch {
return false
}
}
// platform应用的动态路由会根据layout字段自动添加不需要预定义Root布局
// 参考 workcase 的方式:不预定义 404 路由,避免过早匹配
const routes: RouteRecordRaw[] = [
{
path: '/login',
name: 'Login',
component: () => import('@/views/public/Login/Login.vue'),
meta: {
title: '登录',
requiresAuth: false // 不需要登录
}
}
]
const router = createRouter({
history: createWebHistory('/platform/'),
routes
})
// 标记动态路由是否已加载
let dynamicRoutesLoaded = false
// 路由守卫
router.beforeEach(async (to, from, next) => {
console.log('[Platform Router] 路由守卫触发:', {
to: to.path,
from: from.path,
dynamicRoutesLoaded
})
// 设置页面标题
if (to.meta.title) {
document.title = `${to.meta.title} - 泰豪电源 AI 数智化平台`
}
// 检查是否需要登录(使用同步方法,避免阻塞)
const requiresAuth = to.meta.requiresAuth !== false // 默认需要登录
const hasToken = hasTokenSync()
if (requiresAuth && !hasToken) {
// 需要登录但未登录,跳转到登录页
next({
path: '/login',
query: { redirect: to.fullPath } // 保存原始路径
})
return
}
if (to.path === '/login' && hasToken) {
// 已登录但访问登录页,跳转到首页
next('/')
return
}
// 如果已登录且动态路由未加载,先加载动态路由
if (hasToken && !dynamicRoutesLoaded) {
console.log('[Platform Router] 开始加载动态路由...')
dynamicRoutesLoaded = true // 先设置标志,避免重复加载
try {
const loaded = await loadRoutesFromStorage()
console.log('[Platform Router] 动态路由加载结果:', loaded)
if (loaded) {
console.log('[Platform Router] 动态路由加载成功')
console.log('[Platform Router] 所有路由:', router.getRoutes().map(r => r.path))
if (to.path === '/') {
// 访问根路径,重定向到第一个可用路由
const firstRoute = getFirstAvailableRoute()
if (firstRoute && firstRoute !== '/') {
console.log('[Platform Router] 根路径重定向到:', firstRoute)
next({ path: firstRoute, replace: true })
return
}
} else {
// 动态路由加载成功,重新导航以匹配新添加的路由
console.log('[Platform Router] 动态路由加载成功,重新导航到:', to.path)
next({ ...to, replace: true })
return
}
} else {
console.warn('[Platform Router] 动态路由加载失败')
dynamicRoutesLoaded = false // 重置标志,允许下次重试
}
} catch (error) {
console.error('[Platform Router] 加载动态路由失败:', error)
dynamicRoutesLoaded = false // 重置标志,允许下次重试
}
}
// 如果已登录且访问根路径,但动态路由已加载,重定向到第一个可用路由
if (hasToken && to.path === '/' && dynamicRoutesLoaded) {
const firstRoute = getFirstAvailableRoute()
if (firstRoute && firstRoute !== '/') {
console.log('[Platform Router] 已登录访问根路径,重定向到:', firstRoute)
next({ path: firstRoute, replace: true })
return
}
}
console.log('[Platform Router] 继续正常导航')
next()
})
/**
* 获取第一个可用的路由路径
*/
function getFirstAvailableRoute(): string | null {
try {
console.log('[Platform Router] 开始获取第一个可用路由...')
const loginDomainStr = localStorage.getItem('loginDomain')
if (!loginDomainStr) {
console.warn('[Platform Router] localStorage 中没有 loginDomain')
return null
}
const loginDomain = JSON.parse(loginDomainStr)
const userViews = loginDomain.userViews || []
console.log('[Platform Router] 所有用户视图:', userViews.length)
// 过滤出 platform 服务的非 admin 视图
// 注意:不限制 type因为首页路由可能是 type=3路由类型而不是 type=1菜单类型
const platformViews = userViews.filter((view: any) =>
view.service === 'platform' &&
!view.url?.startsWith('/admin') &&
view.url // 必须有 url 字段
)
console.log('[Platform Router] Platform 服务视图:', platformViews)
if (platformViews.length === 0) {
console.warn('[Platform Router] 没有找到 platform 服务的视图')
return null
}
// 按 orderNum 排序
platformViews.sort((a: any, b: any) => (a.orderNum || 0) - (b.orderNum || 0))
const firstRoute = platformViews[0].url
console.log('[Platform Router] 第一个路由:', firstRoute, '视图:', platformViews[0].name)
return firstRoute
} catch (error) {
console.error('[Platform Router] 获取首页路由失败:', error)
return null
}
}
// 导出动态路由生成函数
export { addDynamicRoutes, loadRoutesFromStorage } from './dynamicRoute'
// 重置动态路由加载状态(用于登录后重新加载)
export function resetDynamicRoutes() {
dynamicRoutesLoaded = false
}
export default router