# Debug Session: countdown-stop-counter - **Status**: [OPEN] - **Issue**: 倒计时现在不能用了,且设备到时后仍可能继续计数。 - **Debug Server**: http://127.0.0.1:7777/event - **Log File**: .dbg/trae-debug-log-countdown-stop-counter.ndjson ## Reproduction Steps 1. 进入比赛页并刷新页面。 2. 下载本场并开始考试。 3. 观察页面倒计时是否递减。 4. 等待考试结束,观察设备是否继续计数。 ## Hypotheses & Verification | ID | Hypothesis | Likelihood | Effort | Evidence | |----|------------|------------|--------|----------| | A | 后端当前改成“设备时间优先”后,没有持续收到有效的设备剩余时间,导致前端倒计时不再更新 | High | Med | Confirmed | | B | 后端仍在某些分支过早把 `IsTesting` 置为 `false`,导致前端本地倒计时和后端广播一起停掉 | High | Med | Rejected | | C | 设备真实结束条件与后端假设不一致,后端以为结束了,但设备端还在模式 `0x05/0x02` 继续计数 | High | Med | Pending | | D | 前端能收到状态,但 `remainingSeconds/countdownEndsAt/isTesting` 三者组合不一致,显示层直接停表 | Med | Med | Confirmed | | E | 手动/自动结束后,后端虽然冻结了写分,但设备端没有进入锁定态,所以现场仍能继续跳并看到计数变化 | High | Med | Pending | ## Log Evidence - `CompetitionSessionService.StartAsync` 已成功创建测试状态,`IsTesting=true`,说明“开始”按钮链路正常 - `CompetitionSessionService.ApplyDeviceSnapshotAsync` 日志显示:设备持续上报 `Mode=2`、`RemainingSeconds=0` - `CompetitionSessionService.NormalizeRemainingSecondsUnsafe` 日志显示:每次都把 `deviceElapsedSeconds=0` 反算成 `remaining=60` - 紧接着 `ApplyDeviceSnapshotAsync` 又把 `CountdownStartedAt/CountdownEndsAt` 重置成“当前时刻 + 60 秒” - 前端 `RopeSkippingCounter.applyCompetitionState` 日志显示:页面收到的始终是 `isTesting=true/remainingSeconds=60/countdownEndsAt=当前时刻+60秒` - 这会导致本地倒计时每次刚减 1,又被下一帧状态重置回 60,表现为“倒计时不动” ## Verification Conclusion - 倒计时失效的根因已确认:错误地把设备上报的 `remainingSeconds=0` 当成有效考试进度,并在每次设备帧到来时重置倒计时起点 - 当前最小修复是:倒计时恢复由后端本地时钟驱动;设备结束只保留 `Mode=0x0A` 这条可靠信号 - 用户已确认:倒计时已经恢复 - “设备物理上是否真正停计”仍需单独验证,当前进入下一阶段只验证设备停计