From fffada37618cf30fae406472dc620fa8bd4750dc Mon Sep 17 00:00:00 2001 From: lzh Date: Fri, 23 Jan 2026 13:47:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(iot):=20=E8=B0=83=E6=95=B4=E4=BF=A1?= =?UTF-8?q?=E6=A0=87=E5=92=8C=E4=BF=A1=E5=8F=B7=E4=B8=A2=E5=A4=B1=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=99=A8=E4=BB=A5=E6=94=AF=E6=8C=81=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=8B=86=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 配置已按设备类型拆分(BADGE/BEACON/TRAFFIC_COUNTER 各自存储), 工牌设备需要从区域的 BEACON 设备获取信标配置。 - BeaconDetectionRuleProcessor: 从区域 BEACON 设备获取 beaconPresence 配置 - SignalLossRuleProcessor: 从区域 BEACON 设备获取信标配置用于超时检测 Co-Authored-By: Claude Opus 4.5 --- .../BeaconDetectionRuleProcessor.java | 33 ++++++++++++------- .../processor/SignalLossRuleProcessor.java | 24 +++++++++----- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/BeaconDetectionRuleProcessor.java b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/BeaconDetectionRuleProcessor.java index 978b2bf..4be6d3d 100644 --- a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/BeaconDetectionRuleProcessor.java +++ b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/BeaconDetectionRuleProcessor.java @@ -70,23 +70,32 @@ public class BeaconDetectionRuleProcessor { log.debug("[BeaconDetection] 收到蓝牙属性:deviceId={}", deviceId); - // 2. 获取配置 - CleanOrderIntegrationConfigService.AreaDeviceConfigWrapper configWrapper = + // 2. 获取工牌设备的配置(包含区域ID) + CleanOrderIntegrationConfigService.AreaDeviceConfigWrapper badgeConfigWrapper = configService.getConfigWrapperByDeviceId(deviceId); - if (configWrapper == null || configWrapper.getConfig() == null) { - log.debug("[BeaconDetection] 设备无配置:deviceId={}", deviceId); + if (badgeConfigWrapper == null || badgeConfigWrapper.getAreaId() == null) { + log.debug("[BeaconDetection] 工牌设备无区域配置:deviceId={}", deviceId); return; } - BeaconPresenceConfig beaconConfig = configWrapper.getConfig().getBeaconPresence(); + Long areaId = badgeConfigWrapper.getAreaId(); + + // 3. 获取该区域的信标配置(从 BEACON 类型的设备获取) + CleanOrderIntegrationConfigService.AreaDeviceConfigWrapper beaconConfigWrapper = + configService.getConfigByAreaIdAndRelationType(areaId, "BEACON"); + + if (beaconConfigWrapper == null || beaconConfigWrapper.getConfig() == null) { + log.debug("[BeaconDetection] 区域无信标配置:areaId={}", areaId); + return; + } + + BeaconPresenceConfig beaconConfig = beaconConfigWrapper.getConfig().getBeaconPresence(); if (beaconConfig == null || !beaconConfig.getEnabled()) { - log.debug("[BeaconDetection] 未启用信标检测:deviceId={}", deviceId); + log.debug("[BeaconDetection] 未启用信标检测:areaId={}", areaId); return; } - Long areaId = configWrapper.getAreaId(); - // 3. 解析蓝牙数据,提取目标信标的 RSSI Integer targetRssi = detector.extractTargetRssi(propertyValue, beaconConfig.getBeaconMac()); @@ -118,7 +127,7 @@ public class BeaconDetectionRuleProcessor { // 9. 处理检测结果 switch (result) { case ARRIVE_CONFIRMED: - handleArriveConfirmed(deviceId, areaId, window, beaconConfig, configWrapper); + handleArriveConfirmed(deviceId, areaId, window, beaconConfig, badgeConfigWrapper); break; case LEAVE_CONFIRMED: handleLeaveConfirmed(deviceId, areaId, window, beaconConfig); @@ -134,7 +143,7 @@ public class BeaconDetectionRuleProcessor { */ private void handleArriveConfirmed(Long deviceId, Long areaId, List window, BeaconPresenceConfig beaconConfig, - CleanOrderIntegrationConfigService.AreaDeviceConfigWrapper configWrapper) { + CleanOrderIntegrationConfigService.AreaDeviceConfigWrapper badgeConfigWrapper) { log.info("[BeaconDetection] 到达确认:deviceId={}, areaId={}, window={}", deviceId, areaId, window); @@ -156,11 +165,11 @@ public class BeaconDetectionRuleProcessor { // 5. 发布到岗事件 if (beaconConfig.getEnter().getAutoArrival()) { - publishArriveEvent(deviceId, configWrapper.getDeviceKey(), areaId, triggerData); + publishArriveEvent(deviceId, badgeConfigWrapper.getDeviceKey(), areaId, triggerData); } // 6. 发布审计日志 - publishAuditEvent("BEACON_ARRIVE_CONFIRMED", deviceId, configWrapper.getDeviceKey(), areaId, + publishAuditEvent("BEACON_ARRIVE_CONFIRMED", deviceId, badgeConfigWrapper.getDeviceKey(), areaId, "蓝牙信标自动到岗确认", triggerData); } diff --git a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/SignalLossRuleProcessor.java b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/SignalLossRuleProcessor.java index 2d1f0fd..5efdf8b 100644 --- a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/SignalLossRuleProcessor.java +++ b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/SignalLossRuleProcessor.java @@ -121,17 +121,23 @@ public class SignalLossRuleProcessor { return; } - // 1. 获取配置 - CleanOrderIntegrationConfigService.AreaDeviceConfigWrapper configWrapper = - configService.getConfigWrapperByDeviceId(deviceId); + // 1. 获取该区域的信标配置(从 BEACON 类型的设备获取) + CleanOrderIntegrationConfigService.AreaDeviceConfigWrapper beaconConfigWrapper = + configService.getConfigByAreaIdAndRelationType(areaId, "BEACON"); - if (configWrapper == null || configWrapper.getConfig() == null || - configWrapper.getConfig().getBeaconPresence() == null) { - log.debug("[SignalLoss] 设备无信标配置:deviceId={}", deviceId); + if (beaconConfigWrapper == null || beaconConfigWrapper.getConfig() == null || + beaconConfigWrapper.getConfig().getBeaconPresence() == null) { + log.debug("[SignalLoss] 区域无信标配置:areaId={}", areaId); return; } - BeaconPresenceConfig.ExitConfig exitConfig = configWrapper.getConfig().getBeaconPresence().getExit(); + BeaconPresenceConfig.ExitConfig exitConfig = beaconConfigWrapper.getConfig().getBeaconPresence().getExit(); + + // 2. 获取工牌设备信息(用于获取 deviceKey) + CleanOrderIntegrationConfigService.AreaDeviceConfigWrapper badgeConfigWrapper = + configService.getConfigWrapperByDeviceId(deviceId); + + String badgeDeviceKey = (badgeConfigWrapper != null) ? badgeConfigWrapper.getDeviceKey() : null; // 2. 获取首次丢失时间 Long firstLossTime = signalLossRedisDAO.getFirstLossTime(deviceId, areaId); @@ -175,11 +181,11 @@ public class SignalLossRuleProcessor { // 6. 分支处理:有效 vs 无效作业 if (durationMs < minValidWorkMillis) { // 作业时长不足,抑制完成 - handleInvalidWork(deviceId, configWrapper.getDeviceKey(), areaId, + handleInvalidWork(deviceId, badgeDeviceKey, areaId, durationMs, minValidWorkMillis, exitConfig); } else { // 作业时长有效,触发完成 - handleTimeoutComplete(deviceId, configWrapper.getDeviceKey(), areaId, + handleTimeoutComplete(deviceId, badgeDeviceKey, areaId, durationMs, lastLossTime); } }