diff --git a/src/App.js b/src/App.js index 722443e7..32c87d9f 100755 --- a/src/App.js +++ b/src/App.js @@ -26,6 +26,7 @@ import PageLoader from "components/Loading/PageLoader"; import Admin from "layouts/Admin"; import Auth from "layouts/Auth"; import HomeLayout from "layouts/Home"; +import MainLayout from "layouts/MainLayout"; // ⚡ 使用 React.lazy() 实现路由懒加载 // 首屏不需要的组件按需加载,大幅减少初始 JS 包大小 @@ -48,95 +49,113 @@ import { AuthModalProvider } from "contexts/AuthModalContext"; import ProtectedRoute from "components/ProtectedRoute"; import ErrorBoundary from "components/ErrorBoundary"; import AuthModalManager from "components/Auth/AuthModalManager"; +import ScrollToTop from "components/ScrollToTop"; function AppContent() { const { colorMode } = useColorMode(); return ( - {/* ⚡ Suspense 边界:懒加载组件加载时显示 Loading */} - }> - - {/* 首页路由 */} - } /> + {/* 路由切换时自动滚动到顶部 */} + + + {/* 带导航栏的主布局 - 所有需要导航栏的页面都在这里 */} + {/* MainLayout 内部有 Suspense,确保导航栏始终可见 */} + }> + {/* 首页路由 */} + } /> - {/* Community页面路由 - 需要登录 */} - - - - } - /> - } /> - } /> - } /> - } /> - } /> - {/* 概念中心路由 - 需要登录 */} - - - - } - /> - - - - } - /> - {/* 股票概览页面路由 - 需要登录 */} - - - - } - /> - - - - } - /> - {/* Limit Analyse页面路由 - 需要登录 */} - - - - } - /> - {/* 事件详情独立页面路由(不经 Admin 布局) */} - } /> + {/* Community页面路由 - 需要登录 */} + + + + } + /> - {/* 模拟盘交易系统路由 - 无需登录 */} - } - /> + {/* 概念中心路由 - 需要登录 */} + + + + } + /> + + + + } + /> - {/* 管理后台路由 - 需要登录 */} + {/* 股票概览页面路由 - 需要登录 */} + + + + } + /> + + + + } + /> + + {/* Limit Analyse页面路由 - 需要登录 */} + + + + } + /> + + {/* 模拟盘交易系统路由 - 需要登录 */} + + + + } + /> + + {/* 事件详情独立页面路由 (不经 Admin 布局) */} + } /> + + {/* 公司相关页面 */} + } /> + } /> + } /> + } /> + } /> + + + {/* 管理后台路由 - 需要登录,不使用 MainLayout */} + {/* 这些路由有自己的加载状态处理 */} - - + }> + + + + } /> - {/* 认证页面路由 */} + {/* 认证页面路由 - 不使用 MainLayout */} } /> {/* 默认重定向到首页 */} @@ -145,7 +164,6 @@ function AppContent() { {/* 404 页面 */} } /> - ); } diff --git a/src/components/Auth/AuthFormContent.js b/src/components/Auth/AuthFormContent.js index 84ea9987..ba2efd7e 100644 --- a/src/components/Auth/AuthFormContent.js +++ b/src/components/Auth/AuthFormContent.js @@ -34,6 +34,7 @@ import { authService } from "../../services/authService"; import AuthHeader from './AuthHeader'; import VerificationCodeInput from './VerificationCodeInput'; import WechatRegister from './WechatRegister'; +import { setCurrentUser } from '../../mocks/data/users'; // 统一配置对象 const AUTH_CONFIG = { @@ -261,6 +262,12 @@ export default function AuthFormContent() { } if (response.ok && data.success) { + // ⚡ Mock 模式:先在前端侧写入 localStorage,确保时序正确 + if (process.env.REACT_APP_ENABLE_MOCK === 'true' && data.user) { + setCurrentUser(data.user); + console.log('[Auth] 前端侧设置当前用户(Mock模式):', data.user); + } + // 更新session await checkSession(); diff --git a/src/components/Navbars/HomeNavbar.js b/src/components/Navbars/HomeNavbar.js index af7c109e..ed545b15 100644 --- a/src/components/Navbars/HomeNavbar.js +++ b/src/components/Navbars/HomeNavbar.js @@ -76,6 +76,14 @@ const SecondaryNav = () => { { path: '/stocks', label: '个股中心', badges: [{ text: 'HOT', colorScheme: 'green' }] }, { path: '/trading-simulation', label: '模拟盘', badges: [{ text: 'NEW', colorScheme: 'red' }] } ] + }, + '/trading-simulation': { + title: '行情复盘', + items: [ + { path: '/limit-analyse', label: '涨停分析', badges: [{ text: 'FREE', colorScheme: 'blue' }] }, + { path: '/stocks', label: '个股中心', badges: [{ text: 'HOT', colorScheme: 'green' }] }, + { path: '/trading-simulation', label: '模拟盘', badges: [{ text: 'NEW', colorScheme: 'red' }] } + ] } }; @@ -181,9 +189,9 @@ const NavItems = ({ isAuthenticated, user }) => { const location = useLocation(); // 辅助函数:判断导航项是否激活 - const isActive = (paths) => { + const isActive = useCallback((paths) => { return paths.some(path => location.pathname.includes(path)); - }; + }, [location.pathname]); if (isAuthenticated && user) { return ( @@ -203,45 +211,35 @@ const NavItems = ({ isAuthenticated, user }) => { 高频跟踪 - - navigate('/community')} - py={2} - px={3} - borderRadius="md" - _hover={{ bg: 'gray.100' }} - cursor="pointer" - bg={location.pathname.includes('/community') ? 'blue.50' : 'transparent'} - borderLeft={location.pathname.includes('/community') ? '3px solid' : 'none'} - borderColor="blue.600" - fontWeight={location.pathname.includes('/community') ? 'bold' : 'normal'} - > - - 新闻催化分析 - - HOT - NEW - - - - navigate('/concepts')} - py={2} - px={3} - borderRadius="md" - _hover={{ bg: 'gray.100' }} - cursor="pointer" - bg={location.pathname.includes('/concepts') ? 'blue.50' : 'transparent'} - borderLeft={location.pathname.includes('/concepts') ? '3px solid' : 'none'} - borderColor="blue.600" - fontWeight={location.pathname.includes('/concepts') ? 'bold' : 'normal'} - > - - 概念中心 + navigate('/community')} + borderRadius="md" + bg={location.pathname.includes('/community') ? 'blue.50' : 'transparent'} + borderLeft={location.pathname.includes('/community') ? '3px solid' : 'none'} + borderColor="blue.600" + fontWeight={location.pathname.includes('/community') ? 'bold' : 'normal'} + > + + 新闻催化分析 + + HOT NEW - - - + + + + navigate('/concepts')} + borderRadius="md" + bg={location.pathname.includes('/concepts') ? 'blue.50' : 'transparent'} + borderLeft={location.pathname.includes('/concepts') ? '3px solid' : 'none'} + borderColor="blue.600" + fontWeight={location.pathname.includes('/concepts') ? 'bold' : 'normal'} + > + + 概念中心 + NEW + + @@ -260,59 +258,45 @@ const NavItems = ({ isAuthenticated, user }) => { 行情复盘 - - navigate('/limit-analyse')} - py={2} - px={3} - borderRadius="md" - _hover={{ bg: 'gray.100' }} - cursor="pointer" - bg={location.pathname.includes('/limit-analyse') ? 'blue.50' : 'transparent'} - borderLeft={location.pathname.includes('/limit-analyse') ? '3px solid' : 'none'} - borderColor="blue.600" - fontWeight={location.pathname.includes('/limit-analyse') ? 'bold' : 'normal'} - > - - 涨停分析 - FREE - - - navigate('/stocks')} - py={2} - px={3} - borderRadius="md" - _hover={{ bg: 'gray.100' }} - cursor="pointer" - bg={location.pathname.includes('/stocks') ? 'blue.50' : 'transparent'} - borderLeft={location.pathname.includes('/stocks') ? '3px solid' : 'none'} - borderColor="blue.600" - fontWeight={location.pathname.includes('/stocks') ? 'bold' : 'normal'} - > - - 个股中心 - HOT - - - navigate('/trading-simulation')} - py={2} - px={3} - borderRadius="md" - _hover={{ bg: 'gray.100' }} - cursor="pointer" - bg={location.pathname.includes('/trading-simulation') ? 'blue.50' : 'transparent'} - borderLeft={location.pathname.includes('/trading-simulation') ? '3px solid' : 'none'} - borderColor="blue.600" - fontWeight={location.pathname.includes('/trading-simulation') ? 'bold' : 'normal'} - > - - 模拟盘 - NEW - - - + navigate('/limit-analyse')} + borderRadius="md" + bg={location.pathname.includes('/limit-analyse') ? 'blue.50' : 'transparent'} + borderLeft={location.pathname.includes('/limit-analyse') ? '3px solid' : 'none'} + borderColor="blue.600" + fontWeight={location.pathname.includes('/limit-analyse') ? 'bold' : 'normal'} + > + + 涨停分析 + FREE + + + navigate('/stocks')} + borderRadius="md" + bg={location.pathname.includes('/stocks') ? 'blue.50' : 'transparent'} + borderLeft={location.pathname.includes('/stocks') ? '3px solid' : 'none'} + borderColor="blue.600" + fontWeight={location.pathname.includes('/stocks') ? 'bold' : 'normal'} + > + + 个股中心 + HOT + + + navigate('/trading-simulation')} + borderRadius="md" + bg={location.pathname.includes('/trading-simulation') ? 'blue.50' : 'transparent'} + borderLeft={location.pathname.includes('/trading-simulation') ? '3px solid' : 'none'} + borderColor="blue.600" + fontWeight={location.pathname.includes('/trading-simulation') ? 'bold' : 'normal'} + > + + 模拟盘 + NEW + + @@ -327,30 +311,20 @@ const NavItems = ({ isAuthenticated, user }) => { AGENT社群 - - - 今日热议 - - - 个股社区 - - + + 今日热议 + + + 个股社区 + @@ -373,7 +347,7 @@ const NavItems = ({ isAuthenticated, user }) => { } else { return null; } -} +}; // 计算 API 基础地址(移到组件外部,避免每次 render 重新创建) const getApiBase = () => (process.env.NODE_ENV === 'production' ? '' : (process.env.REACT_APP_API_URL || 'http://49.232.185.254:5001')); diff --git a/src/components/ScrollToTop/index.js b/src/components/ScrollToTop/index.js new file mode 100644 index 00000000..f01ba2d2 --- /dev/null +++ b/src/components/ScrollToTop/index.js @@ -0,0 +1,27 @@ +// src/components/ScrollToTop/index.js +// 路由切换时自动滚动到页面顶部 + +import { useEffect } from 'react'; +import { useLocation } from 'react-router-dom'; + +/** + * ScrollToTop - 路由切换时自动滚动到顶部 + * + * 使用方式:在 App.js 的 Router 内部添加此组件 + * + * @example + * + * + * ... + * + */ +export default function ScrollToTop() { + const { pathname } = useLocation(); + + useEffect(() => { + // 路径改变时滚动到顶部 + window.scrollTo(0, 0); + }, [pathname]); + + return null; +} diff --git a/src/layouts/Home.js b/src/layouts/Home.js index 03f3674f..c52d5204 100755 --- a/src/layouts/Home.js +++ b/src/layouts/Home.js @@ -3,8 +3,8 @@ import React from "react"; import { Routes, Route } from "react-router-dom"; import { Box } from '@chakra-ui/react'; -// 导入导航栏组件 - 使用我们之前修复的版本 -import HomeNavbar from "../components/Navbars/HomeNavbar"; +// 导航栏已由 MainLayout 提供,此处不再导入 +// import HomeNavbar from "../components/Navbars/HomeNavbar"; // 导入页面组件 import HomePage from "views/Home/HomePage"; @@ -25,8 +25,7 @@ import ProtectedRoute from "../components/ProtectedRoute"; export default function Home() { return ( - {/* 导航栏 - 这是关键,确保HomeNavbar被正确包含 */} - + {/* 导航栏已由 MainLayout 提供,此处不再渲染 */} {/* 主要内容区域 */} diff --git a/src/layouts/MainLayout.js b/src/layouts/MainLayout.js new file mode 100644 index 00000000..78996173 --- /dev/null +++ b/src/layouts/MainLayout.js @@ -0,0 +1,31 @@ +// src/layouts/MainLayout.js +// 主布局组件 - 为所有带导航栏的页面提供统一布局 +import React, { Suspense } from "react"; +import { Outlet } from "react-router-dom"; +import { Box } from '@chakra-ui/react'; +import HomeNavbar from "../components/Navbars/HomeNavbar"; +import PageLoader from "../components/Loading/PageLoader"; + +/** + * MainLayout - 带导航栏的主布局 + * + * 使用 渲染子路由,确保导航栏只渲染一次 + * 页面切换时只有 Outlet 内的内容会更新,导航栏保持不变 + * Suspense 边界确保导航栏始终可见,只有内容区域显示 loading + */ +export default function MainLayout() { + return ( + + {/* 导航栏 - 在所有页面间共享,不会重新渲染 */} + + + {/* 页面内容区域 - 通过 Outlet 渲染当前路由对应的组件 */} + {/* Suspense 只包裹内容区域,导航栏保持可见 */} + + }> + + + + + ); +} diff --git a/src/mocks/data/events.js b/src/mocks/data/events.js new file mode 100644 index 00000000..a1ac878e --- /dev/null +++ b/src/mocks/data/events.js @@ -0,0 +1,172 @@ +// Mock 事件相关数据 + +// Mock 股票池 - 常见的A股股票 +const stockPool = [ + { stock_code: '600000.SH', stock_name: '浦发银行', industry: '银行' }, + { stock_code: '600519.SH', stock_name: '贵州茅台', industry: '白酒' }, + { stock_code: '600036.SH', stock_name: '招商银行', industry: '银行' }, + { stock_code: '601318.SH', stock_name: '中国平安', industry: '保险' }, + { stock_code: '600016.SH', stock_name: '民生银行', industry: '银行' }, + { stock_code: '601398.SH', stock_name: '工商银行', industry: '银行' }, + { stock_code: '601288.SH', stock_name: '农业银行', industry: '银行' }, + { stock_code: '601166.SH', stock_name: '兴业银行', industry: '银行' }, + { stock_code: '000001.SZ', stock_name: '平安银行', industry: '银行' }, + { stock_code: '000002.SZ', stock_name: '万科A', industry: '房地产' }, + { stock_code: '000858.SZ', stock_name: '五粮液', industry: '白酒' }, + { stock_code: '000333.SZ', stock_name: '美的集团', industry: '家电' }, + { stock_code: '002415.SZ', stock_name: '海康威视', industry: '安防' }, + { stock_code: '002594.SZ', stock_name: 'BYD比亚迪', industry: '新能源汽车' }, + { stock_code: '300750.SZ', stock_name: '宁德时代', industry: '新能源' }, + { stock_code: '300059.SZ', stock_name: '东方财富', industry: '证券' }, + { stock_code: '601888.SH', stock_name: '中国中免', industry: '免税' }, + { stock_code: '600276.SH', stock_name: '恒瑞医药', industry: '医药' }, + { stock_code: '600887.SH', stock_name: '伊利股份', industry: '乳制品' }, + { stock_code: '601012.SH', stock_name: '隆基绿能', industry: '光伏' }, + { stock_code: '688981.SH', stock_name: '中芯国际', industry: '半导体' }, + { stock_code: '600309.SH', stock_name: '万华化学', industry: '化工' }, + { stock_code: '603259.SH', stock_name: '药明康德', industry: '医药研发' }, + { stock_code: '002475.SZ', stock_name: '立讯精密', industry: '电子' }, + { stock_code: '000063.SZ', stock_name: '中兴通讯', industry: '通信设备' }, +]; + +// 关联描述模板 +const relationDescTemplates = [ + '主营业务直接相关,预计受事件影响较大', + '产业链上游企业,间接受益', + '产业链下游企业,需求端受影响', + '同行业竞争对手,可能受到间接影响', + '参股该领域相关企业,有一定关联性', + '业务板块涉及相关领域,预计有正面影响', + '控股子公司从事相关业务', + '近期公告布局该领域,潜在受益标的', + '行业龙头企业,市场关注度高', + '技术储备充足,有望抢占市场先机', + '已有成熟产品线,短期内可能受益', + '战略转型方向与事件相关', +]; + +// 生成随机关联股票数据 +export function generateRelatedStocks(eventId, count = 5) { + // 使用事件ID作为随机种子,确保相同事件ID返回相同的股票列表 + const seed = parseInt(eventId) || 1; + const selectedStocks = []; + + // 伪随机选择股票(基于事件ID) + for (let i = 0; i < Math.min(count, stockPool.length); i++) { + const index = (seed * 17 + i * 13) % stockPool.length; + const stock = stockPool[index]; + const descIndex = (seed * 7 + i * 11) % relationDescTemplates.length; + + selectedStocks.push({ + stock_code: stock.stock_code, + stock_name: stock.stock_name, + relation_desc: relationDescTemplates[descIndex], + industry: stock.industry, + // 可选字段 - 用于前端显示更多信息 + relevance_score: Math.max(60, 100 - i * 8), // 相关性评分,递减 + impact_level: i < 2 ? 'high' : i < 4 ? 'medium' : 'low', // 影响程度 + }); + } + + return selectedStocks; +} + +// Mock 事件相关股票数据映射 +// 这里可以为特定事件ID预设特定的股票列表 +export const mockEventStocks = { + // 示例:事件ID为1的预设股票 + '1': [ + { + stock_code: '600519.SH', + stock_name: '贵州茅台', + relation_desc: '白酒行业龙头,消费板块受政策影响', + industry: '白酒', + relevance_score: 95, + impact_level: 'high', + }, + { + stock_code: '000858.SZ', + stock_name: '五粮液', + relation_desc: '白酒行业第二梯队,同样受消费政策影响', + industry: '白酒', + relevance_score: 90, + impact_level: 'high', + }, + { + stock_code: '600887.SH', + stock_name: '伊利股份', + relation_desc: '消费品龙头,受益于消费复苏', + industry: '乳制品', + relevance_score: 75, + impact_level: 'medium', + }, + ], + + // 事件ID为2的预设股票(科技类) + '2': [ + { + stock_code: '002415.SZ', + stock_name: '海康威视', + relation_desc: 'AI视觉领域龙头,技术创新受政策支持', + industry: '安防', + relevance_score: 92, + impact_level: 'high', + }, + { + stock_code: '000063.SZ', + stock_name: '中兴通讯', + relation_desc: '5G通信设备商,基础设施建设受益', + industry: '通信设备', + relevance_score: 88, + impact_level: 'high', + }, + { + stock_code: '688981.SH', + stock_name: '中芯国际', + relation_desc: '半导体制造龙头,国产替代核心标的', + industry: '半导体', + relevance_score: 85, + impact_level: 'high', + }, + ], + + // 事件ID为3的预设股票(新能源类) + '3': [ + { + stock_code: '300750.SZ', + stock_name: '宁德时代', + relation_desc: '动力电池龙头,新能源产业链核心', + industry: '新能源', + relevance_score: 98, + impact_level: 'high', + }, + { + stock_code: '002594.SZ', + stock_name: 'BYD比亚迪', + relation_desc: '新能源汽车龙头,产业链一体化布局', + industry: '新能源汽车', + relevance_score: 95, + impact_level: 'high', + }, + { + stock_code: '601012.SH', + stock_name: '隆基绿能', + relation_desc: '光伏组件龙头,清洁能源受政策支持', + industry: '光伏', + relevance_score: 85, + impact_level: 'medium', + }, + ], +}; + +// 获取事件相关股票 +export function getEventRelatedStocks(eventId) { + // 优先返回预设的股票列表 + if (mockEventStocks[eventId]) { + return mockEventStocks[eventId]; + } + + // 否则生成随机股票列表(3-6只股票) + const count = 3 + (parseInt(eventId) % 4); + return generateRelatedStocks(eventId, count); +} diff --git a/src/mocks/data/users.js b/src/mocks/data/users.js index cd1f1efb..e9b10c79 100644 --- a/src/mocks/data/users.js +++ b/src/mocks/data/users.js @@ -86,22 +86,33 @@ export function generateWechatSessionId() { } // ==================== 当前登录用户状态管理 ==================== -// 用于跟踪当前登录的用户(Mock 模式下的全局状态) -let currentLoggedInUser = null; +// Mock 模式下使用 localStorage 持久化登录状态 // 设置当前登录用户 export function setCurrentUser(user) { - currentLoggedInUser = user; - console.log('[Mock State] 设置当前登录用户:', user); + if (user) { + localStorage.setItem('mock_current_user', JSON.stringify(user)); + console.log('[Mock State] 设置当前登录用户:', user); + } } // 获取当前登录用户 export function getCurrentUser() { - return currentLoggedInUser; + try { + const stored = localStorage.getItem('mock_current_user'); + if (stored) { + const user = JSON.parse(stored); + console.log('[Mock State] 获取当前登录用户:', user); + return user; + } + } catch (error) { + console.error('[Mock State] 解析用户数据失败:', error); + } + return null; } // 清除当前登录用户 export function clearCurrentUser() { - currentLoggedInUser = null; + localStorage.removeItem('mock_current_user'); console.log('[Mock State] 清除当前登录用户'); } diff --git a/src/mocks/handlers/event.js b/src/mocks/handlers/event.js new file mode 100644 index 00000000..1f905663 --- /dev/null +++ b/src/mocks/handlers/event.js @@ -0,0 +1,39 @@ +// src/mocks/handlers/event.js +// 事件相关的 Mock API Handlers + +import { http, HttpResponse } from 'msw'; +import { getEventRelatedStocks } from '../data/events'; + +// 模拟网络延迟 +const delay = (ms = 300) => new Promise(resolve => setTimeout(resolve, ms)); + +export const eventHandlers = [ + // 获取事件相关股票 + http.get('/api/events/:eventId/stocks', async ({ params }) => { + await delay(300); + + const { eventId } = params; + + console.log('[Mock] 获取事件相关股票, eventId:', eventId); + + try { + const relatedStocks = getEventRelatedStocks(eventId); + + return HttpResponse.json({ + success: true, + data: relatedStocks, + message: '获取成功' + }); + } catch (error) { + console.error('[Mock] 获取事件相关股票失败:', error); + return HttpResponse.json( + { + success: false, + error: '获取事件相关股票失败', + data: [] + }, + { status: 500 } + ); + } + }), +]; diff --git a/src/mocks/handlers/index.js b/src/mocks/handlers/index.js index 048913d0..47236960 100644 --- a/src/mocks/handlers/index.js +++ b/src/mocks/handlers/index.js @@ -4,15 +4,15 @@ import { authHandlers } from './auth'; import { accountHandlers } from './account'; import { simulationHandlers } from './simulation'; +import { eventHandlers } from './event'; // 可以在这里添加更多的 handlers // import { userHandlers } from './user'; -// import { eventHandlers } from './event'; export const handlers = [ ...authHandlers, ...accountHandlers, ...simulationHandlers, + ...eventHandlers, // ...userHandlers, - // ...eventHandlers, ]; diff --git a/src/views/Community/index.js b/src/views/Community/index.js index 9fb0ae56..6187787d 100644 --- a/src/views/Community/index.js +++ b/src/views/Community/index.js @@ -72,8 +72,7 @@ import ImportanceLegend from './components/ImportanceLegend'; import InvestmentCalendar from './components/InvestmentCalendar'; import { eventService } from '../../services/eventService'; -// 导入导航栏组件 (如果需要保留原有的导航栏) -import HomeNavbar from '../../components/Navbars/HomeNavbar'; +// 导航栏已由 MainLayout 提供,无需在此导入 const filterLabelMap = { date_range: v => v ? `日期: ${v}` : '', @@ -266,8 +265,7 @@ const Community = () => { return ( - {/* 导航栏 - 可以保留原有的或改用Chakra UI版本 */} - + {/* 导航栏已由 MainLayout 提供 */} {/* Midjourney风格英雄区域 */} diff --git a/src/views/Concept/index.js b/src/views/Concept/index.js index 404529e9..3e103ed0 100644 --- a/src/views/Concept/index.js +++ b/src/views/Concept/index.js @@ -83,8 +83,7 @@ import { BsGraphUp, BsLightningFill } from 'react-icons/bs'; import { keyframes } from '@emotion/react'; import ConceptTimelineModal from './ConceptTimelineModal'; import ConceptStatsPanel from './components/ConceptStatsPanel'; -// 导入导航栏组件 -import HomeNavbar from '../../components/Navbars/HomeNavbar'; +// 导航栏已由 MainLayout 提供,无需在此导入 // 导入订阅权限管理 import { useSubscription } from '../../hooks/useSubscription'; import SubscriptionUpgradeModal from '../../components/SubscriptionUpgradeModal'; @@ -1080,8 +1079,7 @@ const ConceptCenter = () => { return ( - {/* 导航栏 */} - + {/* 导航栏已由 MainLayout 提供 */} {/* Hero Section */} - {/* 导航栏 */} - - + {/* 导航栏已由 MainLayout 提供 */} + {/* 顶部Header */} diff --git a/src/views/StockOverview/index.js b/src/views/StockOverview/index.js index d5b4225c..8984974c 100644 --- a/src/views/StockOverview/index.js +++ b/src/views/StockOverview/index.js @@ -61,7 +61,8 @@ import { FaChartLine, FaFire, FaRocket, FaBrain, FaCalendarAlt, FaChevronRight, import { BsGraphUp, BsLightningFill } from 'react-icons/bs'; import { keyframes } from '@emotion/react'; import * as echarts from 'echarts'; -import HomeNavbar from '../../components/Navbars/HomeNavbar'; +// Navigation bar now provided by MainLayout +// import HomeNavbar from '../../components/Navbars/HomeNavbar'; // 动画定义 const pulseAnimation = keyframes` @@ -524,10 +525,9 @@ const StockOverview = () => { return ( - {/* 导航栏 */} - + {/* 导航栏已由 MainLayout 提供 */} + - {/* Hero Section */} - {/* 导航栏 */} - - + {/* 导航栏已由 MainLayout 提供 */} {!isAuthenticated ? (