From c14ea56dd8d5c20d8def85f3f8c470df437cfd0d Mon Sep 17 00:00:00 2001 From: lzh Date: Mon, 30 Mar 2026 15:55:35 +0800 Subject: [PATCH] =?UTF-8?q?Revert=20"fix(iot):=20IoT=20=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E8=A1=A5=E5=85=85=20tenantId=20=E5=B9=B6?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=A7=9F=E6=88=B7=E4=B8=8A=E4=B8=8B=E6=96=87?= =?UTF-8?q?=E7=BC=BA=E9=99=B7"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit fef3e13ff4b08462f12b28969c010f73901f24d1. --- .../rule/IotSceneRuleMessageHandler.java | 12 +++++-- ...leanOrderIntegrationConfigServiceImpl.java | 19 ++++------- .../BeaconDetectionRuleProcessor.java | 3 -- .../processor/ButtonEventRuleProcessor.java | 3 -- .../processor/SignalLossRuleProcessor.java | 12 ++----- .../TrafficThresholdRuleProcessor.java | 2 -- .../RssiSlidingWindowDetectorTest.java | 1 - .../SignalLossRuleProcessorTest.java | 33 ++++++++----------- 8 files changed, 30 insertions(+), 55 deletions(-) diff --git a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/mq/consumer/rule/IotSceneRuleMessageHandler.java b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/mq/consumer/rule/IotSceneRuleMessageHandler.java index 8b61288..7b0a9e4 100644 --- a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/mq/consumer/rule/IotSceneRuleMessageHandler.java +++ b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/mq/consumer/rule/IotSceneRuleMessageHandler.java @@ -1,6 +1,5 @@ package com.viewsh.module.iot.mq.consumer.rule; -import com.viewsh.framework.tenant.core.util.TenantUtils; import com.viewsh.module.iot.core.messagebus.core.IotMessageBus; import com.viewsh.module.iot.core.messagebus.core.IotMessageSubscriber; import com.viewsh.module.iot.core.mq.message.IotDeviceMessage; @@ -10,6 +9,12 @@ import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +// TODO @puhui999:后面重构哈 +/** + * 针对 {@link IotDeviceMessage} 的消费者,处理规则场景 + * + * @author 芋道源码 + */ @Component @Slf4j public class IotSceneRuleMessageHandler implements IotMessageSubscriber { @@ -37,7 +42,8 @@ public class IotSceneRuleMessageHandler implements IotMessageSubscriber sceneRuleService.executeSceneRuleByDevice(message)); + log.info("[onMessage][消息内容({})]", message); + sceneRuleService.executeSceneRuleByDevice(message); } + } diff --git a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/integration/clean/CleanOrderIntegrationConfigServiceImpl.java b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/integration/clean/CleanOrderIntegrationConfigServiceImpl.java index 063a2a9..05935cf 100644 --- a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/integration/clean/CleanOrderIntegrationConfigServiceImpl.java +++ b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/integration/clean/CleanOrderIntegrationConfigServiceImpl.java @@ -2,7 +2,6 @@ package com.viewsh.module.iot.service.integration.clean; import com.viewsh.framework.common.pojo.CommonResult; import com.viewsh.framework.common.util.json.JsonUtils; -import com.viewsh.framework.tenant.core.context.TenantContextHolder; import com.viewsh.module.iot.dal.dataobject.integration.clean.CleanOrderIntegrationConfig; import com.viewsh.module.ops.api.area.AreaDeviceApi; import com.viewsh.module.ops.api.area.AreaDeviceDTO; @@ -30,6 +29,8 @@ public class CleanOrderIntegrationConfigServiceImpl implements CleanOrderIntegra /** * Redis Key 前缀 */ + private static final String AREA_TYPE_CACHE_KEY_PREFIX = "ops:area:%s:type:%s"; + private static final String DEVICE_INDEX_KEY_PREFIX = "ops:device:index:%s"; private static final String NULL_CACHE = "NULL"; /** @@ -92,7 +93,7 @@ public class CleanOrderIntegrationConfigServiceImpl implements CleanOrderIntegra log.debug("[CleanOrderConfig] 查询单个区域配置:areaId={}, relationType={}", areaId, relationType); // 1. 先读 Redis 缓存 - String cacheKey = buildAreaTypeCacheKey(areaId, relationType); + String cacheKey = String.format(AREA_TYPE_CACHE_KEY_PREFIX, areaId, relationType); try { String cached = stringRedisTemplate.opsForValue().get(cacheKey); if (cached != null) { @@ -159,7 +160,7 @@ public class CleanOrderIntegrationConfigServiceImpl implements CleanOrderIntegra log.debug("[CleanOrderConfig] 查询设备配置:deviceId={}", deviceId); // 1. 查询设备反向索引缓存 - String indexKey = buildDeviceIndexCacheKey(deviceId); + String indexKey = String.format(DEVICE_INDEX_KEY_PREFIX, deviceId); try { Map indexMap = stringRedisTemplate.opsForHash().entries(indexKey); @@ -233,7 +234,7 @@ public class CleanOrderIntegrationConfigServiceImpl implements CleanOrderIntegra */ private void writeDeviceIndexCache(Long deviceId, Long areaId, String relationType, Boolean enabled) { try { - String cacheKey = buildDeviceIndexCacheKey(deviceId); + String cacheKey = String.format(DEVICE_INDEX_KEY_PREFIX, deviceId); Map indexData = new HashMap<>(); indexData.put("areaId", String.valueOf(areaId)); indexData.put("relationType", relationType); @@ -254,7 +255,7 @@ public class CleanOrderIntegrationConfigServiceImpl implements CleanOrderIntegra */ private void evictDeviceIndexCache(Long deviceId) { try { - String cacheKey = buildDeviceIndexCacheKey(deviceId); + String cacheKey = String.format(DEVICE_INDEX_KEY_PREFIX, deviceId); stringRedisTemplate.delete(cacheKey); log.debug("[CleanOrderConfig] 清除设备索引缓存:deviceId={}", deviceId); } catch (Exception e) { @@ -342,12 +343,4 @@ public class CleanOrderIntegrationConfigServiceImpl implements CleanOrderIntegra convertConfig(dto.getConfigData()) ); } - - private String buildAreaTypeCacheKey(Long areaId, String relationType) { - return "ops:area:t" + TenantContextHolder.getRequiredTenantId() + ":" + areaId + ":type:" + relationType; - } - - private String buildDeviceIndexCacheKey(Long deviceId) { - return "ops:device:index:t" + TenantContextHolder.getRequiredTenantId() + ":" + deviceId; - } } 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 54bd0fd..be3fcfb 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 @@ -1,6 +1,5 @@ package com.viewsh.module.iot.service.rule.clean.processor; -import com.viewsh.framework.tenant.core.context.TenantContextHolder; import com.viewsh.module.iot.core.integration.constants.CleanOrderTopics; import com.viewsh.module.iot.core.integration.event.clean.CleanOrderArriveEvent; import com.viewsh.module.iot.core.integration.event.clean.CleanOrderAuditEvent; @@ -253,7 +252,6 @@ public class BeaconDetectionRuleProcessor { private void publishArriveEvent(Long deviceId, Long orderId, Long areaId, Map triggerData) { try { CleanOrderArriveEvent event = CleanOrderArriveEvent.builder() - .tenantId(TenantContextHolder.getTenantId()) .eventId(java.util.UUID.randomUUID().toString()) .orderType("CLEAN") .orderId(orderId) @@ -279,7 +277,6 @@ public class BeaconDetectionRuleProcessor { Long areaId, Long orderId, String message, Map data) { try { CleanOrderAuditEvent event = CleanOrderAuditEvent.builder() - .tenantId(TenantContextHolder.getTenantId()) .eventId(java.util.UUID.randomUUID().toString()) .auditType(auditType) .deviceId(deviceId) diff --git a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/ButtonEventRuleProcessor.java b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/ButtonEventRuleProcessor.java index d409857..f78e028 100644 --- a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/ButtonEventRuleProcessor.java +++ b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/ButtonEventRuleProcessor.java @@ -1,7 +1,6 @@ package com.viewsh.module.iot.service.rule.clean.processor; import com.viewsh.framework.common.util.json.JsonUtils; -import com.viewsh.framework.tenant.core.context.TenantContextHolder; import com.viewsh.module.iot.core.integration.constants.CleanOrderTopics; import com.viewsh.module.iot.dal.dataobject.integration.clean.ButtonEventConfig; import com.viewsh.module.iot.dal.redis.clean.BadgeDeviceStatusRedisDAO; @@ -142,7 +141,6 @@ public class ButtonEventRuleProcessor { Map event = new HashMap<>(); event.put("eventId", UUID.randomUUID().toString()); - event.put("tenantId", TenantContextHolder.getTenantId()); event.put("orderType", "CLEAN"); event.put("orderId", orderId); event.put("deviceId", deviceId); @@ -173,7 +171,6 @@ public class ButtonEventRuleProcessor { Map event = new HashMap<>(); event.put("eventId", UUID.randomUUID().toString()); - event.put("tenantId", TenantContextHolder.getTenantId()); event.put("orderType", "CLEAN"); event.put("orderId", orderId); event.put("deviceId", deviceId); 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 73e4e55..492427f 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 @@ -1,6 +1,5 @@ package com.viewsh.module.iot.service.rule.clean.processor; -import com.viewsh.framework.tenant.core.context.TenantContextHolder; import com.viewsh.module.iot.core.integration.constants.CleanOrderTopics; import com.viewsh.module.iot.core.integration.event.clean.CleanOrderAuditEvent; import com.viewsh.module.iot.core.integration.event.clean.CleanOrderCompleteEvent; @@ -76,7 +75,7 @@ public class SignalLossRuleProcessor { public String checkLossTimeout() { // TODO: 设置租户上下文(单租户场景使用固定租户ID=1) // 确保后续发送的 RocketMQ 消息正确携带租户信息 - return doCheckLossTimeout(); + return TenantUtils.execute(1L, () -> doCheckLossTimeout()); } /** @@ -109,12 +108,7 @@ public class SignalLossRuleProcessor { Long areaId = Long.parseLong(parts[5]); // 检查超时 - IotDeviceDO device = deviceService.getDevice(deviceId); - if (device == null || device.getTenantId() == null) { - log.warn("[SignalLoss] 璁惧涓嶅瓨鍦ㄦ垨缂哄皯绉熸埛淇℃伅: deviceId={}", deviceId); - continue; - } - TenantUtils.execute(device.getTenantId(), () -> checkTimeoutForDevice(deviceId, areaId)); + checkTimeoutForDevice(deviceId, areaId); } catch (Exception e) { log.error("[SignalLoss] 处理离岗记录失败:key={}", key, e); @@ -266,7 +260,6 @@ public class SignalLossRuleProcessor { // 3. 发布完成事件 try { CleanOrderCompleteEvent event = CleanOrderCompleteEvent.builder() - .tenantId(TenantContextHolder.getTenantId()) .eventId(java.util.UUID.randomUUID().toString()) .orderType("CLEAN") .orderId(currentOrder.getOrderId()) @@ -317,7 +310,6 @@ public class SignalLossRuleProcessor { Long areaId, Long orderId, String message, Map data) { try { CleanOrderAuditEvent event = CleanOrderAuditEvent.builder() - .tenantId(TenantContextHolder.getTenantId()) .eventId(java.util.UUID.randomUUID().toString()) .auditType(auditType) .deviceId(deviceId) diff --git a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/TrafficThresholdRuleProcessor.java b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/TrafficThresholdRuleProcessor.java index 9e1b096..52e9010 100644 --- a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/TrafficThresholdRuleProcessor.java +++ b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/service/rule/clean/processor/TrafficThresholdRuleProcessor.java @@ -1,6 +1,5 @@ package com.viewsh.module.iot.service.rule.clean.processor; -import com.viewsh.framework.tenant.core.context.TenantContextHolder; import com.viewsh.module.iot.core.integration.constants.CleanOrderTopics; import com.viewsh.module.iot.core.integration.event.clean.CleanOrderCreateEvent; import com.viewsh.module.iot.dal.dataobject.integration.clean.TrafficThresholdConfig; @@ -146,7 +145,6 @@ public class TrafficThresholdRuleProcessor { Long accumulated, Integer threshold) { try { CleanOrderCreateEvent event = CleanOrderCreateEvent.builder() - .tenantId(TenantContextHolder.getTenantId()) .orderType("CLEAN") .areaId(configWrapper.getAreaId()) .triggerSource("IOT_TRAFFIC") diff --git a/viewsh-module-iot/viewsh-module-iot-server/src/test/java/com/viewsh/module/iot/service/rule/clean/detector/RssiSlidingWindowDetectorTest.java b/viewsh-module-iot/viewsh-module-iot-server/src/test/java/com/viewsh/module/iot/service/rule/clean/detector/RssiSlidingWindowDetectorTest.java index 5d61330..dea7d56 100644 --- a/viewsh-module-iot/viewsh-module-iot-server/src/test/java/com/viewsh/module/iot/service/rule/clean/detector/RssiSlidingWindowDetectorTest.java +++ b/viewsh-module-iot/viewsh-module-iot-server/src/test/java/com/viewsh/module/iot/service/rule/clean/detector/RssiSlidingWindowDetectorTest.java @@ -104,7 +104,6 @@ class RssiSlidingWindowDetectorTest { BeaconPresenceConfig.ExitConfig exitConfig = new BeaconPresenceConfig.ExitConfig(); exitConfig.setWeakRssiThreshold(-85); exitConfig.setHitCount(2); - exitConfig.setWindowSize(5); // 场景:在区域内,信号变弱但未达退出阈值 [-80, -82, -84] -> 都在 -70 和 -85 之间 -> 无变化 List window = Arrays.asList(-80, -82, -84); diff --git a/viewsh-module-iot/viewsh-module-iot-server/src/test/java/com/viewsh/module/iot/service/rule/clean/processor/SignalLossRuleProcessorTest.java b/viewsh-module-iot/viewsh-module-iot-server/src/test/java/com/viewsh/module/iot/service/rule/clean/processor/SignalLossRuleProcessorTest.java index 50cdf40..fb8b1e1 100644 --- a/viewsh-module-iot/viewsh-module-iot-server/src/test/java/com/viewsh/module/iot/service/rule/clean/processor/SignalLossRuleProcessorTest.java +++ b/viewsh-module-iot/viewsh-module-iot-server/src/test/java/com/viewsh/module/iot/service/rule/clean/processor/SignalLossRuleProcessorTest.java @@ -1,14 +1,12 @@ package com.viewsh.module.iot.service.rule.clean.processor; import com.viewsh.module.iot.core.integration.constants.CleanOrderTopics; -import com.viewsh.module.iot.dal.dataobject.device.IotDeviceDO; import com.viewsh.module.iot.dal.dataobject.integration.clean.BeaconPresenceConfig; import com.viewsh.module.iot.dal.dataobject.integration.clean.CleanOrderIntegrationConfig; import com.viewsh.module.iot.dal.redis.clean.BadgeDeviceStatusRedisDAO; import com.viewsh.module.iot.dal.redis.clean.BeaconArrivedTimeRedisDAO; import com.viewsh.module.iot.dal.redis.clean.BeaconRssiWindowRedisDAO; import com.viewsh.module.iot.dal.redis.clean.SignalLossRedisDAO; -import com.viewsh.module.iot.service.device.IotDeviceService; import com.viewsh.module.iot.service.integration.clean.CleanOrderIntegrationConfigService; import org.apache.rocketmq.spring.core.RocketMQTemplate; import org.junit.jupiter.api.BeforeEach; @@ -43,8 +41,6 @@ class SignalLossRuleProcessorTest { @Mock private CleanOrderIntegrationConfigService configService; @Mock - private IotDeviceService deviceService; - @Mock private RocketMQTemplate rocketMQTemplate; @Mock private StringRedisTemplate stringRedisTemplate; @@ -59,12 +55,6 @@ class SignalLossRuleProcessorTest { when(stringRedisTemplate.keys(anyString())).thenReturn( Set.of("iot:clean:signal:loss:" + DEVICE_ID + ":" + AREA_ID) ); - - // Mock device lookup (for tenant context) - IotDeviceDO device = new IotDeviceDO(); - device.setId(DEVICE_ID); - device.setTenantId(1L); - when(deviceService.getDevice(DEVICE_ID)).thenReturn(device); } @Test @@ -118,19 +108,18 @@ class SignalLossRuleProcessorTest { } @Test - void testCheckLossTimeout_ShortDuration_StillCompletes() { - // 注意:当前生产代码已暂时取消作业时长不足的抑制逻辑(TODO 注释), - // 所有超时情况均触发完成。此测试验证该行为。 + void testCheckLossTimeout_Suppressed_InvalidDuration() { + // Setup times long now = System.currentTimeMillis(); long firstLossTime = now - 6 * 60 * 1000; // 6 minutes ago (timeout) long lastLossTime = now; - long arrivedTime = now - 5 * 60 * 1000; // Only 5 minutes work + long arrivedTime = now - 5 * 60 * 1000; // Only 5 minutes work (min is 10) // Mock DAOs when(signalLossRedisDAO.getFirstLossTime(DEVICE_ID, AREA_ID)).thenReturn(firstLossTime); when(signalLossRedisDAO.getLastLossTime(DEVICE_ID, AREA_ID)).thenReturn(lastLossTime); when(arrivedTimeRedisDAO.getArrivedTime(DEVICE_ID, AREA_ID)).thenReturn(arrivedTime); - + // Mock Current Order (Valid area) BadgeDeviceStatusRedisDAO.OrderInfo orderInfo = new BadgeDeviceStatusRedisDAO.OrderInfo(); orderInfo.setOrderId(500L); @@ -141,13 +130,13 @@ class SignalLossRuleProcessorTest { BeaconPresenceConfig.ExitConfig exitConfig = new BeaconPresenceConfig.ExitConfig(); exitConfig.setLossTimeoutMinutes(5); exitConfig.setMinValidWorkMinutes(10); - + BeaconPresenceConfig bpConfig = new BeaconPresenceConfig(); bpConfig.setExit(exitConfig); - + CleanOrderIntegrationConfig mainConfig = new CleanOrderIntegrationConfig(); mainConfig.setBeaconPresence(bpConfig); - + CleanOrderIntegrationConfigService.AreaDeviceConfigWrapper wrapper = new CleanOrderIntegrationConfigService.AreaDeviceConfigWrapper(); wrapper.setConfig(mainConfig); @@ -158,7 +147,11 @@ class SignalLossRuleProcessorTest { // Execute processor.checkLossTimeout(); - // Verify: 即使作业时长不足,当前仍会触发完成(抑制逻辑已暂时关闭) - verify(rocketMQTemplate).syncSend(eq(CleanOrderTopics.ORDER_COMPLETE), any(Message.class)); + // Verify + // 1. Should NOT send complete message + verify(rocketMQTemplate, never()).syncSend(eq(CleanOrderTopics.ORDER_COMPLETE), any(Message.class)); + + // 2. Should send Audit Event (TTS) + verify(rocketMQTemplate, atLeastOnce()).syncSend(eq(CleanOrderTopics.ORDER_AUDIT), any(Message.class)); } }