community增加事件详情

This commit is contained in:
2026-01-07 15:30:48 +08:00
parent 36bec225b3
commit c05def335f
2 changed files with 89 additions and 81 deletions

View File

@@ -224,7 +224,7 @@ export const FullCalendarPro: React.FC<FullCalendarProProps> = ({
onMonthChange?.(visibleDate.getFullYear(), visibleDate.getMonth() + 1);
}, [onMonthChange]);
// 自定义日期单元格内容
// 自定义日期单元格内容 - 优化布局,增大字体
const dayCellContent = useCallback((arg: { date: Date; dayNumberText: string; isToday: boolean }) => {
const dateStr = dayjs(arg.date).format('YYYYMMDD');
const dateData = dataMap.get(dateStr);
@@ -234,69 +234,64 @@ export const FullCalendarPro: React.FC<FullCalendarProProps> = ({
const hasIndexChange = dateData?.indexChange !== undefined && dateData?.indexChange !== null;
return (
<Box position="relative" w="100%" h="100%">
{/* 日期数字 */}
<Text
fontSize="lg"
fontWeight={arg.isToday ? 'bold' : '600'}
color={arg.isToday ? '#FFD700' : isWeekend ? 'orange.300' : 'white'}
textAlign="center"
>
{arg.date.getDate()}
</Text>
{/* 上证指数涨跌幅 */}
{hasIndexChange && (
<Box position="relative" w="100%" h="100%" py={1}>
{/* 顶部:日期数字 + 上证涨跌幅 */}
<HStack justify="space-between" align="flex-start" px={1}>
<Text
fontSize="10px"
fontWeight="600"
color={dateData.indexChange! >= 0 ? '#EF4444' : '#22C55E'}
textAlign="center"
mt={0.5}
fontSize="xl"
fontWeight={arg.isToday ? 'bold' : '600'}
color={arg.isToday ? '#FFD700' : isWeekend ? 'orange.300' : 'white'}
>
{dateData.indexChange! >= 0 ? '+' : ''}{dateData.indexChange!.toFixed(2)}%
{arg.date.getDate()}
</Text>
)}
{/* 涨停数据指示器 */}
{hasZtData && (
<HStack
spacing={1}
justify="center"
mt={hasIndexChange ? 0 : 1}
>
<Flame size={12} color={dateData.count >= 60 ? '#EF4444' : '#F59E0B'} />
<Text fontSize="xs" fontWeight="bold" color={dateData.count >= 60 ? '#EF4444' : '#F59E0B'}>
{dateData.count}
</Text>
</HStack>
)}
{/* 未来事件计数 - 显示具体数字而非小圆点 */}
{hasEventCount && (
<HStack
spacing={1}
justify="center"
mt={hasZtData ? 0 : 1}
>
<Box
w="14px"
h="14px"
borderRadius="full"
bg="linear-gradient(135deg, #22C55E 0%, #16A34A 100%)"
display="flex"
alignItems="center"
justifyContent="center"
{/* 上证指数涨跌幅 - 右上角显示 */}
{hasIndexChange && (
<Text
fontSize="sm"
fontWeight="700"
color={dateData.indexChange! >= 0 ? '#EF4444' : '#22C55E'}
>
<Text fontSize="9px" fontWeight="bold" color="white">
{dateData.eventCount}
</Text>
</Box>
<Text fontSize="10px" color="#22C55E" fontWeight="500">
{dateData.indexChange! >= 0 ? '+' : ''}{dateData.indexChange!.toFixed(2)}%
</Text>
</HStack>
)}
)}
</HStack>
{/* 中间区域:涨停数 + 事件数 */}
<VStack spacing={1} mt={1} align="stretch">
{/* 涨停数据 */}
{hasZtData && (
<HStack spacing={1.5} justify="center">
<Flame size={16} color={dateData.count >= 60 ? '#EF4444' : '#F59E0B'} />
<Text fontSize="md" fontWeight="bold" color={dateData.count >= 60 ? '#EF4444' : '#F59E0B'}>
{dateData.count}
</Text>
</HStack>
)}
{/* 未来事件计数 */}
{hasEventCount && (
<HStack spacing={1.5} justify="center">
<Box
w="18px"
h="18px"
borderRadius="full"
bg="linear-gradient(135deg, #22C55E 0%, #16A34A 100%)"
display="flex"
alignItems="center"
justifyContent="center"
boxShadow="0 0 6px rgba(34, 197, 94, 0.4)"
>
<Text fontSize="xs" fontWeight="bold" color="white">
{dateData.eventCount}
</Text>
</Box>
<Text fontSize="sm" color="#22C55E" fontWeight="600">
</Text>
</HStack>
)}
</VStack>
</Box>
);
}, [dataMap]);
@@ -327,9 +322,9 @@ export const FullCalendarPro: React.FC<FullCalendarProProps> = ({
>
<Box
w="100%"
h="22px"
h="26px"
bg={gradient}
borderRadius="md"
borderRadius="lg"
border={`1px solid ${borderColor}`}
display="flex"
alignItems="center"
@@ -356,17 +351,17 @@ export const FullCalendarPro: React.FC<FullCalendarProProps> = ({
opacity={0.5}
/>
<Text
fontSize="xs"
fontSize="sm"
fontWeight="bold"
color={textColor}
noOfLines={1}
px={2}
px={3}
position="relative"
zIndex={1}
>
{arg.event.title}
{daysCount > 1 && (
<Text as="span" fontSize="10px" ml={1} opacity={0.8}>
<Text as="span" fontSize="xs" ml={1} opacity={0.8}>
({daysCount})
</Text>
)}
@@ -444,36 +439,36 @@ export const FullCalendarPro: React.FC<FullCalendarProProps> = ({
animation: `${glow} 2s ease-in-out infinite`,
},
'.fc-daygrid-day-frame': {
minHeight: '90px',
minHeight: '110px',
},
'.fc-daygrid-day-top': {
justifyContent: 'center',
pt: '8px',
display: 'none', // 隐藏默认日期显示,使用自定义
},
'.fc-daygrid-day-number': {
fontSize: '16px',
fontWeight: '600',
color: 'white',
display: 'none', // 隐藏默认数字
},
'.fc-day-today .fc-daygrid-day-number': {
color: '#FFD700 !important',
fontWeight: 'bold !important',
display: 'none',
},
// 非当月日期
'.fc-day-other': {
opacity: 0.4,
},
// 日期内容区域
'.fc-daygrid-day-events': {
marginTop: '0 !important',
},
// 事件
'.fc-daygrid-event': {
borderRadius: '6px',
borderRadius: '8px',
border: 'none !important',
margin: '2px 4px !important',
margin: '3px 4px !important',
},
'.fc-event-main': {
padding: '0 !important',
},
'.fc-daygrid-event-harness': {
marginTop: '2px',
marginTop: '3px',
},
// 更多事件链接
'.fc-daygrid-more-link': {

View File

@@ -26,12 +26,19 @@ export const generateTimelineData = (indexCode) => {
/**
* 生成日线数据 (daily)
* 用于获取历史收盘价等数据
* 默认生成 400 天的数据,覆盖足够的历史范围
*/
export const generateDailyData = (indexCode, days = 30) => {
export const generateDailyData = (indexCode, days = 400) => {
const data = [];
const basePrice = getBasePrice(indexCode);
const today = new Date();
// 使用固定种子生成一致的随机数,确保同一天的涨跌幅一致
const seededRandom = (seed) => {
const x = Math.sin(seed) * 10000;
return x - Math.floor(x);
};
for (let i = days - 1; i >= 0; i--) {
const date = new Date(today);
date.setDate(date.getDate() - i);
@@ -40,11 +47,17 @@ export const generateDailyData = (indexCode, days = 30) => {
const dayOfWeek = date.getDay();
if (dayOfWeek === 0 || dayOfWeek === 6) continue;
const open = basePrice * (1 + (Math.random() * 0.04 - 0.02));
const close = open * (1 + (Math.random() * 0.03 - 0.015));
const high = Math.max(open, close) * (1 + Math.random() * 0.015);
const low = Math.min(open, close) * (1 - Math.random() * 0.015);
const volume = Math.floor(Math.random() * 50000000000 + 10000000000);
// 使用日期作为种子,确保同一天生成相同的数据
const dateSeed = date.getFullYear() * 10000 + (date.getMonth() + 1) * 100 + date.getDate();
const rand1 = seededRandom(dateSeed);
const rand2 = seededRandom(dateSeed + 1);
const rand3 = seededRandom(dateSeed + 2);
const open = basePrice * (1 + (rand1 * 0.04 - 0.02));
const close = open * (1 + (rand2 * 0.03 - 0.015));
const high = Math.max(open, close) * (1 + rand3 * 0.015);
const low = Math.min(open, close) * (1 - seededRandom(dateSeed + 3) * 0.015);
const volume = Math.floor(seededRandom(dateSeed + 4) * 50000000000 + 10000000000);
data.push({
date: formatDate(date),
@@ -54,7 +67,7 @@ export const generateDailyData = (indexCode, days = 30) => {
high: parseFloat(high.toFixed(2)),
low: parseFloat(low.toFixed(2)),
volume: volume,
prev_close: i === 0 ? parseFloat((basePrice * 0.99).toFixed(2)) : data[data.length - 1]?.close
prev_close: data.length === 0 ? parseFloat((basePrice * 0.99).toFixed(2)) : data[data.length - 1]?.close
});
}