From b67ff2879c14c90d47ce608d8743a41c549f4ad8 Mon Sep 17 00:00:00 2001 From: HuangHuiKang Date: Fri, 24 Apr 2026 17:25:03 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E4=BC=98=E5=8C=96=E9=87=87=E9=9B=86?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=88=86=E9=A1=B5=E6=9F=A5=E8=AF=A2=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/service/device/DeviceServiceImpl.java | 2 +- .../iot/service/device/TDengineService.java | 116 +++++++++++------- 2 files changed, 72 insertions(+), 46 deletions(-) diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java index c950d5f07..eb0150190 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java @@ -361,7 +361,7 @@ public class DeviceServiceImpl implements DeviceService { // .orderByDesc(DeviceOperationRecordDO::getCreateTime) // ); - List operationRecords = tdengineService.selectLatestByDeviceAndRuleMinimal(deviceIds,ruleCodes); + List operationRecords = tdengineService.selectLatestByDeviceAndRuleMinimal(deviceIds,null); // 按 deviceId 分组,取最新一条 Map latestRecordMap = operationRecords.stream() diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/TDengineService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/TDengineService.java index 5b20c424b..3a5f66bfe 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/TDengineService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/TDengineService.java @@ -2009,7 +2009,8 @@ public class TDengineService { /** - * 批量查询设备最新一条运行记录 + * 批量查询设备最新一条运行记录(使用TDengine的LAST函数优化) + * 通过GROUP BY device_id一次性查询所有设备的最新记录 */ @DS("tdengine") public List selectLatestByDeviceAndRuleMinimal( @@ -2020,59 +2021,84 @@ public class TDengineService { return Collections.emptyList(); } - // 优化:分组查询每个设备的最新记录 - List allResults = new ArrayList<>(); - - for (Long deviceId : deviceIds) { - StringBuilder sql = new StringBuilder( - "SELECT * FROM besure_server.iot_device_operation_record " + - "WHERE deleted = 0 AND device_id = ? " - ); + // 构建SQL查询,使用TDengine的LAST函数 + StringBuilder sql = new StringBuilder( + "SELECT device_id, " + + "LAST(device_id) as last_device_id, " + + "LAST(rule) as rule, " + + "LAST(address_value) as address_value, " + + "LAST(create_time) as create_time, " + + "LAST(model_id) as model_id, " + + "LAST(creator) as creator, " + + "LAST(updater) as updater, " + + "LAST(update_time) as update_time, " + + "LAST(deleted) as deleted, " + + "LAST(tenant_id) as tenant_id, " + + "LAST(rule_id) as rule_id " + + "FROM besure_server.iot_device_operation_record " + + "WHERE deleted = 0 " + ); + + // 添加设备ID条件 + sql.append("AND device_id IN ("); + List params = new ArrayList<>(); - List params = new ArrayList<>(); - params.add(deviceId); + for (int i = 0; i < deviceIds.size(); i++) { + if (i > 0) { + sql.append(", "); + } + sql.append("?"); + params.add(deviceIds.get(i)); + } + sql.append(") "); - if (CollectionUtils.isNotEmpty(ruleCodes)) { - sql.append("AND rule IN ("); - for (int i = 0; i < ruleCodes.size(); i++) { - if (i > 0) sql.append(", "); - sql.append("?"); - params.add(ruleCodes.get(i)); + // 添加规则代码条件 + if (CollectionUtils.isNotEmpty(ruleCodes)) { + sql.append("AND rule IN ("); + for (int i = 0; i < ruleCodes.size(); i++) { + if (i > 0) { + sql.append(", "); } - sql.append(") "); + sql.append("?"); + params.add(ruleCodes.get(i)); } + sql.append(") "); + } - sql.append("ORDER BY create_time DESC LIMIT 1"); // 每个设备只取最新1条 + // 使用GROUP BY device_id获取每个设备的最新记录 + sql.append("GROUP BY device_id "); - try { - List deviceResults = jdbcTemplate.query( - sql.toString(), - params.toArray(), - (rs, rowNum) -> { - DeviceOperationRecordDO d = new DeviceOperationRecordDO(); - d.setDeviceId(rs.getLong("device_id")); - d.setModelId(rs.getLong("model_id")); - d.setRule(rs.getString("rule")); - d.setAddressValue(rs.getString("address_value")); - d.setCreator(rs.getString("creator")); - d.setCreateTime(rs.getTimestamp("create_time") != null ? rs.getTimestamp("create_time").toLocalDateTime() : null); - d.setUpdater(rs.getString("updater")); - d.setUpdateTime(rs.getTimestamp("update_time") != null ? rs.getTimestamp("update_time").toLocalDateTime() : null); - d.setDeleted(rs.getBoolean("deleted")); - d.setTenantId(String.valueOf(rs.getLong("tenant_id"))); - d.setRuleId(rs.getLong("rule_id")); - return d; - }); - - allResults.addAll(deviceResults); +// // 添加INTERVAL(0)确保正确处理时间窗口 +// sql.append("INTERVAL(0) "); - } catch (Exception e) { - log.error("查询设备{}的最新记录失败", deviceId, e); - } + // 按设备ID排序 + sql.append("ORDER BY device_id"); + try { + return jdbcTemplate.query( + sql.toString(), + params.toArray(), + (rs, rowNum) -> { + DeviceOperationRecordDO d = new DeviceOperationRecordDO(); + d.setDeviceId(rs.getLong("device_id")); + d.setModelId(rs.getLong("model_id")); + d.setRule(rs.getString("rule")); + d.setAddressValue(rs.getString("address_value")); + d.setCreator(rs.getString("creator")); + d.setCreateTime(rs.getTimestamp("create_time") != null ? + rs.getTimestamp("create_time").toLocalDateTime() : null); + d.setUpdater(rs.getString("updater")); + d.setUpdateTime(rs.getTimestamp("update_time") != null ? + rs.getTimestamp("update_time").toLocalDateTime() : null); + d.setDeleted(rs.getBoolean("deleted")); + d.setTenantId(String.valueOf(rs.getLong("tenant_id"))); + d.setRuleId(rs.getLong("rule_id")); + return d; + }); + } catch (Exception e) { + log.error("查询设备最新记录失败,设备ID: {}, 错误: {}", deviceIds, e.getMessage(), e); + return Collections.emptyList(); } - - return allResults; } /**