feat: 修复数据获取bug

This commit is contained in:
zdl
2025-10-27 17:21:31 +08:00
parent 0f3bc06716
commit 03c113fe1b
2 changed files with 138 additions and 61 deletions

View File

@@ -473,6 +473,16 @@ const FinancialPanorama = ({ stockCode: propStockCode }) => {
} }
]; ];
// 数组安全检查
if (!Array.isArray(balanceSheet) || balanceSheet.length === 0) {
return (
<Alert status="info">
<AlertIcon />
暂无资产负债表数据
</Alert>
);
}
const maxColumns = Math.min(balanceSheet.length, 6); const maxColumns = Math.min(balanceSheet.length, 6);
const displayData = balanceSheet.slice(0, maxColumns); const displayData = balanceSheet.slice(0, maxColumns);
@@ -707,6 +717,16 @@ const FinancialPanorama = ({ stockCode: propStockCode }) => {
} }
]; ];
// 数组安全检查
if (!Array.isArray(incomeStatement) || incomeStatement.length === 0) {
return (
<Alert status="info">
<AlertIcon />
暂无利润表数据
</Alert>
);
}
const maxColumns = Math.min(incomeStatement.length, 6); const maxColumns = Math.min(incomeStatement.length, 6);
const displayData = incomeStatement.slice(0, maxColumns); const displayData = incomeStatement.slice(0, maxColumns);
@@ -866,6 +886,16 @@ const FinancialPanorama = ({ stockCode: propStockCode }) => {
{ name: '自由现金流', key: 'free_cash_flow', path: 'key_metrics.free_cash_flow' }, { name: '自由现金流', key: 'free_cash_flow', path: 'key_metrics.free_cash_flow' },
]; ];
// 数组安全检查
if (!Array.isArray(cashflow) || cashflow.length === 0) {
return (
<Alert status="info">
<AlertIcon />
暂无现金流量表数据
</Alert>
);
}
const maxColumns = Math.min(cashflow.length, 8); const maxColumns = Math.min(cashflow.length, 8);
const displayData = cashflow.slice(0, maxColumns); const displayData = cashflow.slice(0, maxColumns);
@@ -1069,6 +1099,16 @@ const FinancialPanorama = ({ stockCode: propStockCode }) => {
} }
}; };
// 数组安全检查
if (!Array.isArray(financialMetrics) || financialMetrics.length === 0) {
return (
<Alert status="info">
<AlertIcon />
暂无财务指标数据
</Alert>
);
}
const maxColumns = Math.min(financialMetrics.length, 6); const maxColumns = Math.min(financialMetrics.length, 6);
const displayData = financialMetrics.slice(0, maxColumns); const displayData = financialMetrics.slice(0, maxColumns);
const currentCategory = metricsCategories[selectedCategory]; const currentCategory = metricsCategories[selectedCategory];
@@ -1426,7 +1466,8 @@ const FinancialPanorama = ({ stockCode: propStockCode }) => {
return ( return (
<VStack spacing={4} align="stretch"> <VStack spacing={4} align="stretch">
{industryRank.map((periodData, periodIdx) => ( {Array.isArray(industryRank) && industryRank.length > 0 ? (
industryRank.map((periodData, periodIdx) => (
<Card key={periodIdx}> <Card key={periodIdx}>
<CardHeader> <CardHeader>
<HStack justify="space-between"> <HStack justify="space-between">
@@ -1486,7 +1527,16 @@ const FinancialPanorama = ({ stockCode: propStockCode }) => {
))} ))}
</CardBody> </CardBody>
</Card> </Card>
))} ))
) : (
<Card>
<CardBody>
<Text textAlign="center" color="gray.500" py={8}>
暂无行业排名数据
</Text>
</CardBody>
</Card>
)}
</VStack> </VStack>
); );
}; };
@@ -1738,7 +1788,7 @@ const FinancialPanorama = ({ stockCode: propStockCode }) => {
// 综合对比分析 // 综合对比分析
const ComparisonAnalysis = () => { const ComparisonAnalysis = () => {
if (!comparison || comparison.length === 0) return null; if (!Array.isArray(comparison) || comparison.length === 0) return null;
const revenueData = comparison.map(item => ({ const revenueData = comparison.map(item => ({
period: formatUtils.getReportType(item.period), period: formatUtils.getReportType(item.period),

View File

@@ -1471,7 +1471,7 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
</HStack> </HStack>
</StatLabel> </StatLabel>
<StatNumber color={theme.textPrimary} fontSize="lg"> <StatNumber color={theme.textPrimary} fontSize="lg">
{minuteData.data[0]?.open.toFixed(2)} {minuteData.data[0]?.open != null ? minuteData.data[0].open.toFixed(2) : '-'}
</StatNumber> </StatNumber>
</Stat> </Stat>
<Stat> <Stat>
@@ -1485,13 +1485,15 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
color={minuteData.data[minuteData.data.length - 1]?.close >= minuteData.data[0]?.open ? theme.success : theme.danger} color={minuteData.data[minuteData.data.length - 1]?.close >= minuteData.data[0]?.open ? theme.success : theme.danger}
fontSize="lg" fontSize="lg"
> >
{minuteData.data[minuteData.data.length - 1]?.close.toFixed(2)} {minuteData.data[minuteData.data.length - 1]?.close != null ? minuteData.data[minuteData.data.length - 1].close.toFixed(2) : '-'}
</StatNumber> </StatNumber>
<StatHelpText fontSize="xs"> <StatHelpText fontSize="xs">
<StatArrow <StatArrow
type={minuteData.data[minuteData.data.length - 1]?.close >= minuteData.data[0]?.open ? 'increase' : 'decrease'} type={minuteData.data[minuteData.data.length - 1]?.close >= minuteData.data[0]?.open ? 'increase' : 'decrease'}
/> />
{Math.abs(((minuteData.data[minuteData.data.length - 1]?.close - minuteData.data[0]?.open) / minuteData.data[0]?.open * 100)).toFixed(2)}% {(minuteData.data[minuteData.data.length - 1]?.close != null && minuteData.data[0]?.open != null)
? Math.abs(((minuteData.data[minuteData.data.length - 1].close - minuteData.data[0].open) / minuteData.data[0].open * 100)).toFixed(2)
: '0.00'}%
</StatHelpText> </StatHelpText>
</Stat> </Stat>
<Stat> <Stat>
@@ -1502,7 +1504,10 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
</HStack> </HStack>
</StatLabel> </StatLabel>
<StatNumber color={theme.success} fontSize="lg"> <StatNumber color={theme.success} fontSize="lg">
{Math.max(...minuteData.data.map(item => item.high)).toFixed(2)} {(() => {
const highs = minuteData.data.map(item => item.high).filter(h => h != null);
return highs.length > 0 ? Math.max(...highs).toFixed(2) : '-';
})()}
</StatNumber> </StatNumber>
</Stat> </Stat>
<Stat> <Stat>
@@ -1513,7 +1518,10 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
</HStack> </HStack>
</StatLabel> </StatLabel>
<StatNumber color={theme.danger} fontSize="lg"> <StatNumber color={theme.danger} fontSize="lg">
{Math.min(...minuteData.data.map(item => item.low)).toFixed(2)} {(() => {
const lows = minuteData.data.map(item => item.low).filter(l => l != null);
return lows.length > 0 ? Math.min(...lows).toFixed(2) : '-';
})()}
</StatNumber> </StatNumber>
</Stat> </Stat>
</SimpleGrid> </SimpleGrid>
@@ -1558,7 +1566,10 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
平均价格 平均价格
</Text> </Text>
<Text fontSize="sm" color={theme.textPrimary}> <Text fontSize="sm" color={theme.textPrimary}>
{(minuteData.data.reduce((sum, item) => sum + item.close, 0) / minuteData.data.length).toFixed(2)} {(() => {
const closes = minuteData.data.map(item => item.close).filter(c => c != null);
return closes.length > 0 ? (closes.reduce((sum, c) => sum + c, 0) / closes.length).toFixed(2) : '-';
})()}
</Text> </Text>
</Box> </Box>
<Box> <Box>
@@ -1744,7 +1755,7 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
成交额: {formatUtils.formatNumber(dayStats.total_amount)}万元 成交额: {formatUtils.formatNumber(dayStats.total_amount)}万元
</Badge> </Badge>
<Badge colorScheme="purple" fontSize="md"> <Badge colorScheme="purple" fontSize="md">
均价: {dayStats.avg_price.toFixed(2)} 均价: {dayStats.avg_price != null ? dayStats.avg_price.toFixed(2) : '-'}
</Badge> </Badge>
</HStack> </HStack>
</HStack> </HStack>
@@ -1766,23 +1777,23 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
{dayStats.deals.map((deal, i) => ( {dayStats.deals.map((deal, i) => (
<Tr key={i} _hover={{ bg: colorMode === 'light' ? 'rgba(43, 108, 176, 0.05)' : 'rgba(255, 215, 0, 0.1)' }}> <Tr key={i} _hover={{ bg: colorMode === 'light' ? 'rgba(43, 108, 176, 0.05)' : 'rgba(255, 215, 0, 0.1)' }}>
<Td color={theme.textPrimary} fontSize="xs" maxW="200px" isTruncated> <Td color={theme.textPrimary} fontSize="xs" maxW="200px" isTruncated>
<Tooltip label={deal.buyer_dept} placement="top"> <Tooltip label={deal.buyer_dept || '-'} placement="top">
<Text>{deal.buyer_dept}</Text> <Text>{deal.buyer_dept || '-'}</Text>
</Tooltip> </Tooltip>
</Td> </Td>
<Td color={theme.textPrimary} fontSize="xs" maxW="200px" isTruncated> <Td color={theme.textPrimary} fontSize="xs" maxW="200px" isTruncated>
<Tooltip label={deal.seller_dept} placement="top"> <Tooltip label={deal.seller_dept || '-'} placement="top">
<Text>{deal.seller_dept}</Text> <Text>{deal.seller_dept || '-'}</Text>
</Tooltip> </Tooltip>
</Td> </Td>
<Td isNumeric color={theme.textPrimary} fontWeight="bold"> <Td isNumeric color={theme.textPrimary} fontWeight="bold">
{deal.price.toFixed(2)} {deal.price != null ? deal.price.toFixed(2) : '-'}
</Td> </Td>
<Td isNumeric color={theme.textPrimary}> <Td isNumeric color={theme.textPrimary}>
{deal.volume.toFixed(2)} {deal.volume != null ? deal.volume.toFixed(2) : '-'}
</Td> </Td>
<Td isNumeric color={theme.textSecondary} fontWeight="bold"> <Td isNumeric color={theme.textSecondary} fontWeight="bold">
{deal.amount.toFixed(2)} {deal.amount != null ? deal.amount.toFixed(2) : '-'}
</Td> </Td>
</Tr> </Tr>
))} ))}
@@ -1845,7 +1856,8 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
买入前五 买入前五
</Text> </Text>
<VStack spacing={1} align="stretch"> <VStack spacing={1} align="stretch">
{dayData.buyers.slice(0, 5).map((buyer, i) => ( {dayData.buyers && dayData.buyers.length > 0 ? (
dayData.buyers.slice(0, 5).map((buyer, i) => (
<HStack <HStack
key={i} key={i}
justify="space-between" justify="space-between"
@@ -1860,7 +1872,10 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
{formatUtils.formatNumber(buyer.buy_amount)} {formatUtils.formatNumber(buyer.buy_amount)}
</Text> </Text>
</HStack> </HStack>
))} ))
) : (
<Text fontSize="sm" color={theme.textMuted}>暂无数据</Text>
)}
</VStack> </VStack>
</Box> </Box>
@@ -1869,7 +1884,8 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
卖出前五 卖出前五
</Text> </Text>
<VStack spacing={1} align="stretch"> <VStack spacing={1} align="stretch">
{dayData.sellers.slice(0, 5).map((seller, i) => ( {dayData.sellers && dayData.sellers.length > 0 ? (
dayData.sellers.slice(0, 5).map((seller, i) => (
<HStack <HStack
key={i} key={i}
justify="space-between" justify="space-between"
@@ -1884,7 +1900,10 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
{formatUtils.formatNumber(seller.sell_amount)} {formatUtils.formatNumber(seller.sell_amount)}
</Text> </Text>
</HStack> </HStack>
))} ))
) : (
<Text fontSize="sm" color={theme.textMuted}>暂无数据</Text>
)}
</VStack> </VStack>
</Box> </Box>
</Grid> </Grid>
@@ -1948,7 +1967,8 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
{pledgeData.map((item, idx) => ( {Array.isArray(pledgeData) && pledgeData.length > 0 ? (
pledgeData.map((item, idx) => (
<Tr key={idx} _hover={{ bg: colorMode === 'light' ? theme.bgDark : 'rgba(255, 215, 0, 0.1)' }}> <Tr key={idx} _hover={{ bg: colorMode === 'light' ? theme.bgDark : 'rgba(255, 215, 0, 0.1)' }}>
<Td color={theme.textPrimary}>{item.end_date}</Td> <Td color={theme.textPrimary}>{item.end_date}</Td>
<Td isNumeric color={theme.textPrimary}>{formatUtils.formatNumber(item.unrestricted_pledge, 0)}</Td> <Td isNumeric color={theme.textPrimary}>{formatUtils.formatNumber(item.unrestricted_pledge, 0)}</Td>
@@ -1960,7 +1980,14 @@ const MarketDataView = ({ stockCode: propStockCode }) => {
</Td> </Td>
<Td isNumeric color={theme.textPrimary}>{item.pledge_count}</Td> <Td isNumeric color={theme.textPrimary}>{item.pledge_count}</Td>
</Tr> </Tr>
))} ))
) : (
<Tr>
<Td colSpan={7} textAlign="center" py={8}>
<Text fontSize="sm" color={theme.textMuted}>暂无数据</Text>
</Td>
</Tr>
)}
</Tbody> </Tbody>
</Table> </Table>
</TableContainer> </TableContainer>