2025-12-13 14:13:31 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 动态路由生成模块(Bidding 特定)
|
|
|
|
|
|
*
|
|
|
|
|
|
* 职责:
|
|
|
|
|
|
* 1. 提供 Bidding 特定的布局和组件配置
|
|
|
|
|
|
* 2. 调用 shared 中的通用路由生成方法
|
|
|
|
|
|
* 3. 将生成的路由添加到 Bidding 的 router 实例
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/// <reference types="vite/client" />
|
|
|
|
|
|
|
|
|
|
|
|
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'
|
2025-12-17 15:32:58 +08:00
|
|
|
|
import { SidebarLayout, BlankLayout, SubSidebarLayout } from '@/layouts'
|
2025-12-13 14:13:31 +08:00
|
|
|
|
|
|
|
|
|
|
// Bidding 布局组件映射
|
|
|
|
|
|
const biddingLayoutMap: Record<string, () => Promise<any>> = {
|
|
|
|
|
|
'SidebarLayout': () => Promise.resolve({ default: SidebarLayout }),
|
|
|
|
|
|
'BlankLayout': () => Promise.resolve({ default: BlankLayout }),
|
|
|
|
|
|
'NavigationLayout': () => Promise.resolve({ default: SidebarLayout }),
|
2025-12-17 15:32:58 +08:00
|
|
|
|
'BasicLayout': () => Promise.resolve({ default: SidebarLayout }),
|
|
|
|
|
|
'SubSidebarLayout': () => Promise.resolve({ default: SubSidebarLayout })
|
2025-12-13 14:13:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 视图组件加载器
|
|
|
|
|
|
const VIEW_MODULES = import.meta.glob<{ default: any }>('../views/**/*.vue')
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 视图组件加载函数
|
|
|
|
|
|
* @param componentPath 组件路径(如 "bidding/Home" 或 "bidding/List")
|
|
|
|
|
|
*/
|
|
|
|
|
|
function viewLoader(componentPath: string): (() => Promise<any>) | 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<any>
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|