refactor(MarketDataView): 使用通用 SubTabContainer 简化代码
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,37 +1,31 @@
|
||||
// src/views/Company/components/MarketDataView/index.tsx
|
||||
// MarketDataView 主组件 - 股票市场数据综合展示
|
||||
|
||||
import React, { useState, useEffect, ReactNode } from 'react';
|
||||
import React, { useState, useEffect, ReactNode, useMemo, useCallback } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Container,
|
||||
Tabs,
|
||||
TabList,
|
||||
TabPanels,
|
||||
Tab,
|
||||
TabPanel,
|
||||
Text,
|
||||
CardBody,
|
||||
Spinner,
|
||||
Center,
|
||||
VStack,
|
||||
HStack,
|
||||
Select,
|
||||
Button,
|
||||
Icon,
|
||||
Text,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
ChevronUpIcon,
|
||||
RepeatIcon,
|
||||
ArrowUpIcon,
|
||||
StarIcon,
|
||||
LockIcon,
|
||||
UnlockIcon,
|
||||
} from '@chakra-ui/icons';
|
||||
ChevronUp,
|
||||
Unlock,
|
||||
ArrowUp,
|
||||
Star,
|
||||
Lock,
|
||||
} from 'lucide-react';
|
||||
|
||||
// 通用组件
|
||||
import SubTabContainer from '@components/SubTabContainer';
|
||||
import type { SubTabConfig } from '@components/SubTabContainer';
|
||||
|
||||
// 内部模块导入
|
||||
import { themes, DEFAULT_PERIOD, PERIOD_OPTIONS } from './constants';
|
||||
import { themes, DEFAULT_PERIOD } from './constants';
|
||||
import { useMarketData } from './hooks/useMarketData';
|
||||
import {
|
||||
ThemedCard,
|
||||
@@ -88,22 +82,67 @@ const MarketDataView: React.FC<MarketDataViewProps> = ({ stockCode: propStockCod
|
||||
}, [propStockCode, stockCode]);
|
||||
|
||||
// 处理图表点击事件
|
||||
const handleChartClick = (params: { seriesName?: string; data?: [number, number] }) => {
|
||||
if (params.seriesName === '涨幅分析' && params.data) {
|
||||
const dataIndex = params.data[0];
|
||||
const analysis = analysisMap[dataIndex];
|
||||
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();
|
||||
if (analysis) {
|
||||
setModalContent(<AnalysisContent analysis={analysis} theme={theme} />);
|
||||
onOpen();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
[analysisMap, theme, onOpen]
|
||||
);
|
||||
|
||||
// Tab 配置 - 使用通用 SubTabContainer
|
||||
const tabConfigs: SubTabConfig[] = [
|
||||
{ key: 'trade', name: '交易数据', icon: ChevronUp, component: TradeDataPanel },
|
||||
{ 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
|
||||
const componentProps = useMemo(
|
||||
() => ({
|
||||
theme,
|
||||
tradeData,
|
||||
minuteData,
|
||||
minuteLoading,
|
||||
analysisMap,
|
||||
onLoadMinuteData: loadMinuteData,
|
||||
onChartClick: handleChartClick,
|
||||
selectedPeriod,
|
||||
onPeriodChange: setSelectedPeriod,
|
||||
fundingData,
|
||||
bigDealData,
|
||||
unusualData,
|
||||
pledgeData,
|
||||
}),
|
||||
[
|
||||
theme,
|
||||
tradeData,
|
||||
minuteData,
|
||||
minuteLoading,
|
||||
analysisMap,
|
||||
loadMinuteData,
|
||||
handleChartClick,
|
||||
selectedPeriod,
|
||||
fundingData,
|
||||
bigDealData,
|
||||
unusualData,
|
||||
pledgeData,
|
||||
]
|
||||
);
|
||||
|
||||
return (
|
||||
<Box bg={theme.bgMain} minH="100vh" color={theme.textPrimary}>
|
||||
<Box bg={'#1A202C'} minH="100vh" color={theme.textPrimary}>
|
||||
<Container maxW="container.xl" py={6}>
|
||||
<VStack spacing={6} align="stretch">
|
||||
<VStack align="stretch">
|
||||
{/* 股票概览 */}
|
||||
{summary && <StockSummaryCard summary={summary} theme={theme} />}
|
||||
|
||||
@@ -126,152 +165,14 @@ const MarketDataView: React.FC<MarketDataViewProps> = ({ stockCode: propStockCod
|
||||
</CardBody>
|
||||
</ThemedCard>
|
||||
) : (
|
||||
<Tabs
|
||||
variant="soft-rounded"
|
||||
colorScheme="blue"
|
||||
<SubTabContainer
|
||||
tabs={tabConfigs}
|
||||
componentProps={componentProps}
|
||||
themePreset="blackGold"
|
||||
index={activeTab}
|
||||
onChange={setActiveTab}
|
||||
>
|
||||
{/* Tab 导航栏 */}
|
||||
<Box
|
||||
bg={theme.bgCard}
|
||||
p={4}
|
||||
borderRadius="xl"
|
||||
border="1px solid"
|
||||
borderColor={theme.border}
|
||||
>
|
||||
<HStack justify="space-between" align="center" spacing={4}>
|
||||
<TabList overflowX="auto" border="none" flex="1">
|
||||
<Tab
|
||||
color={theme.textMuted}
|
||||
_selected={{ color: 'white', bg: theme.primary }}
|
||||
fontSize="sm"
|
||||
px={3}
|
||||
>
|
||||
<HStack spacing={1}>
|
||||
<Icon as={ChevronUpIcon} boxSize={4} />
|
||||
<Text>交易数据</Text>
|
||||
</HStack>
|
||||
</Tab>
|
||||
<Tab
|
||||
color={theme.textMuted}
|
||||
_selected={{ color: 'white', bg: theme.primary }}
|
||||
fontSize="sm"
|
||||
px={3}
|
||||
>
|
||||
<HStack spacing={1}>
|
||||
<Icon as={UnlockIcon} boxSize={4} />
|
||||
<Text>融资融券</Text>
|
||||
</HStack>
|
||||
</Tab>
|
||||
<Tab
|
||||
color={theme.textMuted}
|
||||
_selected={{ color: 'white', bg: theme.primary }}
|
||||
fontSize="sm"
|
||||
px={3}
|
||||
>
|
||||
<HStack spacing={1}>
|
||||
<Icon as={ArrowUpIcon} boxSize={4} />
|
||||
<Text>大宗交易</Text>
|
||||
</HStack>
|
||||
</Tab>
|
||||
<Tab
|
||||
color={theme.textMuted}
|
||||
_selected={{ color: 'white', bg: theme.primary }}
|
||||
fontSize="sm"
|
||||
px={3}
|
||||
>
|
||||
<HStack spacing={1}>
|
||||
<Icon as={StarIcon} boxSize={4} />
|
||||
<Text>龙虎榜</Text>
|
||||
</HStack>
|
||||
</Tab>
|
||||
<Tab
|
||||
color={theme.textMuted}
|
||||
_selected={{ color: 'white', bg: theme.primary }}
|
||||
fontSize="sm"
|
||||
px={3}
|
||||
>
|
||||
<HStack spacing={1}>
|
||||
<Icon as={LockIcon} boxSize={4} />
|
||||
<Text>股权质押</Text>
|
||||
</HStack>
|
||||
</Tab>
|
||||
</TabList>
|
||||
|
||||
{/* 时间范围选择和刷新按钮 */}
|
||||
<HStack spacing={2} flexShrink={0} ml="auto">
|
||||
<Text color={theme.textPrimary} whiteSpace="nowrap" fontSize="sm">
|
||||
时间范围:
|
||||
</Text>
|
||||
<Select
|
||||
size="sm"
|
||||
value={selectedPeriod}
|
||||
onChange={(e) => setSelectedPeriod(Number(e.target.value))}
|
||||
bg={theme.bgDark}
|
||||
borderColor={theme.border}
|
||||
color={theme.textPrimary}
|
||||
maxW="120px"
|
||||
>
|
||||
{PERIOD_OPTIONS.map((option) => (
|
||||
<option
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
style={{ background: theme.bgDark }}
|
||||
>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
<Button
|
||||
leftIcon={<RepeatIcon />}
|
||||
variant="outline"
|
||||
colorScheme="blue"
|
||||
onClick={refetch}
|
||||
isLoading={loading}
|
||||
size="sm"
|
||||
>
|
||||
刷新
|
||||
</Button>
|
||||
</HStack>
|
||||
</HStack>
|
||||
</Box>
|
||||
|
||||
<TabPanels>
|
||||
{/* 交易数据 Tab */}
|
||||
<TabPanel px={0}>
|
||||
<TradeDataPanel
|
||||
theme={theme}
|
||||
tradeData={tradeData}
|
||||
minuteData={minuteData}
|
||||
minuteLoading={minuteLoading}
|
||||
analysisMap={analysisMap}
|
||||
onLoadMinuteData={loadMinuteData}
|
||||
onChartClick={handleChartClick}
|
||||
/>
|
||||
</TabPanel>
|
||||
|
||||
{/* 融资融券 Tab */}
|
||||
<TabPanel px={0}>
|
||||
<FundingPanel theme={theme} fundingData={fundingData} />
|
||||
</TabPanel>
|
||||
|
||||
{/* 大宗交易 Tab */}
|
||||
<TabPanel px={0}>
|
||||
<BigDealPanel theme={theme} bigDealData={bigDealData} />
|
||||
</TabPanel>
|
||||
|
||||
{/* 龙虎榜 Tab */}
|
||||
<TabPanel px={0}>
|
||||
<UnusualPanel theme={theme} unusualData={unusualData} />
|
||||
</TabPanel>
|
||||
|
||||
{/* 股权质押 Tab */}
|
||||
<TabPanel px={0}>
|
||||
<PledgePanel theme={theme} pledgeData={pledgeData} />
|
||||
</TabPanel>
|
||||
</TabPanels>
|
||||
</Tabs>
|
||||
onTabChange={(index) => setActiveTab(index)}
|
||||
isLazy
|
||||
/>
|
||||
)}
|
||||
</VStack>
|
||||
</Container>
|
||||
|
||||
Reference in New Issue
Block a user