154 lines
4.5 KiB
TypeScript
154 lines
4.5 KiB
TypeScript
/**
|
||
* 动态路由管理工具
|
||
* 用于动态注册和移除工具路由
|
||
*/
|
||
|
||
import type { Router, RouteRecordRaw } from 'vue-router'
|
||
import type { Tool } from '../stores/tools'
|
||
|
||
/**
|
||
* 动态注册工具路由
|
||
* @param router Vue Router 实例
|
||
* @param tool 工具定义
|
||
* @param componentPath 组件路径(相对于 src/views)
|
||
*/
|
||
export function registerToolRoute(
|
||
router: Router,
|
||
tool: Tool,
|
||
componentPath?: string
|
||
): boolean {
|
||
if (tool.type !== 'route' || !tool.routeName) {
|
||
return false
|
||
}
|
||
|
||
// 检查路由是否已存在
|
||
if (router.hasRoute(tool.routeName)) {
|
||
console.warn(`Route ${tool.routeName} already exists, skipping registration`)
|
||
return false
|
||
}
|
||
|
||
// 确定组件路径
|
||
// 1. 如果提供了 componentPath,使用它
|
||
// 2. 如果工具有 componentPath 属性,使用它
|
||
// 3. 默认使用 tools/{routeName}.vue
|
||
const finalComponentPath =
|
||
componentPath ||
|
||
tool.componentPath ||
|
||
`../../views/tools/${tool.routeName}.vue`
|
||
|
||
// 构建路由路径
|
||
// 默认使用 tools/{id},但可以通过 tool.routePath 自定义
|
||
const routePath = tool.routePath || `tools/${tool.id}`
|
||
|
||
// 创建路由配置,添加组件加载错误处理
|
||
const route: RouteRecordRaw = {
|
||
path: routePath,
|
||
name: tool.routeName,
|
||
component: () => import(finalComponentPath).catch((error) => {
|
||
console.error(`Failed to load tool component: ${finalComponentPath}`, error)
|
||
// 返回一个简单的错误组件
|
||
return {
|
||
name: 'ToolComponentError',
|
||
template: '<div style="padding: 20px; text-align: center;"><h3>Component Not Found</h3><p>Failed to load component</p></div>'
|
||
}
|
||
}),
|
||
meta: {
|
||
requiresAuth: true,
|
||
toolId: tool.id,
|
||
toolName: tool.name
|
||
}
|
||
}
|
||
|
||
try {
|
||
// 将路由添加到 AppLayout 的 children 下
|
||
// AppLayout 路由应该在应用启动时已存在
|
||
const parentRouteName = router.hasRoute('AppLayout') ? 'AppLayout' : null
|
||
if (parentRouteName) {
|
||
router.addRoute(parentRouteName, route)
|
||
} else {
|
||
// 如果 AppLayout 不存在,直接添加到根路由(不应该发生,但作为降级方案)
|
||
console.warn('AppLayout route not found, adding tool route to root')
|
||
router.addRoute(route)
|
||
}
|
||
console.log(`Tool route registered: ${tool.routeName} -> ${routePath}`)
|
||
return true
|
||
} catch (error) {
|
||
console.error(`Failed to register tool route ${tool.routeName}:`, error)
|
||
return false
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 移除工具路由
|
||
* @param router Vue Router 实例
|
||
* @param routeName 路由名称
|
||
*/
|
||
export function unregisterToolRoute(router: Router, routeName: string): boolean {
|
||
if (!router.hasRoute(routeName)) {
|
||
return false
|
||
}
|
||
|
||
try {
|
||
router.removeRoute(routeName)
|
||
console.log(`Tool route removed: ${routeName}`)
|
||
return true
|
||
} catch (error) {
|
||
console.error(`Failed to remove tool route ${routeName}:`, error)
|
||
return false
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 注册所有用户工具的路由
|
||
* @param router Vue Router 实例
|
||
* @param tools 工具列表
|
||
*/
|
||
export function registerAllToolRoutes(router: Router, tools: Tool[]): void {
|
||
const routeTools = tools.filter(t => t.type === 'route' && t.routeName && !t.isDefault)
|
||
|
||
routeTools.forEach(tool => {
|
||
registerToolRoute(router, tool)
|
||
})
|
||
|
||
console.log(`Registered ${routeTools.length} tool routes`)
|
||
}
|
||
|
||
/**
|
||
* 同步工具路由(移除不存在的工具路由,添加新的工具路由)
|
||
* @param router Vue Router 实例
|
||
* @param currentTools 当前工具列表
|
||
*/
|
||
export function syncToolRoutes(router: Router, currentTools: Tool[]): void {
|
||
// 获取所有已注册的路由
|
||
const registeredRoutes = router.getRoutes()
|
||
|
||
// 找出所有工具路由(通过 meta.toolId 识别)
|
||
const toolRoutes = registeredRoutes.filter((route) =>
|
||
route.meta?.toolId && !route.meta?.isDefault
|
||
)
|
||
|
||
// 当前应该存在的工具路由名称
|
||
const currentRouteNames = new Set(
|
||
currentTools
|
||
.filter(t => t.type === 'route' && t.routeName && !t.isDefault)
|
||
.map(t => t.routeName!)
|
||
)
|
||
|
||
// 移除不再存在的工具路由
|
||
toolRoutes.forEach((route) => {
|
||
if (route.name && typeof route.name === 'string' && !currentRouteNames.has(route.name)) {
|
||
unregisterToolRoute(router, route.name)
|
||
}
|
||
})
|
||
|
||
// 添加新的工具路由
|
||
currentTools
|
||
.filter(t => t.type === 'route' && t.routeName && !t.isDefault)
|
||
.forEach(tool => {
|
||
if (tool.routeName && !router.hasRoute(tool.routeName)) {
|
||
registerToolRoute(router, tool)
|
||
}
|
||
})
|
||
}
|
||
|