From 03d4f60e8027b2e6125e2db4077d87c72ba72ccf Mon Sep 17 00:00:00 2001 From: alwayssuper <191763414@qq.com> Date: Fri, 24 Jan 2025 15:56:01 +0800 Subject: [PATCH] =?UTF-8?q?[fix]=EF=BC=9Acode=20=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dataobject/tdengine/SelectVisualDO.java | 3 ++ .../dal/dataobject/tdengine/TdTableDO.java | 4 ++ .../dal/tdengine/IotDeviceLogDataMapper.java | 11 ++++- .../tdengine/IotDevicePropertyDataMapper.java | 43 +++++++++++++++++++ .../deviceconsumer/DeviceConsumer.java | 4 +- .../device/IotDeviceLogDataServiceImpl.java | 8 +++- .../IotDevicePropertyDataServiceImpl.java | 5 ++- .../IotThingModelMessageServiceImpl.java | 23 +++++++--- .../mapper/device/IotDeviceLogDataMapper.xml | 8 +++- .../device/IotDevicePropertyDataMapper.xml | 42 ++++++++++++++++++ 10 files changed, 138 insertions(+), 13 deletions(-) diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java index 584562bfa6..c9ac20af22 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java @@ -19,6 +19,9 @@ public class SelectVisualDO { */ private String tableName; + + private String deviceKey; + /** * 属性 */ diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java index 3265c3ebed..104be26837 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java @@ -33,6 +33,10 @@ public class TdTableDO { */ private String tableName; + private String productKey; + + private String deviceKey; + /** * COLUMN 字段 */ diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java index 40516c7944..2d8230f1f6 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java @@ -68,6 +68,15 @@ public interface IotDeviceLogDataMapper { /** * 查询设备日志表是否存在 * + * @return 不存在返回null */ - Object checkDeviceLogTableExists(); + Object checkDeviceLogSTableExists(); + + /** + * 检查设备日志子表是否存在 + * + * @param deviceKey 设备标识 + * @return 不存在返回null + */ + Object checkDeviceLogTableExists(@Param("deviceKey") String deviceKey); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyDataMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyDataMapper.java index 6053444fea..1599ce957c 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyDataMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyDataMapper.java @@ -2,6 +2,9 @@ package cn.iocoder.yudao.module.iot.dal.tdengine; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO; +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO; import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField; import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS; import com.baomidou.mybatisplus.annotation.InterceptorIgnore; @@ -10,6 +13,7 @@ import org.apache.ibatis.annotations.Param; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @Mapper @@ -74,4 +78,43 @@ public interface IotDevicePropertyDataMapper { void alterProductPropertySTableDropField(@Param("productKey") String productKey, @Param("field") TDengineTableField field); + //TODO:先参考一下老逻辑,后续改进 + /** + * 插入数据 - 指定列插入数据 + * + * @param table 数据 + * productKey 产品 key + * deviceKey 设备 key + * columns 列 + */ + void insertDevicePropertyData(TdTableDO table); + + //TODO:先参考一下老逻辑,后续改进 + /** + * 查看超级表 - 获取超级表的结构信息 + * SQL:DESCRIBE [db_name.]stb_name; + * + * @param superTable 超级表信息 + * productKey 产品 key + */ + List> describeSuperTable(TdTableDO superTable); + + /** + * 获取历史数据列表 + * + * @param selectVisualDO 查询条件 + * @return 历史数据列表 + */ + @TenantIgnore + List> selectHistoryDataList(SelectVisualDO selectVisualDO); + + /** + * 获取历史数据条数 + * + * @param selectVisualDO 查询条件 + * @return 数据条数 + */ + @TenantIgnore + Long selectHistoryCount(SelectVisualDO selectVisualDO); + } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java index 862fb4d826..1daa05f920 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/deviceconsumer/DeviceConsumer.java @@ -30,8 +30,10 @@ public class DeviceConsumer { @Async public void onMessage(ThingModelMessage message) { log.info("[onMessage][消息内容({})]", message); + //TODO:数据插入这块整体写的比较混乱,整体借鉴了浩浩哥之前写的逻辑,目前是通过模拟设备科插入数据了,但之前的逻辑有大量弃用的部分,后续看看怎么完善 + // 设备数据记录 -// deviceDataService.saveDeviceDataTest(message); + deviceDataService.saveDeviceDataTest(message); // 设备日志记录 iotDeviceLogDataService.saveDeviceLog(message); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java index bee966e72c..f66bcc8ad2 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java @@ -43,8 +43,8 @@ public class IotDeviceLogDataServiceImpl implements IotDeviceLogDataService{ // } // throw e; // } - if(iotDeviceLogDataMapper.checkDeviceLogTableExists()==null){ - log.info("[TDengine] 设备日志超级表不存在,开始创建 {}",iotDeviceLogDataMapper.checkDeviceLogTableExists()); + if(iotDeviceLogDataMapper.checkDeviceLogSTableExists()==null){ + log.info("[TDengine] 设备日志超级表不存在,开始创建"); iotDeviceLogDataMapper.createDeviceLogSTable(); }else{ log.info("[TDengine] 设备日志超级表已存在,跳过创建"); @@ -72,6 +72,10 @@ public class IotDeviceLogDataServiceImpl implements IotDeviceLogDataService{ // 讨论:艿菇 这就是iotDeviceLogDataService的Impl @Override public PageResult getDeviceLogPage(IotDeviceLogPageReqVO pageReqVO) { + // 当设备日志表未创建时,查询会出现报错 + if(iotDeviceLogDataMapper.checkDeviceLogTableExists(pageReqVO.getDeviceKey())==null){ + return null; + } // 查询数据 List list = iotDeviceLogDataMapper.selectPage(pageReqVO); Long total = iotDeviceLogDataMapper.selectCount(pageReqVO); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java index 134803c8e9..2b998e7886 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java @@ -244,6 +244,7 @@ public class IotDevicePropertyDataServiceImpl implements IotDevicePropertyDataSe SelectVisualDO selectVisualDO = new SelectVisualDO(); selectVisualDO.setDataBaseName(getDatabaseName()); selectVisualDO.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName())); + selectVisualDO.setDeviceKey(device.getDeviceKey()); selectVisualDO.setFieldName(deviceDataReqVO.getIdentifier()); selectVisualDO.setStartTime(DateUtil.date(deviceDataReqVO.getTimes()[0].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime()); selectVisualDO.setEndTime(DateUtil.date(deviceDataReqVO.getTimes()[1].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime()); @@ -251,8 +252,8 @@ public class IotDevicePropertyDataServiceImpl implements IotDevicePropertyDataSe params.put("rows", deviceDataReqVO.getPageSize()); params.put("page", (deviceDataReqVO.getPageNo() - 1) * deviceDataReqVO.getPageSize()); selectVisualDO.setParams(params); - pageResult.setList(tdEngineDMLMapper.selectHistoryDataList(selectVisualDO)); - pageResult.setTotal(tdEngineDMLMapper.selectHistoryCount(selectVisualDO)); + pageResult.setList(devicePropertyDataMapper.selectHistoryDataList(selectVisualDO)); + pageResult.setTotal(devicePropertyDataMapper.selectHistoryCount(selectVisualDO)); return pageResult; } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java index e094b34cb6..c35bb3a28b 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java @@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO; import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO; +import cn.iocoder.yudao.module.iot.dal.tdengine.IotDevicePropertyDataMapper; import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDDLMapper; import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper; import cn.iocoder.yudao.module.iot.enums.IotConstants; @@ -61,6 +62,9 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ @Resource private TdEngineDMLMapper tdEngineDMLMapper; + @Resource + private IotDevicePropertyDataMapper iotDevicePropertyDataMapper; + @Resource private DeviceDataRedisDAO deviceDataRedisDAO; @@ -71,7 +75,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ // 1. 判断设备状态,如果为未激活状态,创建数据表并更新设备状态 if (IotDeviceStatusEnum.INACTIVE.getStatus().equals(device.getStatus())) { // 1.1 创建设备表 - createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey()); +// createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey()); iotDeviceService.updateDeviceStatus(new IotDeviceStatusUpdateReqVO() .setId(device.getId()).setStatus(IotDeviceStatusEnum.ONLINE.getStatus())); } @@ -85,14 +89,20 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ // 3. 过滤并收集有效的属性字段,缓存设备属性 List schemaFieldValues = filterAndCollectValidFields(params, thingModelList, device, thingModelMessage.getTime()); - if (schemaFieldValues.size() == 1) { // 仅有时间字段,无需保存 + if (schemaFieldValues.size() == 0) { // 没有字段,无需保存 return; } // 4. 构建并保存设备属性数据 - tdEngineDMLMapper.insertData(TdTableDO.builder() - .dataBaseName(getDatabaseName()) - .tableName(getDeviceTableName(device.getProductKey(), device.getDeviceName())) +// tdEngineDMLMapper.insertData(TdTableDO.builder() +// .dataBaseName(getDatabaseName()) +// .tableName(getDeviceTableName(device.getProductKey(), device.getDeviceName())) +// .columns(schemaFieldValues) +// .build()); + // TODO:复用了旧逻辑,先过渡一下 + iotDevicePropertyDataMapper.insertDevicePropertyData(TdTableDO.builder() + .productKey(device.getProductKey()) + .deviceKey(device.getDeviceKey()) .columns(schemaFieldValues) .build()); } @@ -145,7 +155,8 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ // 3. 过滤并收集有效的属性字段 List schemaFieldValues = new ArrayList<>(); - schemaFieldValues.add(new TdFieldDO(TIME, time)); + //TODO:新版本是使用ts字段 +// schemaFieldValues.add(new TdFieldDO(TIME, time)); params.forEach((key, val) -> { if (propertyIdentifiers.contains(key)) { schemaFieldValues.add(new TdFieldDO(key.toLowerCase(), val)); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml index 1e9b3fdfff..828522ed70 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml @@ -76,8 +76,14 @@ - SHOW STABLES LIKE 'device_log' + + + + \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyDataMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyDataMapper.xml index 9894e27a0e..3ac238d751 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyDataMapper.xml +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyDataMapper.xml @@ -42,4 +42,46 @@ DROP COLUMN ${field.field} + + INSERT INTO device_property_${deviceKey} + USING product_property_${productKey} + TAGS ('${deviceKey}') + (ts + + ,${item.fieldName} + + ) + VALUES + (NOW + + ,#{item.fieldValue} + + ) + + + + + + + + + + + \ No newline at end of file