一卡通人员全量转发与可选本地保存实施计划

实施状态(2026-09-03):源端 1000 人分页、业务响应 unchanged 兼容和 OUTID → xh 人员编号修复均已落地;156 个 JVM 测试及 Debug 构建通过,待真机重新发起业务转发验证。

Goal:从新开普按每批最多 1000 人获取完整人员列表,完整校验后按每批最多 1000 条 JSON 转发业务服务器,并在开关启用且业务全部成功后静默保存本地快照。

Architecture:将旧的“拉取即落库、再从库上传”拆为分页获取并内存汇总、业务分批转发、可选本地保存三个职责。协调器以连接返回的总人数驱动 1000 人源端分页;全部分页完成并映射校验后再串行上传;本地保存只在业务零失败后执行。

Tech Stack:Java 8、Android API 24-30、Retrofit 2.1、Gson、SQLite、MMKV、JUnit 4。

文件结构

Task 1:全量获取服务

  1. 先写 2601 人拆为 1000/1000/601、游标推进、跨批重复、空批失败和 0 人不请求的测试。
  2. 实现 CustomerFullFetchService.fetch(expectedCount, listener),按独立源端常量每批最多 1000 人拉取并汇总。
  3. 运行定向测试并确认通过。

Task 2:字段和 JSON 契约

  1. 先写 CUSTDEPT/OUTID 映射、缺少 OUTID、固定 one_card_type=新开普 和 JSON Header 测试。
  2. 修改 mapper、请求 DTO 和 Retrofit 注解。
  3. 运行 mapper 与请求契约测试。

Task 3:内存列表分批转发

  1. 改写服务测试,证明 2601 条拆为 1000/1000/601。
  2. 增加第 1001 条非法时第一批也未发送的回归测试。
  3. 先映射全部 DTO,再按 MAX_ITEMS 串行请求。
  4. 兼容业务响应 unchanged,按 created + updated + unchanged + failed == total 校验汇总。

Task 4:后置可选本地快照

  1. 测试成功顺序、部分失败不保存、异常不保存和本地失败隔离。
  2. 实现 replaceSnapshot,在一个 SQLite 事务中写全量、删除旧数据、核数和标记成功。
  3. 协调器只在业务 failed == 0 时调用保存任务。

Task 5:设置和装配

  1. 新增默认 false 的 MMKV 键和 SwitchButton
  2. 每轮同步开始时冻结设置;关闭时不实例化 SQLite。
  3. CustomerFetchResult 替代旧同步结果并移除旧耦合入口。

Task 6:验证与记录

  1. 运行 :app:testDebugUnitTest
  2. 运行 :app:assembleDebug
  3. 运行 git diff --check 和旧字段 / 50000 硬编码扫描。
  4. 在业务环境允许时完成真机 26,082 条验证,否则明确标记待验。
  5. 补齐同名 Markdown + HTML 变更记录。

精确命令

JAVA_HOME=/Users/liang/Library/Java/JavaVirtualMachines/corretto-1.8.0_482/Contents/Home ./gradlew -q :app:testDebugUnitTest
JAVA_HOME=/Users/liang/Library/Java/JavaVirtualMachines/corretto-1.8.0_482/Contents/Home ./gradlew -q :app:assembleDebug
git diff --check
rg -n '"BM"|"XH"|DEFAULT_BATCH_SIZE = 50000' app/src/main app/src/test