mes-vue/src/router/index.ts
2026-06-11 09:04:16 +08:00

421 lines
13 KiB
TypeScript

import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
import { useUserStore } from '@/stores/user'
//import type { MenuInfo } from '@/api/auth'
// 动态导入所有页面组件
const modules = import.meta.glob('/src/views/**/*.vue')
// iframe 通用组件
const IframeComponent = () => import('@/views/common/iframe.vue')
// 路由配置
const routes: RouteRecordRaw[] = [
{
path: '/login',
name: 'Login',
component: () => import('@/views/login/index.vue'),
meta: { title: '登录', requiresAuth: false }
},
{
path: '/register',
name: 'Register',
component: () => import('@/views/register/index.vue'),
meta: { title: '注册', requiresAuth: false }
},
{
path: '/',
name: 'Layout',
component: () => import('@/layout/index.vue'),
redirect: '/dashboard',
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index.vue'),
meta: { title: '首页', icon: 'HomeOutline' }
},
// 个人中心
{
path: 'profile',
name: 'Profile',
component: () => import('@/views/profile/index.vue'),
meta: { title: '个人中心', icon: 'PersonOutline' }
},
// 系统管理
{
path: 'system/user',
name: 'SystemUser',
component: () => import('@/views/system/user/index.vue'),
meta: { title: '用户管理', icon: 'PersonOutline' }
},
{
path: 'system/role',
name: 'SystemRole',
component: () => import('@/views/system/role/index.vue'),
meta: { title: '角色管理', icon: 'PeopleOutline' }
},
{
path: 'system/menu',
name: 'SystemMenu',
component: () => import('@/views/system/menu/index.vue'),
meta: { title: '菜单管理', icon: 'MenuOutline' }
},
{
path: 'system/dict',
name: 'SystemDict',
component: () => import('@/views/system/dict/index.vue'),
meta: { title: '字典管理', icon: 'BookOutline' }
},
{
path: 'system/config',
name: 'SystemConfig',
component: () => import('@/views/system/config/index.vue'),
meta: { title: '系统配置', icon: 'SettingsSharp' }
},
{
path: 'system/file',
name: 'SystemFile',
component: () => import('@/views/system/file/index.vue'),
meta: { title: '文件列表', icon: 'FolderOutline' }
},
{
path: 'system/file-config',
name: 'SystemFileConfig',
component: () => import('@/views/system/file-config/index.vue'),
meta: { title: '文件配置', icon: 'CloudOutline' }
},
{
path: 'system/customer',
name: 'Customer',
component: () => import('@/views/system/customer/index.vue'),
meta: { title: '客户管理', icon: 'StarOutline' }
},
// 消息中心
{
path: 'message/notice',
name: 'MessageNotice',
component: () => import('@/views/message/notice/index.vue'),
meta: { title: '系统通知', icon: 'NotificationsOutline' }
},
{
path: 'message/chat',
name: 'MessageChat',
component: () => import('@/views/message/chat/index.vue'),
meta: { title: '即时聊天', icon: 'ChatbubbleOutline' }
},
// 组织管理
{
path: 'org/dept',
name: 'OrgDept',
component: () => import('@/views/org/dept/index.vue'),
meta: { title: '部门管理', icon: 'GitNetworkOutline' }
},
{
path: 'org/post',
name: 'OrgPost',
component: () => import('@/views/org/post/index.vue'),
meta: { title: '岗位管理', icon: 'IdCardOutline' }
},
// 项目管理
{
path: 'biz/orderProject',
name: 'OrderProject',
component: () => import('@/views/biz/orderProject/index.vue'),
meta: { title: '项目管理', icon: 'PersonOutline' }
},
{
path: 'biz/orderProject/gantt',
name: 'OrderProjectGantt',
component: () => import('@/views/biz/orderProject/components/GanttSchedule.vue'),
meta: { title: '甘特图排产', icon: 'CalendarOutline', activeMenu: '/biz/orderProject' }
},
//运营管理
{
path: 'biz/orderItem',
name: 'orderItem',
component: () => import('@/views/biz/orderItem/index.vue'),
meta: { title: '生产订单', icon: 'ListOutline' }
},
{
path: 'biz/orderProcessPlan',
name: 'orderProcessPlan',
component: () => import('@/views/biz/orderProcessPlan/index.vue'),
meta: { title: '工序计划', icon: 'ListOutline' }
},
{
path: 'biz/user',
name: 'user',
component: () => import('@/views/biz/user/index.vue'),
meta: { title: '客户管理', icon: 'ListOutline' }
},
{
path: 'biz/order',
name: 'order',
component: () => import('@/views/biz/order/index.vue'),
meta: { title: '订单管理', icon: 'ListOutline' }
},
{
path: 'biz/code',
name: 'code',
component: () => import('@/views/biz/code/index.vue'),
meta: { title: '邀请码配置', icon: 'SettingsSharp' }
},
// 系统日志
{
path: 'log/operlog',
name: 'LogOper',
component: () => import('@/views/log/operlog/index.vue'),
meta: { title: '操作日志', icon: 'ListOutline' }
},
{
path: 'log/loginlog',
name: 'LogLogin',
component: () => import('@/views/log/loginlog/index.vue'),
meta: { title: '登录日志', icon: 'LogInOutline' }
},
// 系统监控
{
path: 'monitor/online',
name: 'MonitorOnline',
component: () => import('@/views/monitor/online/index.vue'),
meta: { title: '在线用户', icon: 'PeopleCircleOutline' }
},
{
path: 'monitor/job',
name: 'MonitorJob',
component: () => import('@/views/monitor/job/index.vue'),
meta: { title: '定时任务', icon: 'TimerOutline' }
},
{
path: 'monitor/cache',
name: 'MonitorCache',
component: () => import('@/views/monitor/cache/index.vue'),
meta: { title: '缓存监控', icon: 'ServerOutline' }
},
{
path: 'monitor/api-access',
name: 'MonitorApiAccess',
component: () => import('@/views/monitor/api-access/index.vue'),
meta: { title: 'API访问统计', icon: 'StatsChartOutline' }
},
{
path: 'monitor/server',
name: 'MonitorServer',
component: () => import('@/views/monitor/server/index.vue'),
meta: { title: '服务监控', icon: 'DesktopOutline' }
},
{
path: 'monitor/server-manager',
name: 'ServerManager',
component: () => import('@/views/monitor/server-manager/index.vue'),
meta: { title: '服务器管理', icon: 'ServerOutline' }
},
{
path: 'monitor/druid',
name: 'MonitorDruid',
component: IframeComponent,
meta: { title: 'Druid监控', icon: 'PieChartOutline', frameSrc: '/druid/index.html' }
},
{
path: 'test/test',
name: 'Test',
component: () => import('@/views/test/test/index.vue'),
meta: { title: '测试菜单', icon: 'StarOutline' }
},
{
path: 'biz/submitLog',
name: 'submitLog',
component: () => import('@/views/biz/submitLog/index.vue'),
meta: { title: '派工工单汇报记录', icon: 'ListOutline' }
},
{
// 开发工具
path: 'tool/gen',
name: 'ToolGen',
component: () => import('@/views/tool/gen/index.vue'),
meta: { title: '代码生成', icon: 'CodeSlashOutline' }
},
// 页签刷新中转路由
{
path: 'redirect/:path(.*)',
name: 'Redirect',
component: () => import('@/views/redirect/index.vue'),
meta: { title: '重定向', requiresAuth: true }
}
]
},
// {
// path: '/:pathMatch(.*)',
// name: 'NotFound',
// component: () => import('@/views/error/404.vue'),
// meta: { title: '404', requiresAuth: false }
// }
{
path: '/:pathMatch(.*)',
component: () => import('@/views/error/404.vue'),
// meta: { title: '404', requiresAuth: false }
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
// 已添加的动态路由
const addedRouteNames = new Set<string>()
/**
* 根据菜单动态添加新路由(只添加静态路由中没有的)
*/
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
const pathExists = existingRoutes.some(r => r.path === '/' + menuPath || r.path === menuPath)
if (pathExists) {
// console.log(`[动态路由] 跳过(已存在): ${menuPath}`)
continue
}
if (addedRouteNames.has(routeName)) {
//console.log(`[动态路由] 跳过(已添加): ${menuPath}`)
continue
}
// 判断是否是外链菜单
if (menu.isFrame === 1 && menu.component) {
// 外链菜单,使用 iframe 组件
router.addRoute('Layout', {
path: menuPath,
name: routeName,
component: IframeComponent,
meta: {
title: menu.name,
icon: menu.icon,
permission: menu.permission,
frameSrc: menu.component // 外链地址存在 component 字段
}
})
addedRouteNames.add(routeName)
console.log(`[动态路由] ✓ 添加外链成功: ${menuPath} -> ${menu.component}`)
} else if (menu.component) {
// 普通菜单,加载组件
const componentName = menu.component.startsWith('/') ? menu.component.slice(1) : menu.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,
name: routeName,
component: component,
meta: {
title: menu.name,
icon: menu.icon,
permission: menu.permission
}
})
addedRouteNames.add(routeName)
//console.log(`[动态路由] ✓ 添加成功: ${menuPath}`)
} else {
//console.warn(`[动态路由] ✗ 组件不存在: ${componentPath}`)
}
}
}
// 递归处理子菜单
if (menu.children && menu.children.length > 0) {
addRoutes(menu.children)
}
}
}
addRoutes(menus)
//console.log('[动态路由] 当前所有路由:', router.getRoutes().map(r => r.path))
}
/**
* 重置动态路由
*/
export function resetRouter() {
addedRouteNames.forEach(name => {
if (router.hasRoute(name)) {
router.removeRoute(name)
}
})
addedRouteNames.clear()
}
// 路由守卫
router.beforeEach(async (to, _from, next) => {
console.log('路由测试');
const userStore = useUserStore()
//document.title = `${to.meta.title || ''} - CSY Admin`
if (to.meta.requiresAuth === false) {
next()
return
}
if (!userStore.token) {
next({ name: 'Login', query: { redirect: to.fullPath } })
return
}
if (userStore.init) {
try {
await userStore.getInfo()
// 添加动态路由(只添加新的,不影响已有的)
addDynamicRoutes(userStore.menus)
userStore.setinit(false)
// userStore.init = false
next({ ...to, replace: true })
//return
} catch (error) {
userStore.logout()
//userStore.init = false
userStore.setinit(true)
next({ name: 'Login' })
//return
}
}else{
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