You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
haoliang-net/frontend/src/router/index.ts

140 lines
6.0 KiB
TypeScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
// 部署在/admin/子路径下时base必须是/admin/
// 本地开发(npm run dev)时base是/
const routerBase = import.meta.env.BASE_URL
// 管理后台Layout
const AdminLayout = () => import('@/layouts/AdminLayout.vue')
// 大屏Layout
const ScreenLayout = () => import('@/layouts/ScreenLayout.vue')
// 页面组件
const LoginPage = () => import('@/views/login/LoginPage.vue')
const DashboardPage = () => import('@/views/dashboard/DashboardPage.vue')
const MachineListPage = () => import('@/views/machine/MachineListPage.vue')
const MachineDetailPage = () => import('@/views/machine/MachineDetailPage.vue')
const BrandListPage = () => import('@/views/brand/BrandListPage.vue')
const BrandEditPage = () => import('@/views/brand/BrandEditPage.vue')
const CollectAddressListPage = () => import('@/views/collect-address/CollectAddressListPage.vue')
const CollectAddressDetailPage = () => import('@/views/collect-address/CollectAddressDetailPage.vue')
const WorkerListPage = () => import('@/views/worker/WorkerListPage.vue')
const WorkerDetailPage = () => import('@/views/worker/WorkerDetailPage.vue')
const ProductionPage = () => import('@/views/production/ProductionPage.vue')
const AlertPage = () => import('@/views/alert/AlertPage.vue')
const SettingsPage = () => import('@/views/settings/SettingsPage.vue')
const LogPage = () => import('@/views/log/LogPage.vue')
const ScreenConfigPage = () => import('@/views/screen-config/ScreenConfigPage.vue')
const ScreenPage = () => import('@/views/screen/ScreenPage.vue')
const CollectLogPage = () => import('@/views/collect-log/CollectLogPage.vue')
const SimulatorPage = () => import('@/views/simulator/SimulatorPage.vue')
const SimulatorDetailPage = () => import('@/views/simulator/SimulatorDetailPage.vue')
// 正常路由
const normalRoutes: RouteRecordRaw[] = [
{ path: '/login', name: 'Login', component: LoginPage, meta: { title: '登录' } },
{
path: '/',
component: AdminLayout,
redirect: '/dashboard',
children: [
{ path: 'dashboard', name: 'Dashboard', component: DashboardPage, meta: { title: '仪表盘' } },
{ path: 'machine', name: 'MachineList', component: MachineListPage, meta: { title: '设备管理' } },
{ path: 'machine/:id', name: 'MachineDetail', component: MachineDetailPage, meta: { title: '设备详情' } },
{ path: 'brand', name: 'BrandList', component: BrandListPage, meta: { title: '品牌模板' } },
{ path: 'brand/create', name: 'BrandCreate', component: BrandEditPage, meta: { title: '新增品牌' } },
{ path: 'brand/:id/edit', name: 'BrandEdit', component: BrandEditPage, meta: { title: '编辑品牌' } },
{ path: 'collect-address', name: 'CollectAddressList', component: CollectAddressListPage, meta: { title: '采集地址' } },
{ path: 'collect-address/:id', name: 'CollectAddressDetail', component: CollectAddressDetailPage, meta: { title: '采集地址详情' } },
{ path: 'collect-log', name: 'CollectLog', component: CollectLogPage, meta: { title: '采集日志' } },
{ path: 'worker', name: 'WorkerList', component: WorkerListPage, meta: { title: '员工管理' } },
{ path: 'worker/:id', name: 'WorkerDetail', component: WorkerDetailPage, meta: { title: '员工详情' } },
{ path: 'production', name: 'Production', component: ProductionPage, meta: { title: '产量报表' } },
{ path: 'alert', name: 'Alert', component: AlertPage, meta: { title: '告警中心' } },
{ path: 'settings', name: 'Settings', component: SettingsPage, meta: { title: '系统设置' } },
{ path: 'log', name: 'Log', component: LogPage, meta: { title: '操作日志' } },
{ path: 'screen-config', name: 'ScreenConfig', component: ScreenConfigPage, meta: { title: '大屏配置' } },
{ path: 'simulator', name: 'Simulator', component: SimulatorPage, meta: { title: '模拟采集' } },
{ path: 'simulator/:port', name: 'SimulatorDetail', component: SimulatorDetailPage, meta: { title: '模拟详情' } },
],
},
{
path: '/screen',
component: ScreenLayout,
children: [
{ path: '', name: 'Screen', component: ScreenPage, meta: { title: '大屏看板' } },
],
},
]
// Mock路由复制正常路由添加/mock前缀
function generateMockRoutes(routes: RouteRecordRaw[]): RouteRecordRaw[] {
const mockRoutes: RouteRecordRaw[] = []
for (const route of routes) {
if (route.path === '/login') {
mockRoutes.push({ path: '/mock/login', name: 'MockLogin', component: route.component!, meta: { ...route.meta, mock: true } })
} else if (route.path === '/') {
mockRoutes.push({
path: '/mock',
component: route.component,
redirect: '/mock/dashboard',
children: (route.children || []).map(child => ({
...child,
path: child.path,
name: `Mock${String(child.name)}`,
meta: { ...child.meta, mock: true },
})),
})
} else if (route.path === '/screen') {
mockRoutes.push({
path: '/mock/screen',
component: route.component,
children: (route.children || []).map(child => ({
...child,
path: child.path,
name: `Mock${String(child.name)}`,
meta: { ...child.meta, mock: true },
})),
})
}
}
return mockRoutes
}
const router = createRouter({
history: createWebHistory(routerBase),
routes: [...normalRoutes, ...generateMockRoutes(normalRoutes)],
})
// 路由守卫
router.beforeEach((to, _from, next) => {
const token = localStorage.getItem('token')
const isMock = to.path.startsWith('/mock')
// 大屏免认证
if (to.path === '/screen' || to.path === '/mock/screen') {
next()
return
}
// 访问登录页:已登录则跳转首页
if (to.path === '/login' || to.path === '/mock/login') {
if (token) {
next(isMock ? '/mock/dashboard' : '/dashboard')
} else {
next()
}
return
}
// 访问管理后台:未登录则跳转登录
if (!token) {
next(isMock ? '/mock/login' : '/login')
return
}
next()
})
export default router