196 lines
6.4 KiB
JavaScript
196 lines
6.4 KiB
JavaScript
const axios = require('axios');
|
|
|
|
const API_BASE_URL = 'http://47.101.56.101:8976/api/app_calendar';
|
|
|
|
// 复制 recurrence 相关函数
|
|
function parseRecurrenceStr(str) {
|
|
const r = (str || '').trim();
|
|
if (!r) return { type: 'NONE', interval: 0, by: [] };
|
|
const type = r.startsWith('DAILY') ? 'DAILY' : (r.startsWith('WEEKLY') ? 'WEEKLY' : 'NONE');
|
|
const mInt = /interval=(\d+)/.exec(r);
|
|
const interval = mInt ? Math.max(1, parseInt(mInt[1], 10)) : 1;
|
|
const mBy = /by=([0-9,]+)/.exec(r);
|
|
const by = mBy ? mBy[1].split(',').map(s => parseInt(s, 10)).filter(n => n >= 1 && n <= 7) : [];
|
|
return { type, interval, by };
|
|
}
|
|
|
|
function extractDateStr(dateStr) {
|
|
if (dateStr.includes('T')) {
|
|
return dateStr.split('T')[0];
|
|
}
|
|
if (dateStr.includes(' ')) {
|
|
return dateStr.split(' ')[0];
|
|
}
|
|
return dateStr;
|
|
}
|
|
|
|
function safeParseDate(dateStr) {
|
|
try {
|
|
let date = new Date(dateStr);
|
|
if (!isNaN(date.getTime())) {
|
|
return date;
|
|
}
|
|
} catch (e) {}
|
|
|
|
if (dateStr.includes(' ')) {
|
|
try {
|
|
let date = new Date(dateStr.replace(' ', 'T'));
|
|
if (!isNaN(date.getTime())) {
|
|
return date;
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
|
|
const match = dateStr.match(/(\d{4})-(\d{2})-(\d{2})/);
|
|
if (match) {
|
|
const year = parseInt(match[1], 10);
|
|
const month = parseInt(match[2], 10) - 1;
|
|
const day = parseInt(match[3], 10);
|
|
return new Date(year, month, day);
|
|
}
|
|
|
|
return new Date();
|
|
}
|
|
|
|
function shouldShowEventOnDate(event, targetDate) {
|
|
const eventDate = extractDateStr(event.start);
|
|
const targetDateStr = targetDate.toISOString().split('T')[0];
|
|
|
|
if (eventDate === targetDateStr) return true;
|
|
|
|
const evStart = safeParseDate(event.start);
|
|
const targetDayStart = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate());
|
|
const eventStartDay = new Date(evStart.getFullYear(), evStart.getMonth(), evStart.getDate());
|
|
|
|
if (event.end) {
|
|
const evEnd = safeParseDate(event.end);
|
|
const eventEndDay = new Date(evEnd.getFullYear(), evEnd.getMonth(), evEnd.getDate());
|
|
|
|
if (targetDayStart >= eventStartDay && targetDayStart <= eventEndDay) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
const rec = parseRecurrenceStr(event.recurrence);
|
|
if (rec.type === 'NONE') return false;
|
|
|
|
if (targetDayStart < eventStartDay) return false;
|
|
|
|
if (event.end) {
|
|
const evEnd = safeParseDate(event.end);
|
|
const eventEndDay = new Date(evEnd.getFullYear(), evEnd.getMonth(), evEnd.getDate());
|
|
if (targetDayStart > eventEndDay) return false;
|
|
}
|
|
|
|
if (rec.type === 'DAILY') {
|
|
const diffDays = Math.floor((targetDayStart.getTime() - eventStartDay.getTime()) / (24 * 3600 * 1000));
|
|
return diffDays % rec.interval === 0;
|
|
}
|
|
|
|
if (rec.type === 'WEEKLY') {
|
|
const weeksSinceStart = Math.floor((targetDayStart.getTime() - eventStartDay.getTime()) / (7 * 24 * 3600 * 1000));
|
|
const weekday = targetDayStart.getDay() === 0 ? 7 : targetDayStart.getDay();
|
|
const by = rec.by.length ? rec.by : [(safeParseDate(event.start).getDay() || 7)];
|
|
return by.includes(weekday) && (weeksSinceStart % rec.interval === 0);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
async function getEvents(year, month) {
|
|
const response = await axios.get(`${API_BASE_URL}/events`, { params: { year, month } });
|
|
return response.data.data || [];
|
|
}
|
|
|
|
async function loadTodayTabEvents(targetDate) {
|
|
console.log('加载【今日】Tab 数据...');
|
|
const allEvents = await getEvents(targetDate.getFullYear(), targetDate.getMonth() + 1);
|
|
const todayEvents = allEvents.filter(event => {
|
|
if (event.deleted) return false;
|
|
return shouldShowEventOnDate(event, targetDate);
|
|
}).sort((a, b) => safeParseDate(a.start).getTime() - safeParseDate(b.start).getTime());
|
|
|
|
return todayEvents;
|
|
}
|
|
|
|
async function loadCalendarTabEvents(targetDate) {
|
|
console.log('加载【日历】Tab 数据...');
|
|
const allEvents = [];
|
|
const seenIds = new Set();
|
|
|
|
for (let i = -6; i <= 1; i++) {
|
|
let tempDate = new Date(targetDate);
|
|
tempDate.setMonth(tempDate.getMonth() + i);
|
|
const year = tempDate.getFullYear();
|
|
const month = tempDate.getMonth() + 1;
|
|
|
|
const monthEvents = await getEvents(year, month);
|
|
for (const event of monthEvents) {
|
|
if (!seenIds.has(event.id)) {
|
|
seenIds.add(event.id);
|
|
allEvents.push(event);
|
|
}
|
|
}
|
|
}
|
|
|
|
const validEvents = allEvents.filter(e => !e.deleted);
|
|
const targetEvents = validEvents.filter(event => {
|
|
return shouldShowEventOnDate(event, targetDate);
|
|
}).sort((a, b) => safeParseDate(a.start).getTime() - safeParseDate(b.start).getTime());
|
|
|
|
return targetEvents;
|
|
}
|
|
|
|
async function compare() {
|
|
console.log('========================================');
|
|
console.log('对比 2026-06-29 两个 Tab 的事件');
|
|
console.log('========================================\n');
|
|
|
|
const targetDate = new Date(2026, 5, 29);
|
|
|
|
const [todayEvents, calendarEvents] = await Promise.all([
|
|
loadTodayTabEvents(targetDate),
|
|
loadCalendarTabEvents(targetDate)
|
|
]);
|
|
|
|
console.log('\n===== 【今日】Tab 2026-06-29 事件 =====');
|
|
console.log('总数:', todayEvents.length);
|
|
todayEvents.forEach((event, index) => {
|
|
console.log(`${index + 1}. ${event.title} (id: ${event.id})`);
|
|
});
|
|
|
|
console.log('\n===== 【日历】Tab 2026-06-29 事件 =====');
|
|
console.log('总数:', calendarEvents.length);
|
|
calendarEvents.forEach((event, index) => {
|
|
console.log(`${index + 1}. ${event.title} (id: ${event.id})`);
|
|
});
|
|
|
|
console.log('\n===== 差异对比 =====');
|
|
const todayIds = new Set(todayEvents.map(e => e.id));
|
|
const calendarIds = new Set(calendarEvents.map(e => e.id));
|
|
|
|
const onlyInToday = todayEvents.filter(e => !calendarIds.has(e.id));
|
|
const onlyInCalendar = calendarEvents.filter(e => !todayIds.has(e.id));
|
|
|
|
if (onlyInToday.length === 0 && onlyInCalendar.length === 0) {
|
|
console.log('✅ 两个 Tab 的事件完全一致!');
|
|
} else {
|
|
if (onlyInToday.length > 0) {
|
|
console.log(`❌ 只在【今日】Tab 中的事件 (${onlyInToday.length} 个):`);
|
|
onlyInToday.forEach((event, index) => {
|
|
console.log(` ${index + 1}. ${event.title} (id: ${event.id})`);
|
|
});
|
|
}
|
|
if (onlyInCalendar.length > 0) {
|
|
console.log(`❌ 只在【日历】Tab 中的事件 (${onlyInCalendar.length} 个):`);
|
|
onlyInCalendar.forEach((event, index) => {
|
|
console.log(` ${index + 1}. ${event.title} (id: ${event.id})`);
|
|
});
|
|
}
|
|
}
|
|
|
|
console.log('\n========================================');
|
|
}
|
|
|
|
compare().catch(console.error);
|