审计范围:用户给出的在线 HTML 及其本地 MD;对照 Android 应用实际源码,未修改仓库或在线页。
来源 URL:https://zhctpmt.yyangpt.cn/zhctprompt/work_android/ZhctWeightingTableYoukate/docs/2026-09-09-tray-removal-confirmation-count-code-locations.html
在线 HTML:主代理已确认 HTTP 200,本代理使用其保存文件 /tmp/scan-interruption-audit-20260909/code-locations-online.html。
目标源码快照:master 2f759f9415b46a7166215fa670d5b4fafeef615e;origin/zymy_ongoing 21a5d3d956f0a2dabec036a947e315e957a86997。相关 HomeActivity、配置/硬件/策略源码两分支完全一致,故本报告行号适用这两个已冻结快照。
结论
此页是准确度较高的配置和使用点索引,明确修正了会议“未设置一律默认7”的说法,并正确指出当前按空码回调次数判断、没有900/1200ms持续时间门槛。不能把它当作完整的扫码中断诊断或完整业务代码展示。
需要修正/补充的重点是:MD总览把“配置变化才清计数”写成“返回就清”;HTML/MD多段代码省略真实语句却没标节选;三个共享N的业务分支并不是相同状态机,“连续空码”在A02查询进行中和管理卡介入时有例外;A03原盘判断并没有验证回来的非空码是否属于原盘。
1. 页面准确内容和行号核对
以下文件路径相对 app/src/main/。
| 页面定位 | 实际源码定位 | 核验 |
|---|---|---|
| Constants:89 | java/com/cpt/zhct/weighting/utils/Constants.java:89 是配置注释,键值92,默认94、升级95、范围96-97 |
正确,为段落起始行 |
| Policy:11 | .../antiescape/TrayRemovalConfirmationCountPolicy.java:11 isValid,16 normalize,23 initialValue |
正确 |
| Config:16 | .../antiescape/TrayRemovalConfirmationCountConfig.java:16 get,34 save |
正确;代码片段仅换行格式差异 |
| activity_set.xml:169 | res/layout/activity_set.xml:169 为该SettingItemView |
正确 |
| SetActivity:815 / 847 | .../activity/SetActivity.java:815 方法注释,816输入方法,847保存方法 |
正确;代码有换行整理 |
| HomeActivity:181 | 普通/A03空计数181,N字段183 | 正确 |
| HomeActivity:1875 | 方法注释1875,实际方法1876,onStart调用276 | 正确,但MD总览作用描述需收窄 |
| HomeActivity:1473 | handleEmptyScanCode实际起始1473 | 正确,网页代码为节选 |
| HomeActivity:1497 | handleA03OriginalTrayRemoved实际起始1497 | 正确,网页代码为节选 |
| HomeActivity:1089 | 认领状态下空码支路 | 正确,但单看片段缺少前置A03/动作状态分流 |
| A02TrayClaimCodePolicy:38 | onTrayCodeCleared实际起始38 | 正确 |
配置范围3—10、新装7、升级兼容3均与源码一致。保存后回首页onStart会读取配置,无需重启;已有合法存量值仍保留,缺配置时才按安装历史取3/7,非法值改7。
2. 片段不是逐字完整源码,必须明确标注节选
| 片段 | 被省略的真实语句 | 影响 |
|---|---|---|
| HTML普通离盘 | HomeActivity:1477-1479 起始计时;1484-1487 tray_removed 性能日志;1491 stopLegacyTrayNotBoundBlink() |
保留核心阈值,但漏掉计时证据和灯光收尾;不能用完整方法外观暗示这些语句不存在 |
| MD普通离盘 | HomeActivity:1484-1487 性能日志 | 计数逻辑一致,但不是逐字全文 |
| HTML A03原盘移走 | HomeActivity:1507计时字段清零;1512-1514 SOURCE_TRAY_REMOVED日志;1515 updateTrayRequiredAlarmAfterTrayRemoval() |
不只略去日志,还略去后续告警动作/界面状态更新 |
| MD A03原盘移走 | HomeActivity:1512-1514 SOURCE_TRAY_REMOVED日志 |
保留主要状态更新,仍应标节选 |
建议在每段前写“关键判断节选,省略日志/提示/告警状态更新,完整行为以SHA固定源码为准”,或直接引用完整短方法。页面只写“源码分支zymy_ongoing”不足以长期保持行号有效,建议同时记录完整commit SHA和核验日期。
3. 配置刷新文案需要精确区分
MD位置总览目前写“返回首页后读取配置并清空旧计数”。准确措辞应为:
返回首页时读取并同步配置;只有新读到的N与内存N不同,才清空普通/A03旧空码计数和性能计时。A02计数策略在N变化时也清计数。
HomeActivity:1877-1883 的清零受 mTrayRemovalConfirmationCount != configuredCount 控制。A02TrayClaimCodePolicy:17-23 同样只在N变化时清自己的计数。不能写每次返回首页都由刷新方法清计数。
另外,A02还有生命周期/动作切换重置:HomeActivity:573,1177-1184 onStop会调用clearA02ActionState并reset其策略。因此“刷新方法未清A02”也不等于一次真正离开再回来的A02一定保留旧计数;要分别审视每个调用路径。普通/A03共享的scanEmptyFrameCount不在该clearA02ActionState中清零。
4. 同一个N控制三个业务结果,不是三个相同离盘动作
| 分支 | 空输入何时计数 | 非空输入是否清零 | 达到N的后果 |
|---|---|---|---|
| 普通取餐 | 有mCurrentCode时,普通分流的空码计数 | 普通有效餐盘码会在Home:1037清零;解除卡888880—888899先被忽略,未清零 | scanCodeResult(2)清当前码、读取取餐重量、切回Before、按条件保存/调度上传旧取餐记录 |
| A03原未绑定盘仍未确认离开 | Home:1080-1084:A03、未离盘、空码且动作不为WAIT_MANAGER_CARD时 | Home:1070-1074:任何非空码都会清零,并未比对sourceTrayCode;WAIT_TRAY_CLAIM随后直接return,不查询该码 | Home:1506-1515:清当前码/人员,标原盘已移走,切Before并更新告警动作;不执行普通空人员取餐收尾,保留报警补录语义 |
| A02/A03放盘补录认领 | 进入WAIT_TRAY_CLAIM的空码调用policy.onTrayCodeCleared | 只有真正调用policy.shouldQuery的有效普通码才清零;请求in-flight、长度不合规、忽略解除卡时存在跳过清零 | 清lastQueriedTrayCode、清policy空计数并让mA02TrayClaimCodePresent=false;使同盘以后可再查人,不代表普通取餐会话结束 |
A02命名的认领策略也被A03补录复用。因此页面“同一个配置控制三处”准确,但把它概括成所有模式下都按完全相同的连续空码语义是不充分的。
4.1 新确认:A02查询进行中,有效码不清计数
HomeActivity:1242-1244 采用短路条件:
if (mA02ClaimRequestInFlight || trayCode.length() != Constants.CODE_LENGTH_NUMBER
|| !mA02TrayClaimCodePolicy.shouldQuery(trayCode)) {
return;
}
policy.shouldQuery在 A02TrayClaimCodePolicy:30 才会清空计数。因in-flight短路,该方法不执行;与此同时空码仍从Home:1089-1094递增。真实控制路径回放:N=3,已经查询盘003401且请求未结束,输入“空、空、003401、空”,mA02TrayClaimCodePresent会被清为false。非空有效码并未打断空计数。
这不直接证明普通取餐中断的现场根因;它证明不能用普通分支的11项验证覆盖共享N的A02分支,也不能简单把A02称为“连续原始空回调”。建议把“接收有效盘码刷新存在性”和“是否发起新查人请求”分开验证,避免网络请求状态改变传感器连续性。
4.2 管理卡与A03异码是有区别的边界
- 普通分支:解除卡在归零前被消费,空/空/管理卡/空可累计到3。
- A02认领分支:Home:1109-1111忽略解除卡,不进shouldQuery,空计数同样保持。
- A03原盘未离开:Home:1070-1074对任何非空码清零,包括另一餐盘B和管理卡。没有确认该码等于原sourceTrayCode。WAIT_TRAY_CLAIM时接着直接return,B不会触发认领查询;从现有源码只能说“又看到了某个非空码”,不能说“原盘重新识别成功”。
- A03 WAIT_MANAGER_CARD:Home:1082特意跳过空输入的原盘离开判断,空输入不会递增该计数;后续合法管理卡走解除操作。此为特殊模式,不应拿一般离盘条件推断。
这些可能包含有意业务选择。当前审计确认的是实现和例外,不替产品决定哪个管理卡策略才正确。
5. 此页仍未覆盖的诊断问题
- 上游
YoukateHardwareManager.cleanScanCode把非6位非空码变空,SDK自身也可把协议长度异常变空;因此“空码回调”不一定是硬件真实无盘。 - PC681 SDK的半包/粘包/残包、校验/帧尾冲突、新鲜度问题并没有在定位页中解决。硬件100ms×3或50ms×6例子是条件假设,不能仅因代码计数就认定现场控制板确实按此重复。
- 大N与快速A→B换盘直接覆盖旧会话的权衡;普通异码重新设置起始重量,没有先走普通离盘收尾。
- 带盘进设置/返回的页面状态恢复、查人晚回包、无新回调与空码的区分。
- 缺少SDK原始帧、解析结果、清洗分类、N/T、计数前后、会话结束原因和物理动作时间轴。页内提到约1秒方案仅是后续方向,不构成已批准/已实现/已验收方案。
6. 本次新增验证
原有11项验证专注普通扫码分支及配置,不能证明A02/A03完整正确。本次新增独立脚本:app-verification/run_a02_audit.py,唯一参数为真实repo path,可从任意cwd运行。依赖同目录run_audit.py的精确方法提取与JDK选择函数。
- 动态编译真实A02TrayClaimCodePolicy、相关配置Policy/Constants/UnlockCodePolicy/AlarmType。
- 直接运行仓库现有A02TrayClaimCodePolicyTest的3个测试方法:同盘只查一次、到7空可再查同盘、异盘无需等旧盘清空。
- 因未引入外部JUnit依赖,使用最小org.junit.Test/Assert兼容替身运行这3个原始方法,不是宣称已跑完整JUnit/Gradle测试平台。
- 再以精确签名和括号匹配抽取实际handleA02ScanDuringAlarm、handleA03OriginalTrayRemoved;claimA02AlarmByTray仅使用原样前置guard,UI/网络副作用以计数边界替身替代。
- 新增7项验证普通有效码清零、同N保留/换N清零、in-flight有效码不清零、管理卡不清零、A03异码清零无身份核对、WAIT_MANAGER_CARD忽略空输入。
- 共10项全部PASS。PASS表示实际实现被成功复现,不等于实现符合业务需求或现场已验收。Android生命周期、完整网络/数据库/串口和真机未运行。
- 临时业务源文件和class只在脚本自行创建的临时目录存在,结束清理;输入仓库未修改。
运行结果:app-verification/a02-a03-verification-result.json。
10项实际结果
- PASS Existing unmodified JUnit test: sendsOnlyOneQueryWhileTheSameTrayRemainsPresent
- PASS Existing unmodified JUnit test: usesConfiguredEmptyFrameCountBeforeAllowingSameTrayAgain
- PASS Existing unmodified JUnit test: allowsAnotherTrayWithoutWaitingForTheFirstTrayToClear
- PASS Actual A02 policy: normal repeated valid code resets prior empty count
- PASS Actual A02 policy: setting unchanged N preserves partial empty count
- PASS Actual A02 policy: changed N clears old empty count
- PASS Actual A02 route + original query guard: valid code during in-flight query does not break empty count
- PASS Actual A02 route: ignored manager code preserves empty count
- PASS Actual A03 route: different nonempty code resets original-tray removal counter, not identity-checked
- PASS Actual A03 route: waiting for manager card ignores empty input for original-tray removal
来源冻结
- HTML SHA-256:
feae2495a7aeea59c3bc0194b8b5846e08e62956db3904976c2310e4ccd1d6d6 - MD SHA-256:
7613abd73b9b38c1094d09340370f111af919cec6213a31ddf4eb0081c614858