diff --git a/src/components/Navbars/components/NavStockSearch/index.js b/src/components/Navbars/components/NavStockSearch/index.js
new file mode 100644
index 00000000..eea7ad28
--- /dev/null
+++ b/src/components/Navbars/components/NavStockSearch/index.js
@@ -0,0 +1,213 @@
+// src/components/Navbars/components/NavStockSearch/index.js
+// 导航栏股票搜索组件 - 支持代码、名称、拼音缩写搜索
+
+import React, { useRef, useEffect, useCallback, memo } from 'react';
+import { useNavigate } from 'react-router-dom';
+import {
+ Box,
+ Input,
+ InputGroup,
+ InputLeftElement,
+ InputRightElement,
+ IconButton,
+ Text,
+ VStack,
+ HStack,
+ Spinner,
+ Tag,
+ Center,
+ List,
+ ListItem,
+ Flex,
+ Portal,
+} from '@chakra-ui/react';
+import { Search, X } from 'lucide-react';
+import { useStockSearch } from '@hooks/useStockSearch';
+
+/**
+ * 导航栏股票搜索组件
+ * 浅色主题,适配导航栏使用
+ */
+const NavStockSearch = memo(() => {
+ const navigate = useNavigate();
+ const containerRef = useRef(null);
+ const inputRef = useRef(null);
+
+ // 浅色主题颜色配置
+ const searchIconColor = 'gray.400';
+ const inputBg = 'gray.50';
+ const dropdownBg = 'white';
+ const borderColor = 'gray.200';
+ const hoverBg = 'gray.50';
+ const textColor = 'gray.800';
+ const subTextColor = 'gray.500';
+ const accentColor = 'blue.500';
+
+ // 使用搜索 Hook
+ const {
+ searchQuery,
+ searchResults,
+ isSearching,
+ showResults,
+ handleSearch,
+ clearSearch,
+ setShowResults,
+ } = useStockSearch({ limit: 8, debounceMs: 300 });
+
+ // 点击外部关闭下拉
+ useEffect(() => {
+ const handleClickOutside = (event) => {
+ if (containerRef.current && !containerRef.current.contains(event.target)) {
+ setShowResults(false);
+ }
+ };
+ document.addEventListener('mousedown', handleClickOutside);
+ return () => document.removeEventListener('mousedown', handleClickOutside);
+ }, [setShowResults]);
+
+ // 选择股票 - 跳转到详情页
+ const handleSelectStock = useCallback((stock) => {
+ clearSearch();
+ navigate(`/company/${stock.stock_code}`);
+ }, [navigate, clearSearch]);
+
+ // 处理键盘事件
+ const handleKeyDown = useCallback((e) => {
+ if (e.key === 'Enter' && searchResults.length > 0) {
+ handleSelectStock(searchResults[0]);
+ } else if (e.key === 'Escape') {
+ setShowResults(false);
+ inputRef.current?.blur();
+ }
+ }, [searchResults, handleSelectStock, setShowResults]);
+
+ // 计算下拉框位置
+ const getDropdownPosition = () => {
+ if (!containerRef.current) return {};
+ const rect = containerRef.current.getBoundingClientRect();
+ return {
+ position: 'fixed',
+ top: `${rect.bottom + 8}px`,
+ left: `${rect.left}px`,
+ width: '300px',
+ };
+ };
+
+ return (
+
+
+
+
+
+ handleSearch(e.target.value)}
+ onKeyDown={handleKeyDown}
+ onFocus={() => searchQuery && searchResults.length > 0 && setShowResults(true)}
+ borderColor={borderColor}
+ borderRadius="md"
+ _hover={{ borderColor: 'gray.300' }}
+ _focus={{
+ borderColor: accentColor,
+ boxShadow: '0 0 0 1px var(--chakra-colors-blue-500)',
+ bg: 'white'
+ }}
+ _placeholder={{ color: 'gray.400' }}
+ />
+ {(searchQuery || isSearching) && (
+
+ {isSearching ? (
+
+ ) : (
+ }
+ onClick={clearSearch}
+ aria-label="清除搜索"
+ color="gray.400"
+ _hover={{ bg: 'transparent', color: 'gray.600' }}
+ />
+ )}
+
+ )}
+
+
+ {/* 搜索结果下拉 - 使用 Portal 避免被导航栏裁剪 */}
+ {showResults && (
+
+
+ {searchResults.length > 0 ? (
+
+ {searchResults.map((stock, index) => (
+ handleSelectStock(stock)}
+ borderBottomWidth={index < searchResults.length - 1 ? '1px' : '0'}
+ borderColor="gray.100"
+ >
+
+
+
+ {stock.stock_name}
+
+
+
+ {stock.stock_code}
+
+ {stock.pinyin_abbr && (
+
+ {stock.pinyin_abbr.toUpperCase()}
+
+ )}
+
+
+ {stock.exchange && (
+
+ {stock.exchange === 'SH' ? '沪' : stock.exchange === 'SZ' ? '深' : stock.exchange}
+
+ )}
+
+
+ ))}
+
+ ) : (
+
+
+ {searchQuery ? '未找到相关股票' : '输入代码/名称/拼音搜索'}
+
+
+ )}
+
+
+ )}
+
+ );
+});
+
+NavStockSearch.displayName = 'NavStockSearch';
+
+export default NavStockSearch;
diff --git a/src/components/Navbars/components/NavbarActions/index.js b/src/components/Navbars/components/NavbarActions/index.js
index b4394575..a67e6093 100644
--- a/src/components/Navbars/components/NavbarActions/index.js
+++ b/src/components/Navbars/components/NavbarActions/index.js
@@ -8,6 +8,7 @@ import LoginButton from '../LoginButton';
// import CalendarButton from '../CalendarButton'; // 暂时注释
import { DesktopUserMenu, TabletUserMenu } from '../UserMenu';
import { MySpaceButton, MoreMenu } from '../Navigation';
+import NavStockSearch from '../NavStockSearch';
/**
* Navbar 右侧功能区组件
@@ -50,9 +51,10 @@ const NavbarActions = memo(({
{/* 投资日历 - 暂时注释 */}
{/* {isDesktop && } */}
- {/* 桌面端布局:[我的空间] | [头像][用户名] */}
+ {/* 桌面端布局:[搜索框] [我的空间] | [头像][用户名] */}
{isDesktop ? (
<>
+
{
{/* 主内容区域 - padding 由 MainLayout 统一设置 */}
{/* ⚡ 顶部说明面板(懒加载):产品介绍 + 沪深指数 + 热门概念词云 */}
-
-
-
- }>
-
-
+ {/* 📱 移动端隐藏:HeroPanel 在小屏幕上显示效果不佳,仅在 md 及以上尺寸显示 */}
+
+
+
+
+ }>
+
+
+
{/* 实时要闻·动态追踪 - 横向滚动 */}
onStockClick?.(stock)}
- role="group"
+ trigger="hover"
+ placement="left"
+ openDelay={300}
+ closeDelay={100}
+ isLazy
>
- {/* 第一行:股票名称 + 价格/涨跌幅 + 取消关注按钮 */}
-
-
-
- {stock.stock_name || stock.stock_code}
-
-
- {stock.stock_code}
-
-
-
-
-
- {quote?.current_price?.toFixed(2) || stock.current_price || '--'}
-
-
- {changePercent !== undefined && changePercent !== null
- ? `${isUp ? '+' : ''}${Number(changePercent).toFixed(2)}%`
- : '--'}
-
-
- e.stopPropagation()}>
- handleUnwatch(stock.stock_code)}
- size="sm"
- colorScheme="gold"
- showTooltip={true}
- />
-
-
-
- {/* 第二行:日均、周涨 Badge */}
- {(dailyChg || weeklyChg) && (
-
- {dailyChg && (
-
- 日均 {dailyChg.text}
-
+
+ onStockClick?.(stock)}
+ role="group"
+ >
+ {/* 第一行:股票名称 + 价格/涨跌幅 + 取消关注按钮 */}
+
+
+
+ {stock.stock_name || stock.stock_code}
+
+
+ {stock.stock_code}
+
+
+
+
+
+ {quote?.current_price?.toFixed(2) || stock.current_price || '--'}
+
+
+ {changePercent !== undefined && changePercent !== null
+ ? `${isUp ? '+' : ''}${Number(changePercent).toFixed(2)}%`
+ : '--'}
+
+
+ e.stopPropagation()}>
+ handleUnwatch(stock.stock_code)}
+ size="sm"
+ colorScheme="gold"
+ showTooltip={true}
+ />
+
+
+
+ {/* 第二行:日均、周涨 Badge */}
+ {(dailyChg || weeklyChg) && (
+
+ {dailyChg && (
+
+ 日均 {dailyChg.text}
+
+ )}
+ {weeklyChg && (
+
+ 周涨 {weeklyChg.text}
+
+ )}
+
)}
- {weeklyChg && (
-
+
+
+
+
+ {/* 股票信息头部 */}
+
+
+
+ {stock.stock_name}
+
+
+ {stock.stock_code}
+
+
+
+
+ {quote?.current_price?.toFixed(2) || stock.current_price || '--'}
+
+
+ {changePercent !== undefined && changePercent !== null
+ ? `${isUp ? '+' : ''}${Number(changePercent).toFixed(2)}%`
+ : '--'}
+
+
+
+ {/* 分时图 */}
+
- 周涨 {weeklyChg.text}
-
- )}
-
- )}
-
+
+
+ {/* 提示文字 */}
+
+ 点击查看详情
+
+
+
+
+
);
})}