Merge branch 'feature_bugfix/251201_vf_h5_ui' into feature_bugfix/251201_py_h5_ui
* feature_bugfix/251201_vf_h5_ui: feat: Company 页面搜索框添加股票模糊搜索功能 fix: 个股中心bug修复
This commit is contained in:
@@ -544,11 +544,19 @@ const InvestmentCalendar = () => {
|
||||
render: (concepts) => (
|
||||
<Space wrap>
|
||||
{concepts && concepts.length > 0 ? (
|
||||
concepts.slice(0, 3).map((concept, index) => (
|
||||
concepts.slice(0, 3).map((concept, index) => {
|
||||
// 兼容多种数据格式:字符串、数组、对象
|
||||
const conceptName = typeof concept === 'string'
|
||||
? concept
|
||||
: Array.isArray(concept)
|
||||
? concept[0]
|
||||
: concept?.concept || concept?.name || '';
|
||||
return (
|
||||
<Tag key={index} icon={<TagsOutlined />}>
|
||||
{Array.isArray(concept) ? concept[0] : concept}
|
||||
{conceptName}
|
||||
</Tag>
|
||||
))
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<Text type="secondary">无</Text>
|
||||
)}
|
||||
|
||||
@@ -2426,7 +2426,7 @@ const CompanyAnalysisComplete = ({ stockCode: propStockCode }) => {
|
||||
<>
|
||||
{event.keywords.slice(0, 4).map((keyword, kidx) => (
|
||||
<Tag key={kidx} size="sm" colorScheme="cyan" variant="subtle">
|
||||
{keyword}
|
||||
{typeof keyword === 'string' ? keyword : keyword.concept}
|
||||
</Tag>
|
||||
))}
|
||||
</>
|
||||
|
||||
@@ -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 = () => {
|
||||
</VStack>
|
||||
|
||||
<HStack spacing={3}>
|
||||
<InputGroup size="lg" maxW="300px">
|
||||
<InputLeftElement pointerEvents="none">
|
||||
<SearchIcon color="gray.400" />
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
placeholder="输入股票代码"
|
||||
<AutoComplete
|
||||
value={inputCode}
|
||||
onChange={(e) => setInputCode(e.target.value)}
|
||||
onKeyPress={handleKeyPress}
|
||||
borderRadius="md"
|
||||
_focus={{
|
||||
borderColor: 'blue.500',
|
||||
boxShadow: '0 0 0 1px #3182ce'
|
||||
options={stockOptions}
|
||||
onSearch={handleStockSearch}
|
||||
onSelect={handleStockSelect}
|
||||
onChange={(value) => setInputCode(value)}
|
||||
placeholder="输入股票代码或名称"
|
||||
style={{ width: 260 }}
|
||||
size="large"
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
handleSearch();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</InputGroup>
|
||||
<Button
|
||||
colorScheme="blue"
|
||||
size="lg"
|
||||
|
||||
Reference in New Issue
Block a user