A02 报警认领补录实施计划

项目:ZhctWeightingTableYoukate · 日期:2026-08-25 · 状态:保存三次失败管理员兜底、网络三次失败离线兜底、上传成功累计刷新策略已实施,待真机与服务端联调验收

目标:为 A02 未放餐盘报警增加两按钮门控的刷管理卡解除与放餐盘认领补录,复用现有本地取餐记录和 Worker 上传链路,并确保报警日报志完整可追溯。

实施边界

文件地图

路径职责
antiescape/A02AlarmAction.java新增三态按钮门控枚举
NoTrayPickDetector.java暴露 A02 触发基准和重量证据
AntiEscapeAlarm.java报警流水号、固定基准和实时逃单重量
HomeActivity.java实时重量、恢复自动解除、刷卡/认领分支、Worker 结果事件处理和审计
AntiEscapeAlarmDialogFragment.javaA02 按钮、等待状态和实时重量展示
PickMealRecord、DAO、DB Helper来源/报警关联与安全迁移
UploadPickMealRecordWorker.java上传结果回写日报警日志并发布 A02 专用结果事件

任务 1:A02 基准与实时重量

新增 A02AlarmActionNONEWAIT_MANAGER_CARDWAIT_TRAY_CLAIM。保持 NoTrayPickDetector.onWeight(...) 的布尔返回值不变,在触发分支保存固定基准和触发重量证据。活动 A02 在无餐盘、稳定、取餐前页时按 max(0, baselineWeight - currentWeight) 实时更新;当前稳定重量恢复至基准或更高时写 WEIGHT_RECOVERED 并自动解除。

单元测试覆盖 1000g 基准从 990g 变为 998g 时由 10g 更新为 2g,以及恢复至 1000g 自动解除、无取餐记录和无上传。

任务 2:A02 两按钮页面

在既有全屏 A02 报警图上增加默认隐藏的操作容器:实时逃单重量、提示、刷管理卡按钮和放餐盘认领按钮。两按钮必须左右等宽地位于同一横行,中间间距 12dp;文案水平居中,最多可在按钮内换两行,不能截断。等待任一输入时显示“返回重新选择”;默认选择页、餐盘查人或上传进行中、以及 LOCAL_SAVE_FAILED 均隐藏它。Fragment 仅对 A02 显示控件,并通过 Activity 回调上报选择或取消。传入初始 alarmPickWeight 后,由 Activity 在无餐盘有效稳定读数时更新页面;餐盘识别后保持最后一次有效值。

在设备触发 A01、A03,确认按钮不出现且现有拿盘提示保持原样;触发 A02,确认重量实时变化、恢复基准后自动关闭,且两按钮在同一行。

任务 3:60 秒门控与扫码拦截

HomeActivity 增加当前动作、认领请求标记和 60,000ms Runnable。选择动作后写 ACTION_SELECT、启动计时;超时写 ACTION_TIMEOUT、回到 NONE,但不停止报警。尚未接收有效输入时可主动取消:移除计时、清空待处理餐盘状态、写 ACTION_CANCEL 并回到 NONE;查询/上传进行中和 LOCAL_SAVE_FAILED 拒绝取消。触发、解除、停止、销毁均取消旧计时。

A02 扫码优先走专用分支:默认状态忽略全部;管理卡等待态仅接受有效解除卡;餐盘等待态仅接受非管理卡的六位餐盘码,且不进入普通扫码流程。

选择任一方式后,在扫描或放盘前点击“返回重新选择”,确认报警、实时重量和时长不变,另一个方式可选且日志有 ACTION_CANCEL;再验证 60 秒超时后日志有 ACTION_TIMEOUT

任务 4:管理卡解除审计

仅在管理卡等待态读取有效卡。写入 RESOLVE|method=MANAGER_CARD|cardCode=...|durationMs=... 后调用既有解除方法,不创建取餐记录。A02 触发日志增加 alarmId、固定基准重量、触发重量与最终实时逃单重量。

选择管理卡后扫描 888888:一条选择日志、一条含卡值/时长/最终实时逃单重量的解除日志、无新增取餐记录。

任务 5:放盘认领复用现有上传

uploadPickInfo(int) 提取参数化的 savePickMealRecord(...)。正常取餐传 source=NORMAL;A02 传触发时间、认领前最后一次有效实时重量、绑定人员、认领餐盘、source=ANTI_ESCAPE_A02 与 alarmId。

认领使用现有 newGetStaffInfoByTray(trayCode, dishUuid)。同一餐盘持续上报时只查询一次。查到人员后使用同一认领上下文保存,首次保存失败自动再试 2 次;三次失败进入 LOCAL_SAVE_FAILED:隐藏或禁用放盘认领、忽略后续餐盘码,提示“取餐记录保存失败,无法进行放盘补录,请工作人员刷管理卡解除报警。”,仅管理卡可用 LOCAL_SAVE_FAILED_ADMIN_OVERRIDE 解除。保存成功后立即上传;网络类失败重试 3 次后入既有定时队列并以 TRAY_CLAIM_DEFERRED_NETWORK 放行,页面提示累计可能暂未同步。只有 code=0 且本地删除成功才以正常成功原因解除。延迟上传成功时当前餐盘仍在打餐页则刷新人员累计。code=1 时按旧策略删除候选记录但不解除,提示先绑定餐盘后重新认领。

强制三次落库失败时只剩管理卡解除;强制三次网络失败时存在待上传记录和累计延迟提示;延迟成功后当前餐盘累计会刷新。

任务 6:安全数据库迁移

PickMealRecord、DAO 和表增加 sourcealarm_id。数据库升至 v2,v1 升 v2 使用两条 ALTER TABLE,绝不删除 pick_record。旧记录的来源默认 NORMAL、alarmId 为空。

先用旧包留下离线普通记录,再覆盖安装新包且不清数据;确认 Worker 仍能读取和上传。

任务 7:同步结果写入日报警日志

Worker 和即时上传协调器对 ANTI_ESCAPE_A02 来源追加日志:code 0 且删除成功为 UPLOAD_SUCCESS;code 1 为 UPLOAD_DROPPED_LEGACY_POLICY;本地删除失败为 UPLOAD_DELETE_FAILED。仅网络类失败计数,第三次写 UPLOAD_DEFERRED_NETWORK,保留记录进定时队列并以 TRAY_CLAIM_DEFERRED_NETWORK 解除。延迟成功携带餐盘码;若仍为当前打餐餐盘则刷新人员累计。业务失败保持报警。

离线 A02 认领后恰好三次即时尝试,再离线放行并提示累计延迟;恢复网络后当前餐盘累计刷新。验证 code 1 后仍锁定并提示绑盘。

任务 8:构建、验收与变更记录

使用 JDK 8 运行 :app:testDebugUnitTest:app:assembleDebug。设备覆盖默认忽略、管理卡、有效/无效餐盘、60 秒超时、落库失败、离线补传、A01/A03、正常取餐和旧库升级。源码实施并验证后,在项目 change_records/ 创建同名 Markdown 与 HTML 变更记录,附构建、测试与设备证据。

完成标准

  1. A02 默认状态不响应任何扫描或放盘。
  2. 无餐盘、稳定状态下,A02 逃单重量按固定基准与当前重量实时更新;重量恢复至基准或更高时自动解除并写 WEIGHT_RECOVERED,无取餐记录和上传。
  3. A02 两种解除按钮左右等宽、同一行显示,间距 12dp,文案完整可读。
  4. 三次本地保存失败时仅管理卡可解除、没有上传队列记录;每次保存尝试和最后错误可审计。
  5. 三次网络类上传失败时记录进入定时队列、离线解除并提示累计延迟;成功后当前餐盘累计刷新。
  6. code=1 时删除候选记录但保持报警,提示先绑盘后移开、重新放盘认领。
  7. 上传最终结果可在日报警分类日志中关联到报警流水号和本地记录 ID。
  8. A01、A03、正常取餐和历史离线记录无回归。