update ui
This commit is contained in:
@@ -14,11 +14,6 @@ import {
|
||||
useColorModeValue,
|
||||
SimpleGrid,
|
||||
Icon,
|
||||
Stat,
|
||||
StatLabel,
|
||||
StatNumber,
|
||||
StatHelpText,
|
||||
StatArrow,
|
||||
Spinner,
|
||||
Center,
|
||||
} from '@chakra-ui/react';
|
||||
@@ -27,15 +22,20 @@ import ReactECharts from 'echarts-for-react';
|
||||
import { logger } from '../../../utils/logger';
|
||||
|
||||
/**
|
||||
* 获取指数行情数据
|
||||
* 获取指数行情数据(日线数据)
|
||||
*/
|
||||
const fetchIndexKline = async (indexCode) => {
|
||||
try {
|
||||
const response = await fetch(`/api/index/${indexCode}/kline`);
|
||||
// 使用日线数据,获取最近60个交易日
|
||||
const response = await fetch(`/api/index/${indexCode}/kline?type=daily`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
logger.debug('HeroPanel', 'fetchIndexKline success', { indexCode, dataLength: data?.data?.length });
|
||||
return data;
|
||||
} catch (error) {
|
||||
logger.error('HeroPanel', 'fetchIndexKline', error);
|
||||
logger.error('HeroPanel', 'fetchIndexKline error', { indexCode, error: error.message });
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -86,30 +86,41 @@ const MiniIndexChart = ({ indexCode, indexName }) => {
|
||||
const areaColor = useColorModeValue('rgba(255, 215, 0, 0.15)', 'rgba(255, 215, 0, 0.1)');
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
const loadData = async () => {
|
||||
setLoading(true);
|
||||
const data = await fetchIndexKline(indexCode);
|
||||
|
||||
if (data && data.data && data.data.length > 0) {
|
||||
if (isMounted && data && data.data && data.data.length > 0) {
|
||||
// 取最近一个交易日的数据
|
||||
const latest = data.data[data.data.length - 1];
|
||||
const prevClose = latest.prev_close || latest.close;
|
||||
|
||||
setLatestData({
|
||||
close: latest[2],
|
||||
change: ((latest[2] - latest[1]) / latest[1] * 100).toFixed(2),
|
||||
isPositive: latest[2] >= latest[1]
|
||||
close: latest.close,
|
||||
change: prevClose ? (((latest.close - prevClose) / prevClose) * 100).toFixed(2) : '0.00',
|
||||
isPositive: latest.close >= prevClose
|
||||
});
|
||||
|
||||
// 准备图表数据(最近60个交易日)
|
||||
const recentData = data.data.slice(-60);
|
||||
setChartData({
|
||||
dates: recentData.map(item => item[0]),
|
||||
values: recentData.map(item => item[2])
|
||||
dates: recentData.map(item => item.time),
|
||||
values: recentData.map(item => item.close)
|
||||
});
|
||||
}
|
||||
setLoading(false);
|
||||
|
||||
if (isMounted) {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
loadData();
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
}, [indexCode]);
|
||||
|
||||
const chartOption = useMemo(() => {
|
||||
@@ -184,13 +195,12 @@ const MiniIndexChart = ({ indexCode, indexName }) => {
|
||||
</Text>
|
||||
</VStack>
|
||||
<HStack spacing={1}>
|
||||
<StatArrow type={latestData?.isPositive ? 'increase' : 'decrease'} />
|
||||
<Text
|
||||
fontSize="sm"
|
||||
fontWeight="bold"
|
||||
color={latestData?.isPositive ? 'green.300' : 'red.300'}
|
||||
>
|
||||
{latestData?.isPositive ? '+' : ''}{latestData?.change}%
|
||||
{latestData?.isPositive ? '↑' : '↓'} {latestData?.isPositive ? '+' : ''}{latestData?.change}%
|
||||
</Text>
|
||||
</HStack>
|
||||
</HStack>
|
||||
@@ -215,14 +225,24 @@ const ConceptWordCloud = () => {
|
||||
const chartBg = useColorModeValue('transparent', 'transparent');
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
const loadConcepts = async () => {
|
||||
setLoading(true);
|
||||
const data = await fetchPopularConcepts();
|
||||
setConcepts(data);
|
||||
setLoading(false);
|
||||
if (isMounted && data && data.length > 0) {
|
||||
setConcepts(data);
|
||||
}
|
||||
if (isMounted) {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
loadConcepts();
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const chartOption = useMemo(() => {
|
||||
|
||||
Reference in New Issue
Block a user