Browse Source

[fix]:code review

alwayssuper 7 months ago
parent
commit
03d4f60e80

+ 3 - 0
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;
+
     /**
      * 属性
      */

+ 4 - 0
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 字段
      */

+ 10 - 1
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);
 }

+ 43 - 0
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<Map<String, Object>> describeSuperTable(TdTableDO superTable);
+
+    /**
+     * 获取历史数据列表
+     *
+     * @param selectVisualDO 查询条件
+     * @return 历史数据列表
+     */
+    @TenantIgnore
+    List<Map<String, Object>> selectHistoryDataList(SelectVisualDO selectVisualDO);
+
+    /**
+     * 获取历史数据条数
+     *
+     * @param selectVisualDO 查询条件
+     * @return 数据条数
+     */
+    @TenantIgnore
+    Long selectHistoryCount(SelectVisualDO selectVisualDO);
+
 }

+ 3 - 1
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);
     }

+ 6 - 2
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<IotDeviceLogDO> getDeviceLogPage(IotDeviceLogPageReqVO pageReqVO) {
+        // 当设备日志表未创建时,查询会出现报错
+        if(iotDeviceLogDataMapper.checkDeviceLogTableExists(pageReqVO.getDeviceKey())==null){
+            return null;
+        }
         // 查询数据
         List<IotDeviceLogDO> list = iotDeviceLogDataMapper.selectPage(pageReqVO);
         Long total = iotDeviceLogDataMapper.selectCount(pageReqVO);

+ 3 - 2
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;
     }
 

+ 17 - 6
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<TdFieldDO> 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<TdFieldDO> 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));

+ 7 - 1
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml

@@ -76,8 +76,14 @@
     </select>
 
     <!-- 检查设备日志超级表是否存在 -->
-    <select id="checkDeviceLogTableExists" resultType="Object">
+    <select id="checkDeviceLogSTableExists" resultType="Object">
         SHOW STABLES LIKE 'device_log'
     </select>
 
+    <!-- 检查设备日志子表是否存在 -->
+    <select id="checkDeviceLogTableExists" resultType="Object">
+        SHOW TABLES LIKE 'device_log_${deviceKey}'
+    </select>
+
+
 </mapper>

+ 42 - 0
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyDataMapper.xml

@@ -42,4 +42,46 @@
         DROP COLUMN ${field.field}
     </update>
 
+    <insert id="insertDevicePropertyData">
+        INSERT INTO device_property_${deviceKey} 
+        USING product_property_${productKey} 
+        TAGS ('${deviceKey}')
+        (ts
+        <foreach item="item" collection="columns" separator=",">
+            ,${item.fieldName}
+        </foreach>
+        ) 
+        VALUES 
+        (NOW
+        <foreach item="item" collection="columns" separator=",">
+            ,#{item.fieldValue}
+        </foreach>
+        )
+    </insert>
+
+    <!-- 描述超级表结构 -->
+    <select id="describeSuperTable" resultType="java.util.Map">
+        DESCRIBE product_property_${productKey}
+    </select>
+
+    <!-- 获取历史数据 -->
+    <select id="selectHistoryDataList" resultType="java.util.Map"
+            parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
+        SELECT ${fieldName} AS data, ts AS time
+        FROM device_property_${deviceKey}
+        WHERE ts BETWEEN #{startTime} AND #{endTime}
+          AND ${fieldName} IS NOT NULL
+        ORDER BY ts DESC
+        LIMIT #{params.rows} OFFSET #{params.page}
+    </select>
+
+    <!-- 统计历史数据总数 -->
+    <select id="selectHistoryCount" resultType="java.lang.Long"
+            parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
+        SELECT COUNT(*)
+        FROM device_property_${deviceKey}
+        WHERE ts BETWEEN #{startTime} AND #{endTime}
+          AND ${fieldName} IS NOT NULL
+    </select>
+
 </mapper>