需求:公司需要开发一个日程功能(ps:和钉钉一模一样),需要查看不同的时间段的成员闲忙状态,因此需要将后端返回的数据将时间有重叠的数据进行分组显示,方便创建人可以更直观的查看
// 测试数据
const data = [
{
startTime: '2023-11-23 10:00',
endTime: '2023-11-23 11:00',
title: '吃饭',
},
{
startTime: '2023-11-23 11:00',
endTime: '2023-11-23 12:00',
title: '睡觉',
},
{
startTime: '2023-11-23 10:30',
endTime: '2023-11-23 13:00',
title: '打豆豆',
},
{
startTime: '2023-11-23 15:30',
endTime: '2023-11-23 16:30',
title: '打豆豆',
},
{
startTime: '2023-11-23 17:30',
endTime: '2023-11-23 18:30',
title: '打豆豆',
},
{
startTime: '2023-11-23 15:30',
endTime: '2023-11-23 18:30',
title: '开会',
}
]
// 日期转时间戳,注意如果是ios设备,日期格式化的时候需要将短横线替换成斜线
const handleDateToTimestamp = (date) => {
return new Date(date).getTime();
};
const handleCalendarData = (data) => {
// 将数据按开始时间升序排列
const newData = data
.sort(
(a, b) =>
handleDateToTimestamp(a.startTime) - handleDateToTimestamp(b.startTime)
);
const tempArray = []; // 存储最终返回值,格式为二维数组
const IndexList = []; // 记录已经处理过的数据下标,下次循环直接跳过
for (let index = 0; index < newData.length; index++) {
if (IndexList.includes(index)) continue;
const startTime = handleDateToTimestamp(newData[index].startTime);
let endTime = handleDateToTimestamp(newData[index].endTime);
IndexList.push(index);
const InnerArray = [newData[index]];
for (let n = 1; n < newData.length; n++) {
if (IndexList.includes(n)) continue;
// 将日期转时间戳进行对比,如果n的开始时间大于等于index的开始时间,且小于等于index的结束时间,则说明时间有交叉,结束时间同理
if (
(handleDateToTimestamp(newData[n].startTime) >= startTime &&
handleDateToTimestamp(newData[n].startTime) <= endTime) ||
(handleDateToTimestamp(newData[n].endTime) >= startTime &&
handleDateToTimestamp(newData[n].endTime) <= endTime)
) {
// 取两个结束时间中的最大值作为下一次循环对比的结束时间
endTime = Math.max(handleDateToTimestamp(newData[n].endTime), endTime);
InnerArray.push(newData[n]);
IndexList.push(n);
}
}
tempArray.push(InnerArray);
};
return tempArray;
}