2026-08-27 消费方案 B 代码落地变更记录
1. 变更结论
消费功能已从诊断面板改为方案 B“金额聚焦型”三步产品页面,并完成订单自动分流、一卡通三阶段交易、本地结构化记录、接口 C 先入队后上传以及每3分钟可靠补传。代码与 Debug APK 已在本地构建通过,真实硬件和服务端环境验收留待现场协作。
2. 变更原因
此前消费页仍依赖支付按钮、临时测试地址和模拟一分钱订单;移盘会让迟到订单失效;扣款与接口 C 结果主要停留在页面和日志,应用重启后无法可靠补传。这些行为与本次确认的产品需求和方案 B 原型不一致,必须以单订单状态机统一收口。
3. 主要实现
3.1 单订单会话
- 新增纯 Java
ConsumptionFlowStateMachine,统一三页面、订单、卡交易、反馈和终态。
- 餐盘识别后锁定本轮订单;餐盘移走只更新在位状态,不取消网络请求或硬件交易。
- 正金额订单自动进入卡支付,取消支付按钮和二次确认;零元订单不读卡、不扣款。
- 终态结果展示后,餐盘已移走且需要支付的订单同时确认卡片已移走,才释放下一单。
3.2 一卡通交易安全
ConsumptionCardTransactionExecutor 增加消费前读卡、扣款、消费后读卡真实阶段回调。
- 进入第三步时若读卡区已有卡,先等待遗留卡移走;确认无卡后的新放卡事件才能触发本单交易。
- 卡片保护窗口使用“请勿拿走卡片”;语音和页面统一为“请放卡片进行支付”。
- 只有前读卡、完整金额扣款、后读卡、前后客户号与卡号一致全部通过,才组装接口 C 成功结果。
- 前读卡失败只保存本地;部分扣款、结果不确定或后读卡失败保存为异常且禁止自动重扣,不伪造服务端失败码。
3.3 本地记录与接口 C
- 新增
consumption_records.db,以订单号关联餐盘、金额、前读卡、扣款、后读卡、错误、接口 C 原请求和上传状态。
- 零元单请求为成功码0、金额0、前后卡信息空对象;正金额成功请求携带三阶段真实结果。
- 所有可反馈结果先保存接口 C 原始 JSON,再发网络请求;反馈成功或失败都推进前台。
- 上传失败保留
PENDING,应用启动、网络恢复和3分钟定时均可触发唯一后台任务。
- 每批50条、单轮最多2批共100条;单条失败不阻塞其余记录;补传只重发原接口 C 请求,不执行卡交易。
- 前台入队后后台最早3分钟接管,避免前台在途时重复发送同一订单。
3.4 方案 B 页面
- 第一页沿用放盘插画;第二页聚焦订单号与金额;第三页聚焦卡片动作、金额和结果。
- 三步水平导航、面板、色板、字号和间距全部资源化,未在布局或业务代码中散落可避免的魔法值。
- 查询和支付过程中对餐盘保持中性;只有终态需要清场时提示取走仍在设备上的物品。
- 原始协议和内部阶段不再作为调试面板暴露给用户,仍完整进入本地数据库和读卡日志。
4. 被替代的旧实现
ConsumptionNetworkConfig 的临时 192.168.* 地址和模拟订单已删除,消费页使用应用统一网络配置。
ConsumptionPaymentGate 和支付按钮已删除,正金额由金额判断后自动进入第三步。
- 原
please_swipe_card 不再由消费流程引用,新语音资源为 please_place_card.wav。
- 早期“接口 C 失败仅写页面日志、不持久补传”和“餐盘移走丢弃迟到订单”的记录已由本变更覆盖。
5. 验证证据
- 命令:
JAVA_HOME=.../corretto-1.8.0_482/Contents/Home bash gradlew :app:testDebugUnitTest :app:assembleDebug --no-daemon --console=plain。
- 最终结果:
BUILD SUCCESSFUL in 17s。
- 单测:84个测试,0 failure、0 error、0 skipped。
- APK:
app/build/outputs/apk/debug/app-debug.apk,约61 MB。
- 静态检查:
git diff --check 通过;消费主流程未引用临时地址、模拟订单、支付按钮和旧刷卡语音。
- 覆盖重点:状态转换、移盘不中断、接口 C 零元/正金额 JSON、硬件阶段顺序、补传100条上限、失败隔离与并发防重。
- 生命周期:交易在途时短暂切后台保持硬件任务和最终回调,结果收尾后停止后台寻卡;交易期间禁止返回离开页面。
6. 真机待验与边界
- 需要真实餐盘扫码器、新开普读卡器、测试卡和目标服务端订单进行现场验收。
- 必测零元、补贴/主钱包、余额不足、遗留卡、三阶段移卡、餐盘提前移走、接口 C 失败补传和应用重启恢复。
- 当前一卡通 SDK 没有提供可直接映射到接口 C 的真实非零扣款失败码,因此明确未扣款失败只保存在本地,不发送伪造失败结果。
- 本次没有执行 Git 暂存、提交、推送、拉取、分支切换、合并、重置或清理;工作区既有改动保持原样。
7. 中间产物索引
- 产品需求:
docs/2026-08-27-consumption-product-requirements.md/.html。
- 方案 B 标注:
prototypes/2026-08-27-consumption-flow/scheme-b-ui-spec.md/.html。
- 技术设计:
docs/2026-08-27-consumption-code-implementation-design.md/.html。
- 实施过程与记录原因:
docs/2026-08-27-consumption-implementation-worklog.md/.html。
- 接口 C 契约矩阵:
docs/2026-08-27-interface-c-contract-test-matrix.md/.html。