Files
timeTableFix/docs/auto-save-design.md
zikai 037b70deec feat: 自动保存/移除撤销与红点, 间隔合并改进(DAILY/稀疏/交错拆分), 删死代码, 更新测试与文档
- organize: seriesKey 移除 weekday, 解锁每3天等 DAILY 序列合并
- organize: fitSeries 放宽阈值(稀疏序列如 BUS LAW Workshop 合并)
- organize: 新增 splitIntoChains, GCD=1 的交错多班次拆为多个系列
- useCalendar: 移除 dirty/history/undo/snapshot/markSaved 死代码
- HeaderBar: 移除撤销按钮与红点●, 下载兜底序列化当前状态
- 测试: 42 项(原32), 覆盖 DAILY/稀疏/交错拆分/两两和候选等场景
- 文档: README 精简, 新增 docs/organize-algorithm.md 与 auto-save-design.md
- 保留移动端 CSS 适配
2026-07-22 06:32:47 +00:00

2.9 KiB
Raw Blame History

自动保存设计

本文档记录 src/composables/useCalendar.jssrc/components/HeaderBar.vue 的保存模型重构。

背景

原设计有「dirty 标记 + 下载前确认弹窗 + 快照式 undo/redo最多 50 步)」。 EventDetail 的表单已改为自动应用(watch(form) 即时写回 store commit 1c6ecf9dirty 仅用于「下载前提示未保存」与红点显示。撤销是 独立的历史栈。

重构:移除 dirty / undo

纯前端工具,无持久化需求,所有编辑本就即时生效(自动应用 watch。 dirty 标记与确认弹窗是冗余的仪式感undo 栈在自动应用场景下也意义 有限(每次 keystroke 都会 push 历史,栈迅速填满噪声)。移除以降低 复杂度、减少状态字段。

删除的死代码(useCalendar.js

  • state.history(快照栈)、state.dirty
  • MAX_HISTORY 常量
  • snapshot()pushHistory()restore()
  • undo() action、canUndo computed
  • markSaved() action
  • 各 actionorganize/updateEvent/deleteEvent/addEvent/ splitEvent/toggleOccurrence)内的 pushHistory()state.dirty = true 调用
  • loadFile 内的 state.history = []state.dirty = false
  • 不再使用的 cloneEvent 导入snapshot 曾用)

HeaderBar.vue 改动

  • 移除「撤销」按钮
  • 移除下载按钮后的红点 <span class="dirty-dot">)与 .dirty-dot 样式
  • onDownload():移除 if (state.dirty && !confirm(...)) 确认弹窗与 markSaved() 调用;直接 serialize() 下载

自动保存语义

  • 所有编辑即时生效updateEvent/deleteEvent/addEvent/ splitEvent/toggleOccurrence 直接 mutate 响应式 state.events 无中间缓冲。EventDetail 的 watch(form, { deep: true }) 把表单变化 立即 patch 回 store。
  • 下载兜底onDownloadserialize() 序列化当前最新状态。 即便有任何未触发渲染的边界改动,下载时也会被序列化包含。文件名取 原文件名去 .ics.edited.ics
  • occurrences 不持久化EventModel 不存 occurrencesOccurrenceGrid 渲染时实时调 expandOccurrences(ev) 计算,toggleOccurrence 直接改 exdates。无缓存,无不同步风险。

状态字段(重构后)

const state = reactive({
  meta: null,
  events: [],
  selectedUid: null,
  fileName: null,
  viewMode: 'edit',        // 'edit' | 'month' | 'week'
  previewDate: todayISO(),
})

history、无 dirty、无 redoStack。store 仅承载当前状态与视图锚点。

取消确认弹窗的理由

onDownloaddirty 时弹「有未保存的更改,仍要下载?」。但自动 应用下,所有更改已在 store 中,下载即序列化 store不存在「未保存」。 弹窗只会误导用户以为有数据丢失风险。移除后下载是一次性操作。