diff --git a/docs/superpowers/specs/2026-07-10-time-check-design.md b/docs/superpowers/specs/2026-07-10-time-check-design.md new file mode 100644 index 0000000..0b07893 --- /dev/null +++ b/docs/superpowers/specs/2026-07-10-time-check-design.md @@ -0,0 +1,211 @@ +# 守时检测设计 + +## 背景 + +现有守时页面 `frontend/src/views/home/components/timeTest.vue` 是演示式页面,包含假数据、步骤条和旧的“标准时间/上送时刻”展示方式,不符合新的业务流程。新的守时检测需要同时支持多台装置,动态展示每台装置的暂态触发时刻、守时误差和结果,并与现有检测弹窗、后端 `startPreTest` 流程联动。 + +后端项目位于 `D:\njcn\test\CN_Gather`。本设计覆盖前端与后端协同修改。 + +## 目标 + +- 守时页面只展示守时检测用时和设备结果表,不展示源连接、设备连接、协议校验、相序校验等前置阶段。 +- 表格列固定为:装置名称、暂态1触发时刻、暂态2触发时刻、守时误差、结果。 +- 未收到对应数据时,单元格显示 loading 转圈状态。 +- 守时检测计时格式为 `HH:mm:ss`。 +- 支持多台设备同时检测。 +- 守时检测过程要像 `factorTest.vue` 一样监听并拦截 WebSocket 错误,错误时终止流程。 +- 守时完成后,如果后续还有正式检测,前后端自动流向正式检测且保持组件状态;如果没有正式检测,则清理连接和 WebSocket 资源。 + +## 检测项契约 + +`PreDetectionParam.testItemList` 从 3 位改为 4 位: + +1. 第 1 位:预检测 +2. 第 2 位:系数校准 +3. 第 3 位:守时校验 +4. 第 4 位:正式检测 + +前端所有调用 `startPreTest` 的位置都必须发送 4 位数组,例如: + +- 只做守时检测:`[false, false, true, false]` +- 预检测 + 守时检测:`[true, false, true, false]` +- 守时检测 + 正式检测:`[false, false, true, true]` +- 预检测 + 守时检测 + 正式检测:`[true, false, true, true]` + +后端所有读取 `testItemList` 的逻辑同步使用新索引,不能继续把第三位解释为正式检测。 + +## 前端流程 + +### 启动规则 + +`testPopup.vue` 继续作为检测弹窗流程编排入口。 + +只勾选守时检测时,前端调用现有 `startPreTest`。接口成功返回后,认为守时检测开始,`timeTest.vue` 开始计时。后端随后执行源连接、设备连接、协议校验、相序校验,再进入守时暂态流程。 + +勾选预检测 + 守时检测时,守时检测不在 `startPreTest` 成功后立刻开始计时。预检测包含源连接、设备连接、协议校验、相序校验四个阶段;这四个阶段完成后,后端推送守时开始/暂态数据相关消息,前端开始守时计时并展示表格更新。 + +### 页面结构 + +`timeTest.vue` 改为轻量结果页: + +- 顶部为紧凑计时区域,显示 `守时检测用时:HH:mm:ss`。 +- 下方为结果表格,列为 `装置名称 / 暂态1触发时刻 / 暂态2触发时刻 / 守时误差 / 结果`。 +- 行数据初始化自 `checkStore.devices`。 +- 未收到数据的字段显示 Element Plus loading 转圈。 +- `time_waiting_second` 消息只触发轻量提示,例如“已收到第一组暂态数据,等待第二组暂态数据”,不增加页面状态区和统计区。 + +### Step 切换与状态保活 + +守时检测完成且后续进入正式检测后,用户可以点击弹窗顶部 step 切回守时检测页。此时守时页只读展示已完成结果,不重启监听、不重置 loading、不重新计时。 + +用户再切回正式检测页时,正式检测组件的表格信息、计时信息、日志进度和当前检测步骤不能初始化。实现上应保持组件实例存活,只切换 `stepsActiveView` 的显示状态,避免因 step 切换触发正式检测组件重建或初始化。 + +### 错误处理 + +`timeTest.vue` 需要接收并监听 `webMsgSend`,与 `factorTest.vue` 保持一致的错误拦截思路: + +- 通用错误码如 `10520`、`10521`、`10522`、`10523`、`10524`、`10525`、`10527`、`10528`、`10529`、`10550`、`10551`、`10552`、`-1`。 +- WebSocket 连接类错误,如 `socket_timeout`、`server_error`、`device_error`、`connect/Source`、`connect/Dev`。 +- 源连接、设备连接、协议校验、相序校验阶段虽然不展示在页面中,但这些阶段的错误必须被守时页捕获,弹窗提示后 `emit('update:testStatus', 'error')`,父流程终止。 + +## 后端流程 + +### 总体接入 + +后端采用复用现有检测链路的方案。`startPreTest` 仍作为统一入口,守时校验作为现有检测链路中的独立业务阶段插入。 + +单独勾选守时检测时,后端需要执行完整前置阶段: + +1. 源连接 +2. 设备连接 +3. 协议校验 +4. 相序校验 +5. 守时检测暂态流程 + +勾选预检测 + 守时检测时,预检测已经包含前四个阶段。后端不重复执行、不关闭源连接和设备连接,直接进入守时检测暂态流程。 + +### 守时业务规则 + +守时检测使用后端内置的两段守时专用暂态脚本,不由前端传脚本编号。 + +业务过程: + +1. 下发暂态脚本 1。 +2. 收取每台装置的一组暂态数据。 +3. 两次暂态触发时刻均从 `DevData.time` 读取。 +4. 同一设备存在多个监测点数据时,以第一条数据为准。 +5. 第一组数据收齐后,后端推送 `time_waiting_second` 事件。 +6. 后端等待 `waitTime - 暂态持续时间1 - fRampOut - fPreTime - fRampIn`。 +7. 下发暂态脚本 2。 +8. 收取每台装置第二组暂态数据。 +9. 计算 `dtMs = 暂态1触发时刻 - 暂态2触发时刻 - waitTime`。 +10. `dtMs <= 10ms` 为合格,否则不合格。 + +结果判定完全由后端负责。前端只展示后端推送的守时误差和结果,不自行计算合格性。 + +### 守时结束后的资源处理 + +如果 `testItemList[3]` 为 `true`,守时检测完成后自动流向正式检测: + +- 后端不关闭源连接。 +- 后端不关闭设备连接。 +- 后端不清理正式检测需要的流程上下文。 +- 前端不关闭 WebSocket,不重建正式检测组件。 +- 前端收到守时成功后自动切到正式检测步骤。 + +如果 `testItemList[3]` 为 `false`,守时检测后没有正式检测: + +- 后端在守时结束后断开设备连接和源连接。 +- 后端清理检测流程上下文。 +- 前端停止计时,展示最终结果,状态置为 `success` 或 `error`。 +- 弹窗关闭时清理 WebSocket 回调或连接。 + +如果守时检测失败,无论是否勾选正式检测,都终止流程,不进入正式检测,并按错误流程释放资源。 + +## WebSocket 消息 + +守时阶段使用独立的守时消息语义,避免前端混在正式检测或系数校准消息里猜状态。推荐 `requestId` 使用 `Time_Check`。 + +### `time_first_data` + +收到某台设备第一次暂态数据。 + +`data` 建议字段: + +- `deviceId` +- `deviceName` +- `monitorId` 或监测点标识 +- `firstTriggerTime` + +### `time_waiting_second` + +第一组暂态数据已收齐,后端已进入等待第二次暂态数据阶段。 + +该消息只作为事件触发标志,前端只做提示,不依赖业务字段。 + +### `time_second_data` + +收到某台设备第二次暂态数据。 + +`data` 建议字段: + +- `deviceId` +- `deviceName` +- `monitorId` 或监测点标识 +- `secondTriggerTime` + +### `time_result` + +某台设备守时结果计算完成。 + +`data` 建议字段: + +- `deviceId` +- `deviceName` +- `firstTriggerTime` +- `secondTriggerTime` +- `waitTimeMs` +- `dtMs` +- `result` +- `message` + +`result` 可以使用后端现有结果约定,也可以明确为 `passed` / `failed`。前端需统一映射为“合格 / 不合格”。 + +### `time_finish` + +全部守时检测完成。 + +`data` 建议字段: + +- `allPassed` +- `results` +- `hasFormalTest` + +前端收到后停止守时计时。如果 `hasFormalTest` 为 `true`,自动流向正式检测;否则结束当前检测流程。 + +## 涉及文件 + +前端: + +- `frontend/src/views/home/components/timeTest.vue` +- `frontend/src/views/home/components/testPopup.vue` +- `frontend/src/api/socket/socket.ts` +- 必要时检查 `frontend/src/views/home/components/compareTestPopup.vue` 是否存在同类 `testItemList` 构造逻辑。 + +后端: + +- `D:\njcn\test\CN_Gather\detection\src\main\java\com\njcn\gather\detection\pojo\param\PreDetectionParam.java` +- `D:\njcn\test\CN_Gather\detection\src\main\java\com\njcn\gather\detection\controller\PreDetectionController.java` +- `D:\njcn\test\CN_Gather\detection\src\main\java\com\njcn\gather\detection\service\impl\PreDetectionServiceImpl.java` +- `D:\njcn\test\CN_Gather\detection\src\main\java\com\njcn\gather\detection\handler\SocketDevResponseService.java` +- `D:\njcn\test\CN_Gather\detection\src\main\java\com\njcn\gather\detection\pojo\enums\SourceOperateCodeEnum.java` + +## 测试建议 + +- 单独勾选守时检测:验证 `startPreTest` 成功后计时立即开始,前置四阶段错误可被前端拦截,最终无正式检测时资源被清理。 +- 勾选预检测 + 守时检测:验证前置四阶段不重复执行、不关闭连接,守时计时从预检测四阶段完成后开始。 +- 勾选守时检测 + 正式检测:验证守时成功后自动进入正式检测,连接和 WebSocket 不被清理。 +- 正式检测中点击 step 切回守时页,再切回正式检测页:验证正式检测表格、计时、日志和进度不初始化。 +- 多设备且多监测点:验证每台设备只取第一条监测点数据参与守时计算。 +- 守时失败:验证不进入正式检测,并按错误流程释放资源。 +- `time_waiting_second`:验证只提示,不改变表格结构。