feat: 创建声明式路由配置系统'

This commit is contained in:
zdl
2025-10-30 14:37:20 +08:00
parent d5881462d2
commit b29c37149a
3 changed files with 335 additions and 0 deletions

101
src/routes/index.js Normal file
View File

@@ -0,0 +1,101 @@
// src/routes/index.js
// 路由渲染器 - 根据配置自动生成 Routes
import React from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
import { Box, useColorMode } from '@chakra-ui/react';
// 路由配置
import { routeConfig, PROTECTION_MODES, getMainLayoutRoutes, getStandaloneRoutes } from './routeConfig';
// 布局组件 (非懒加载)
import Auth from '../layouts/Auth';
import HomeLayout from '../layouts/Home';
import MainLayout from '../layouts/MainLayout';
// 保护路由组件
import ProtectedRoute from '../components/ProtectedRoute';
import ProtectedRouteRedirect from '../components/ProtectedRouteRedirect';
/**
* 根据保护模式包装组件
*/
function wrapWithProtection(Component, protection) {
if (protection === PROTECTION_MODES.MODAL) {
return (
<ProtectedRoute>
<Component />
</ProtectedRoute>
);
}
if (protection === PROTECTION_MODES.REDIRECT) {
return (
<ProtectedRouteRedirect>
<Component />
</ProtectedRouteRedirect>
);
}
// PUBLIC - 无保护
return <Component />;
}
/**
* 渲染单个路由
*/
function renderRoute(routeItem, index) {
const { path, component, protection } = routeItem;
// 处理特殊组件(非懒加载)
let Component;
if (component === 'Auth') {
Component = Auth;
} else if (component === 'HomeLayout') {
Component = HomeLayout;
} else {
Component = component;
}
return (
<Route
key={`${path}-${index}`}
path={path}
element={wrapWithProtection(Component, protection)}
/>
);
}
/**
* AppRoutes - 应用路由组件
* 替代 App.js 中的 Routes 部分
*/
export function AppRoutes() {
const { colorMode } = useColorMode();
// 分离路由
const mainLayoutRoutes = getMainLayoutRoutes();
const standaloneRoutes = getStandaloneRoutes();
return (
<Box minH="100vh" bg={colorMode === 'dark' ? 'gray.800' : 'white'}>
<Routes>
{/* 带导航栏的主布局 - 所有需要导航栏的页面都在这里 */}
<Route element={<MainLayout />}>
{mainLayoutRoutes.map((route, index) => renderRoute(route, index))}
</Route>
{/* 不使用布局的路由 */}
{standaloneRoutes.map((route, index) => renderRoute(route, index))}
{/* 默认重定向到首页 */}
<Route path="/" element={<Navigate to="/home" replace />} />
{/* 404 页面 */}
<Route path="*" element={<Navigate to="/home" replace />} />
</Routes>
</Box>
);
}
export default AppRoutes;

View File

@@ -0,0 +1,44 @@
// src/routes/lazy-components.js
// 集中管理所有懒加载组件
import React from 'react';
/**
* 懒加载组件配置
* 使用 React.lazy() 实现路由懒加载,大幅减少初始 JS 包大小
*/
export const lazyComponents = {
// 社区/内容模块
Community: React.lazy(() => import('../views/Community')),
ConceptCenter: React.lazy(() => import('../views/Concept')),
StockOverview: React.lazy(() => import('../views/StockOverview')),
LimitAnalyse: React.lazy(() => import('../views/LimitAnalyse')),
// 交易模块
TradingSimulation: React.lazy(() => import('../views/TradingSimulation')),
// 事件模块
EventDetail: React.lazy(() => import('../views/EventDetail')),
// 公司相关模块
CompanyIndex: React.lazy(() => import('../views/Company')),
ForecastReport: React.lazy(() => import('../views/Company/ForecastReport')),
FinancialPanorama: React.lazy(() => import('../views/Company/FinancialPanorama')),
MarketDataView: React.lazy(() => import('../views/Company/MarketDataView')),
};
/**
* 按需导出单个组件(可选)
*/
export const {
Community,
ConceptCenter,
StockOverview,
LimitAnalyse,
TradingSimulation,
EventDetail,
CompanyIndex,
ForecastReport,
FinancialPanorama,
MarketDataView,
} = lazyComponents;

190
src/routes/routeConfig.js Normal file
View File

@@ -0,0 +1,190 @@
// src/routes/routeConfig.js
// 声明式路由配置
import { lazyComponents } from './lazy-components';
/**
* 路由保护模式
* - 'modal': 使用 ProtectedRoute (弹窗模式登录)
* - 'redirect': 使用 ProtectedRouteRedirect (跳转模式登录)
* - 'public': 公开访问,无需登录
*/
export const PROTECTION_MODES = {
MODAL: 'modal',
REDIRECT: 'redirect',
PUBLIC: 'public',
};
/**
* 路由配置
* 每个路由对象包含:
* - path: 路由路径
* - component: 组件(从 lazyComponents 引用)
* - protection: 保护模式 (modal/redirect/public)
* - layout: 布局类型 (main/auth/none)
* - meta: 路由元数据(可选,用于面包屑、标题等)
*/
export const routeConfig = [
// ==================== 首页 ====================
{
path: 'home/*',
component: 'HomeLayout', // 非懒加载,直接在 App.js 导入
protection: PROTECTION_MODES.PUBLIC,
layout: 'main',
meta: {
title: '首页',
description: '价值前沿首页'
}
},
// ==================== 社区/内容模块 ====================
{
path: 'community',
component: lazyComponents.Community,
protection: PROTECTION_MODES.MODAL,
layout: 'main',
meta: {
title: '社区',
description: '投资社区交流'
}
},
{
path: 'concepts',
component: lazyComponents.ConceptCenter,
protection: PROTECTION_MODES.MODAL,
layout: 'main',
meta: {
title: '概念中心',
description: '热门概念追踪'
}
},
{
path: 'stocks',
component: lazyComponents.StockOverview,
protection: PROTECTION_MODES.MODAL,
layout: 'main',
meta: {
title: '股票概览',
description: '全市场股票概览'
}
},
{
path: 'limit-analyse',
component: lazyComponents.LimitAnalyse,
protection: PROTECTION_MODES.MODAL,
layout: 'main',
meta: {
title: '涨停分析',
description: '涨停板数据分析'
}
},
// ==================== 交易模块 ====================
{
path: 'trading-simulation',
component: lazyComponents.TradingSimulation,
protection: PROTECTION_MODES.MODAL,
layout: 'main',
meta: {
title: '模拟交易',
description: '模拟盘交易系统'
}
},
// ==================== 事件模块 ====================
{
path: 'event-detail/:eventId',
component: lazyComponents.EventDetail,
protection: PROTECTION_MODES.REDIRECT,
layout: 'main',
meta: {
title: '事件详情',
description: '事件详细信息'
}
},
// ==================== 公司相关模块 ====================
{
path: 'forecast-report',
component: lazyComponents.ForecastReport,
protection: PROTECTION_MODES.REDIRECT,
layout: 'main',
meta: {
title: '财报预测',
description: '上市公司财报预测'
}
},
{
path: 'Financial',
component: lazyComponents.FinancialPanorama,
protection: PROTECTION_MODES.MODAL,
layout: 'main',
meta: {
title: '财务全景',
description: '公司财务全景分析'
}
},
{
path: 'company',
component: lazyComponents.CompanyIndex,
protection: PROTECTION_MODES.MODAL,
layout: 'main',
meta: {
title: '公司',
description: '上市公司信息'
}
},
{
path: 'company/:code',
component: lazyComponents.CompanyIndex,
protection: PROTECTION_MODES.REDIRECT,
layout: 'main',
meta: {
title: '公司详情',
description: '公司详细信息'
}
},
{
path: 'market-data',
component: lazyComponents.MarketDataView,
protection: PROTECTION_MODES.MODAL,
layout: 'main',
meta: {
title: '市场数据',
description: '实时市场数据'
}
},
// ==================== 认证模块 ====================
{
path: 'auth/*',
component: 'Auth', // 非懒加载,直接在 App.js 导入
protection: PROTECTION_MODES.PUBLIC,
layout: 'none',
meta: {
title: '登录/注册',
description: '用户认证'
}
},
];
/**
* 获取所有需要 MainLayout 的路由
*/
export function getMainLayoutRoutes() {
return routeConfig.filter(route => route.layout === 'main');
}
/**
* 获取不需要布局的路由
*/
export function getStandaloneRoutes() {
return routeConfig.filter(route => route.layout === 'none');
}
/**
* 根据路径查找路由配置
*/
export function findRouteByPath(path) {
return routeConfig.find(route => route.path === path);
}