update pay promo
This commit is contained in:
@@ -1,30 +1,73 @@
|
||||
// 热门板块/概念排行组件 - 紧凑版(与 WatchlistPanel 风格保持一致)
|
||||
import React from 'react';
|
||||
import { Box, Text, VStack, HStack, Icon } from '@chakra-ui/react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Box, Text, VStack, HStack, Icon, Spinner } from '@chakra-ui/react';
|
||||
import { TrendingUp, Flame } from 'lucide-react';
|
||||
import { getApiBase } from '@utils/apiConfig';
|
||||
import MiniTrendLine from './MiniTrendLine';
|
||||
|
||||
/**
|
||||
* 根据涨跌幅生成模拟趋势数据
|
||||
* @param {number} change - 涨跌幅
|
||||
* @returns {number[]} 趋势数据数组
|
||||
*/
|
||||
const generateTrendFromChange = (change) => {
|
||||
const baseValue = 100;
|
||||
const points = 6;
|
||||
const trend = [baseValue];
|
||||
const direction = change >= 0 ? 1 : -1;
|
||||
const step = Math.abs(change) / points;
|
||||
|
||||
for (let i = 1; i < points; i++) {
|
||||
// 添加一些随机波动,但保持整体趋势方向
|
||||
const randomFactor = (Math.random() - 0.5) * step * 0.5;
|
||||
const value = baseValue + direction * (step * i + randomFactor);
|
||||
trend.push(value);
|
||||
}
|
||||
// 最后一个点确保反映实际涨跌幅
|
||||
trend.push(baseValue * (1 + change / 100));
|
||||
return trend;
|
||||
};
|
||||
|
||||
const HotSectorsRanking = ({ sectors = [], title = '热门板块', type = 'sector', onSectorClick }) => {
|
||||
// 默认板块数据
|
||||
const defaultSectors = [
|
||||
{ rank: 1, name: '人工智能', change: 3.2, trend: [100, 102, 101, 104, 103, 106] },
|
||||
{ rank: 2, name: '新能源车', change: 1.8, trend: [100, 99, 101, 102, 101, 103] },
|
||||
{ rank: 3, name: '生物医药', change: 1.3, trend: [100, 101, 100, 102, 101, 102] },
|
||||
{ rank: 4, name: '消费科技', change: 1.2, trend: [100, 100, 101, 100, 102, 102] },
|
||||
{ rank: 5, name: '芯片半导体', change: 0.4, trend: [100, 100, 100, 101, 100, 101] },
|
||||
];
|
||||
const [apiData, setApiData] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// 默认概念数据
|
||||
const defaultConcepts = [
|
||||
{ rank: 1, name: '锂电池', change: 4.5, trend: [100, 103, 105, 104, 108, 110] },
|
||||
{ rank: 2, name: '人工智能', change: 3.8, trend: [100, 102, 104, 103, 106, 108] },
|
||||
{ rank: 3, name: '机器人', change: 2.9, trend: [100, 101, 103, 102, 104, 106] },
|
||||
{ rank: 4, name: '国企改革', change: 2.1, trend: [100, 101, 102, 101, 103, 104] },
|
||||
{ rank: 5, name: '新能源', change: 1.6, trend: [100, 100, 101, 102, 101, 103] },
|
||||
];
|
||||
// 从 API 获取热门概念数据
|
||||
useEffect(() => {
|
||||
// 如果外部传入了数据,则不调用 API
|
||||
if (sectors.length > 0) return;
|
||||
|
||||
const defaultData = type === 'concept' ? defaultConcepts : defaultSectors;
|
||||
const data = sectors.length > 0 ? sectors : defaultData;
|
||||
const fetchHotConcepts = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await fetch(`${getApiBase()}/api/concepts/daily-top?limit=5`);
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success && result.data) {
|
||||
// 转换 API 数据为组件所需格式
|
||||
const formattedData = result.data.map((concept, index) => ({
|
||||
rank: index + 1,
|
||||
name: concept.concept_name || concept.concept,
|
||||
change: concept.change_percent || 0,
|
||||
trend: generateTrendFromChange(concept.change_percent || 0),
|
||||
// 保留原始数据供点击事件使用
|
||||
concept_id: concept.concept_id,
|
||||
stocks: concept.stocks,
|
||||
}));
|
||||
setApiData(formattedData);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取热门概念失败:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchHotConcepts();
|
||||
}, [sectors.length]);
|
||||
|
||||
// 优先使用外部传入的数据,其次使用 API 数据
|
||||
const data = sectors.length > 0 ? sectors : apiData;
|
||||
|
||||
// 根据类型选择图标和颜色
|
||||
const IconComponent = type === 'concept' ? Flame : TrendingUp;
|
||||
@@ -45,7 +88,23 @@ const HotSectorsRanking = ({ sectors = [], title = '热门板块', type = 'secto
|
||||
</HStack>
|
||||
</HStack>
|
||||
|
||||
{/* 加载状态 */}
|
||||
{loading && (
|
||||
<HStack justify="center" py={4}>
|
||||
<Spinner size="sm" color="purple.400" />
|
||||
<Text fontSize="xs" color="rgba(255, 255, 255, 0.5)">加载中...</Text>
|
||||
</HStack>
|
||||
)}
|
||||
|
||||
{/* 无数据提示 */}
|
||||
{!loading && data.length === 0 && (
|
||||
<Text fontSize="xs" color="rgba(255, 255, 255, 0.4)" textAlign="center" py={4}>
|
||||
暂无数据
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{/* 板块列表 - 固定高度可滚动 */}
|
||||
{!loading && data.length > 0 && (
|
||||
<Box
|
||||
maxH="200px"
|
||||
overflowY="auto"
|
||||
@@ -122,6 +181,7 @@ const HotSectorsRanking = ({ sectors = [], title = '热门板块', type = 'secto
|
||||
})}
|
||||
</VStack>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user