From 7c00763999fd78c10f2925d935d6772fb66dae1f Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Wed, 10 Dec 2025 13:29:08 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E4=B8=AA=E8=82=A1=E4=B8=AD=E5=BF=83?= =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/InvestmentCalendar/index.js | 18 +++++++++++++----- src/views/Company/CompanyOverview.js | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) 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} ))} From fbeb66fb39c8a741d0997012aff9b5bb3e6b5449 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Wed, 10 Dec 2025 14:26:16 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20Company=20=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A1=86=E6=B7=BB=E5=8A=A0=E8=82=A1=E7=A5=A8?= =?UTF-8?q?=E6=A8=A1=E7=B3=8A=E6=90=9C=E7=B4=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 AutoComplete 组件替换原 Input,支持下拉选择 - 集成 stockService.fuzzySearch 实现按代码/名称模糊匹配 - 从 Redux 获取 allStocks 数据,自动加载保障 - 选中股票自动触发查询并更新 URL 参数 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/views/Company/index.js | 75 ++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 19 deletions(-) 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(); + } + }} + />