fix: 适配 watchlist 新数据结构

- CompactSearchBox: 改用 Redux 获取股票列表
 - useWatchlist: 适配 { stock_code, stock_name }[] 结构
 - Center: 修复 watchlist key + H5 评论 Badge 溢出
This commit is contained in:
zdl
2025-12-05 17:23:51 +08:00
parent e8a9a6f180
commit b74d88e592
3 changed files with 30 additions and 17 deletions

View File

@@ -14,6 +14,7 @@ import dayjs from 'dayjs';
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import { useSelector, useDispatch } from 'react-redux'; import { useSelector, useDispatch } from 'react-redux';
import { fetchIndustryData, selectIndustryData, selectIndustryLoading } from '@store/slices/industrySlice'; import { fetchIndustryData, selectIndustryData, selectIndustryLoading } from '@store/slices/industrySlice';
import { loadAllStocks } from '@store/slices/stockSlice';
import { stockService } from '@services/stockService'; import { stockService } from '@services/stockService';
import { logger } from '@utils/logger'; import { logger } from '@utils/logger';
import TradingTimeFilter from './TradingTimeFilter'; import TradingTimeFilter from './TradingTimeFilter';
@@ -61,6 +62,7 @@ const CompactSearchBox = ({
const dispatch = useDispatch(); const dispatch = useDispatch();
const industryData = useSelector(selectIndustryData); const industryData = useSelector(selectIndustryData);
const industryLoading = useSelector(selectIndustryLoading); const industryLoading = useSelector(selectIndustryLoading);
const reduxAllStocks = useSelector((state) => state.stock.allStocks);
// 防抖搜索 // 防抖搜索
const debouncedSearchRef = useRef(null); const debouncedSearchRef = useRef(null);
@@ -82,16 +84,19 @@ const CompactSearchBox = ({
}; };
}, [triggerSearch]); }, [triggerSearch]);
// 加载股票数据 // 加载股票数据(从 Redux 获取)
useEffect(() => { useEffect(() => {
const loadStocks = async () => { if (!reduxAllStocks || reduxAllStocks.length === 0) {
const response = await stockService.getAllStocks(); dispatch(loadAllStocks());
if (response.success && response.data) {
setAllStocks(response.data);
} }
}; }, [dispatch, reduxAllStocks]);
loadStocks();
}, []); // 同步 Redux 数据到本地状态
useEffect(() => {
if (reduxAllStocks && reduxAllStocks.length > 0) {
setAllStocks(reduxAllStocks);
}
}, [reduxAllStocks]);
// 预加载行业数据(解决第一次点击无数据问题) // 预加载行业数据(解决第一次点击无数据问题)
useEffect(() => { useEffect(() => {

View File

@@ -1,9 +1,9 @@
// src/views/Community/components/StockDetailPanel/hooks/useWatchlist.js // src/views/Community/components/StockDetailPanel/hooks/useWatchlist.js
import { useSelector, useDispatch, shallowEqual } from 'react-redux'; import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import { useEffect, useCallback, useMemo } from 'react'; import { useEffect, useCallback, useMemo } from 'react';
import { loadWatchlist, toggleWatchlist as toggleWatchlistAction } from '../../../../../store/slices/stockSlice'; import { loadWatchlist, toggleWatchlist as toggleWatchlistAction } from '@store/slices/stockSlice';
import { message } from 'antd'; import { message } from 'antd';
import { logger } from '../../../../../utils/logger'; import { logger } from '@utils/logger';
/** /**
* 标准化股票代码为6位格式 * 标准化股票代码为6位格式
@@ -41,8 +41,9 @@ export const useWatchlist = (shouldLoad = true) => {
const loading = useSelector(state => state.stock.loading.watchlist); const loading = useSelector(state => state.stock.loading.watchlist);
// 转换为 Set 方便快速查询标准化为6位代码 // 转换为 Set 方便快速查询标准化为6位代码
// 注意: watchlistArray 现在是 { stock_code, stock_name }[] 格式
const watchlistSet = useMemo(() => { const watchlistSet = useMemo(() => {
return new Set(watchlistArray.map(normalizeStockCode)); return new Set(watchlistArray.map(item => normalizeStockCode(item.stock_code)));
}, [watchlistArray]); }, [watchlistArray]);
// 初始化时加载自选股列表(只在 shouldLoad 为 true 时) // 初始化时加载自选股列表(只在 shouldLoad 为 true 时)

View File

@@ -321,7 +321,7 @@ export default function CenterDashboard() {
<VStack align="stretch" spacing={2}> <VStack align="stretch" spacing={2}>
{watchlist.slice(0, 10).map((stock) => ( {watchlist.slice(0, 10).map((stock) => (
<LinkBox <LinkBox
key={stock.id} key={stock.stock_code}
p={3} p={3}
borderRadius="md" borderRadius="md"
_hover={{ bg: hoverBg }} _hover={{ bg: hoverBg }}
@@ -568,15 +568,22 @@ export default function CenterDashboard() {
<Text fontSize="sm" noOfLines={3}> <Text fontSize="sm" noOfLines={3}>
{comment.content} {comment.content}
</Text> </Text>
<HStack justify="space-between" fontSize="xs" color={secondaryText}> <HStack justify="space-between" fontSize="xs" color={secondaryText} spacing={2}>
<HStack> <HStack flexShrink={0}>
<Icon as={FiClock} /> <Icon as={FiClock} />
<Text>{formatDate(comment.created_at)}</Text> <Text>{formatDate(comment.created_at)}</Text>
</HStack> </HStack>
{comment.event_title && ( {comment.event_title && (
<Tooltip label={comment.event_title}> <Tooltip label={comment.event_title}>
<Badge variant="subtle" fontSize="xs"> <Badge
{comment.event_title.slice(0, 20)}... variant="subtle"
fontSize="xs"
maxW={{ base: '120px', md: '180px' }}
overflow="hidden"
textOverflow="ellipsis"
whiteSpace="nowrap"
>
{comment.event_title}
</Badge> </Badge>
</Tooltip> </Tooltip>
)} )}