实现效果

特殊需求
依赖组件
完整代码
import React, {useState, useEffect} from 'react';
import {Icon} from 'antd-mobile';
import styles from './index.less';
import moment from 'moment';
import {useSelector} from "dva";
moment.locale('zh-cn');
const dateFormatStr = 'YYYY-MM-DD';
const monthFormatterStr = 'YYYY年MM月';
const week = ['星期一', '星期二', '星期三', '星期四', '星期五']
const CustomCalendar = () => {
const {rehydrated} = useSelector(state => state._persist);
const {everyDayList} = useSelector(state => state.lianLianYing);
const [currentDate, setCurrentDate] = useState(moment());
const [dayList, setDayList] = useState([]);
const {loginStatus} = useSelector(state => state.global);
useEffect(() => {
if (!rehydrated || !loginStatus) return;
let temp = getMonthFirstDate(currentDate).endOf('month');
initDate();
}, [currentDate, rehydrated, loginStatus, everyDayList]);
const getMonthFirstDate = (date) => {
return moment(date.year() + '-' + (date.month() + 1) + '-01', dateFormatStr);
};
const initDate = () => {
let dateArr = [];
let monthFirstDate = getMonthFirstDate(currentDate);
while (monthFirstDate.day() === 0 || monthFirstDate.day() === 6) {
monthFirstDate.add(1, 'd');
}
let preMonthDate = moment(monthFirstDate).subtract(1, 'M').endOf('month');
while (preMonthDate.day() !== 0 && preMonthDate.day() !== 6 && preMonthDate.day() !== 5) {
let date = {
date: '',
day: preMonthDate.day(),
}
dateArr.push(date);
preMonthDate.subtract(1, 'd');
}
while (monthFirstDate.month() === currentDate.month()) {
if (monthFirstDate.day() !== 0 && monthFirstDate.day() !== 6) {
const dayVal = everyDayList.find((val) => val?.init_date === monthFirstDate.format('YYYYMMDD'));
let date = {
date: monthFirstDate.date(),
day: monthFirstDate.day(),
total: dayVal?.total
}
dateArr.push(date);
}
monthFirstDate.add(1, 'd');
}
setDayList(dateArr);
};
const preMonth = () => {
const newDate = moment(currentDate).subtract(1, 'M');
setCurrentDate(newDate)
};
const nextMonth = () => {
const newDate = moment(currentDate).add(1, 'M');
setCurrentDate(newDate)
};
return <div className={styles.wrap}>
<div className={styles.title}>
<div onClick={preMonth} className={styles.btn}><Icon type={'left'}/></div>
<div>{currentDate.format(monthFormatterStr)}</div>
{currentDate.isBefore(moment(), 'month') ?
<div onClick={nextMonth} className={styles.btn}><Icon type={'right'}/></div> : <div className={styles.btn}/>}
</div>
<div className={styles.week}>
{week.map((item, index) => {
return <div className={styles.weekText} key={index}>{item}</div>
})}
</div>
<div className={styles.days}>
{dayList.map((item, index) => {
return <div className={styles.day} key={index}>
<div className={styles.date}>{item?.date}</div>
{item?.date ?
(item?.total ? (
<div className={item?.total > 0 ? styles.red : styles.green}>{item?.total}</div>
) : <div className={styles.grey}>--</div>)
: <div/>}
</div>
})}
</div>
</div>;
};
export default CustomCalendar;
@import (reference) '../../styles/index.less';
.wrap {
padding: 5*@rem;
.title {
display: flex;
justify-content: center;
align-items: center;
padding-bottom: 10*@rem;
.btn{
width: 50*@rem;
}
& > div {
display: flex;
justify-content: center;
align-items: center;
font-size: 20*@rem;
}
}
.week {
display: flex;
justify-content: space-around;
.weekText {
text-align: right;
flex: 20%;
padding-right: 10*@rem;
}
}
.days {
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
.day {
width: 20%;
padding-right: 5*@rem;
border-top: solid @greyBorder 0.1px;
padding-bottom: 5*@rem;
padding-top: 5*@rem;
color: white;
.date {
height: 30*@rem;
display: flex;
justify-content: flex-end;
align-items: flex-end;
font-size: 16*@rem;
color: black;
padding-right: 5*@rem;
}
.red {
display: flex;
justify-content: flex-end;
align-items: center;
width: 100%;
background: #FF6764;
border-radius: 2*@rem;
padding-right: 5*@rem;
font-size: 14*@rem;
}
.green {
display: flex;
justify-content: flex-end;
align-items: center;
background: #91C874;
border-radius: 2*@rem;
width: 100%;
padding-right: 5*@rem;
font-size: 14*@rem;
}
.grey {
display: flex;
justify-content: flex-end;
align-items: center;
background: #e1e4ea;
border-radius: 2*@rem;
width: 100%;
padding-right: 5*@rem;
font-size: 14*@rem;
}
}
}
}