From 0caf6464028614824ab4dc7c491815e5b45897d7 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 8 Oct 2026 12:27:58 +0800 Subject: [PATCH] fix(iot): 使用复合主键修复设备消息日志同毫秒覆盖问题 --- yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceMessageServiceImpl.java | 3 +++ yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceMessageMapper.xml | 8 ++++---- yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceMessageServiceImplTest.java | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceMessageServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceMessageServiceImpl.java index 7bfef2a..dae8855 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceMessageServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceMessageServiceImpl.java @@ -95,6 +95,9 @@ public class IotDeviceMessageServiceImpl implements IotDeviceMessageService { if (messageDO.getData() != null) { messageDO.setData(JsonUtils.toJsonString(messageDO.getData())); } + if (StrUtil.isEmpty(messageDO.getId())) { + messageDO.setId(IotDeviceMessageUtils.generateMessageId()); + } if (messageDO.getTs() == null) { messageDO.setTs(System.currentTimeMillis()); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceMessageMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceMessageMapper.xml index 1292ca6..15185d1 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceMessageMapper.xml +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceMessageMapper.xml @@ -7,7 +7,7 @@ CREATE STABLE IF NOT EXISTS device_message ( ts TIMESTAMP, - id NCHAR(50), + id VARCHAR(50) COMPOSITE KEY, report_time TIMESTAMP, tenant_id BIGINT, server_id NCHAR(50), @@ -63,7 +63,7 @@ AND identifier = #{reqVO.identifier} - ORDER BY ts DESC + ORDER BY ts DESC, id DESC - \ No newline at end of file + diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceMessageServiceImplTest.java b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceMessageServiceImplTest.java index 78bf74d..e880621 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceMessageServiceImplTest.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceMessageServiceImplTest.java @@ -104,6 +104,21 @@ public class IotDeviceMessageServiceImplTest extends BaseMockitoUnitTest { } @Test + public void testCreateDeviceLogAsync_idFallback_whenBlank() { + // 准备:构造一条 id 为空的消息,复合主键字段不能为 null + IotDeviceMessage message = buildMessage(IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod()) + .setId(null); + + // 调用 + service.createDeviceLogAsync(message); + + // 断言:mapper.insert 接收到的 messageDO 已补充 id + ArgumentCaptor captor = ArgumentCaptor.forClass(IotDeviceMessageDO.class); + verify(deviceMessageMapper).insert(captor.capture()); + assertNotNull(captor.getValue().getId(), "id 不应为空"); + } + + @Test public void testCreateDeviceLogAsync_swallowMapperException() { // 准备:mapper.insert 抛异常,验证 @Async 方法内部 try/catch 兜底,不向上抛 IotDeviceMessage message = buildMessage(IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod()); -- libgit2 0.21.4