]> acesimba.cloud Git - words.git/commit
feat: PWA 离线优先同步方案(9+11 规格)+ 日历日期修复 + 云端日志重建
authorroot <root@localhost.localdomain>
Thu, 13 Aug 2026 09:38:47 +0000 (17:38 +0800)
committerroot <root@localhost.localdomain>
Thu, 13 Aug 2026 09:38:47 +0000 (17:38 +0800)
commit11fff5b1fbab0b22c88e865e0ecaa40b38c4cdfc
treef5e6faf321b1a7f65626d2f51dee49a70433c08b
parentd4ff3314441530eff8f1422a45a9388af7a97e73
feat: PWA 离线优先同步方案(9+11 规格)+ 日历日期修复 + 云端日志重建

## 任务一:PWA 离线学习方案(满足 9 条规格)
搭建离线能力底座:
- 前端:Service Worker (public/sw.js)、manifest.json、PWA 注册 (index.js/App.js)
- IndexedDB 封装 (db.js):words/progress/meta 三 store,离线进度读写、dirty 标记、meta 元数据
- 同步骨架 (sync.js):sync_push 布尔并集、sync_pull 拉取
- 在线状态探测 (useOnlineStatus.js):navigator.onLine + online/offline 事件
- 学习日历离线降级 (StudyCalendar.js)
- 后端 main.py:sync_push/sync_pull、/api/calendar、/api/home 等
- 配套样式与组件:SyncNotifications.css/js、Home/StudyMode/TestMode 离线改造

## 任务二:PWA 离线优先同步重构(满足 11 条规格)
在底座之上实现离线优先 + 后台自动同步体系,核心规则:
1. 本地 IndexedDB 始终优先显示(Home 直接读本地,不依赖云端)
2. 严格脏数据推送(strict dirty-push):sync.js 只上传 dirty=true 记录,
   非脏(pull 所得)不上传,避免回声/重复
3. 布尔并集合并(boolean-union):任一方完成某 (group,op) 即完成,不删、不比时间
4. 同步状态机(idle / syncing[upload|merge|init] / synced / failed),
   经 subscribeSyncStatus 发布订阅
5. 联网后台自动同步 triggerAutoSync(幂等锁),不覆盖本地已学进度
6. 顶部状态条 7 种状态:初始化中 / 上传中 / 合并中 / 同步完成 / 同步失败 /
   离线待同步 / 离线可用(含周日);synced 4s 自动隐藏;失败显示重试按钮
7. 首次离线阻塞学习 (needInit);同步中且有 dirty 阻塞新学习 (blocking)
8. StudyMode/TestMode 完成即写本地 dirty 并在线触发自动同步
9. iOS Safari 在线不可靠 → useOnlineStatus 每 5s 主动 fetch 探测兜底
10. 保留周日提示;本地优先完成学习/测试/复习

修改文件:sync.js(状态机+triggerAutoSync+recomputeLearnableGroups)、db.js(isInitialized)、
Home.js(本地优先+needInit/blocking)、SyncNotifications.js/.css(状态条重写)、
StudyMode.js/TestMode.js(写 dirty+自动同步)、useOnlineStatus.js、api.js 及
GroupView/UploadPicture/StudyCalendar/App/index 适配。

## 任务三:修复学习日历日期分组 bug + 云端日志重建
日历 bug 根因:/api/calendar、sync_pull、get_progress_from_db、update_progress 均优先或仅用
created_at(入库时间)作日期,导致批量插入记录全显示为插入当天(8/13)。
修复 backend/main.py:
- /api/calendar 改用 COALESCE(log_date, substr(created_at,1,10)) 优先业务日期
- sync_pull: MAX(COALESCE(log_date, created_at))
- get_progress_from_db: MAX(COALESCE(log_date, created_at))
- update_progress: 在线写入补 log_date,去重条件同步改为按 log_date

云端日志重建 (bcd.db):按梯度学习规则(学 G_N = G_N 学+测 + G_(N-1)R1 + G_(N-2)R2 + G_(N-3)R3)
重建 8/1–8/12 连续进度:
- 8/3、8/6 改为仅 R3 执行日
- 8/8、8/9 补学(原为空),保证 8 月每天都有学习进度
- 8/12 严格保持:学 G49、测 G49、R1 G48、R2 G47、R3 G46
- 当前最大组 G49,最大日期 2026-08-12
19 files changed:
backend/db/bcd.db
backend/main.py
frontend/public/index.html
frontend/public/manifest.json
frontend/public/sw.js [new file with mode: 0644]
frontend/src/App.js
frontend/src/api.js [new file with mode: 0644]
frontend/src/components/GroupView.js
frontend/src/components/Home.js
frontend/src/components/StudyCalendar.js
frontend/src/components/StudyMode.js
frontend/src/components/SyncNotifications.css [new file with mode: 0644]
frontend/src/components/SyncNotifications.js [new file with mode: 0644]
frontend/src/components/TestMode.js
frontend/src/components/UploadPicture.js
frontend/src/db.js [new file with mode: 0644]
frontend/src/hooks/useOnlineStatus.js [new file with mode: 0644]
frontend/src/index.js
frontend/src/sync.js [new file with mode: 0644]