Files
vf_react/src/views/Company/components/MarketDataView/index.tsx
zdl 08842b9097 fix: 优化加载状态和布局
MarketDataView:
- 移除重复的 LoadingState,改用 KLineModule 内部骨架屏
- 修复点击股票行情后数据不显示的问题

FinancialPanorama:
- 移除表格右上角"显示 6 期"标签
- 优化 loadingTab 状态处理

SubTabContainer:
- 重构布局:Tab 区域可滚动,右侧元素固定

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-19 18:55:04 +08:00

167 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// src/views/Company/components/MarketDataView/index.tsx
// MarketDataView 主组件 - 股票市场数据综合展示
import React, { useState, useEffect, ReactNode, useMemo, useCallback, memo } from 'react';
import {
Box,
Container,
VStack,
useDisclosure,
} from '@chakra-ui/react';
import { Unlock, ArrowUp, Star, Lock } from 'lucide-react';
// 通用组件
import SubTabContainer from '@components/SubTabContainer';
import type { SubTabConfig } from '@components/SubTabContainer';
// 内部模块导入
import { themes, DEFAULT_PERIOD } from './constants';
import { useMarketData } from './hooks/useMarketData';
import {
ThemedCard,
StockSummaryCard,
AnalysisModal,
AnalysisContent,
} from './components';
import {
TradeDataPanel,
FundingPanel,
BigDealPanel,
UnusualPanel,
PledgePanel,
} from './components/panels';
import type { MarketDataViewProps } from './types';
/**
* MarketDataView 主组件
* 展示股票的市场数据:交易数据、融资融券、大宗交易、龙虎榜、股权质押
*/
const MarketDataView: React.FC<MarketDataViewProps> = ({ stockCode: propStockCode }) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const [modalContent, setModalContent] = useState<ReactNode>(null);
// 获取当前主题
const theme = themes.light;
// 状态管理
const [stockCode, setStockCode] = useState(propStockCode || '600000');
const [activeTab, setActiveTab] = useState(0);
const [selectedPeriod, setSelectedPeriod] = useState(DEFAULT_PERIOD);
// 使用自定义 Hook 获取数据
const {
loading,
summary,
tradeData,
fundingData,
bigDealData,
unusualData,
pledgeData,
minuteData,
minuteLoading,
analysisMap,
loadMinuteData,
loadDataByType,
} = useMarketData(stockCode, selectedPeriod);
// Tab 切换时按需加载数据
const handleTabChange = useCallback((index: number) => {
setActiveTab(index);
// 根据 tab index 加载对应数据
const tabDataMap: Record<number, 'funding' | 'bigDeal' | 'unusual' | 'pledge'> = {
0: 'funding',
1: 'bigDeal',
2: 'unusual',
3: 'pledge',
};
const dataType = tabDataMap[index];
if (dataType) {
loadDataByType(dataType);
}
}, [loadDataByType]);
// 监听 props 中的 stockCode 变化
useEffect(() => {
if (propStockCode && propStockCode !== stockCode) {
setStockCode(propStockCode);
}
}, [propStockCode, stockCode]);
// 处理图表点击事件
const handleChartClick = useCallback(
(params: { seriesName?: string; data?: [number, number] }) => {
if (params.seriesName === '涨幅分析' && params.data) {
const dataIndex = params.data[0];
const analysis = analysisMap[dataIndex];
if (analysis) {
setModalContent(<AnalysisContent analysis={analysis} theme={theme} />);
onOpen();
}
}
},
[analysisMap, theme, onOpen]
);
// Tab 配置 - 使用通用 SubTabContainer不含交易数据交易数据单独显示在上方
const tabConfigs: SubTabConfig[] = [
{ key: 'funding', name: '融资融券', icon: Unlock, component: FundingPanel },
{ key: 'bigDeal', name: '大宗交易', icon: ArrowUp, component: BigDealPanel },
{ key: 'unusual', name: '龙虎榜', icon: Star, component: UnusualPanel },
{ key: 'pledge', name: '股权质押', icon: Lock, component: PledgePanel },
];
// 传递给 Tab 组件的 props - 只传递各 Tab 需要的数据
const componentProps = useMemo(
() => ({
// 各 Tab 只使用自己需要的数据
fundingData,
bigDealData,
unusualData,
pledgeData,
}),
[fundingData, bigDealData, unusualData, pledgeData]
);
return (
<Box bg={'#1A202C'} minH="100vh" color={theme.textPrimary}>
<Container maxW="container.xl" py={6}>
<VStack align="stretch" spacing={6}>
{/* 股票概览 */}
{summary && <StockSummaryCard summary={summary} theme={theme} />}
{/* 交易数据 - 日K/分钟K线独立显示在 Tab 上方) */}
<TradeDataPanel
theme={theme}
tradeData={tradeData}
minuteData={minuteData}
minuteLoading={minuteLoading}
analysisMap={analysisMap}
onLoadMinuteData={loadMinuteData}
onChartClick={handleChartClick}
selectedPeriod={selectedPeriod}
onPeriodChange={setSelectedPeriod}
stockCode={stockCode}
loading={loading}
/>
{/* 主要内容区域 - Tab */}
<SubTabContainer
tabs={tabConfigs}
componentProps={componentProps}
themePreset="blackGold"
index={activeTab}
onTabChange={handleTabChange}
isLazy
/>
</VStack>
</Container>
{/* 涨幅分析模态框 */}
<AnalysisModal isOpen={isOpen} onClose={onClose} content={modalContent} theme={theme} />
</Box>
);
};
export default memo(MarketDataView);