update pay promo

This commit is contained in:
2026-02-04 17:06:01 +08:00
parent d972150a80
commit 4c8addedc8

View File

@@ -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>
);
};