Просмотр исходного кода

【优化功能】 优化 tdengine 操作数据库相关代码

安浩浩 9 месяцев назад
Родитель
Сommit
89fb71e857
35 измененных файлов с 415 добавлено и 952 удалено
  1. 38 0
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/IotConstants.java
  2. 7 9
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java
  3. 1 2
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataPageReqVO.java
  4. 0 3
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataRespVO.java
  5. 15 5
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDataDO.java
  6. 0 6
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectDO.java
  7. 3 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java
  8. 0 159
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TableManager.java
  9. 49 11
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDDLMapper.java
  10. 103 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDMLMapper.java
  11. 0 25
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDataWriterMapper.java
  12. 0 24
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDatabaseMapper.java
  13. 0 86
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineQueryMapper.java
  14. 0 41
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineTableMapper.java
  15. 3 3
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataService.java
  16. 12 10
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataServiceImpl.java
  17. 24 21
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java
  18. 1 1
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotSuperTableService.java
  19. 34 25
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotSuperTableServiceImpl.java
  20. 70 58
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java
  21. 0 19
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDataWriterService.java
  22. 0 21
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDataWriterServiceImpl.java
  23. 0 14
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDatabaseService.java
  24. 0 22
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDatabaseServiceImpl.java
  25. 0 28
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineQueryService.java
  26. 0 26
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineQueryServiceImpl.java
  27. 0 123
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineSuperTableService.java
  28. 0 90
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineSuperTableServiceImpl.java
  29. 0 21
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineTableService.java
  30. 0 23
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineTableServiceImpl.java
  31. 32 2
      yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDDLMapper.xml
  32. 23 9
      yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDMLMapper.xml
  33. 0 21
      yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDataWriterMapper.xml
  34. 0 12
      yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDatabaseMapper.xml
  35. 0 32
      yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineTableMapper.xml

+ 38 - 0
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/IotConstants.java

@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.iot.enums;
+
+/**
+ * Iot 常量
+ *
+ * @author 芋道源码
+ */
+public interface IotConstants {
+
+    /**
+     * 获取设备表名
+     * <p>
+     * 格式为 device_{productKey}_{deviceName}
+     */
+    String DEVICE_TABLE_NAME_FORMAT = "device_%s_%s";
+
+    /**
+     * 获取产品属性超级表名 - 网关子设备
+     * <p>
+     * 格式为 gateway_sub_{productKey}
+     */
+    String GATEWAY_SUB_STABLE_NAME_FORMAT = "gateway_sub_%s";
+
+    /**
+     * 获取产品属性超级表名 - 网关
+     * <p>
+     * 格式为 gateway_{productKey}
+     */
+    String GATEWAY_STABLE_NAME_FORMAT = "gateway_%s";
+
+    /**
+     * 获取产品属性超级表名 - 设备
+     * <p>
+     * 格式为 device_{productKey}
+     */
+    String DEVICE_STABLE_NAME_FORMAT = "device_%s";
+
+}

+ 7 - 9
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataRespVO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotTimeDataRespVO;
@@ -31,19 +31,17 @@ public class IotDeviceDataController {
     @Resource
     private IotDeviceDataService deviceDataService;
 
-    // TODO @haohao:是不是叫 get-latest 就好了。因为 data 已经在 url 里了哈
-    @GetMapping("/latest-data")
+    @GetMapping("/latest")
     @Operation(summary = "获取设备属性最新数据")
-    public CommonResult<List<IotDeviceDataRespVO>> getDevicePropertiesLatestData(@Valid IotDeviceDataReqVO deviceDataReqVO) {
-        List<IotDeviceDataDO> list = deviceDataService.getDevicePropertiesLatestData(deviceDataReqVO);
+    public CommonResult<List<IotDeviceDataRespVO>> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
+        List<IotDeviceDataDO> list = deviceDataService.getLatestDeviceProperties(deviceDataReqVO);
         return success(BeanUtils.toBean(list, IotDeviceDataRespVO.class));
     }
 
-    // TODO @haohao:是不是叫 /history-data => page
-    @GetMapping("/history-data")
+    @GetMapping("/history")
     @Operation(summary = "获取设备属性历史数据")
-    public CommonResult<PageResult<IotTimeDataRespVO>> getDevicePropertiesHistoryData(@Valid IotDeviceDataReqVO deviceDataReqVO) {
-        PageResult<Map<String, Object>> list = deviceDataService.getDevicePropertiesHistoryData(deviceDataReqVO);
+    public CommonResult<PageResult<IotTimeDataRespVO>> getHistoryDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
+        PageResult<Map<String, Object>> list = deviceDataService.getHistoryDeviceProperties(deviceDataReqVO);
         return success(BeanUtils.toBean(list, IotTimeDataRespVO.class));
     }
 

+ 1 - 2
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataReqVO.java → yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataPageReqVO.java

@@ -10,10 +10,9 @@ import java.time.LocalDateTime;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
-// TODO @haohao:IotDeviceDataPageReqVO
 @Schema(description = "管理后台 - IoT 设备数据 Request VO")
 @Data
-public class IotDeviceDataReqVO extends PageParam {
+public class IotDeviceDataPageReqVO extends PageParam {
 
     @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
     private Long deviceId;

+ 0 - 3
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataRespVO.java

@@ -1,9 +1,6 @@
 package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData;
 
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Builder;
 import lombok.Data;
 
 import java.time.LocalDateTime;

+ 15 - 5
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDataDO.java

@@ -1,15 +1,12 @@
 package cn.iocoder.yudao.module.iot.dal.dataobject.device;
 
 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
-import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
-import com.baomidou.mybatisplus.annotation.TableId;
-import io.swagger.v3.oas.annotations.media.Schema;
+import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-import java.math.BigDecimal;
 import java.time.LocalDateTime;
 
 /**
@@ -23,39 +20,52 @@ import java.time.LocalDateTime;
 @AllArgsConstructor
 public class IotDeviceDataDO {
 
-    // TODO @haohao:每个字段的关联关系,可以 @ 下哈。
     /**
      * 设备编号
+     * <p>
+     * 关联 {@link IotDeviceDO#getId()}
      */
     private Long deviceId;
 
     /**
      * 物模型编号
+     * <p>
+     * 关联 {@link IotThinkModelFunctionDO#getId()}
      */
     private Long thinkModelFunctionId;
 
     /**
      * 产品标识
+     * <p>
+     * 关联 {@link IotProductDO#getProductKey()}
      */
     private String productKey;
 
     /**
      * 设备名称
+     * <p>
+     * 冗余 {@link IotDeviceDO#getDeviceName()}
      */
     private String deviceName;
 
     /**
      * 属性标识符
+     * <p>
+     * 关联 {@link IotThinkModelFunctionDO#getIdentifier()}
      */
     private String identifier;
 
     /**
      * 属性名称
+     * <p>
+     * 关联 {@link IotThinkModelFunctionDO#getName()}
      */
     private String name;
 
     /**
      * 数据类型
+     * <p>
+     * 关联 {@link IotThinkModelFunctionDO#getProperty()#getDataType()}
      */
     private String dataType;
 

+ 0 - 6
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectDO.java

@@ -42,12 +42,6 @@ public class SelectDO {
      */
     private String type;
 
-    // TODO @haohao:这个字段,是啥哈?
-    /**
-     * 查询条件
-     */
-    private Set<Integer> orgIds;
-
     /**
      * 设备ID
      */

+ 3 - 0
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java

@@ -27,14 +27,17 @@ public class SelectVisualDO {
      * 查询类型,0历史数据,1实时数据,2聚合数据
      */
     private int type;
+
     /**
      * 查询的数据量
      */
     private int num;
+
     /**
      * 聚合函数
      */
     private String aggregate;
+
     /**
      * 统计间隔数字+s/m/h/d
      * 比如1s,1m,1h,1d代表1秒,1分钟,1小时,1天

+ 0 - 159
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TableManager.java

@@ -1,159 +0,0 @@
-package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
-
-import java.util.List;
-
-// TODO @haohao:这个还有用哇?
-/**
- * TableManager 类用于管理 TDengine 表的创建、删除和结构信息获取
- */
-public class TableManager {
-
-    /**
-     * 创建超级表模板(含存在判断)
-     */
-    private static final String CREATE_STABLE_INE_TPL = "CREATE STABLE IF NOT EXISTS %s (%s) TAGS (%s);";
-
-    /**
-     * 删除超级表
-     */
-    private static final String DROP_STABLE_TPL = "DROP STABLE IF EXISTS %s;";
-
-    /**
-     * 获取表的结构信息
-     */
-    private static final String DESC_TB_TPL = "DESCRIBE %s;";
-
-    /**
-     * 超级表增加列
-     */
-    private static final String ALTER_STABLE_ADD_COL_TPL = "ALTER STABLE %s ADD COLUMN %s;";
-
-    /**
-     * 超级表修改列
-     */
-    private static final String ALTER_STABLE_MODIFY_COL_TPL = "ALTER STABLE %s MODIFY COLUMN %s;";
-
-    /**
-     * 超级表删除列
-     */
-    private static final String ALTER_STABLE_DROP_COL_TPL = "ALTER STABLE %s DROP COLUMN %s;";
-
-    /**
-     * 创建普通表模板(含存在判断)
-     */
-    private static final String CREATE_CTABLE_INE_TPL = "CREATE TABLE IF NOT EXISTS %s (%s)";
-
-    /**
-     * 获取创建表sql
-     */
-    public static String getCreateSTableSql(String tbName, List<TdFieldDO> fields, TdFieldDO... tags) {
-        if (fields.isEmpty()) {
-            return null;
-        }
-
-        // 生成字段片段
-        StringBuilder sbField = new StringBuilder("time TIMESTAMP,");
-
-        for (TdFieldDO field : fields) {
-            sbField.append(FieldParser.getFieldDefine(field));
-            sbField.append(",");
-        }
-        sbField.deleteCharAt(sbField.length() - 1);
-
-        String fieldFrag = sbField.toString();
-
-        // 生成tag
-        StringBuilder sbTag = new StringBuilder();
-        for (TdFieldDO tag : tags) {
-            sbTag.append(FieldParser.getFieldDefine(tag))
-                    .append(",");
-        }
-        sbTag.deleteCharAt(sbTag.length() - 1);
-
-        return String.format(CREATE_STABLE_INE_TPL, tbName, fieldFrag, sbTag);
-
-    }
-
-    /**
-     * 获取创建普通表sql
-     */
-    public static String getCreateCTableSql(String tbName, List<TdFieldDO> fields) {
-        if (fields.size() == 0) {
-            return null;
-        }
-
-        //生成字段片段
-        StringBuilder sbField = new StringBuilder("time timestamp,");
-
-        for (TdFieldDO field : fields) {
-            sbField.append(FieldParser.getFieldDefine(field));
-            sbField.append(",");
-        }
-        sbField.deleteCharAt(sbField.length() - 1);
-
-        String fieldFrag = sbField.toString();
-
-        return String.format(CREATE_CTABLE_INE_TPL, tbName, fieldFrag);
-
-    }
-
-
-    /**
-     * 取正确的表名
-     *
-     * @param name 表象
-     */
-    public static String rightTbName(String name) {
-        return name.toLowerCase().replace("-" , "_");
-    }
-
-    /**
-     * 获取表详情的sql
-     */
-    public static String getDescTableSql(String tbName) {
-        return String.format(DESC_TB_TPL, tbName);
-    }
-
-    /**
-     * 获取添加字段sql
-     */
-    public static String getAddSTableColumnSql(String tbName, List<TdFieldDO> fields) {
-        StringBuilder sbAdd = new StringBuilder();
-        for (TdFieldDO field : fields) {
-            sbAdd.append(String.format(ALTER_STABLE_ADD_COL_TPL,
-                    tbName,
-                    FieldParser.getFieldDefine(field)
-            ));
-        }
-        return sbAdd.toString();
-    }
-
-    /**
-     * 获取修改字段sql
-     */
-    public static String getModifySTableColumnSql(String tbName, List<TdFieldDO> fields) {
-        StringBuilder sbModify = new StringBuilder();
-        for (TdFieldDO field : fields) {
-            sbModify.append(String.format(ALTER_STABLE_MODIFY_COL_TPL,
-                    tbName,
-                    FieldParser.getFieldDefine(field)
-            ));
-        }
-        return sbModify.toString();
-    }
-
-    /**
-     * 获取删除字段sql
-     */
-    public static String getDropSTableColumnSql(String tbName, List<TdFieldDO> fields) {
-        StringBuilder sbDrop = new StringBuilder();
-        for (TdFieldDO field : fields) {
-            sbDrop.append(String.format(ALTER_STABLE_DROP_COL_TPL,
-                    tbName,
-                    field.getFieldName()
-            ));
-        }
-        return sbDrop.toString();
-    }
-
-}

+ 49 - 11
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineSuperTableMapper.java → yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDDLMapper.java

@@ -1,19 +1,30 @@
 package cn.iocoder.yudao.module.iot.dal.tdengine;
 
+import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
 import com.baomidou.dynamic.datasource.annotation.DS;
 import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 import java.util.Map;
 
 /**
- * TD 引擎的超级表 Mapper
+ * 专门处理 DDL(数据定义语言)操作,包含所有的数据库和表的定义操作,例如创建数据库、创建超级表、创建子表等
  */
 @Mapper
 @DS("tdengine")
-public interface TdEngineSuperTableMapper {
+public interface TdEngineDDLMapper {
+
+    /**
+     * 创建数据库
+     * SQL:CREATE DATABASE [IF NOT EXISTS] db_name [database_options];
+     *
+     * @param dataBaseName 数据库名称
+     */
+    @TenantIgnore
+    void createDatabase(@Param("dataBaseName") String dataBaseName);
 
     /**
      * 创建超级表
@@ -25,7 +36,7 @@ public interface TdEngineSuperTableMapper {
      *                   columns        列信息
      *                   tags           标签信息
      */
-    @InterceptorIgnore(tenantLine = "true")
+    @TenantIgnore
     void createSuperTable(TdTableDO superTable);
 
     /**
@@ -36,7 +47,7 @@ public interface TdEngineSuperTableMapper {
      *                   dataBaseName 数据库名称
      *                   superTableName 超级表名称
      */
-    @InterceptorIgnore(tenantLine = "true")
+    @TenantIgnore
     List<Map<String, Object>> showSuperTables(TdTableDO superTable);
 
     /**
@@ -47,7 +58,7 @@ public interface TdEngineSuperTableMapper {
      *                   dataBaseName   数据库名称
      *                   superTableName 超级表名称
      */
-    @InterceptorIgnore(tenantLine = "true")
+    @TenantIgnore
     List<Map<String, Object>> describeSuperTable(TdTableDO superTable);
 
     /**
@@ -59,7 +70,7 @@ public interface TdEngineSuperTableMapper {
      *                   superTableName 超级表名称
      *                   column         列信息
      */
-    @InterceptorIgnore(tenantLine = "true")
+    @TenantIgnore
     void addColumnForSuperTable(TdTableDO superTable);
 
     /**
@@ -71,7 +82,7 @@ public interface TdEngineSuperTableMapper {
      *                   superTableName 超级表名称
      *                   column         列信息
      */
-    @InterceptorIgnore(tenantLine = "true")
+    @TenantIgnore
     void dropColumnForSuperTable(TdTableDO superTable);
 
     /**
@@ -83,7 +94,7 @@ public interface TdEngineSuperTableMapper {
      *                   superTableName 超级表名称
      *                   column         列信息
      */
-    @InterceptorIgnore(tenantLine = "true")
+    @TenantIgnore
     void modifyColumnWidthForSuperTable(TdTableDO superTable);
 
 
@@ -95,7 +106,7 @@ public interface TdEngineSuperTableMapper {
      *                   superTableName 超级表名称
      *                   tag            标签信息
      */
-    @InterceptorIgnore(tenantLine = "true")
+    @TenantIgnore
     void addTagForSuperTable(TdTableDO superTable);
 
     /**
@@ -106,6 +117,33 @@ public interface TdEngineSuperTableMapper {
      *                   superTableName 超级表名称
      *                   tag            标签信息
      */
-    @InterceptorIgnore(tenantLine = "true")
+    @TenantIgnore
     void dropTagForSuperTable(TdTableDO superTable);
-}
+
+    /**
+     * 创建子表 - 创建子表
+     * SQL:CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);
+     *
+     * @param table 表信息
+     *              dataBaseName   数据库名称
+     *              superTableName 超级表名称
+     *              tableName      子表名称
+     *              tags           TAG 字段
+     */
+    @TenantIgnore
+    void createTable(TdTableDO table);
+
+    /**
+     * 创建子表 - 创建子表并指定标签的值
+     * SQL:CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...);
+     *
+     * @param table 表信息
+     *              dataBaseName   数据库名称
+     *              superTableName 超级表名称
+     *              tableName      子表名称
+     *              tags           TAG 字段
+     */
+    @TenantIgnore
+    void createTableWithTags(TdTableDO table);
+
+}

+ 103 - 0
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDMLMapper.java

@@ -0,0 +1,103 @@
+package cn.iocoder.yudao.module.iot.dal.tdengine;
+
+import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
+import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
+import com.baomidou.dynamic.datasource.annotation.DS;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 专门处理 TD Engine 的 DML(数据操作语言)操作,处理所有的数据查询和写入操作,如插入数据、查询数据等
+ */
+@Mapper
+@DS("tdengine")
+public interface TdEngineDMLMapper {
+
+    /**
+     * 插入数据 - 指定列插入数据
+     *
+     * @param table 数据
+     *              dataBaseName 数据库名
+     *              tableName 表名
+     *              columns 列
+     */
+    @TenantIgnore
+    void insertData(TdTableDO table);
+
+    /**
+     * 根据时间戳查询数据
+     *
+     * @param selectDO 查询条件
+     * @return 查询结果列表
+     */
+    @TenantIgnore
+    List<Map<String, Object>> selectByTimestamp(SelectDO selectDO);
+
+    /**
+     * 根据时间戳获取数据条数
+     *
+     * @param selectDO 查询条件
+     * @return 数据条数
+     */
+    @TenantIgnore
+    Map<String, Long> selectCountByTimestamp(SelectDO selectDO);
+
+    /**
+     * 获取最新数据
+     *
+     * @param selectDO 查询条件
+     * @return 最新数据
+     */
+    @TenantIgnore
+    Map<String, Object> selectOneLastData(SelectDO selectDO);
+
+    /**
+     * 获取历史数据列表
+     *
+     * @param selectVisualDO 查询条件
+     * @return 历史数据列表
+     */
+    @TenantIgnore
+    List<Map<String, Object>> selectHistoryDataList(SelectVisualDO selectVisualDO);
+
+    /**
+     * 获取实时数据列表
+     *
+     * @param selectVisualDO 查询条件
+     * @return 实时数据列表
+     */
+    @TenantIgnore
+    List<Map<String, Object>> selectRealtimeDataList(SelectVisualDO selectVisualDO);
+
+    /**
+     * 获取聚合数据列表
+     *
+     * @param selectVisualDO 查询条件
+     * @return 聚合数据列表
+     */
+    @TenantIgnore
+    List<Map<String, Object>> selectAggregateDataList(SelectVisualDO selectVisualDO);
+
+    /**
+     * 根据标签获取最新数据列表
+     *
+     * @param tagsSelectDO 查询条件
+     * @return 最新数据列表
+     */
+    @TenantIgnore
+    List<Map<String, Object>> selectLastDataListByTags(TagsSelectDO tagsSelectDO);
+
+    /**
+     * 获取历史数据条数
+     *
+     * @param selectVisualDO 查询条件
+     * @return 数据条数
+     */
+    @TenantIgnore
+    Long selectHistoryCount(SelectVisualDO selectVisualDO);
+}

+ 0 - 25
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDataWriterMapper.java

@@ -1,25 +0,0 @@
-package cn.iocoder.yudao.module.iot.dal.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
-import com.baomidou.dynamic.datasource.annotation.DS;
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import org.apache.ibatis.annotations.Mapper;
-
-/**
- * TD 引擎的数据写入 Mapper
- */
-@Mapper
-@DS("tdengine")
-public interface TdEngineDataWriterMapper {
-
-    /**
-     * 插入数据 - 指定列插入数据
-     *
-     * @param table 数据
-     *              dataBaseName 数据库名
-     *              tableName 表名
-     *              columns 列
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    void insertData(TdTableDO table);
-}

+ 0 - 24
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDatabaseMapper.java

@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.iot.dal.tdengine;
-
-import com.baomidou.dynamic.datasource.annotation.DS;
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-
-// TODO @haohao:InterceptorIgnore 忽略租户,可以在每个方法上,添加 @TenantIgnore 哈。
-/**
- * TD 引擎的数据库 Mapper
- */
-@Mapper
-@DS("tdengine")
-public interface TdEngineDatabaseMapper {
-
-    /**
-     * 创建数据库
-     * SQL:CREATE DATABASE [IF NOT EXISTS] db_name [database_options];
-     *
-     * @param dataBaseName 数据库名称
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    void createDatabase(@Param("dataBaseName") String dataBaseName);
-}

+ 0 - 86
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineQueryMapper.java

@@ -1,86 +0,0 @@
-package cn.iocoder.yudao.module.iot.dal.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO;
-import com.baomidou.dynamic.datasource.annotation.DS;
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * TD 引擎的查询 Mapper
- */
-@Mapper
-@DS("tdengine")
-public interface TdEngineQueryMapper {
-
-    /**
-     * 根据时间戳查询数据
-     *
-     * @param selectDO 查询条件
-     * @return 查询结果
-     */
-    List<Map<String, Object>> selectByTimestamp(SelectDO selectDO);
-
-    // TODO @haohao:最好方法的命名,和数据库操作的保持一直。get => select。然后 selectList or selectOne
-    /**
-     * 根据时间戳获取数据条数
-     *
-     * @param selectDO 查询条件
-     * @return 数据条数
-     */
-    Map<String, Long> getCountByTimestamp(SelectDO selectDO);
-
-    /**
-     * 获取最新数据
-     *
-     * @param selectDO 查询条件
-     * @return 最新数据
-     */
-    Map<String, Object> getLastData(SelectDO selectDO);
-
-    /**
-     * 获取历史数据
-     *
-     * @param selectVisualDO 查询条件
-     * @return 历史数据列表
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    List<Map<String, Object>> getHistoryData(SelectVisualDO selectVisualDO);
-
-    /**
-     * 获取实时数据
-     *
-     * @param selectVisualDO 查询条件
-     * @return 实时数据列表
-     */
-    List<Map<String, Object>> getRealtimeData(SelectVisualDO selectVisualDO);
-
-    /**
-     * 获取聚合数据
-     *
-     * @param selectVisualDO 查询条件
-     * @return 聚合数据列表
-     */
-    List<Map<String, Object>> getAggregateData(SelectVisualDO selectVisualDO);
-
-    /**
-     * 根据标签获取最新数据
-     *
-     * @param tagsSelectDO 查询条件
-     * @return 最新数据列表
-     */
-    List<Map<String, Object>> getLastDataByTags(TagsSelectDO tagsSelectDO);
-
-    /**
-     * 获取历史数据条数
-     *
-     * @param selectVisualDO 查询条件
-     * @return 数据条数
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    Long getHistoryCount(SelectVisualDO selectVisualDO);
-}

+ 0 - 41
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineTableMapper.java

@@ -1,41 +0,0 @@
-package cn.iocoder.yudao.module.iot.dal.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
-import com.baomidou.dynamic.datasource.annotation.DS;
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import org.apache.ibatis.annotations.Mapper;
-
-/**
- * TD 引擎的表 Mapper
- */
-@Mapper
-@DS("tdengine")
-public interface TdEngineTableMapper {
-
-    /**
-     * 创建子表 - 创建子表
-     * SQL:CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);
-     *
-     * @param table 表信息
-     *              dataBaseName   数据库名称
-     *              superTableName 超级表名称
-     *              tableName      子表名称
-     *              tags           TAG 字段
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    void createTable(TdTableDO table);
-
-    /**
-     * 创建子表 - 创建子表并指定标签的值
-     * SQL:CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...);
-     *
-     * @param table 表信息
-     *              dataBaseName   数据库名称
-     *              superTableName 超级表名称
-     *              tableName      子表名称
-     *              tags           TAG 字段
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    void createTableWithTags(TdTableDO table);
-
-}

+ 3 - 3
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataService.java

@@ -1,7 +1,7 @@
 package cn.iocoder.yudao.module.iot.service.device;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
 import jakarta.validation.Valid;
 
@@ -31,7 +31,7 @@ public interface IotDeviceDataService {
      * @param deviceId 设备编号
      * @return 设备属性最新数据
      */
-    List<IotDeviceDataDO> getDevicePropertiesLatestData(@Valid IotDeviceDataReqVO deviceId);
+    List<IotDeviceDataDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceId);
 
     /**
      * 获得设备属性历史数据
@@ -39,5 +39,5 @@ public interface IotDeviceDataService {
      * @param deviceDataReqVO 设备属性历史数据 Request VO
      * @return 设备属性历史数据
      */
-    PageResult<Map<String, Object>> getDevicePropertiesHistoryData(@Valid IotDeviceDataReqVO deviceDataReqVO);
+    PageResult<Map<String, Object>> getHistoryDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO);
 }

+ 12 - 10
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataServiceImpl.java

@@ -1,18 +1,20 @@
 package cn.iocoder.yudao.module.iot.service.device;
 
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONObject;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage;
 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
 import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
+import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper;
+import cn.iocoder.yudao.module.iot.enums.IotConstants;
 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
 import cn.iocoder.yudao.module.iot.service.tdengine.IotThingModelMessageService;
-import cn.iocoder.yudao.module.iot.service.tdengine.TdEngineQueryService;
 import cn.iocoder.yudao.module.iot.service.thinkmodelfunction.IotThinkModelFunctionService;
 import jakarta.annotation.Resource;
 import jakarta.validation.Valid;
@@ -40,7 +42,7 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
     @Resource
     private IotThinkModelFunctionService thinkModelFunctionService;
     @Resource
-    private TdEngineQueryService tdEngineQueryService;
+    private TdEngineDMLMapper tdEngineDMLMapper;
 
     @Resource
     private DeviceDataRedisDAO deviceDataRedisDAO;
@@ -66,7 +68,7 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
     }
 
     @Override
-    public List<IotDeviceDataDO> getDevicePropertiesLatestData(@Valid IotDeviceDataReqVO deviceDataReqVO) {
+    public List<IotDeviceDataDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO) {
         List<IotDeviceDataDO> list = new ArrayList<>();
         // 1. 获取设备信息
         IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
@@ -106,7 +108,7 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
     }
 
     @Override
-    public PageResult<Map<String, Object>> getDevicePropertiesHistoryData(IotDeviceDataReqVO deviceDataReqVO) {
+    public PageResult<Map<String, Object>> getHistoryDeviceProperties(IotDeviceDataPageReqVO deviceDataReqVO) {
         PageResult<Map<String, Object>> pageResult = new PageResult<>();
         // 1. 获取设备信息
         IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
@@ -121,17 +123,17 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
         params.put("rows", deviceDataReqVO.getPageSize());
         params.put("page", (deviceDataReqVO.getPageNo() - 1) * deviceDataReqVO.getPageSize());
         selectVisualDO.setParams(params);
-        pageResult.setList(tdEngineQueryService.getHistoryData(selectVisualDO));
-        pageResult.setTotal(tdEngineQueryService.getHistoryCount(selectVisualDO));
+        pageResult.setList(tdEngineDMLMapper.selectHistoryDataList(selectVisualDO));
+        pageResult.setTotal(tdEngineDMLMapper.selectHistoryCount(selectVisualDO));
         return pageResult;
     }
 
     private String getDatabaseName() {
-        return url.substring(url.lastIndexOf("/") + 1);
+        return StrUtil.subAfter(url, "/", true);
     }
 
     private static String getDeviceTableName(String productKey, String deviceName) {
-        return String.format("device_%s_%s", productKey.toLowerCase(), deviceName.toLowerCase());
+        return  String.format(IotConstants.DEVICE_TABLE_NAME_FORMAT, productKey, deviceName);
     }
 
-}
+}

+ 24 - 21
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java

@@ -19,7 +19,9 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
+import java.security.SecureRandom;
 import java.time.LocalDateTime;
+import java.util.Base64;
 import java.util.Objects;
 import java.util.UUID;
 
@@ -137,10 +139,13 @@ public class IotDeviceServiceImpl implements IotDeviceService {
      * @return 生成的 MQTT Password
      */
     private String generateMqttPassword() {
-        // TODO @haohao:【后续优化】在实际应用中,建议使用更安全的方法生成 MQTT Password,如加密或哈希
-        return UUID.randomUUID().toString();
+        SecureRandom secureRandom = new SecureRandom();
+        byte[] passwordBytes = new byte[32]; // 256 位的随机数
+        secureRandom.nextBytes(passwordBytes);
+        return Base64.getUrlEncoder().withoutPadding().encodeToString(passwordBytes);
     }
 
+
     /**
      * 生成唯一的 DeviceName
      *
@@ -214,30 +219,28 @@ public class IotDeviceServiceImpl implements IotDeviceService {
     @Override
     public void updateDeviceStatus(IotDeviceStatusUpdateReqVO updateReqVO) {
         // 1. 校验存在
-        // TODO @haohao:这里的 iotDeviceDO =>  device。一个是去掉 iot,一个是去掉 DO 后缀。这样,简洁一点。
-        IotDeviceDO iotDeviceDO = validateDeviceExists(updateReqVO.getId());
+        IotDeviceDO device = validateDeviceExists(updateReqVO.getId());
 
         // 2.1 更新状态和更新时间
-        IotDeviceDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceDO.class);
-        // TODO @haohao:下面几个状态的处理,可以考虑 if else if。这样,看起来会有层次感哈
-        // 2.2.1 以前是未激活,现在是上线,设置设备激活时间
-        // TODO @haohao:这里可以使用 ObjectUtils.equalsAny 类似这种哈。
-        if (Objects.equals(iotDeviceDO.getStatus(), IotDeviceStatusEnum.INACTIVE.getStatus())
-                && Objects.equals(updateObj.getStatus(), IotDeviceStatusEnum.ONLINE.getStatus())) {
-            updateObj.setActiveTime(LocalDateTime.now());
-        }
-        // 2.2.2 如果是上线,设置上线时间
-        if (Objects.equals(updateObj.getStatus(), IotDeviceStatusEnum.ONLINE.getStatus())) {
-            updateObj.setLastOnlineTime(LocalDateTime.now());
-        }
-        // 2.2.3 如果是离线,设置离线时间
-        if (Objects.equals(updateObj.getStatus(), IotDeviceStatusEnum.OFFLINE.getStatus())) {
-            updateObj.setLastOfflineTime(LocalDateTime.now());
+        IotDeviceDO updateDevice = BeanUtils.toBean(updateReqVO, IotDeviceDO.class);
+        // 2.2 更新状态相关时间
+        if (Objects.equals(device.getStatus(), IotDeviceStatusEnum.INACTIVE.getStatus())
+                && Objects.equals(updateDevice.getStatus(), IotDeviceStatusEnum.ONLINE.getStatus())) {
+            // 从未激活到在线,设置激活时间和最后上线时间
+            updateDevice.setActiveTime(LocalDateTime.now());
+            updateDevice.setLastOnlineTime(LocalDateTime.now());
+        } else if (Objects.equals(updateDevice.getStatus(), IotDeviceStatusEnum.ONLINE.getStatus())) {
+            // 如果是上线,设置最后上线时间
+            updateDevice.setLastOnlineTime(LocalDateTime.now());
+        } else if (Objects.equals(updateDevice.getStatus(), IotDeviceStatusEnum.OFFLINE.getStatus())) {
+            // 如果是离线,设置最后离线时间
+            updateDevice.setLastOfflineTime(LocalDateTime.now());
         }
+
         // 2.3 设置状态更新时间
-        updateObj.setStatusLastUpdateTime(LocalDateTime.now());
+        updateDevice.setStatusLastUpdateTime(LocalDateTime.now());
         // 2.4 更新到数据库
-        deviceMapper.updateById(updateObj);
+        deviceMapper.updateById(updateDevice);
     }
 
     @Override

+ 1 - 1
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotSuperTableService.java

@@ -15,4 +15,4 @@ public interface IotSuperTableService {
      * 创建超级表数据模型
      */
     void createSuperTableDataModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList);
-}
+}

+ 34 - 25
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotSuperTableServiceImpl.java

@@ -9,6 +9,8 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser;
 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
+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.product.IotProductFunctionTypeEnum;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
@@ -26,7 +28,7 @@ import java.util.stream.Collectors;
 public class IotSuperTableServiceImpl implements IotSuperTableService {
 
     @Resource
-    private TdEngineSuperTableService tdEngineSuperTableService;
+    private TdEngineDDLMapper tdEngineDDLMapper;
 
     @Value("${spring.datasource.dynamic.datasource.tdengine.url}")
     private String url;
@@ -42,9 +44,10 @@ public class IotSuperTableServiceImpl implements IotSuperTableService {
 
         String superTableName = getSuperTableName(product.getDeviceType(), product.getProductKey());
         String databaseName = getDatabaseName();
-        Integer tableExists = tdEngineSuperTableService.checkSuperTableExists(new TdTableDO(databaseName, superTableName));
 
-        if (tableExists != null && tableExists > 0) {
+        List<Map<String, Object>> results = tdEngineDDLMapper.showSuperTables(new TdTableDO(databaseName, superTableName));
+        int tableExists = results == null || results.isEmpty() ? 0 : results.size();
+        if (tableExists > 0) {
             updateSuperTable(thingModel, product.getDeviceType());
         } else {
             createSuperTable(thingModel, product.getDeviceType());
@@ -76,7 +79,7 @@ public class IotSuperTableServiceImpl implements IotSuperTableService {
         String databaseName = getDatabaseName();
 
         // 创建超级表
-        tdEngineSuperTableService.createSuperTable(new TdTableDO(databaseName, superTableName, schemaFields, tagsFields));
+        tdEngineDDLMapper.createSuperTable(new TdTableDO(databaseName, superTableName, schemaFields, tagsFields));
     }
 
     /**
@@ -98,7 +101,7 @@ public class IotSuperTableServiceImpl implements IotSuperTableService {
      * 获取表的字段信息
      */
     private List<TdFieldDO> getTableFields(String tableName) {
-        List<Map<String, Object>> tableDescription = tdEngineSuperTableService.describeSuperTable(new TdTableDO(getDatabaseName(), tableName));
+        List<Map<String, Object>> tableDescription = tdEngineDDLMapper.describeSuperTable(new TdTableDO(getDatabaseName(), tableName));
         if (CollUtil.isEmpty(tableDescription)) {
             return Collections.emptyList();
         }
@@ -127,32 +130,38 @@ public class IotSuperTableServiceImpl implements IotSuperTableService {
 
         // 添加新增字段
         if (CollUtil.isNotEmpty(addFields)) {
-            tdEngineSuperTableService.addColumnsForSuperTable(TdTableDO.builder()
-                    .dataBaseName(databaseName)
-                    .superTableName(tableName)
-                    .columns(addFields)
-                    .build());
+            for (TdFieldDO addField : addFields) {
+                tdEngineDDLMapper.addColumnForSuperTable(TdTableDO.builder()
+                        .dataBaseName(databaseName)
+                        .superTableName(tableName)
+                        .column(addField)
+                        .build());
+            }
         }
         // 删除旧字段
         if (CollUtil.isNotEmpty(dropFields)) {
-            tdEngineSuperTableService.dropColumnsForSuperTable(TdTableDO.builder()
-                    .dataBaseName(databaseName)
-                    .superTableName(tableName)
-                    .columns(dropFields)
-                    .build());
+            for (TdFieldDO dropField : dropFields) {
+                tdEngineDDLMapper.dropColumnForSuperTable(TdTableDO.builder()
+                        .dataBaseName(databaseName)
+                        .superTableName(tableName)
+                        .column(dropField)
+                        .build());
+            }
         }
         // 修改字段(先删除再添加)
         if (CollUtil.isNotEmpty(modifyFields)) {
-            tdEngineSuperTableService.dropColumnsForSuperTable(TdTableDO.builder()
-                    .dataBaseName(databaseName)
-                    .superTableName(tableName)
-                    .columns(modifyFields)
-                    .build());
-            tdEngineSuperTableService.addColumnsForSuperTable(TdTableDO.builder()
-                    .dataBaseName(databaseName)
-                    .superTableName(tableName)
-                    .columns(addFields)
-                    .build());
+            for (TdFieldDO modifyField : modifyFields) {
+                tdEngineDDLMapper.dropColumnForSuperTable(TdTableDO.builder()
+                        .dataBaseName(databaseName)
+                        .superTableName(tableName)
+                        .column(modifyField)
+                        .build());
+                tdEngineDDLMapper.addColumnForSuperTable(TdTableDO.builder()
+                        .dataBaseName(databaseName)
+                        .superTableName(tableName)
+                        .column(modifyField)
+                        .build());
+            }
         }
     }
 

+ 70 - 58
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java

@@ -1,6 +1,8 @@
 package cn.iocoder.yudao.module.iot.service.tdengine;
 
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
@@ -11,6 +13,9 @@ 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.thinkmodelfunction.IotThinkModelFunctionDO;
 import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
+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;
 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
@@ -30,6 +35,14 @@ import java.util.stream.Collectors;
 @Service
 public class IotThingModelMessageServiceImpl implements IotThingModelMessageService {
 
+    private static final String TAG_NOTE = "TAG";
+    private static final String NOTE = "note";
+    private static final String TIME = "time";
+    private static final String DEVICE_KEY = "device_key";
+    private static final String DEVICE_NAME = "device_name";
+    private static final String PRODUCT_KEY = "product_key";
+    private static final String DEVICE_TYPE = "device_type";
+
     @Value("${spring.datasource.dynamic.datasource.tdengine.url}")
     private String url;
 
@@ -38,11 +51,9 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
     @Resource
     private IotDeviceService iotDeviceService;
     @Resource
-    private TdEngineTableService tdEngineTableService;
-    @Resource
-    private TdEngineSuperTableService tdEngineSuperTableService;
+    private TdEngineDDLMapper tdEngineDDLMapper;
     @Resource
-    private TdEngineDataWriterService tdEngineDataWriterService;
+    private TdEngineDMLMapper tdEngineDMLMapper;
 
     @Resource
     private DeviceDataRedisDAO deviceDataRedisDAO;
@@ -51,62 +62,64 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
     @Override
     @TenantIgnore
     public void saveThingModelMessage(IotDeviceDO device, ThingModelMessage thingModelMessage) {
-        // 判断设备状态,如果为未激活状态,创建数据表
+        // 1. 判断设备状态,如果为未激活状态,创建数据表并更新设备状态
         if (IotDeviceStatusEnum.INACTIVE.getStatus().equals(device.getStatus())) {
-            // 创建设备数据表
             createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey());
-            // 更新设备状态
-            // TODO @haohao:下面可以考虑,链式调用。iotDeviceService.updateDeviceStatus(new IotDeviceStatusUpdateReqVO().setid().setstatus())
-            IotDeviceStatusUpdateReqVO updateReqVO = new IotDeviceStatusUpdateReqVO();
-            updateReqVO.setId(device.getId());
-            updateReqVO.setStatus(IotDeviceStatusEnum.ONLINE.getStatus());
-            iotDeviceService.updateDeviceStatus(updateReqVO);
+            iotDeviceService.updateDeviceStatus(new IotDeviceStatusUpdateReqVO()
+                    .setId(device.getId())
+                    .setStatus(IotDeviceStatusEnum.ONLINE.getStatus()));
         }
 
-        // TODO @haohao:这个变量,可以和 “过滤并收集有效的属性字段” 那块,因为关联度高一点。
-        // 获取设备属性
+        // 2. 获取设备属性并进行物模型校验,过滤非物模型属性
         Map<String, Object> params = thingModelMessage.dataToMap();
+        List<IotThinkModelFunctionDO> functionList = getValidFunctionList(thingModelMessage.getProductKey());
+        if (functionList.isEmpty()) {
+            return;
+        }
+
+
+        // 3. 过滤并收集有效的属性字段,缓存设备属性
+        List<TdFieldDO> schemaFieldValues = filterAndCollectValidFields(params, functionList, device, thingModelMessage.getTime());
+        if (schemaFieldValues.size() == 1) { // 仅有时间字段,无需保存
+            return;
+        }
+
+        // 4. 构建并保存设备属性数据
+        tdEngineDMLMapper.insertData(TdTableDO.builder()
+                .dataBaseName(getDatabaseName())
+                .tableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()))
+                .columns(schemaFieldValues)
+                .build());
+    }
 
-        // 物模型校验,过滤非物模型属性
-        List<IotThinkModelFunctionDO> functionList = iotThinkModelFunctionService
-                .getThinkModelFunctionListByProductKey(thingModelMessage.getProductKey())
+    private List<IotThinkModelFunctionDO> getValidFunctionList(String productKey) {
+        return iotThinkModelFunctionService
+                .getThinkModelFunctionListByProductKey(productKey)
                 .stream()
                 .filter(function -> IotProductFunctionTypeEnum.PROPERTY.getType().equals(function.getType()))
                 .toList();
-        if (functionList.isEmpty()) {
-            return;
-        }
+    }
 
-        // 获取属性标识符集合
-        // TODO @haohao:这个变量,可以和 “过滤并收集有效的属性字段” 那块,因为关联度高一点。另外,可以使用 CollectionUtils。convertSet
-        Set<String> propertyIdentifiers = functionList.stream()
-                .map(IotThinkModelFunctionDO::getIdentifier)
-                .collect(Collectors.toSet());
+    private List<TdFieldDO> filterAndCollectValidFields(Map<String, Object> params, List<IotThinkModelFunctionDO> functionList, IotDeviceDO device, Long time) {
+        // 1. 获取属性标识符集合
+        Set<String> propertyIdentifiers = CollectionUtils.convertSet(functionList, IotThinkModelFunctionDO::getIdentifier);
 
+        // 2. 构建属性标识符和属性的映射
         Map<String, IotThinkModelFunctionDO> functionMap = functionList.stream()
                 .collect(Collectors.toMap(IotThinkModelFunctionDO::getIdentifier, function -> function));
 
-        // 过滤并收集有效的属性字段
+        // 3. 过滤并收集有效的属性字段
         List<TdFieldDO> schemaFieldValues = new ArrayList<>();
-        schemaFieldValues.add(new TdFieldDO("time", thingModelMessage.getTime()));
+        schemaFieldValues.add(new TdFieldDO(TIME, time));
         params.forEach((key, val) -> {
             if (propertyIdentifiers.contains(key)) {
                 schemaFieldValues.add(new TdFieldDO(key.toLowerCase(), val));
                 // 缓存设备属性
                 // TODO @haohao:这个缓存的写入,可以使用的时候 cache 么?被动读
-                setDeviceDataCache(device, functionMap.get(key), val, thingModelMessage.getTime());
+                setDeviceDataCache(device, functionMap.get(key), val, time);
             }
         });
-        // TODO @haohao:疑问,为什么 1 不继续哈?
-        if (schemaFieldValues.size() == 1) {
-            return;
-        }
-
-        // 构建并保存设备属性数据
-        tdEngineDataWriterService.insertData(TdTableDO.builder().build()
-                .setDataBaseName(getDatabaseName())
-                .setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()))
-                .setColumns(schemaFieldValues));
+        return schemaFieldValues;
     }
 
     /**
@@ -132,7 +145,6 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
         deviceDataRedisDAO.set(deviceData);
     }
 
-    // TODO @haohao:实现没问题哈。这个方法的空行有点多,逻辑分块上没这么明显。看看能不能改下。
     /**
      * 创建设备数据表
      *
@@ -142,36 +154,37 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
      * @param deviceKey  设备 Key
      */
     private void createDeviceTable(Integer deviceType, String productKey, String deviceName, String deviceKey) {
+        // 1. 获取超级表名和数据库名
         String superTableName = getProductPropertySTableName(deviceType, productKey);
         String dataBaseName = getDatabaseName();
 
-        List<Map<String, Object>> maps = tdEngineSuperTableService.describeSuperTable(new TdTableDO(dataBaseName, superTableName));
+        // 2. 获取超级表的结构信息
+        List<Map<String, Object>> maps = tdEngineDDLMapper.describeSuperTable(new TdTableDO(dataBaseName, superTableName));
         List<TdFieldDO> tagsFieldValues = new ArrayList<>();
-
         if (maps != null) {
-            // TODO @haohao:一些字符串,是不是可以枚举起来哈。
-            // TODO @haohao:这种过滤的,常用的,可以考虑用 CollectionUtils.filterList。一些常用的 stream 操作,适合封装哈
-            List<Map<String, Object>> taggedNotesList = maps.stream()
-                    .filter(map -> "TAG".equals(map.get("note")))
-                    .toList();
+            // 2.1 过滤出 TAG 类型的字段
+            List<Map<String, Object>> taggedNotesList = CollectionUtils.filterList(maps, map -> TAG_NOTE.equals(map.get(NOTE)));
+
 
+            // 2.2 解析字段信息
             tagsFieldValues = FieldParser.parse(taggedNotesList.stream()
                     .map(map -> List.of(map.get("field"), map.get("type"), map.get("length")))
                     .collect(Collectors.toList()));
 
+            // 2.3 设置 TAG 字段的值
             for (TdFieldDO tagsFieldValue : tagsFieldValues) {
                 switch (tagsFieldValue.getFieldName()) {
-                    case "product_key" -> tagsFieldValue.setFieldValue(productKey);
-                    case "device_key" -> tagsFieldValue.setFieldValue(deviceKey);
-                    case "device_name" -> tagsFieldValue.setFieldValue(deviceName);
-                    case "device_type" -> tagsFieldValue.setFieldValue(deviceType);
+                    case PRODUCT_KEY -> tagsFieldValue.setFieldValue(productKey);
+                    case DEVICE_KEY -> tagsFieldValue.setFieldValue(deviceKey);
+                    case DEVICE_NAME -> tagsFieldValue.setFieldValue(deviceName);
+                    case DEVICE_TYPE -> tagsFieldValue.setFieldValue(deviceType);
                 }
             }
         }
 
-        // 创建设备数据表
+        // 3. 创建设备数据表
         String tableName = getDeviceTableName(productKey, deviceName);
-        tdEngineTableService.createTable(TdTableDO.builder().build()
+        tdEngineDDLMapper.createTable(TdTableDO.builder().build()
                 .setDataBaseName(dataBaseName)
                 .setSuperTableName(superTableName)
                 .setTableName(tableName)
@@ -184,8 +197,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
      * @return 数据库名称
      */
     private String getDatabaseName() {
-        // TODO @haohao:可以使用 StrUtil.subAftetLast 这种方法
-        return url.substring(url.lastIndexOf("/") + 1);
+        return StrUtil.subAfter(url, "/", true);
     }
 
     /**
@@ -198,9 +210,9 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
     private static String getProductPropertySTableName(Integer deviceType, String productKey) {
         // TODO @haohao:枚举下,会好点哈。
         return switch (deviceType) {
-            case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase();
-            case 2 -> String.format("gateway_%s", productKey).toLowerCase();
-            default -> String.format("device_%s", productKey).toLowerCase();
+            case 1 -> String.format(IotConstants.GATEWAY_SUB_STABLE_NAME_FORMAT, productKey).toLowerCase();
+            case 2 -> String.format(IotConstants.GATEWAY_STABLE_NAME_FORMAT, productKey).toLowerCase();
+            default -> String.format(IotConstants.DEVICE_STABLE_NAME_FORMAT, productKey).toLowerCase();
         };
     }
 
@@ -212,7 +224,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
      * @return 设备表名
      */
     private static String getDeviceTableName(String productKey, String deviceName) {
-        return String.format("device_%s_%s", productKey.toLowerCase(), deviceName.toLowerCase());
+        return String.format(IotConstants.DEVICE_TABLE_NAME_FORMAT, productKey.toLowerCase(), deviceName.toLowerCase());
     }
 
 }

+ 0 - 19
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDataWriterService.java

@@ -1,19 +0,0 @@
-package cn.iocoder.yudao.module.iot.service.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
-
-/**
- * TD 引擎的数据写入 Service 接口
- */
-public interface TdEngineDataWriterService {
-
-    /**
-     * 插入数据 - 指定列插入数据
-     *
-     * @param table 数据
-     *              dataBaseName 数据库名
-     *              tableName 表名
-     *              columns 列
-     */
-    void insertData(TdTableDO table);
-}

+ 0 - 21
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDataWriterServiceImpl.java

@@ -1,21 +0,0 @@
-package cn.iocoder.yudao.module.iot.service.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
-import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDataWriterMapper;
-import jakarta.annotation.Resource;
-import org.springframework.stereotype.Service;
-
-/**
- * TD 引擎的数据写入 Service 实现类
- */
-@Service
-public class TdEngineDataWriterServiceImpl implements TdEngineDataWriterService {
-
-    @Resource
-    private TdEngineDataWriterMapper tdEngineDataWriterMapper;
-
-    @Override
-    public void insertData(TdTableDO table) {
-        tdEngineDataWriterMapper.insertData(table);
-    }
-}

+ 0 - 14
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDatabaseService.java

@@ -1,14 +0,0 @@
-package cn.iocoder.yudao.module.iot.service.tdengine;
-
-/**
- * TD 引擎的数据库 Service 接口
- */
-public interface TdEngineDatabaseService {
-
-    /**
-     * 创建数据库
-     *
-     * @param dataBaseName 数据库名称
-     */
-    void createDatabase(String dataBaseName);
-}

+ 0 - 22
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDatabaseServiceImpl.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.iot.service.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDatabaseMapper;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-/**
- * TD 引擎的数据库 Service 实现类
- */
-@Service
-@Slf4j
-public class TdEngineDatabaseServiceImpl implements TdEngineDatabaseService {
-
-    @Resource
-    private TdEngineDatabaseMapper tdEngineDatabaseMapper;
-
-    @Override
-    public void createDatabase(String dataBaseName) {
-        tdEngineDatabaseMapper.createDatabase(dataBaseName);
-    }
-}

+ 0 - 28
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineQueryService.java

@@ -1,28 +0,0 @@
-package cn.iocoder.yudao.module.iot.service.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * TD 引擎的查询 Service 接口
- */
-public interface TdEngineQueryService {
-
-    /**
-     * 获取历史数据
-     *
-     * @param selectVisualDO 查询条件
-     * @return 历史数据列表
-     */
-    List<Map<String, Object>> getHistoryData(SelectVisualDO selectVisualDO);
-
-    /**
-     * 获取历史数据条数
-     *
-     * @param selectVisualDO 查询条件
-     * @return 数据条数
-     */
-    Long getHistoryCount(SelectVisualDO selectVisualDO);
-}

+ 0 - 26
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineQueryServiceImpl.java

@@ -1,26 +0,0 @@
-package cn.iocoder.yudao.module.iot.service.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
-import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineQueryMapper;
-import jakarta.annotation.Resource;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.Map;
-
-@Service
-public class TdEngineQueryServiceImpl implements TdEngineQueryService {
-
-    @Resource
-    private TdEngineQueryMapper tdEngineQueryMapper;
-
-    @Override
-    public List<Map<String, Object>> getHistoryData(SelectVisualDO selectVisualDO) {
-        return tdEngineQueryMapper.getHistoryData(selectVisualDO);
-    }
-
-    @Override
-    public Long getHistoryCount(SelectVisualDO selectVisualDO) {
-        return tdEngineQueryMapper.getHistoryCount(selectVisualDO);
-    }
-}

+ 0 - 123
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineSuperTableService.java

@@ -1,123 +0,0 @@
-package cn.iocoder.yudao.module.iot.service.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * TD 引擎的超级表 Service 接口
- */
-public interface TdEngineSuperTableService {
-
-    /**
-     * 创建超级表
-     *
-     * @param superTable 超级表信息
-     *                   dataBaseName   数据库名称
-     *                   superTableName 超级表名称
-     *                   columns        列信息
-     *                   tags           标签信息
-     */
-    void createSuperTable(TdTableDO superTable);
-
-    /**
-     * 查看超级表 - 显示当前数据库下的所有超级表信息
-     *
-     * @param superTable 超级表信息
-     *                   dataBaseName 数据库名称
-     *                   superTableName 超级表名称
-     */
-
-    List<Map<String, Object>> showSuperTables(TdTableDO superTable);
-
-    /**
-     * 查看超级表 - 获取超级表的结构信息
-     *
-     * @param superTable 超级表信息
-     *                   dataBaseName   数据库名称
-     *                   superTableName 超级表名称
-     */
-    List<Map<String, Object>> describeSuperTable(TdTableDO superTable);
-
-    /**
-     * 修改超级表 - 增加列
-     *
-     * @param superTable 超级表信息
-     *                   dataBaseName   数据库名称
-     *                   superTableName 超级表名称
-     *                   column         列信息
-     */
-    void addColumnForSuperTable(TdTableDO superTable);
-
-    /**
-     * 修改超级表 - 删除列
-     *
-     * @param superTable 超级表信息
-     *                   dataBaseName   数据库名称
-     *                   superTableName 超级表名称
-     *                   column         列信息
-     */
-    void dropColumnForSuperTable(TdTableDO superTable);
-
-    /**
-     * 修改超级表 - 修改列宽
-     *
-     * @param superTable 超级表信息
-     *                   dataBaseName   数据库名称
-     *                   superTableName 超级表名称
-     *                   column         列信息
-     */
-    void modifyColumnWidthForSuperTable(TdTableDO superTable);
-
-
-    /**
-     * 修改超级表 - 为超级表添加标签
-     *
-     * @param superTable 超级表信息
-     *                   dataBaseName   数据库名称
-     *                   superTableName 超级表名称
-     *                   tag            标签信息
-     */
-    void addTagForSuperTable(TdTableDO superTable);
-
-    /**
-     * 修改超级表 - 为超级表删除标签
-     *
-     * @param superTable 超级表信息
-     *                   dataBaseName   数据库名称
-     *                   superTableName 超级表名称
-     *                   tag            标签信息
-     */
-    void dropTagForSuperTable(TdTableDO superTable);
-
-    /**
-     * 检查超级表是否存在
-     *
-     * @param superTable 超级表信息
-     *                   dataBaseName   数据库名称
-     *                   superTableName 超级表名称
-     * @return 超级表数量
-     */
-    Integer checkSuperTableExists(TdTableDO superTable);
-
-    /**
-     * 为超级表添加列
-     *
-     * @param superTable 超级表信息
-     *                   dataBaseName   数据库名称
-     *                   superTableName 超级表名称
-     *                   columns        列信息
-     */
-    void addColumnsForSuperTable(TdTableDO superTable);
-
-    /**
-     * 为超级表删除列
-     *
-     * @param superTable 超级表信息
-     *                   dataBaseName   数据库名称
-     *                   superTableName 超级表名称
-     *                   columns        列信息
-     */
-    void dropColumnsForSuperTable(TdTableDO superTable);
-}

+ 0 - 90
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineSuperTableServiceImpl.java

@@ -1,90 +0,0 @@
-package cn.iocoder.yudao.module.iot.service.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
-import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineSuperTableMapper;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * TD 引擎的超级表 Service 实现类
- */
-@Slf4j
-@Service
-public class TdEngineSuperTableServiceImpl implements TdEngineSuperTableService {
-
-    @Resource
-    private TdEngineSuperTableMapper tdEngineSuperTableMapper;
-
-    @Override
-    public void createSuperTable(TdTableDO superTable) {
-        tdEngineSuperTableMapper.createSuperTable(superTable);
-    }
-
-    @Override
-    public List<Map<String, Object>> showSuperTables(TdTableDO superTable) {
-        return tdEngineSuperTableMapper.showSuperTables(superTable);
-    }
-
-    @Override
-    public List<Map<String, Object>> describeSuperTable(TdTableDO superTable) {
-        return tdEngineSuperTableMapper.describeSuperTable(superTable);
-    }
-
-    @Override
-    public void addColumnForSuperTable(TdTableDO superTable) {
-        tdEngineSuperTableMapper.addColumnForSuperTable(superTable);
-    }
-
-    @Override
-    public void dropColumnForSuperTable(TdTableDO superTable) {
-        tdEngineSuperTableMapper.dropColumnForSuperTable(superTable);
-    }
-
-    @Override
-    public void modifyColumnWidthForSuperTable(TdTableDO superTable) {
-        tdEngineSuperTableMapper.modifyColumnWidthForSuperTable(superTable);
-    }
-
-    @Override
-    public void addTagForSuperTable(TdTableDO superTable) {
-        tdEngineSuperTableMapper.addTagForSuperTable(superTable);
-    }
-
-    @Override
-    public void dropTagForSuperTable(TdTableDO superTable) {
-        tdEngineSuperTableMapper.dropTagForSuperTable(superTable);
-    }
-
-    @Override
-    public Integer checkSuperTableExists(TdTableDO superTable) {
-        List<Map<String, Object>> results = tdEngineSuperTableMapper.showSuperTables(superTable);
-        return results == null || results.isEmpty() ? 0 : results.size();
-    }
-
-    @Override
-    public void addColumnsForSuperTable(TdTableDO superTable) {
-        for (TdFieldDO column : superTable.getColumns()) {
-            tdEngineSuperTableMapper.addColumnForSuperTable(TdTableDO.builder()
-                    .dataBaseName(superTable.getDataBaseName())
-                    .superTableName(superTable.getSuperTableName())
-                    .column(column)
-                    .build());
-        }
-    }
-
-    @Override
-    public void dropColumnsForSuperTable(TdTableDO superTable) {
-        for (TdFieldDO column : superTable.getColumns()) {
-            tdEngineSuperTableMapper.dropColumnForSuperTable(TdTableDO.builder()
-                    .dataBaseName(superTable.getDataBaseName())
-                    .superTableName(superTable.getSuperTableName())
-                    .column(column)
-                    .build());
-        }
-    }
-}

+ 0 - 21
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineTableService.java

@@ -1,21 +0,0 @@
-package cn.iocoder.yudao.module.iot.service.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
-
-/**
- * TD 引擎的表 Service 接口
- */
-public interface TdEngineTableService {
-
-    /**
-     * 创建表 - 创建超级表的子表
-     *
-     * @param table 表信息
-     *              dataBaseName   数据库名称
-     *              superTableName 超级表名称
-     *              tableName      子表名称
-     *              tags           TAG 字段
-     */
-    void createTable(TdTableDO table);
-
-}

+ 0 - 23
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineTableServiceImpl.java

@@ -1,23 +0,0 @@
-package cn.iocoder.yudao.module.iot.service.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
-import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineTableMapper;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-/**
- * TD 引擎的表 Service 实现类
- */
-@Slf4j
-@Service
-public class TdEngineTableServiceImpl implements TdEngineTableService {
-
-    @Resource
-    private TdEngineTableMapper tdEngineTableMapper;
-
-    @Override
-    public void createTable(TdTableDO table) {
-        tdEngineTableMapper.createTable(table);
-    }
-}

+ 32 - 2
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineSuperTableMapper.xml → yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDDLMapper.xml

@@ -2,7 +2,12 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineSuperTableMapper">
+<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDDLMapper">
+
+    <!-- 创建数据库 -->
+    <update id="createDatabase" parameterType="String">
+        CREATE DATABASE IF NOT EXISTS ${dataBaseName}
+    </update>
 
     <!-- 创建超级表 -->
     <update id="createSuperTable">
@@ -68,4 +73,29 @@
         ALTER STABLE ${dataBaseName}.${superTableName} DROP TAG ${tag.fieldName}
     </update>
 
-</mapper>
+    <!-- 创建子表 -->
+    <update id="createTable">
+        CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
+        USING ${dataBaseName}.${superTableName}
+        TAGS
+        <foreach item="item" collection="tags" separator=","
+                 open="(" close=")">
+            #{item.fieldValue}
+        </foreach>
+    </update>
+
+    <!-- 创建子表,带有 TAGS -->
+    <update id="createTableWithTags">
+        CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
+        USING ${dataBaseName}.${superTableName}
+        <foreach item="item" collection="tags" separator="," open="(" close=")">
+            #{item.fieldName}
+        </foreach>
+        TAGS
+        <foreach item="item" collection="tags" separator=","
+                 open="(" close=")">
+            #{item.fieldValue}
+        </foreach>
+    </update>
+
+</mapper>

+ 23 - 9
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineQueryMapper.xml → yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDMLMapper.xml

@@ -2,7 +2,21 @@
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineQueryMapper">
+<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper">
+
+    <!-- 插入数据 -->
+    <insert id="insertData">
+        INSERT INTO ${dataBaseName}.${tableName}
+        <foreach item="item" collection="columns" separator=","
+                 open="(" close=")">
+            ${item.fieldName}
+        </foreach>
+        VALUES
+        <foreach item="item" collection="columns" separator=","
+                 open="(" close=")">
+            #{item.fieldValue}
+        </foreach>
+    </insert>
 
     <!-- 根据时间戳查询数据 -->
     <select id="selectByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO"
@@ -12,7 +26,7 @@
     </select>
 
     <!-- 获取时间范围内的数据条数 -->
-    <select id="getCountByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO"
+    <select id="selectCountByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO"
             resultType="java.util.Map">
         SELECT COUNT(0) AS count
         FROM ${dataBaseName}.${tableName}
@@ -20,14 +34,14 @@
     </select>
 
     <!-- 获取最新数据 -->
-    <select id="getLastData" resultType="java.util.Map">
+    <select id="selectOneLastData" resultType="java.util.Map">
         SELECT LAST(time), *
         FROM ${tableName}
         WHERE device_id = #{deviceId}
     </select>
 
     <!-- 根据标签获取最新数据 -->
-    <select id="getLastDataByTags" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO"
+    <select id="selectLastDataListByTags" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO"
             resultType="Map">
         SELECT LAST(*)
         FROM ${dataBaseName}.${stableName}
@@ -35,7 +49,7 @@
     </select>
 
     <!-- 获取历史数据 -->
-    <select id="getHistoryData" resultType="java.util.Map"
+    <select id="selectHistoryDataList" resultType="java.util.Map"
             parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
         SELECT ${fieldName} AS data, time
         FROM ${dataBaseName}.${tableName}
@@ -46,14 +60,14 @@
     </select>
 
     <!-- 获取实时数据 -->
-    <select id="getRealtimeData" resultType="java.util.Map"
+    <select id="selectRealtimeDataList" resultType="java.util.Map"
             parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
         SELECT ${fieldName}, time
         FROM ${dataBaseName}.${tableName}
     </select>
 
     <!-- 获取聚合数据 -->
-    <select id="getAggregateData" resultType="java.util.Map"
+    <select id="selectAggregateDataList" resultType="java.util.Map"
             parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
         SELECT ${aggregate}(${fieldName})
         FROM ${dataBaseName}.${tableName}
@@ -62,11 +76,11 @@
     </select>
 
     <!-- 获取历史数据条数 -->
-    <select id="getHistoryCount" resultType="java.lang.Long">
+    <select id="selectHistoryCount" resultType="java.lang.Long">
         SELECT COUNT(time)
         FROM ${dataBaseName}.${tableName}
         WHERE time BETWEEN #{startTime} AND #{endTime}
           AND ${fieldName} IS NOT NULL
     </select>
 
-</mapper>
+</mapper>

+ 0 - 21
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDataWriterMapper.xml

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper
-        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDataWriterMapper">
-
-    <!-- 插入数据 -->
-    <insert id="insertData">
-        INSERT INTO ${dataBaseName}.${tableName}
-        <foreach item="item" collection="columns" separator=","
-                 open="(" close=")">
-            ${item.fieldName}
-        </foreach>
-        VALUES
-        <foreach item="item" collection="columns" separator=","
-                 open="(" close=")">
-            #{item.fieldValue}
-        </foreach>
-    </insert>
-
-</mapper>

+ 0 - 12
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDatabaseMapper.xml

@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper
-        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDatabaseMapper">
-
-    <!-- 创建数据库 -->
-    <update id="createDatabase" parameterType="String">
-        CREATE DATABASE IF NOT EXISTS ${dataBaseName}
-    </update>
-
-</mapper>

+ 0 - 32
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineTableMapper.xml

@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper
-        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineTableMapper">
-
-    <!-- 创建子表 -->
-    <update id="createTable">
-        CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
-        USING ${dataBaseName}.${superTableName}
-        TAGS
-        <foreach item="item" collection="tags" separator=","
-                 open="(" close=")">
-            #{item.fieldValue}
-        </foreach>
-    </update>
-
-    <!-- 创建子表,带有 TAGS -->
-    <update id="createTableWithTags">
-        CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
-        USING ${dataBaseName}.${superTableName}
-        <foreach item="item" collection="tags" separator="," open="(" close=")">
-            #{item.fieldName}
-        </foreach>
-        TAGS
-        <foreach item="item" collection="tags" separator=","
-                 open="(" close=")">
-            #{item.fieldValue}
-        </foreach>
-    </update>
-
-</mapper>