/** * 动态路由生成模块(Bidding 特定) * * 职责: * 1. 提供 Bidding 特定的布局和组件配置 * 2. 调用 shared 中的通用路由生成方法 * 3. 将生成的路由添加到 Bidding 的 router 实例 */ /// import { generateSimpleRoutes, loadViewsFromStorage, type RouteGeneratorConfig, type GenerateSimpleRoutesOptions } from 'shared/utils/route' import type { TbSysViewDTO } from 'shared/types' import type { RouteRecordRaw } from 'vue-router' import router from './index' import { SidebarLayout, BlankLayout, SubSidebarLayout } from '@/layouts' // Bidding 布局组件映射 const biddingLayoutMap: Record Promise> = { 'SidebarLayout': () => Promise.resolve({ default: SidebarLayout }), 'BlankLayout': () => Promise.resolve({ default: BlankLayout }), 'NavigationLayout': () => Promise.resolve({ default: SidebarLayout }), 'BasicLayout': () => Promise.resolve({ default: SidebarLayout }), 'SubSidebarLayout': () => Promise.resolve({ default: SubSidebarLayout }) } // 视图组件加载器 const VIEW_MODULES = import.meta.glob<{ default: any }>('../views/**/*.vue') /** * 视图组件加载函数 * @param componentPath 组件路径(如 "bidding/Home" 或 "bidding/List") */ function viewLoader(componentPath: string): (() => Promise) | null { // 将后台路径转换为 ../views 格式 let path = componentPath // 移除开头的斜杠(如果有) if (path.startsWith('/')) { path = path.substring(1) } // 补全 .vue 后缀(如果没有) if (!path.endsWith('.vue')) { path += '.vue' } // 转换为 ../views 格式(匹配 import.meta.glob 的 key) const fullPath = `../views/${path}` console.log('[Bidding viewLoader] 尝试加载组件:', componentPath, '→', fullPath) const loader = VIEW_MODULES[fullPath] if (!loader) { console.warn('[Bidding viewLoader] 组件未找到:', fullPath) console.log('[Bidding viewLoader] 可用的组件:', Object.keys(VIEW_MODULES)) return null } return loader as () => Promise } // Bidding 路由生成器配置 const routeConfig: RouteGeneratorConfig = { layoutMap: biddingLayoutMap, viewLoader, notFoundComponent: () => import('vue').then(({ h }) => ({ default: { render() { return h('div', { style: { padding: '20px', textAlign: 'center' } }, '404 - 页面未找到') } } })) } // Bidding 路由生成选项 const routeOptions: GenerateSimpleRoutesOptions = { asRootChildren: false, // 直接作为根级路由,不是某个布局的子路由 iframePlaceholder: () => import('shared/components').then(m => ({ default: m.IframeView })), verbose: true // 启用详细日志 } /** * 添加动态路由(Bidding 特定) * @param views 视图列表(用作菜单) */ export function addDynamicRoutes(views: TbSysViewDTO[]) { if (!views || views.length === 0) { console.warn('[Bidding] addDynamicRoutes: 视图列表为空') return } console.log('[Bidding] addDynamicRoutes: 开始添加动态路由,视图数量:', views.length) console.log('[Bidding] addDynamicRoutes: 路由配置:', routeConfig) console.log('[Bidding] addDynamicRoutes: 路由选项:', routeOptions) try { // 使用 shared 中的通用方法生成路由 const routes = generateSimpleRoutes(views, routeConfig, routeOptions) // 直接将路由添加到根级别(不是作为Root的children) routes.forEach(route => { console.log('[Bidding] addDynamicRoutes: 添加路由', route.path, '使用布局:', route.component?.name || 'unknown') router.addRoute(route) }) } catch (error) { console.error('[Bidding] addDynamicRoutes: 添加路由失败', error) throw error } } /** * 从 LocalStorage 获取菜单并生成路由(Bidding 特定) * * 使用 shared 中的通用 loadViewsFromStorage 方法 * 筛选出 service='bidding' 的视图 */ export function loadRoutesFromStorage(): boolean { try { console.log('[Bidding] loadRoutesFromStorage: 开始加载动态路由') // 使用 shared 中的通用方法加载视图数据 const allViews = loadViewsFromStorage('loginDomain', 'userViews') console.log('[Bidding] loadRoutesFromStorage: 加载的所有视图数量:', allViews?.length || 0) if (allViews) { // 过滤出 bidding 服务的视图 const biddingViews = allViews.filter((view: TbSysViewDTO) => view.service === 'bidding' ) console.log('[Bidding] loadRoutesFromStorage: 过滤后的 bidding 视图:', biddingViews) if (biddingViews.length === 0) { console.warn('[Bidding] loadRoutesFromStorage: 没有找到 bidding 服务的视图') return false } // 使用 Bidding 的 addDynamicRoutes 添加路由 addDynamicRoutes(biddingViews) return true } console.warn('[Bidding] loadRoutesFromStorage: 未能加载视图数据') return false } catch (error) { console.error('[Bidding] loadRoutesFromStorage: 加载路由失败', error) return false } }