diff --git a/src/components/InvestmentCalendar/index.js b/src/components/InvestmentCalendar/index.js index a84a9c1f..fc689cce 100644 --- a/src/components/InvestmentCalendar/index.js +++ b/src/components/InvestmentCalendar/index.js @@ -544,11 +544,19 @@ const InvestmentCalendar = () => { render: (concepts) => ( {concepts && concepts.length > 0 ? ( - concepts.slice(0, 3).map((concept, index) => ( - }> - {Array.isArray(concept) ? concept[0] : concept} - - )) + concepts.slice(0, 3).map((concept, index) => { + // 兼容多种数据格式:字符串、数组、对象 + const conceptName = typeof concept === 'string' + ? concept + : Array.isArray(concept) + ? concept[0] + : concept?.concept || concept?.name || ''; + return ( + }> + {conceptName} + + ); + }) ) : ( )} diff --git a/src/views/Company/CompanyOverview.js b/src/views/Company/CompanyOverview.js index 15fa08ee..d5db0be8 100644 --- a/src/views/Company/CompanyOverview.js +++ b/src/views/Company/CompanyOverview.js @@ -2426,7 +2426,7 @@ const CompanyAnalysisComplete = ({ stockCode: propStockCode }) => { <> {event.keywords.slice(0, 4).map((keyword, kidx) => ( - {keyword} + {typeof keyword === 'string' ? keyword : keyword.concept} ))} diff --git a/src/views/Company/index.js b/src/views/Company/index.js index cf5b3723..0eb747e2 100644 --- a/src/views/Company/index.js +++ b/src/views/Company/index.js @@ -1,5 +1,9 @@ import React, { useState, useEffect, useCallback } from 'react'; import { useSearchParams } from 'react-router-dom'; +import { useSelector, useDispatch } from 'react-redux'; +import { loadAllStocks } from '@store/slices/stockSlice'; +import { AutoComplete } from 'antd'; +import { stockService } from '@services/stockService'; import { Container, Heading, @@ -12,10 +16,7 @@ import { TabPanel, HStack, VStack, - Input, Button, - InputGroup, - InputLeftElement, Text, Badge, Divider, @@ -41,10 +42,22 @@ const CompanyIndex = () => { const [searchParams, setSearchParams] = useSearchParams(); const [stockCode, setStockCode] = useState(searchParams.get('scode') || '000001'); const [inputCode, setInputCode] = useState(stockCode); + const [stockOptions, setStockOptions] = useState([]); const { colorMode, toggleColorMode } = useColorMode(); const toast = useToast(); const { isAuthenticated } = useAuth(); + // 从 Redux 获取股票列表数据 + const dispatch = useDispatch(); + const allStocks = useSelector((state) => state.stock.allStocks); + + // 确保股票数据已加载 + useEffect(() => { + if (!allStocks || allStocks.length === 0) { + dispatch(loadAllStocks()); + } + }, [dispatch, allStocks]); + // 🎯 PostHog 事件追踪 const { trackStockSearched, @@ -113,6 +126,31 @@ const CompanyIndex = () => { } }; + // 模糊搜索股票(由 onSearch 触发) + const handleStockSearch = (value) => { + if (!value || !allStocks || allStocks.length === 0) { + setStockOptions([]); + return; + } + const results = stockService.fuzzySearch(value, allStocks, 10); + const options = results.map((stock) => ({ + value: stock.code, + label: `${stock.code} ${stock.name}`, + })); + setStockOptions(options); + }; + + // 选中股票 + const handleStockSelect = (value) => { + setInputCode(value); + setStockOptions([]); + if (value !== stockCode) { + trackStockSearched(value, stockCode); + setStockCode(value); + setSearchParams({ scode: value }); + } + }; + const handleWatchlistToggle = async () => { if (!stockCode) { logger.warn('CompanyIndex', 'handleWatchlistToggle', '无效的股票代码', { stockCode }); @@ -190,22 +228,21 @@ const CompanyIndex = () => { - - - - - setInputCode(e.target.value)} - onKeyPress={handleKeyPress} - borderRadius="md" - _focus={{ - borderColor: 'blue.500', - boxShadow: '0 0 0 1px #3182ce' - }} - /> - + setInputCode(value)} + placeholder="输入股票代码或名称" + style={{ width: 260 }} + size="large" + onKeyDown={(e) => { + if (e.key === 'Enter') { + handleSearch(); + } + }} + />