以日历的形式,展示支出数据
SalesCalendar组件
import { FC, useState, useEffect } from 'react';
import styles from './index.module.scss';
interface ISalesCalendar {
SalesData: any;
year: number;
month: number;
}
const SalesCalendar: FC<ISalesCalendar> = (props: ISalesCalendar) => {
const { SalesData, year, month } = props;
const [currentDate, setCurrentDate] = useState<string>('');
useEffect(() => {
const today = new Date();
setCurrentDate(today.toISOString().split('T')[0]); // 格式化为 YYYY-MM-DD
}, []);
// 获取指定月份的第一天是星期几,以及该月的天数
const getMonthInfo = (year: number, month: number) => {
// 获取该月的第一天
const firstDay = new Date(year, month - 1, 1);
const firstDayOfWeek = firstDay.getDay(); // 获取第一天是星期几
const daysInMonth = new Date(year, month, 0).getDate(); // 获取该月的天数
return { firstDayOfWeek, daysInMonth };
};
// 获取该月的日历数据
const { firstDayOfWeek, daysInMonth } = getMonthInfo(year, month);
// 将 SalesData 转换为一个对象,方便通过日期查找对应的收入
const salesMap: { [key: string]: number } = {};
SalesData.forEach((item: any) => {
salesMap[item.data] = item.coins;
});
// 获取当前月的所有日期和对应的收入
const calendarDays: any = Array.from({ length: daysInMonth }, (_, i) => {
const day = i + 1;
const formattedDate = `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`;
return {
day,
coins: salesMap[formattedDate] || 0, // 如果没有对应的收入,则为 0
formattedDate,
};
});
// 填充日历,添加前置空白(补齐到第一天的星期几)
const calendarCells = Array.from({ length: firstDayOfWeek })
.map(() => null)
.concat(calendarDays);
// 获取当前日期的高亮样式
const isToday = (date: string) => date === currentDate;
console.log(Array.from({ length: firstDayOfWeek }), firstDayOfWeek, calendarCells);
return (
<div className={styles.sales_calendar}>
{/* 日历头部 */}
<div className={'flex f-ai-c f-jc-sb'}>
{['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'].map(day => (
<div className={styles.name} key={day} style={{}}>
{day}
</div>
))}
</div>
<div className="days" style={{ display: 'flex', flexWrap: 'wrap' }}>
{calendarCells.map((cell, index) => {
if (cell === null) {
return <div key={index} style={{ width: '14%', height: '60px' }}></div>;
}
const { day, coins, formattedDate } = cell;
return (
<div
key={formattedDate}
style={{
width: '14%',
height: '80px',
textAlign: 'center',
padding: '5px',
backgroundColor: isToday(formattedDate) ? '#f39c12' : '#ecf0f1',
border: '1px solid #bdc3c7',
borderRadius: '5px',
marginBottom: '5px',
position: 'relative',
}}
>
<div>{day}</div>
<div style={{ fontSize: '12px', color: '#2c3e50' }}>{coins > 0 ? `${coins} coins` : ''}</div>
{isToday(formattedDate) && (
<div
style={{
position: 'absolute',
top: '5px',
right: '5px',
fontSize: '12px',
color: 'white',
backgroundColor: 'red',
padding: '2px 5px',
borderRadius: '5px',
}}
>
今天
</div>
)}
</div>
);
})}
</div>
</div>
);
};
export default SalesCalendar;
运用
const SalesData = [
{ data: '2025-01-01', 支出: 1000 },
{ data: '2025-01-02', 支出: 3000 },
{ data: '2025-01-03', 支出: 5000 },
{ data: '2025-01-04', 支出: 7000 },
{ data: '2025-01-05', 支出: 9000 },
{ data: '2025-01-06', 支出: 11000 },
{ data: '2025-01-07', 支出: 13000 },
{ data: '2025-01-08', 支出: 15000 },
{ data: '2025-01-09', 支出: 17000 },
{ data: '2025-01-10', 支出: 19000 },
];
<SalesCalendar SalesData={SalesData} year={2025} month={1} />