按需加载路由

This commit is contained in:
mmc
2026-04-24 16:18:24 +08:00
parent 218602870a
commit f5f27b7668
5 changed files with 569 additions and 489 deletions

View File

@@ -1,86 +1,110 @@
import React from 'react';
import { createBrowserRouter } from 'react-router-dom';
import Layout from '../components/Layout';
import ProtectedRoute from '../components/ProtectedRoute';
import Login from '../pages/Login';
import Home from '../pages/Home';
import Devices from '../pages/Devices';
import VideoControl from '../pages/Video';
import Alerts from '../pages/Alerts';
import Downloads from '../pages/Downloads';
import Roles from '../pages/Roles';
import Users from '../pages/Users';
import SerialNumGenerate from '../pages/SerialNumGenerate';
import MenuList from '../pages/MenuList';
import Organization from '../pages/Organization';
import StationManage from '../pages/StationManage';
import React, { lazy, Suspense } from 'react';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import type { RouteObject } from 'react-router-dom';
export const router = createBrowserRouter([
{
path: '/login',
element: <Login />,
},
{
element: <ProtectedRoute />,
children: [
{
path: '/',
element: <Layout />,
children: [
{
index: true,
element: <Home />,
},
{
path: 'devices',
element: <Devices />,
},
{
path: 'video',
element: <VideoControl />,
},
{
path: 'alerts',
element: <Alerts />,
},
{
path: 'downloads',
element: <Downloads />,
},
{
path: 'roles',
element: <Roles />,
},
{
path: 'users',
element: <Users />,
},
{
path: 'serialNumGenerate',
element: <SerialNumGenerate />,
},
{
path: 'menuList',
element: <MenuList />,
},
{
path: 'menuList',
element: <MenuList />,
},
{
path: 'organization',
element: <Organization />,
},
{
path: 'station',
element: <StationManage />,
},
{
path: '*',
element: <div className="p-10 text-center font-bold text-gray-400">模块开发中...</div>,
},
],
},
],
},
]);
// ============================================================
// 路由懒加载 & 分层架构
// 所有业务 Page 均通过 React.lazy 实现按需加载,减小首屏 JS 体积
// ============================================================
// 布局组件
const Layout = lazy(() => import('../components/Layout'));
const ProtectedRoute = lazy(() => import('../components/ProtectedRoute'));
const Login = lazy(() => import('../pages/Login'));
// 业务页面(按需加载)
const Home = lazy(() => import('../pages/Home'));
const Devices = lazy(() => import('../pages/Devices'));
const Video = lazy(() => import('../pages/Video'));
const Alerts = lazy(() => import('../pages/Alerts'));
const Downloads = lazy(() => import('../pages/Downloads'));
const Roles = lazy(() => import('../pages/Roles'));
const Users = lazy(() => import('../pages/Users'));
const MenuList = lazy(() => import('../pages/MenuList'));
const Organization = lazy(() => import('../pages/Organization'));
const StationManage = lazy(() => import('../pages/StationManage'));
const SerialNumGenerate = lazy(() => import('../pages/SerialNumGenerate'));
// 公共加载骨架(路由切换时闪烁优化)
function PageFallback() {
return (
<div className="flex items-center justify-center h-full min-h-[200px]">
<div className="w-8 h-8 border-4 border-blue-500 border-t-transparent rounded-full animate-spin" />
</div>
);
}
// ============================================================
// 路由元信息表(权限 · 标题 · 图标)
// ============================================================
export const routeMeta: Record<string, {
title: string;
roles: string[];
requiresAuth: boolean;
}> = {
'/': { title: '概览控制台', roles: ['admin', 'operator', 'viewer'], requiresAuth: true },
'/devices': { title: '设备管理', roles: ['admin', 'operator'], requiresAuth: true },
'/video': { title: '在线视频', roles: ['admin', 'operator', 'viewer'], requiresAuth: true },
'/alerts': { title: '警报中心', roles: ['admin', 'operator'], requiresAuth: true },
'/downloads': { title: '视频下载', roles: ['admin', 'operator'], requiresAuth: true },
'/serialNumGenerate': { title: '序列号生成', roles: ['admin'], requiresAuth: true },
'/users': { title: '用户管理', roles: ['admin'], requiresAuth: true },
'/roles': { title: '角色管理', roles: ['admin'], requiresAuth: true },
'/menuList': { title: '菜单管理', roles: ['admin'], requiresAuth: true },
'/organization': { title: '组织管理', roles: ['admin'], requiresAuth: true },
'/station': { title: '场站管理', roles: ['admin'], requiresAuth: true },
};
// ============================================================
// 路由表(完整配置,支持权限过滤)
// ============================================================
const routes: RouteObject[] = [
{
path: '/login',
element: (
<Suspense fallback={<PageFallback />}>
<Login />
</Suspense>
),
},
{
element: (
<Suspense fallback={<PageFallback />}>
<ProtectedRoute />
</Suspense>
),
children: [
{
element: (
<Suspense fallback={<PageFallback />}>
<Layout />
</Suspense>
),
children: [
{ index: true, element: <Home /> },
{ path: 'devices', element: <Devices /> },
{ path: 'video', element: <Video /> },
{ path: 'alerts', element: <Alerts /> },
{ path: 'downloads', element: <Downloads /> },
{ path: 'roles', element: <Roles /> },
{ path: 'users', element: <Users /> },
{ path: 'serialNumGenerate', element: <SerialNumGenerate /> },
{ path: 'menuList', element: <MenuList /> },
{ path: 'organization', element: <Organization /> },
{ path: 'station', element: <StationManage /> },
{
path: '*',
element: (
<div className="flex flex-col items-center justify-center h-full gap-4 text-gray-400 select-none">
<span className="text-6xl opacity-20">🚧</span>
<p className="text-lg font-medium">模块开发中</p>
</div>
),
},
],
},
],
},
];
export const router = createBrowserRouter(routes);