/** * 重复网格展开 - 移植自 ical_editor.py 的 occurrence 生成逻辑。 * occurrence 按需从 exdates 计算, 不存储在模型上。 */ import { toISODate, toDate, addDays } from './date.js' /** 重复事件的间隔天数。 */ export function intervalDays(ev) { if (!ev.rrule) return 0 const { freq, interval } = ev.rrule const step = interval || 1 return freq === 'WEEKLY' ? 7 * step : step } const MAX_OCCURRENCES = 500 /** * 将重复事件展开为 occurrence 网格。 * 返回 [{ date: 'YYYY-MM-DD', skipped: boolean }]。 */ export function expandOccurrences(ev) { // 非重复事件: 单个 occurrence if (!ev.rrule) { return [{ date: ev.dtstartDate, skipped: false }] } const step = intervalDays(ev) if (step <= 0) { return [{ date: ev.dtstartDate, skipped: false }] } const until = ev.rrule.untilDate ? toDate(ev.rrule.untilDate) : new Date(toDate(ev.dtstartDate).getTime() + 365 * 24 * 3600 * 1000) const exdateSet = new Set(ev.exdates || []) const occs = [] let cur = ev.dtstartDate let count = 0 while (cur <= toISODate(until) && count < MAX_OCCURRENCES) { occs.push({ date: cur, skipped: exdateSet.has(cur) }) cur = addDays(cur, step) count++ } return occs }