feat: 实现小程序离线巡检与可靠同步

This commit is contained in:
weijuesen
2026-08-14 09:03:48 +08:00
parent 6b222abb7b
commit 69ef5a0704
19 changed files with 543 additions and 19 deletions
+30
View File
@@ -1058,3 +1058,33 @@ MVP 沿用 IoTDB(现状);TDengine 作为生产规模化候选(先基准
- 本任务前分支提交为 `cc93c9a`;回滚可还原 Task 10 提交;
- 数据库回滚执行 `000006_biosecurity.down.sql`,可删除种源、消毒、二维码映射表和 `batches.seed_source_id`
- 页面回滚需同时还原 Web 路由/菜单、小程序页面与设置入口,并移除 `biosecurity` 权限种子。
## 2026-08-14 整改 Task 11:实现小程序离线巡检与可靠同步
### 做了什么
- 新增小程序本地持久队列 `offlineQueue.ts`,队列状态为 `pending/uploading/synced/conflict/failed`
- 拍照巡检改为先保存图片到本地队列,网络恢复后串行上传;同一 `idempotencyKey` 创建后不再变化,重试复用;
- 上传 401 时先刷新 token 再重试一次;5xx/超时按指数退避重试,4xx 永久失败并展示错误,409 标记为冲突;
- 巡检页展示离线队列数量、剩余容量、失败/冲突和清理已同步入口;
- 登录恢复后会尝试同步离线队列;`scripts/verify.ps1` 新增 `miniapp test`,队列单测进入统一门禁;
- 服务端幂等键增加用户作用域:新增 `000007_inspection_idempotency` 迁移,唯一索引改为 `(user_id, idempotency_key)`,迁移先对既有同用户冲突键追加记录 ID,不删除任何记录。
### 设计思路与决策依据
- 离线上传不能依赖临时文件路径,页面入队前先用文件系统保存为本地持久路径;
- 幂等键必须客户端生成且固定,服务端按用户+键查询和唯一约束,避免不同用户撞键导致误返回;
- 4xx 通常是数据或权限问题,重试不会解决,所以进入人工处理;网络类错误才退避重试;
- 队列容量先按条目数量限制,页面显示剩余名额;后续需要更严格空间控制时可再引入文件大小统计。
### 验证结果
- `scripts/verify.ps1` exit 0Go test/vet/build、Web test/lint/build、小程序 test/typecheck/build、APP typecheck/lint、AI pytest 15/15 均通过;
- 队列单测 5/5:重启恢复、重复点击、4xx 永久失败、指数退避后最终失败、同步后清理引用;
- 未部署开发服务器,未执行 `000007` 迁移;未在微信开发者工具完成离线→重启→联网截图取证。
### 回滚点
- 本任务前分支提交为 `6b222ab`;回滚可还原 Task 11 提交;
- 数据库回滚执行 `000007_inspection_idempotency.down.sql` 可恢复全局唯一索引,但已被迁移追加后缀的历史键不会自动还原;
- 小程序回滚需还原队列服务、巡检页、请求刷新逻辑和 store,并移除 `scripts/verify.ps1` 中的 `miniapp test` 步骤。