Pārlūkot izejas kodu

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

安浩浩 9 mēneši atpakaļ
vecāks
revīzija
e3dcea9cb3
51 mainītis faili ar 1206 papildinājumiem un 1386 dzēšanām
  1. 0 18
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/BaseEntity.java
  2. 0 35
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/DeviceDataExportExcelDto.java
  3. 0 19
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/DeviceDataVo.java
  4. 0 65
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/Fields.java
  5. 0 31
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/FieldsVo.java
  6. 0 71
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/IotSequential.java
  7. 0 25
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/MessageCountVo.java
  8. 0 29
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/ProductSuperTableModel.java
  9. 0 30
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/SelectDto.java
  10. 0 31
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/SuperTableDto.java
  11. 0 26
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/TableDto.java
  12. 0 25
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/TagsSelectDao.java
  13. 0 73
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/Weather.java
  14. 51 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectDO.java
  15. 2 2
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java
  16. 0 27
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TableDO.java
  17. 0 44
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TableData.java
  18. 36 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TagsSelectDO.java
  19. 5 5
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdFieldDO.java
  20. 65 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java
  21. 25 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDataWriterMapper.java
  22. 23 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDatabaseMapper.java
  23. 0 129
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineMapper.java
  24. 85 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineQueryMapper.java
  25. 111 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineSuperTableMapper.java
  26. 41 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineTableMapper.java
  27. 13 14
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataServiceImpl.java
  28. 2 13
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotSuperTableService.java
  29. 122 75
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotSuperTableServiceImpl.java
  30. 0 142
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotTdEngineService.java
  31. 0 107
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotTdEngineServiceImpl.java
  32. 2 2
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageService.java
  33. 20 18
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java
  34. 19 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDataWriterService.java
  35. 21 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDataWriterServiceImpl.java
  36. 14 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDatabaseService.java
  37. 22 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDatabaseServiceImpl.java
  38. 28 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineQueryService.java
  39. 26 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineQueryServiceImpl.java
  40. 123 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineSuperTableService.java
  41. 90 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineSuperTableServiceImpl.java
  42. 21 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineTableService.java
  43. 23 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineTableServiceImpl.java
  44. 1 1
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thinkmodelfunction/IotThinkModelFunctionService.java
  45. 2 2
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thinkmodelfunction/IotThinkModelFunctionServiceImpl.java
  46. 22 0
      yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDataWriterMapper.xml
  47. 13 0
      yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDatabaseMapper.xml
  48. 0 327
      yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineMapper.xml
  49. 73 0
      yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineQueryMapper.xml
  50. 72 0
      yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineSuperTableMapper.xml
  51. 33 0
      yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineTableMapper.xml

+ 0 - 18
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/BaseEntity.java

@@ -1,18 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import lombok.Data;
-
-@Data
-public class BaseEntity {
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 数据库名称
-     */
-    private String dataBaseName;
-
-    /**
-     * 超级表名称
-     */
-    private String superTableName;
-}

+ 0 - 35
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/DeviceDataExportExcelDto.java

@@ -1,35 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import lombok.Data;
-
-/**
- * 设备数据导出 excel DTO
- */
-@Data
-public class DeviceDataExportExcelDto {
-
-    /**
-     * 设备标识
-     */
-    private String deviceKey;
-
-    /**
-     * 导出形式 1 单个参数导出 2 全部参数导出
-     */
-    private String exportType;
-
-    /**
-     * 导出开始时间
-     */
-    private String exportBeginTime;
-
-    /**
-     * 导出结束时间
-     */
-    private String exportEndTime;
-
-    /**
-     * 导出参数,空则导出全部
-     */
-    private String exportParameter;
-}

+ 0 - 19
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/DeviceDataVo.java

@@ -1,19 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import lombok.Data;
-
-/**
- * @ClassDescription: 查询可视化所需入参对象
- * @ClassName: SelectDto
- * @Author: andyz
- * @Date: 2022-07-29 14:12:26
- * @Version 1.0
- */
-@Data
-public class DeviceDataVo {
-
-
-    private String deviceId;
-
-    private Long lastTime;
-}

+ 0 - 65
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/Fields.java

@@ -1,65 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import lombok.Data;
-
-@Data
-public class Fields {
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 字段名称
-     */
-    private String fieldName;
-
-    /**
-     * 字段值
-     */
-    private Object fieldValue;
-
-    /**
-     * 字段数据类型
-     */
-//    private DataTypeEnum dataType;
-
-    /**
-     * 字段字节大小
-     */
-    private Integer size;
-
-    public Fields() {
-    }
-
-    public Fields(String fieldName, String dataType, Integer size) {
-//        this.fieldName = fieldName;
-//        //根据规则匹配字段数据类型
-//        switch (dataType.toLowerCase()) {
-//            case ("json"):
-//                this.dataType = DataTypeEnum.JSON;
-//                this.size = size;
-//                break;
-//            case ("string"):
-//                this.dataType = DataTypeEnum.NCHAR;
-//                this.size = size;
-//                break;
-//            case ("binary"):
-//                this.dataType = DataTypeEnum.BINARY;
-//                this.size = size;
-//                break;
-//            case ("int"):
-//                this.dataType = DataTypeEnum.INT;
-//                break;
-//            case ("bool"):
-//                this.dataType = DataTypeEnum.BOOL;
-//                break;
-//            case ("decimal"):
-//                this.dataType = DataTypeEnum.DOUBLE;
-//                break;
-//            case ("timestamp"):
-//                if ("eventTime".equals(fieldName)) {
-//                    this.fieldName = "eventTime";
-//                }
-//                this.dataType = DataTypeEnum.TIMESTAMP;
-//                break;
-//        }
-    }
-}

+ 0 - 31
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/FieldsVo.java

@@ -1,31 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import lombok.Builder;
-import lombok.Data;
-
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 字段信息 VO
- */
-@Data
-@Builder
-public class FieldsVo {
-
-    /**
-     * 字段名称
-     */
-    private String fieldName;
-
-    /**
-     * 字段数据类型
-     */
-    private String dataType;
-
-    /**
-     * 字段字节大小
-     */
-    private Integer size;
-}

+ 0 - 71
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/IotSequential.java

@@ -1,71 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-
-import java.sql.Timestamp;
-
-public class IotSequential extends BaseEntity {
-    private static final long serialVersionUID = 1L;
-
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS" , timezone = "GMT+8")
-    private Timestamp statetime;
-
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS" , timezone = "GMT+8")
-    private Timestamp endtime;
-
-    private String deviceid;
-
-    private String eventtime;
-
-    private String serviceid;
-
-    private String devices;
-
-    public String getDeviceid() {
-        return deviceid;
-    }
-
-    public void setDeviceid(String deviceid) {
-        this.deviceid = deviceid;
-    }
-
-    public String getEventtime() {
-        return eventtime;
-    }
-
-    public void setEventtime(String eventtime) {
-        this.eventtime = eventtime;
-    }
-
-    public String getServiceid() {
-        return serviceid;
-    }
-
-    public void setServiceid(String serviceid) {
-        this.serviceid = serviceid;
-    }
-
-    public String getDevices() {
-        return devices;
-    }
-
-    public void setDevices(String devices) {
-        this.devices = devices;
-    }
-
-    public Timestamp getStatetime() {
-        return statetime;
-    }
-
-    public void setStatetime(Timestamp statetime) {
-        this.statetime = statetime;
-    }
-
-    public Timestamp getEndtime() {
-        return endtime;
-    }
-
-    public void setEndtime(Timestamp endtime) {
-        this.endtime = endtime;
-    }
-}

+ 0 - 25
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/MessageCountVo.java

@@ -1,25 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * 统计的时间数据
- */
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class MessageCountVo {
-
-    /**
-     * 时间
-     */
-    private String time;
-
-    /**
-     * 数据值
-     */
-    private Object data;
-
-}

+ 0 - 29
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/ProductSuperTableModel.java

@@ -1,29 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import lombok.Data;
-
-import java.sql.Timestamp;
-import java.util.HashMap;
-import java.util.Optional;
-
-@Data
-public class ProductSuperTableModel {
-    private static final long serialVersionUID = 1L;
-
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+8")
-    private Timestamp ts;
-
-    private String superTableName;
-
-    /**
-     * columnsName,columnsProperty
-     */
-    private HashMap<Optional, Optional> columns;
-
-    /**
-     * tagsName,tagsProperty
-     */
-    private HashMap<Optional, Optional> tags;
-
-}

+ 0 - 30
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/SelectDto.java

@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import lombok.Data;
-
-import java.util.Set;
-
-@Data
-public class SelectDto {
-
-    //    @NotBlank(message = "invalid operation: dataBaseName can not be empty")
-    private String dataBaseName;
-
-//    @NotBlank(message = "invalid operation: tableName can not be empty")
-    private String tableName;
-
-    //    @NotBlank(message = "invalid operation: fieldName can not be empty")
-    private String fieldName;
-
-    //    @NotNull(message = "invalid operation: startTime can not be null")
-    private Long startTime;
-
-    //    @NotNull(message = "invalid operation: endTime can not be null")
-    private Long endTime;
-
-    private String type;
-
-    private Set<Integer> orgIds;
-
-    private String deviceId;
-}

+ 0 - 31
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/SuperTableDto.java

@@ -1,31 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import lombok.Data;
-
-import java.util.List;
-
-@Data
-public class SuperTableDto extends BaseEntity {
-
-    /**
-     * 超级表的表结构(业务相关)
-     * 第一个字段的数据类型必须为timestamp
-     * 字符相关数据类型必须指定大小
-     * 字段名称和字段数据类型不能为空
-     */
-//    @NotEmpty(message = "invalid operation: schemaFields can not be empty")
-    private List<Fields> schemaFields;
-
-    /**
-     * 超级表的标签字段,可以作为子表在超级表里的标识
-     * 字符相关数据类型必须指定大小
-     * 字段名称和字段数据类型不能为空
-     */
-//    @NotEmpty(message = "invalid operation: tagsFields can not be empty")
-    private List<Fields> tagsFields;
-
-    /**
-     * 字段信息对象,超级表添加列时使用该属性
-     */
-    private Fields fields;
-}

+ 0 - 26
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/TableDto.java

@@ -1,26 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import lombok.Data;
-
-import java.util.List;
-
-@Data
-public class TableDto extends BaseEntity {
-
-    /**
-     * 超级表普通列字段的值
-     * 值需要与创建超级表时普通列字段的数据类型对应上
-     */
-    private List<Fields> schemaFieldValues;
-
-    /**
-     * 超级表标签字段的值
-     * 值需要与创建超级表时标签字段的数据类型对应上
-     */
-    private List<Fields> tagsFieldValues;
-
-    /**
-     * 表名称
-     */
-    private String tableName;
-}

+ 0 - 25
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/TagsSelectDao.java

@@ -1,25 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import lombok.Data;
-
-
-@Data
-public class TagsSelectDao {
-
-    //    @NotBlank(message = "invalid operation: dataBaseName can not be empty")
-    private String dataBaseName;
-
-    //    @NotBlank(message = "invalid operation: stableName can not be empty")
-    private String stableName;
-
-    //    @NotBlank(message = "invalid operation: tagsName can not be empty")
-    private String tagsName;
-
-    //    @NotNull(message = "invalid operation: startTime can not be null")
-    private Long startTime;
-
-    //    @NotNull(message = "invalid operation: endTime can not be null")
-    private Long endTime;
-
-
-}

+ 0 - 73
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/Weather.java

@@ -1,73 +0,0 @@
-package cn.iocoder.yudao.module.iot.domain;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-
-import java.sql.Timestamp;
-
-public class Weather {
-
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS" , timezone = "GMT+8")
-    private Timestamp ts;
-    private Float temperature;
-    private Float humidity;
-    private String location;
-    private String note;
-    private int groupId;
-
-    public Weather() {
-    }
-
-    public Weather(Timestamp ts, float temperature, float humidity) {
-        this.ts = ts;
-        this.temperature = temperature;
-        this.humidity = humidity;
-    }
-
-    public Timestamp getTs() {
-        return ts;
-    }
-
-    public void setTs(Timestamp ts) {
-        this.ts = ts;
-    }
-
-    public Float getTemperature() {
-        return temperature;
-    }
-
-    public void setTemperature(Float temperature) {
-        this.temperature = temperature;
-    }
-
-    public Float getHumidity() {
-        return humidity;
-    }
-
-    public void setHumidity(Float humidity) {
-        this.humidity = humidity;
-    }
-
-    public String getLocation() {
-        return location;
-    }
-
-    public void setLocation(String location) {
-        this.location = location;
-    }
-
-    public int getGroupId() {
-        return groupId;
-    }
-
-    public void setGroupId(int groupId) {
-        this.groupId = groupId;
-    }
-
-    public String getNote() {
-        return note;
-    }
-
-    public void setNote(String note) {
-        this.note = note;
-    }
-}

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

@@ -0,0 +1,51 @@
+package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
+
+import lombok.Data;
+
+import java.util.Set;
+/**
+ * 查询DO
+ */
+@Data
+public class SelectDO {
+
+    /**
+     * 数据库名称
+     */
+    private String dataBaseName;
+
+    /**
+     * 超级表名称
+     */
+    private String tableName;
+
+    /**
+     * 查询字段
+     */
+    private String fieldName;
+
+    /**
+     * 开始时间
+     */
+    private Long startTime;
+
+    /**
+     * 结束时间
+     */
+    private Long endTime;
+
+    /**
+     * 查询类型
+     */
+    private String type;
+
+    /**
+     * 查询条件
+     */
+    private Set<Integer> orgIds;
+
+    /**
+     * 设备ID
+     */
+    private String deviceId;
+}

+ 2 - 2
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/visual/SelectVisualDto.java → yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java

@@ -1,11 +1,11 @@
-package cn.iocoder.yudao.module.iot.domain.visual;
+package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
 
 import lombok.Data;
 
 import java.util.Map;
 
 @Data
-public class SelectVisualDto {
+public class SelectVisualDO {
 
     /**
      * 数据库名称

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

@@ -1,27 +0,0 @@
-package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
-
-import cn.iocoder.yudao.module.iot.domain.BaseEntity;
-import lombok.Data;
-
-import java.util.List;
-
-@Data
-public class TableDO extends BaseEntity {
-
-    /**
-     * 超级表普通列字段的值
-     * 值需要与创建超级表时普通列字段的数据类型对应上
-     */
-    private List<TdFieldDO> schemaFieldValues;
-
-    /**
-     * 超级表标签字段的值
-     * 值需要与创建超级表时标签字段的数据类型对应上
-     */
-    private List<TdFieldDO> tagsFieldValues;
-
-    /**
-     * 表名称
-     */
-    private String tableName;
-}

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

@@ -1,44 +0,0 @@
-package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
-
-import lombok.Data;
-
-import java.util.List;
-
-/**
- * TableData 类用于存储和操作 TDengine 表数据
- */
-@Data
-public class TableData {
-
-    /**
-     * 超级表普通列字段的名称
-     */
-    private List<String> schemaFieldList;
-
-    /**
-     * 超级表普通列字段的值
-     * 值需要与创建超级表时普通列字段的数据类型对应上
-     */
-    private List<Object> schemaValueList;
-
-    /**
-     * 超级表标签字段的名称
-     */
-    private List<String> tagsFieldList;
-
-    /**
-     * 超级表标签字段的值
-     * 值需要与创建超级表时标签字段的数据类型对应上
-     */
-    private List<Object> tagsValueList;
-
-    /**
-     * 表名称
-     */
-    private String tableName;
-
-    /**
-     * 超级表名称
-     */
-    private String superTableName;
-}

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

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
+
+import lombok.Data;
+
+/**
+ * tags查询DO
+ */
+@Data
+public class TagsSelectDO {
+
+    /**
+     * 数据库名称
+     */
+    private String dataBaseName;
+
+    /**
+     * 超级表名称
+     */
+    private String stableName;
+
+    /**
+     * tags名称
+     */
+    private String tagsName;
+
+    /**
+     * tags值
+     */
+    private Long startTime;
+
+    /**
+     * tags值
+     */
+    private Long endTime;
+
+}

+ 5 - 5
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdFieldDO.java

@@ -19,11 +19,6 @@ public class TdFieldDO {
      */
     private String fieldName;
 
-    /**
-     * 字段值
-     */
-    private Object fieldValue;
-
     /**
      * 字段类型
      */
@@ -34,6 +29,11 @@ public class TdFieldDO {
      */
     private Integer dataLength = 0;
 
+    /**
+     * 字段值
+     */
+    private Object fieldValue;
+
     public TdFieldDO(String fieldName, String dataType, Integer dataLength) {
         this.fieldName = fieldName;
         this.dataType = dataType;

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

@@ -0,0 +1,65 @@
+package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * TD 引擎的数据库
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class TdTableDO {
+
+    /**
+     * 数据库名称
+     */
+    private String dataBaseName;
+
+    /**
+     * 超级表名称
+     */
+    private String superTableName;
+
+    /**
+     * 表名称
+     */
+    private String tableName;
+
+    /**
+     * COLUMN 字段
+     */
+    private TdFieldDO column;
+
+    /**
+     * TAG 字段
+     */
+    private TdFieldDO tag;
+
+    /**
+     * COLUMN 字段 - 列表
+     */
+    private List<TdFieldDO> columns;
+
+    /**
+     * TAG 字段 - 列表
+     */
+    private List<TdFieldDO> tags;
+
+    public TdTableDO(String dataBaseName, String superTableName, List<TdFieldDO> columns, List<TdFieldDO> tags) {
+        this.dataBaseName = dataBaseName;
+        this.superTableName = superTableName;
+        this.columns = columns;
+        this.tags = tags;
+    }
+
+    public TdTableDO(String dataBaseName, String superTableName) {
+        this.dataBaseName = dataBaseName;
+        this.superTableName = superTableName;
+    }
+}

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

@@ -0,0 +1,25 @@
+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);
+}

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

@@ -0,0 +1,23 @@
+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;
+
+/**
+ * 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 - 129
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineMapper.java

@@ -1,129 +0,0 @@
-package cn.iocoder.yudao.module.iot.dal.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
-import cn.iocoder.yudao.module.iot.domain.FieldsVo;
-import cn.iocoder.yudao.module.iot.domain.SelectDto;
-import cn.iocoder.yudao.module.iot.domain.TagsSelectDao;
-import cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto;
-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;
-
-@Mapper
-@DS("tdengine")
-public interface TdEngineMapper {
-
-    /**
-     * 创建数据库
-     *
-     * @param dataBaseName 数据库名称
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    void createDatabase(@Param("dataBaseName") String dataBaseName);
-
-    /**
-     * 创建超级表
-     *
-     * @param schemaFields   schema字段
-     * @param tagsFields     tags字段
-     * @param dataBaseName   数据库名称
-     * @param superTableName 超级表名称
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    void createSuperTable(@Param("schemaFields") List<TdFieldDO> schemaFields,
-                          @Param("tagsFields") List<TdFieldDO> tagsFields,
-                          @Param("dataBaseName") String dataBaseName,
-                          @Param("superTableName") String superTableName);
-
-    /**
-     * 查看超级表 - 显示当前数据库下的所有超级表信息
-     * SQL:SHOW STABLES [LIKE tb_name_wildcard];
-     *
-     * @param dataBaseName   数据库名称
-     * @param superTableName 超级表名称
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    List<Map<String, Object>> showSuperTables(@Param("dataBaseName") String dataBaseName,
-                                              @Param("superTableName") String superTableName);
-
-    /**
-     * 查看超级表 - 获取超级表的结构信息
-     * SQL:DESCRIBE [db_name.]stb_name;
-     * <p>
-     * * @param dataBaseName 数据库名称
-     * * @param superTableName 超级表名称
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    List<Map<String, Object>> describeSuperTable(@Param("dataBaseName") String dataBaseName,
-                                                 @Param("superTableName") String superTableName);
-
-    /**
-     * 为超级表添加列
-     *
-     * @param dataBaseName   数据库名称
-     * @param superTableName 超级表名称
-     * @param field          字段信息
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    void addColumnForSuperTable(@Param("dataBaseName") String dataBaseName,
-                                @Param("superTableName") String superTableName,
-                                @Param("field") TdFieldDO field);
-
-    /**
-     * 为超级表删除列
-     *
-     * @param dataBaseName   数据库名称
-     * @param superTableName 超级表名称
-     * @param field          字段信息
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    void dropColumnForSuperTable(@Param("dataBaseName") String dataBaseName,
-                                 @Param("superTableName") String superTableName,
-                                 @Param("field") TdFieldDO field);
-
-    /**
-     * 创建表 - 创建超级表的子表
-     *
-     * @param tableDO 表信息
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    void createTable(TableDO tableDO);
-
-    /**
-     * 插入数据 - 指定列插入数据
-     *
-     * @param tableDto 数据
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    void insertData(TableDO tableDto);
-
-    List<Map<String, Object>> selectByTimestamp(SelectDto selectDto);
-
-
-    void addTagForSuperTable(@Param("superTableName") String superTableName,
-                             @Param("fieldsVo") FieldsVo fieldsVo);
-
-    void dropTagForSuperTable(@Param("superTableName") String superTableName,
-                              @Param("fieldsVo") FieldsVo fieldsVo);
-
-    Map<String, Long> getCountByTimestamp(SelectDto selectDto);
-
-    Map<String, Object> getLastData(SelectDto selectDto);
-
-    @InterceptorIgnore(tenantLine = "true")
-    List<Map<String, Object>> getHistoryData(SelectVisualDto selectVisualDto);
-
-    List<Map<String, Object>> getRealtimeData(SelectVisualDto selectVisualDto);
-
-    List<Map<String, Object>> getAggregateData(SelectVisualDto selectVisualDto);
-
-    List<Map<String, Object>> getLastDataByTags(TagsSelectDao tagsSelectDao);
-
-    @InterceptorIgnore(tenantLine = "true")
-    Long getHistoryCount(SelectVisualDto selectVisualDto);
-}

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

@@ -0,0 +1,85 @@
+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);
+
+    /**
+     * 根据时间戳获取数据条数
+     *
+     * @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);
+}

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

@@ -0,0 +1,111 @@
+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;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * TD 引擎的超级表 Mapper
+ */
+@Mapper
+@DS("tdengine")
+public interface TdEngineSuperTableMapper {
+
+    /**
+     * 创建超级表
+     * SQL:CREATE STABLE [IF NOT EXISTS] stb_name (create_definition [, create_definition] ...) TAGS (create_definition [, create_definition] ...) [table_options];
+     *
+     * @param superTable 超级表信息
+     *                   dataBaseName   数据库名称
+     *                   superTableName 超级表名称
+     *                   columns        列信息
+     *                   tags           标签信息
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    void createSuperTable(TdTableDO superTable);
+
+    /**
+     * 查看超级表 - 显示当前数据库下的所有超级表信息
+     * SQL:SHOW STABLES [LIKE tb_name_wildcard];
+     *
+     * @param superTable 超级表信息
+     *                   dataBaseName 数据库名称
+     *                   superTableName 超级表名称
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    List<Map<String, Object>> showSuperTables(TdTableDO superTable);
+
+    /**
+     * 查看超级表 - 获取超级表的结构信息
+     * SQL:DESCRIBE [db_name.]stb_name;
+     *
+     * @param superTable 超级表信息
+     *                   dataBaseName   数据库名称
+     *                   superTableName 超级表名称
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    List<Map<String, Object>> describeSuperTable(TdTableDO superTable);
+
+    /**
+     * 修改超级表 - 增加列
+     * SQL:ALTER STABLE stb_name ADD COLUMN col_name column_type;
+     *
+     * @param superTable 超级表信息
+     *                   dataBaseName   数据库名称
+     *                   superTableName 超级表名称
+     *                   column         列信息
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    void addColumnForSuperTable(TdTableDO superTable);
+
+    /**
+     * 修改超级表 - 删除列
+     * SQL:ALTER STABLE stb_name DROP COLUMN col_name;
+     *
+     * @param superTable 超级表信息
+     *                   dataBaseName   数据库名称
+     *                   superTableName 超级表名称
+     *                   column         列信息
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    void dropColumnForSuperTable(TdTableDO superTable);
+
+    /**
+     * 修改超级表 - 修改列宽
+     * SQL:ALTER STABLE stb_name MODIFY COLUMN col_name data_type(length);
+     *
+     * @param superTable 超级表信息
+     *                   dataBaseName   数据库名称
+     *                   superTableName 超级表名称
+     *                   column         列信息
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    void modifyColumnWidthForSuperTable(TdTableDO superTable);
+
+
+    /**
+     * 修改超级表 - 为超级表添加标签
+     *
+     * @param superTable 超级表信息
+     *                   dataBaseName   数据库名称
+     *                   superTableName 超级表名称
+     *                   tag            标签信息
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    void addTagForSuperTable(TdTableDO superTable);
+
+    /**
+     * 修改超级表 - 为超级表删除标签
+     *
+     * @param superTable 超级表信息
+     *                   dataBaseName   数据库名称
+     *                   superTableName 超级表名称
+     *                   tag            标签信息
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    void dropTagForSuperTable(TdTableDO superTable);
+}

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

@@ -0,0 +1,41 @@
+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);
+
+}

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

@@ -6,13 +6,13 @@ 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.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.TdEngineMapper;
-import cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto;
 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;
@@ -39,12 +39,11 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
     private IotThingModelMessageService thingModelMessageService;
     @Resource
     private IotThinkModelFunctionService thinkModelFunctionService;
-
     @Resource
-    private DeviceDataRedisDAO deviceDataRedisDAO;
+    private TdEngineQueryService tdEngineQueryService;
 
     @Resource
-    private TdEngineMapper tdEngineMapper;
+    private DeviceDataRedisDAO deviceDataRedisDAO;
 
     @Override
     public void saveDeviceData(String productKey, String deviceName, String message) {
@@ -112,18 +111,18 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
         // 1. 获取设备信息
         IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
         // 2. 获取设备属性历史数据
-        SelectVisualDto selectVisualDto = new SelectVisualDto();
-        selectVisualDto.setDataBaseName(getDatabaseName());
-        selectVisualDto.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()));
-        selectVisualDto.setFieldName(deviceDataReqVO.getIdentifier());
-        selectVisualDto.setStartTime(DateUtil.date(deviceDataReqVO.getTimes()[0].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime());
-        selectVisualDto.setEndTime(DateUtil.date(deviceDataReqVO.getTimes()[1].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime());
+        SelectVisualDO selectVisualDO = new SelectVisualDO();
+        selectVisualDO.setDataBaseName(getDatabaseName());
+        selectVisualDO.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()));
+        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());
         Map<String, Object> params = new HashMap<>();
         params.put("rows", deviceDataReqVO.getPageSize());
         params.put("page", (deviceDataReqVO.getPageNo() - 1) * deviceDataReqVO.getPageSize());
-        selectVisualDto.setParams(params);
-        pageResult.setList(tdEngineMapper.getHistoryData(selectVisualDto));
-        pageResult.setTotal(tdEngineMapper.getHistoryCount(selectVisualDto));
+        selectVisualDO.setParams(params);
+        pageResult.setList(tdEngineQueryService.getHistoryData(selectVisualDO));
+        pageResult.setTotal(tdEngineQueryService.getHistoryCount(selectVisualDO));
         return pageResult;
     }
 

+ 2 - 13
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotDbStructureDataService.java → yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotSuperTableService.java

@@ -1,26 +1,15 @@
 package cn.iocoder.yudao.module.iot.service.tdengine;
 
 
-import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelRespVO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
 
 import java.util.List;
 
 /**
- * 数据结构接口
+ * IoT 超级表服务,负责根据物模型创建和更新超级表,以及创建超级表的子表等操作。
  */
-public interface IotDbStructureDataService {
-
-    /**
-     * 创建物模型定义
-     */
-    void createSuperTable(ThingModelRespVO thingModel, Integer deviceType);
-
-    /**
-     * 更新物模型定义
-     */
-    void updateSuperTable(ThingModelRespVO thingModel, Integer deviceType);
+public interface IotSuperTableService {
 
     /**
      * 创建超级表数据模型

+ 122 - 75
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotDbStructureDataServiceImpl.java → yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotSuperTableServiceImpl.java

@@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingMode
 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
 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.enums.product.IotProductFunctionTypeEnum;
 import jakarta.annotation.Resource;
@@ -17,19 +18,44 @@ import org.springframework.stereotype.Service;
 import java.util.*;
 import java.util.stream.Collectors;
 
+/**
+ * IoT 超级表服务实现类,负责根据物模型创建和更新超级表,以及创建超级表的子表等操作。
+ */
 @Service
 @Slf4j
-public class IotDbStructureDataServiceImpl implements IotDbStructureDataService {
+public class IotSuperTableServiceImpl implements IotSuperTableService {
 
     @Resource
-    private IotTdEngineService iotTdEngineService;
+    private TdEngineSuperTableService tdEngineSuperTableService;
 
     @Value("${spring.datasource.dynamic.datasource.tdengine.url}")
     private String url;
 
     @Override
-    public void createSuperTable(ThingModelRespVO thingModel, Integer deviceType) {
-        // 1. 解析物模型,获得字段列表
+    public void createSuperTableDataModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList) {
+        ThingModelRespVO thingModel = buildThingModel(product, functionList);
+
+        if (thingModel.getModel() == null || CollUtil.isEmpty(thingModel.getModel().getProperties())) {
+            log.warn("物模型属性列表为空,不创建超级表");
+            return;
+        }
+
+        String superTableName = getSuperTableName(product.getDeviceType(), product.getProductKey());
+        String databaseName = getDatabaseName();
+        Integer tableExists = tdEngineSuperTableService.checkSuperTableExists(new TdTableDO(databaseName, superTableName));
+
+        if (tableExists != null && tableExists > 0) {
+            updateSuperTable(thingModel, product.getDeviceType());
+        } else {
+            createSuperTable(thingModel, product.getDeviceType());
+        }
+    }
+
+    /**
+     * 创建超级表
+     */
+    private void createSuperTable(ThingModelRespVO thingModel, Integer deviceType) {
+        // 解析物模型,获取字段列表
         List<TdFieldDO> schemaFields = new ArrayList<>();
         schemaFields.add(TdFieldDO.builder()
                 .fieldName("time")
@@ -37,80 +63,102 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
                 .build());
         schemaFields.addAll(FieldParser.parse(thingModel));
 
-        // 3. 设置超级表的标签
-        List<TdFieldDO> tagsFields = Arrays.asList(
+        // 设置超级表的标签
+        List<TdFieldDO> tagsFields = List.of(
                 TdFieldDO.builder().fieldName("product_key").dataType("NCHAR").dataLength(64).build(),
                 TdFieldDO.builder().fieldName("device_key").dataType("NCHAR").dataLength(64).build(),
                 TdFieldDO.builder().fieldName("device_name").dataType("NCHAR").dataLength(64).build(),
                 TdFieldDO.builder().fieldName("device_type").dataType("INT").build()
         );
 
-        // 4. 获取超级表的名称
-        String superTableName = getProductPropertySTableName(deviceType, thingModel.getProductKey());
+        // 获取超级表的名称和数据库名称
+        String superTableName = getSuperTableName(deviceType, thingModel.getProductKey());
+        String databaseName = getDatabaseName();
 
-        // 5. 创建超级表
-        String dataBaseName = getDatabaseName();
-        iotTdEngineService.createSuperTable(schemaFields, tagsFields, dataBaseName, superTableName);
+        // 创建超级表
+        tdEngineSuperTableService.createSuperTable(new TdTableDO(databaseName, superTableName, schemaFields, tagsFields));
     }
 
-    @Override
-    public void updateSuperTable(ThingModelRespVO thingModel, Integer deviceType) {
+    /**
+     * 更新超级表
+     */
+    private void updateSuperTable(ThingModelRespVO thingModel, Integer deviceType) {
+        String superTableName = getSuperTableName(deviceType, thingModel.getProductKey());
         try {
-            String tbName = getProductPropertySTableName(deviceType, thingModel.getProductKey());
-            List<TdFieldDO> oldFields = getTableFields(tbName);
+            List<TdFieldDO> oldFields = getTableFields(superTableName);
             List<TdFieldDO> newFields = FieldParser.parse(thingModel);
 
-            updateTableFields(tbName, oldFields, newFields);
+            updateTableFields(superTableName, oldFields, newFields);
         } catch (Exception e) {
-            log.error("更新物模型超级表失败", e);
+            log.error("更新物模型超级表失败: {}", e.getMessage(), e);
         }
     }
 
-    // 获取表字段
+    /**
+     * 获取表的字段信息
+     */
     private List<TdFieldDO> getTableFields(String tableName) {
-        List<TdFieldDO> fields = new ArrayList<>();
-        // 获取超级表的描述信息
-        List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(getDatabaseName(), tableName);
-        if (maps != null) {
-            // 过滤掉 note 字段为 TAG 的记录和 time 字段
-            List<Map<String, Object>> filteredMaps = maps.stream()
-                    .filter(map -> !"TAG".equals(map.get("note")))
-                    .filter(map -> !"time".equals(map.get("field")))
-                    .toList();
-            // 解析字段信息
-            fields = FieldParser.parse(filteredMaps.stream()
-                    .map(map -> List.of(map.get("field"), map.get("type"), map.get("length")))
-                    .collect(Collectors.toList()));
+        List<Map<String, Object>> tableDescription = tdEngineSuperTableService.describeSuperTable(new TdTableDO(getDatabaseName(), tableName));
+        if (CollUtil.isEmpty(tableDescription)) {
+            return Collections.emptyList();
         }
-        return fields;
+
+        return tableDescription.stream()
+                .filter(map -> !"TAG".equals(map.get("note")))
+                .filter(map -> !"time".equals(map.get("field")))
+                .map(map -> TdFieldDO.builder()
+                        .fieldName((String) map.get("field"))
+                        .dataType((String) map.get("type"))
+                        .dataLength((Integer) map.get("length"))
+                        .build())
+                .collect(Collectors.toList());
     }
 
-    // 更新表字段
+    /**
+     * 更新表的字段,包括新增、修改和删除字段
+     */
     private void updateTableFields(String tableName, List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
-        // 获取新增字段
+        String databaseName = getDatabaseName();
+
+        // 获取新增、修改、删除的字段
         List<TdFieldDO> addFields = getAddFields(oldFields, newFields);
-        // 获取修改字段
         List<TdFieldDO> modifyFields = getModifyFields(oldFields, newFields);
-        // 获取删除字段
         List<TdFieldDO> dropFields = getDropFields(oldFields, newFields);
 
-        String dataBaseName = getDatabaseName();
         // 添加新增字段
         if (CollUtil.isNotEmpty(addFields)) {
-            iotTdEngineService.addColumnForSuperTable(dataBaseName, tableName, addFields);
+            tdEngineSuperTableService.addColumnsForSuperTable(TdTableDO.builder()
+                    .dataBaseName(databaseName)
+                    .superTableName(tableName)
+                    .columns(addFields)
+                    .build());
         }
         // 删除旧字段
         if (CollUtil.isNotEmpty(dropFields)) {
-            iotTdEngineService.dropColumnForSuperTable(dataBaseName, tableName, dropFields);
+            tdEngineSuperTableService.dropColumnsForSuperTable(TdTableDO.builder()
+                    .dataBaseName(databaseName)
+                    .superTableName(tableName)
+                    .columns(dropFields)
+                    .build());
         }
         // 修改字段(先删除再添加)
         if (CollUtil.isNotEmpty(modifyFields)) {
-            iotTdEngineService.dropColumnForSuperTable(dataBaseName, tableName, modifyFields);
-            iotTdEngineService.addColumnForSuperTable(dataBaseName, tableName, modifyFields);
+            tdEngineSuperTableService.dropColumnsForSuperTable(TdTableDO.builder()
+                    .dataBaseName(databaseName)
+                    .superTableName(tableName)
+                    .columns(modifyFields)
+                    .build());
+            tdEngineSuperTableService.addColumnsForSuperTable(TdTableDO.builder()
+                    .dataBaseName(databaseName)
+                    .superTableName(tableName)
+                    .columns(addFields)
+                    .build());
         }
     }
 
-    // 获取新增字段
+    /**
+     * 获取需要新增的字段
+     */
     private List<TdFieldDO> getAddFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
         Set<String> oldFieldNames = oldFields.stream()
                 .map(TdFieldDO::getFieldName)
@@ -120,7 +168,9 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
                 .collect(Collectors.toList());
     }
 
-    // 获取修改字段
+    /**
+     * 获取需要修改的字段
+     */
     private List<TdFieldDO> getModifyFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
         Map<String, TdFieldDO> oldFieldMap = oldFields.stream()
                 .collect(Collectors.toMap(TdFieldDO::getFieldName, f -> f));
@@ -128,78 +178,75 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService
         return newFields.stream()
                 .filter(f -> {
                     TdFieldDO oldField = oldFieldMap.get(f.getFieldName());
-                    return oldField != null &&
-                            (!oldField.getDataType().equals(f.getDataType()) ||
-                                    !Objects.equals(oldField.getDataLength(), f.getDataLength()));
+                    return oldField != null && (
+                            !oldField.getDataType().equals(f.getDataType()) ||
+                                    !Objects.equals(oldField.getDataLength(), f.getDataLength())
+                    );
                 })
                 .collect(Collectors.toList());
     }
 
-    // 获取删除字段
+    /**
+     * 获取需要删除的字段
+     */
     private List<TdFieldDO> getDropFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
         Set<String> newFieldNames = newFields.stream()
                 .map(TdFieldDO::getFieldName)
                 .collect(Collectors.toSet());
         return oldFields.stream()
-                .filter(f -> !"time".equals(f.getFieldName()) && !"device_id".equals(f.getFieldName()))
+                .filter(f -> !"time".equals(f.getFieldName()))
                 .filter(f -> !newFieldNames.contains(f.getFieldName()))
                 .collect(Collectors.toList());
     }
 
-    @Override
-    public void createSuperTableDataModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList) {
-        ThingModelRespVO thingModel = buildThingModel(product, functionList);
-
-        if (thingModel.getModel() == null || CollUtil.isEmpty(thingModel.getModel().getProperties())) {
-            log.warn("物模型属性列表为空,不创建超级表");
-            return;
-        }
-
-        String superTableName = getProductPropertySTableName(product.getDeviceType(), product.getProductKey());
-        String dataBaseName = getDatabaseName();
-        Integer tableExists = iotTdEngineService.checkSuperTableExists(dataBaseName, superTableName);
-
-        if (tableExists != null && tableExists > 0) {
-            updateSuperTable(thingModel, product.getDeviceType());
-        } else {
-            createSuperTable(thingModel, product.getDeviceType());
-        }
-    }
-
+    /**
+     * 构建物模型
+     */
     private ThingModelRespVO buildThingModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList) {
         ThingModelRespVO thingModel = new ThingModelRespVO();
         thingModel.setId(product.getId());
         thingModel.setProductKey(product.getProductKey());
 
-        ThingModelRespVO.Model model = new ThingModelRespVO.Model();
         List<ThingModelProperty> properties = functionList.stream()
                 .filter(function -> IotProductFunctionTypeEnum.PROPERTY.equals(
                         IotProductFunctionTypeEnum.valueOfType(function.getType())))
                 .map(this::buildThingModelProperty)
                 .collect(Collectors.toList());
 
+        ThingModelRespVO.Model model = new ThingModelRespVO.Model();
         model.setProperties(properties);
         thingModel.setModel(model);
 
         return thingModel;
     }
 
+    /**
+     * 构建物模型属性
+     */
     private ThingModelProperty buildThingModelProperty(IotThinkModelFunctionDO function) {
         ThingModelProperty property = BeanUtil.copyProperties(function, ThingModelProperty.class);
         property.setDataType(function.getProperty().getDataType());
         return property;
     }
 
+    /**
+     * 获取数据库名称
+     */
     private String getDatabaseName() {
-        return url.substring(url.lastIndexOf("/") + 1);
+        int index = url.lastIndexOf("/");
+        return index != -1 ? url.substring(index + 1) : url;
     }
 
-    static String getProductPropertySTableName(Integer deviceType, String productKey) {
-        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();
+    /**
+     * 获取超级表名称
+     */
+    private String getSuperTableName(Integer deviceType, String productKey) {
+        String prefix = switch (deviceType) {
+            case 1 -> "gateway_sub_";
+            case 2 -> "gateway_";
+            default -> "device_";
         };
+        return (prefix + productKey).toLowerCase();
     }
 
 }

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

@@ -1,142 +0,0 @@
-package cn.iocoder.yudao.module.iot.service.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
-import cn.iocoder.yudao.module.iot.domain.SelectDto;
-import cn.iocoder.yudao.module.iot.domain.TagsSelectDao;
-import cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * TdEngineService
- */
-public interface IotTdEngineService {
-
-    /**
-     * 创建数据库
-     *
-     * @param dataBaseName 数据库名称
-     * @throws Exception 异常
-     */
-    void createDateBase(String dataBaseName) throws Exception;
-
-    /**
-     * 创建超级表
-     *
-     * @param schemaFields   schema字段
-     * @param tagsFields     tags字段
-     * @param superTableName 超级表名称
-     */
-    void createSuperTable(List<TdFieldDO> schemaFields, List<TdFieldDO> tagsFields, String dataBaseName, String superTableName);
-
-    /**
-     * 检查超级表是否存在
-     */
-    Integer checkSuperTableExists(String dataBaseName, String superTableName);
-
-
-    /**
-     * 获取超级表的结构信息
-     */
-    List<Map<String, Object>> describeSuperTable(String dataBaseName, String superTableName);
-
-    /**
-     * 为超级表添加列
-     *
-     * @param dataBaseName   数据库名称
-     * @param superTableName 超级表名称
-     * @param fieldsVo       字段信息
-     */
-    void addColumnForSuperTable(String dataBaseName, String superTableName, List<TdFieldDO> fieldsVo);
-
-    /**
-     * 为超级表删除列
-     *
-     * @param dataBaseName   数据库名称
-     * @param superTableName 超级表名称
-     * @param fieldsVo       字段信息
-     */
-    void dropColumnForSuperTable(String dataBaseName, String superTableName, List<TdFieldDO> fieldsVo);
-
-    /**
-     * 为超级表添加tag
-     */
-    Long getCountByTimesTamp(SelectDto selectDto) throws Exception;
-
-
-    /**
-     * 创建表
-     *
-     * @param tableDto 表信息
-     */
-    void createTable(TableDO tableDto);
-
-    /**
-     * 插入数据
-     *
-     * @param tableDto 表信息
-     */
-    void insertData(TableDO tableDto);
-
-    /**
-     * 根据时间戳查询数据
-     *
-     * @param selectDto 查询条件
-     * @return 数据
-     * @throws Exception 异常
-     */
-    List<Map<String, Object>> selectByTimesTamp(SelectDto selectDto) throws Exception;
-
-    /**
-     * 初始化超级表
-     *
-     * @param msg 消息
-     * @throws Exception 异常
-     */
-    void initSTableFrame(String msg) throws Exception;
-
-    /**
-     * 获取最新数据
-     *
-     * @param selectDto 查询条件
-     * @return 数据
-     * @throws Exception 异常
-     */
-    Map<String, Object> getLastData(SelectDto selectDto) throws Exception;
-
-    /**
-     * 根据tag查询最新数据
-     *
-     * @param tagsSelectDao 查询条件
-     * @return 数据
-     */
-    Map<String, Map<String, Object>> getLastDataByTags(TagsSelectDao tagsSelectDao);
-
-    /**
-     * 获取历史数据
-     *
-     * @param selectVisualDto 查询条件
-     * @return 数据
-     */
-    List<Map<String, Object>> getHistoryData(SelectVisualDto selectVisualDto);
-
-    /**
-     * 获取实时数据
-     *
-     * @param selectVisualDto 查询条件
-     * @return 数据
-     */
-    List<Map<String, Object>> getRealtimeData(SelectVisualDto selectVisualDto);
-
-    /**
-     * 获取聚合数据
-     *
-     * @param selectVisualDto 查询条件
-     * @return 数据
-     */
-    List<Map<String, Object>> getAggregateData(SelectVisualDto selectVisualDto);
-
-
-}

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

@@ -1,107 +0,0 @@
-package cn.iocoder.yudao.module.iot.service.tdengine;
-
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
-import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineMapper;
-import cn.iocoder.yudao.module.iot.domain.SelectDto;
-import cn.iocoder.yudao.module.iot.domain.TagsSelectDao;
-import cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.Map;
-
-@Service
-@Slf4j
-public class IotTdEngineServiceImpl implements IotTdEngineService {
-
-    @Resource
-    private TdEngineMapper tdEngineMapper;
-
-    @Override
-    public void createDateBase(String dataBaseName) {
-        tdEngineMapper.createDatabase(dataBaseName);
-    }
-
-    @Override
-    public void createSuperTable(List<TdFieldDO> schemaFields, List<TdFieldDO> tagsFields, String dataBaseName, String superTableName) {
-        tdEngineMapper.createSuperTable(schemaFields, tagsFields, dataBaseName, superTableName);
-    }
-
-    @Override
-    public void createTable(TableDO tableDto) {
-        tdEngineMapper.createTable(tableDto);
-    }
-
-    @Override
-    public void insertData(TableDO tableDto) {
-        tdEngineMapper.insertData(tableDto);
-    }
-
-    @Override
-    public List<Map<String, Object>> selectByTimesTamp(SelectDto selectDto) {
-        return List.of();
-    }
-
-    @Override
-    public void addColumnForSuperTable(String dataBaseName,String superTableName, List<TdFieldDO> fields) {
-        for (TdFieldDO field : fields) {
-            tdEngineMapper.addColumnForSuperTable(dataBaseName,superTableName, field);
-        }
-    }
-
-    @Override
-    public void dropColumnForSuperTable(String dataBaseName,String superTableName, List<TdFieldDO> fields) {
-        for (TdFieldDO field : fields) {
-            tdEngineMapper.dropColumnForSuperTable(dataBaseName,superTableName, field);
-        }
-    }
-
-    @Override
-    public Long getCountByTimesTamp(SelectDto selectDto) {
-        return 0L;
-    }
-
-    @Override
-    public void initSTableFrame(String msg) {
-
-    }
-
-    @Override
-    public Map<String, Object> getLastData(SelectDto selectDto) {
-        return Map.of();
-    }
-
-    @Override
-    public Map<String, Map<String, Object>> getLastDataByTags(TagsSelectDao tagsSelectDao) {
-        return Map.of();
-    }
-
-    @Override
-    public List<Map<String, Object>> getHistoryData(SelectVisualDto selectVisualDto) {
-        return List.of();
-    }
-
-    @Override
-    public List<Map<String, Object>> getRealtimeData(SelectVisualDto selectVisualDto) {
-        return List.of();
-    }
-
-    @Override
-    public List<Map<String, Object>> getAggregateData(SelectVisualDto selectVisualDto) {
-        return List.of();
-    }
-
-    @Override
-    public Integer checkSuperTableExists(String dataBaseName, String superTableName) {
-        List<Map<String, Object>> results = tdEngineMapper.showSuperTables(dataBaseName, superTableName);
-        return results == null || results.isEmpty() ? 0 : results.size();
-    }
-
-    @Override
-    public List<Map<String, Object>> describeSuperTable(String dataBaseName, String superTableName) {
-        return tdEngineMapper.describeSuperTable(dataBaseName, superTableName);
-    }
-}

+ 2 - 2
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageService.java

@@ -11,8 +11,8 @@ public interface IotThingModelMessageService {
     /**
      * 保存物模型消息
      *
-     * @param device 设备
+     * @param device            设备
      * @param thingModelMessage 物模型消息
      */
-    void saveThingModelMessage(IotDeviceDO device,ThingModelMessage thingModelMessage);
+    void saveThingModelMessage(IotDeviceDO device, ThingModelMessage thingModelMessage);
 }

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

@@ -6,8 +6,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceSt
 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.FieldParser;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO;
 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.tdengine.ThingModelMessage;
 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
 import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
@@ -23,6 +23,9 @@ import org.springframework.stereotype.Service;
 import java.util.*;
 import java.util.stream.Collectors;
 
+/**
+ * 物模型消息 Service 实现类
+ */
 @Slf4j
 @Service
 public class IotThingModelMessageServiceImpl implements IotThingModelMessageService {
@@ -35,7 +38,11 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
     @Resource
     private IotDeviceService iotDeviceService;
     @Resource
-    private IotTdEngineService iotTdEngineService;
+    private TdEngineTableService tdEngineTableService;
+    @Resource
+    private TdEngineSuperTableService tdEngineSuperTableService;
+    @Resource
+    private TdEngineDataWriterService tdEngineDataWriterService;
 
     @Resource
     private DeviceDataRedisDAO deviceDataRedisDAO;
@@ -90,14 +97,11 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
             return;
         }
 
-        // 构建并保存设备属性
-        TableDO tableData = new TableDO();
-        tableData.setDataBaseName(getDatabaseName());
-        tableData.setSuperTableName(getProductPropertySTableName(device.getDeviceType(), device.getProductKey()));
-        tableData.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()));
-        tableData.setSchemaFieldValues(schemaFieldValues);
-
-        iotTdEngineService.insertData(tableData);
+        // 构建并保存设备属性数据
+        tdEngineDataWriterService.insertData(TdTableDO.builder().build()
+                .setDataBaseName(getDatabaseName())
+                .setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()))
+                .setColumns(schemaFieldValues));
     }
 
     /**
@@ -135,7 +139,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
         String superTableName = getProductPropertySTableName(deviceType, productKey);
         String dataBaseName = getDatabaseName();
 
-        List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(dataBaseName, superTableName);
+        List<Map<String, Object>> maps = tdEngineSuperTableService.describeSuperTable(new TdTableDO(dataBaseName, superTableName));
         List<TdFieldDO> tagsFieldValues = new ArrayList<>();
 
         if (maps != null) {
@@ -159,13 +163,11 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
 
         // 创建设备数据表
         String tableName = getDeviceTableName(productKey, deviceName);
-        TableDO tableDto = new TableDO();
-        tableDto.setDataBaseName(dataBaseName);
-        tableDto.setSuperTableName(superTableName);
-        tableDto.setTableName(tableName);
-        tableDto.setTagsFieldValues(tagsFieldValues);
-
-        iotTdEngineService.createTable(tableDto);
+        tdEngineTableService.createTable(TdTableDO.builder().build()
+                .setDataBaseName(dataBaseName)
+                .setSuperTableName(superTableName)
+                .setTableName(tableName)
+                .setTags(tagsFieldValues));
     }
 
     /**

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

@@ -0,0 +1,19 @@
+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);
+}

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

@@ -0,0 +1,21 @@
+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);
+    }
+}

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

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

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

@@ -0,0 +1,22 @@
+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);
+    }
+}

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

@@ -0,0 +1,28 @@
+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);
+}

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

@@ -0,0 +1,26 @@
+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);
+    }
+}

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

@@ -0,0 +1,123 @@
+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);
+}

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

@@ -0,0 +1,90 @@
+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());
+        }
+    }
+}

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

@@ -0,0 +1,21 @@
+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);
+
+}

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

@@ -0,0 +1,23 @@
+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);
+    }
+}

+ 1 - 1
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thinkmodelfunction/IotThinkModelFunctionService.java

@@ -75,5 +75,5 @@ public interface IotThinkModelFunctionService {
      * @param productKey 产品 Key
      * @return 产品物模型列表
      */
-    List<IotThinkModelFunctionDO>  getThinkModelFunctionListByProductKey(String productKey);
+    List<IotThinkModelFunctionDO> getThinkModelFunctionListByProductKey(String productKey);
 }

+ 2 - 2
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thinkmodelfunction/IotThinkModelFunctionServiceImpl.java

@@ -22,7 +22,7 @@ import cn.iocoder.yudao.module.iot.enums.product.IotAccessModeEnum;
 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
 import cn.iocoder.yudao.module.iot.enums.product.IotProductStatusEnum;
 import cn.iocoder.yudao.module.iot.service.product.IotProductService;
-import cn.iocoder.yudao.module.iot.service.tdengine.IotDbStructureDataService;
+import cn.iocoder.yudao.module.iot.service.tdengine.IotSuperTableService;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -52,7 +52,7 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
     @Resource
     private IotProductService productService;
     @Resource
-    private IotDbStructureDataService dbStructureDataService;
+    private IotSuperTableService dbStructureDataService;
 
     @Override
     @Transactional(rollbackFor = Exception.class)

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

@@ -0,0 +1,22 @@
+<?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>

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

@@ -0,0 +1,13 @@
+<?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 - 327
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineMapper.xml

@@ -1,327 +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.TdEngineMapper">
-    <!-- TODO 对 $ 符号有安全要求的话,后期改为接口方式 -->
-
-    <update id="createDatabase" parameterType="String">
-        CREATE DATABASE IF NOT EXISTS ${dataBaseName}
-    </update>
-
-    <update id="createSuperTable">
-        CREATE STABLE IF NOT EXISTS ${dataBaseName}.${superTableName}
-        <foreach item="item" collection="schemaFields" separator=","
-                 open="(" close=")" index="">
-            <if test="item.fieldName != null || item.fieldName != ''">
-                ${item.fieldName}
-            </if>
-            <if test="item.dataType != null || item.dataType != ''">
-                <choose>
-                    <when test="item.dataType == 'TIMESTAMP'">
-                        TIMESTAMP
-                    </when>
-                    <when test="item.dataType == 'TINYINT'">
-                        TINYINT
-                    </when>
-                    <when test="item.dataType == 'SMALLINT'">
-                        SMALLINT
-                    </when>
-                    <when test="item.dataType == 'INT'">
-                        INT
-                    </when>
-                    <when test="item.dataType == 'BIGINT'">
-                        BIGINT
-                    </when>
-                    <when test="item.dataType == 'FLOAT'">
-                        FLOAT
-                    </when>
-                    <when test="item.dataType == 'DOUBLE'">
-                        DOUBLE
-                    </when>
-                    <when test="item.dataType == 'BINARY'">
-                        BINARY
-                    </when>
-                    <when test="item.dataType == 'NCHAR'">
-                        NCHAR
-                    </when>
-                    <when test="item.dataType == 'BOOL'">
-                        BOOL
-                    </when>
-                    <when test="item.dataType == 'JSON'">
-                        JSON
-                    </when>
-                </choose>
-            </if>
-            <if test="item.dataLength > 0">
-                (
-                ${item.dataLength}
-                )
-            </if>
-        </foreach>
-        TAGS
-        <!--tdEngine不支持动态tags里的数据类型,只能使用choose标签比对-->
-        <foreach item="item" collection="tagsFields" separator=","
-                 open="(" close=")" index="">
-            <if test="item.fieldName != null || item.fieldName != ''">
-                ${item.fieldName}
-            </if>
-            <if test="item.dataType != null || item.dataType != ''">
-                <choose>
-                    <when test="item.dataType == 'TIMESTAMP'">
-                        TIMESTAMP
-                    </when>
-                    <when test="item.dataType == 'TINYINT'">
-                        TINYINT
-                    </when>
-                    <when test="item.dataType == 'SMALLINT'">
-                        SMALLINT
-                    </when>
-                    <when test="item.dataType == 'INT'">
-                        INT
-                    </when>
-                    <when test="item.dataType == 'BIGINT'">
-                        BIGINT
-                    </when>
-                    <when test="item.dataType == 'FLOAT'">
-                        FLOAT
-                    </when>
-                    <when test="item.dataType == 'DOUBLE'">
-                        DOUBLE
-                    </when>
-                    <when test="item.dataType == 'BINARY'">
-                        BINARY
-                    </when>
-                    <when test="item.dataType == 'NCHAR'">
-                        NCHAR
-                    </when>
-                    <when test="item.dataType == 'BOOL'">
-                        BOOL
-                    </when>
-                    <when test="item.dataType == 'JSON'">
-                        JSON
-                    </when>
-                </choose>
-            </if>
-            <if test="item.dataLength > 0">
-                (
-                ${item.dataLength}
-                )
-            </if>
-        </foreach>
-    </update>
-
-    <!--    CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);-->
-    <update id="createTable">
-        CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
-        USING ${dataBaseName}.${superTableName}
-        <foreach item="item" collection="tagsFieldValues" separator="," open="(" close=")">
-            ${item.fieldName}
-        </foreach>
-        TAGS
-        <foreach item="item" collection="tagsFieldValues" separator="," open="(" close=")">
-            #{item.fieldValue}
-        </foreach>
-    </update>
-
-    <!--    insert into d1004 (ts, voltage, phase) values("2018-10-04 14:38:06", 223, 0.29) -->
-    <insert id="insertData">
-        INSERT INTO ${dataBaseName}.${tableName}
-        <foreach item="item" collection="schemaFieldValues" separator=","
-                 open="(" close=")" index="">
-            ${item.fieldName}
-        </foreach>
-        VALUES
-        <foreach item="item" collection="schemaFieldValues" separator=","
-                 open="(" close=")" index="">
-            #{item.fieldValue}
-        </foreach>
-    </insert>
-
-    <select id="selectByTimestamp" parameterType="cn.iocoder.yudao.module.iot.domain.SelectDto"
-            resultType="Map">
-        select * from #{dataBaseName}.#{tableName}
-        <!--查询这里不能使用#{}占位符的方式,使用这种方式,tdEngine不识别为列名,只能使用${}占位的方式-->
-        <!--因为tdEngine引擎一次只执行一条sql,所以有效预防了sql的注入,且该服务该接口为内部调用,所以可以使用${}-->
-        where ${fieldName}
-        between #{startTime} and #{endTime}
-    </select>
-
-    <update id="addColumnForSuperTable">
-        ALTER STABLE ${dataBaseName}.${superTableName} ADD COLUMN
-        <if test="field.fieldName != null || field.fieldName != ''">
-            #{field.fieldName}
-        </if>
-        <if test="field.dataType != null || field.dataType != ''">
-            <choose>
-                <when test="field.dataType == 'TIMESTAMP'">
-                    TIMESTAMP
-                </when>
-                <when test="field.dataType == 'TINYINT'">
-                    TINYINT
-                </when>
-                <when test="field.dataType == 'SMALLINT'">
-                    SMALLINT
-                </when>
-                <when test="field.dataType == 'INT'">
-                    INT
-                </when>
-                <when test="field.dataType == 'BIGINT'">
-                    BIGINT
-                </when>
-                <when test="field.dataType == 'FLOAT'">
-                    FLOAT
-                </when>
-                <when test="field.dataType == 'DOUBLE'">
-                    DOUBLE
-                </when>
-                <when test="field.dataType == 'BINARY'">
-                    BINARY
-                </when>
-                <when test="field.dataType == 'NCHAR'">
-                    NCHAR
-                </when>
-                <when test="field.dataType == 'BOOL'">
-                    BOOL
-                </when>
-                <when test="field.dataType == 'JSON'">
-                    JSON
-                </when>
-            </choose>
-        </if>
-        <if test="field.dataLength > 0">
-            (
-            #{field.dataLength}
-            )
-        </if>
-    </update>
-
-    <update id="dropColumnForSuperTable">
-        ALTER STABLE ${dataBaseName}.${superTableName} DROP COLUMN
-        <if test="field.fieldName != null || field.fieldName != ''">
-            #{field.fieldName}
-        </if>
-    </update>
-
-    <update id="addTagForSuperTable">
-        ALTER
-        STABLE
-        #{superTableName}
-        ADD
-        TAG
-        <if test="field.fieldName != null || fieldDO.fieldName != ''">
-            #{fieldDO.fieldName}
-        </if>
-        <if test="fieldDO.dataType != null || fieldDO.dataType != ''">
-            <choose>
-                <when test="fieldDO.dataType == 'timestamp'">
-                    timestamp
-                </when>
-                <when test="fieldDO.dataType == 'tinyint'">
-                    tinyint
-                </when>
-                <when test="fieldDO.dataType == 'smallint'">
-                    smallint
-                </when>
-                <when test="fieldDO.dataType == 'int'">
-                    int
-                </when>
-                <when test="fieldDO.dataType == 'bigint'">
-                    bigint
-                </when>
-                <when test="fieldDO.dataType == 'float'">
-                    float
-                </when>
-                <when test="fieldDO.dataType == 'double'">
-                    double
-                </when>
-                <when test="fieldDO.dataType == 'binary'">
-                    binary
-                </when>
-                <when test="fieldDO.dataType == 'nchar'">
-                    nchar
-                </when>
-                <when test="fieldDO.dataType == 'bool'">
-                    bool
-                </when>
-                <when test="fieldDO.dataType == 'json'">
-                    json
-                </when>
-            </choose>
-        </if>
-        <if test="fieldDO.dataLength > 0">
-            (
-            #{fieldDO.dataLength}
-            )
-        </if>
-    </update>
-
-    <update id="dropTagForSuperTable">
-        ALTER
-        STABLE
-        #{superTableName}
-        DROP
-        TAG
-        <if test="fieldsVo.fieldName != null || fieldsVo.fieldName != ''">
-            #{fieldsVo.fieldName}
-        </if>
-    </update>
-
-    <select id="getCountByTimestamp" parameterType="cn.iocoder.yudao.module.iot.domain.SelectDto"
-            resultType="java.util.Map">
-        SELECT count(0) AS count
-        FROM #{dataBaseName}.#{tableName}
-        WHERE ${fieldName} BETWEEN #{startTime} AND #{endTime}
-    </select>
-
-    <select id="showSuperTables" resultType="java.util.Map">
-        SHOW ${dataBaseName}.STABLES LIKE '${superTableName}'
-    </select>
-
-    <select id="getLastData" resultType="java.util.Map">
-        select last(time), *
-        from #{tableName}
-        where device_id = #{deviceId}
-    </select>
-
-    <select id="getLastDataByTags" parameterType="cn.iocoder.yudao.module.iot.domain.TagsSelectDao"
-            resultType="Map">
-        select last(*)
-        from #{dataBaseName}.#{stableName}
-        group by ${tagsName}
-    </select>
-
-    <select id="getHistoryData" resultType="java.util.Map"
-            parameterType="cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto">
-        SELECT ${fieldName} as data, time
-        FROM ${dataBaseName}.${tableName}
-        WHERE time BETWEEN #{startTime} AND #{endTime}
-          AND ${fieldName} IS NOT NULL
-        ORDER BY time DESC
-        LIMIT #{params.rows} offset #{params.page}
-    </select>
-
-    <select id="getRealtimeData" resultType="java.util.Map"
-            parameterType="cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto">
-        SELECT #{fieldName}, time
-        FROM #{dataBaseName}.#{tableName}
-    </select>
-
-    <select id="getAggregateData" resultType="java.util.Map"
-            parameterType="cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto">
-        SELECT #{aggregate}(${fieldName})
-        FROM #{dataBaseName}.#{tableName}
-        WHERE ts BETWEEN #{startTime} AND #{endTime} interval (${interval})
-        LIMIT #{num}
-    </select>
-
-    <select id="describeSuperTable" resultType="java.util.Map">
-        DESCRIBE ${dataBaseName}.${superTableName}
-    </select>
-    <select id="getHistoryCount" resultType="java.lang.Long">
-        SELECT count(time)
-        FROM ${dataBaseName}.${tableName}
-        WHERE time BETWEEN #{startTime} AND #{endTime}
-          AND ${fieldName} IS NOT NULL
-    </select>
-
-</mapper>

+ 73 - 0
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineQueryMapper.xml

@@ -0,0 +1,73 @@
+<?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.TdEngineQueryMapper">
+
+    <!-- 根据时间戳查询数据 -->
+    <select id="selectByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO"
+            resultType="Map">
+        SELECT * FROM ${dataBaseName}.${tableName}
+        WHERE ${fieldName} BETWEEN #{startTime} AND #{endTime}
+    </select>
+
+    <!-- 获取时间范围内的数据条数 -->
+    <select id="getCountByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO"
+            resultType="java.util.Map">
+        SELECT COUNT(0) AS count
+        FROM ${dataBaseName}.${tableName}
+        WHERE ${fieldName} BETWEEN #{startTime} AND #{endTime}
+    </select>
+
+    <!-- 获取最新数据 -->
+    <select id="getLastData" 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"
+            resultType="Map">
+        SELECT LAST(*)
+        FROM ${dataBaseName}.${stableName}
+        GROUP BY ${tagsName}
+    </select>
+
+    <!-- 获取历史数据 -->
+    <select id="getHistoryData" resultType="java.util.Map"
+            parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
+        SELECT ${fieldName} AS data, time
+        FROM ${dataBaseName}.${tableName}
+        WHERE time BETWEEN #{startTime} AND #{endTime}
+          AND ${fieldName} IS NOT NULL
+        ORDER BY time DESC
+        LIMIT #{params.rows} OFFSET #{params.page}
+    </select>
+
+    <!-- 获取实时数据 -->
+    <select id="getRealtimeData" 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"
+            parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
+        SELECT ${aggregate}(${fieldName})
+        FROM ${dataBaseName}.${tableName}
+        WHERE ts BETWEEN #{startTime} AND #{endTime} INTERVAL (${interval})
+        LIMIT #{num}
+    </select>
+
+    <!-- 获取历史数据条数 -->
+    <select id="getHistoryCount" resultType="java.lang.Long">
+        SELECT COUNT(time)
+        FROM ${dataBaseName}.${tableName}
+        WHERE time BETWEEN #{startTime} AND #{endTime}
+          AND ${fieldName} IS NOT NULL
+    </select>
+
+</mapper>

+ 72 - 0
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineSuperTableMapper.xml

@@ -0,0 +1,72 @@
+<?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.TdEngineSuperTableMapper">
+
+    <!-- 创建超级表 -->
+    <update id="createSuperTable">
+        CREATE STABLE IF NOT EXISTS ${dataBaseName}.${superTableName}
+        <foreach item="item" collection="columns" separator=","
+                 open="(" close=")">
+            ${item.fieldName} ${item.dataType}
+            <if test="item.dataLength > 0">
+                (${item.dataLength})
+            </if>
+        </foreach>
+        TAGS
+        <foreach item="item" collection="tags" separator=","
+                 open="(" close=")">
+            ${item.fieldName} ${item.dataType}
+            <if test="item.dataLength > 0">
+                (${item.dataLength})
+            </if>
+        </foreach>
+    </update>
+
+    <!-- 查看超级表 -->
+    <select id="showSuperTables" resultType="java.util.Map">
+        SHOW ${dataBaseName}.STABLES LIKE '${superTableName}'
+    </select>
+
+    <!-- 描述超级表结构 -->
+    <select id="describeSuperTable" resultType="java.util.Map">
+        DESCRIBE ${dataBaseName}.${superTableName}
+    </select>
+
+    <!-- 为超级表添加列 -->
+    <update id="addColumnForSuperTable">
+        ALTER STABLE ${dataBaseName}.${superTableName} ADD COLUMN ${column.fieldName} ${column.dataType}
+        <if test="column.dataLength > 0">
+            (${column.dataLength})
+        </if>
+    </update>
+
+    <!-- 为超级表删除列 -->
+    <update id="dropColumnForSuperTable">
+        ALTER STABLE ${dataBaseName}.${superTableName} DROP COLUMN ${column.fieldName}
+    </update>
+
+    <!-- 修改列宽 -->
+    <update id="modifyColumnWidthForSuperTable">
+        ALTER STABLE ${dataBaseName}.${superTableName} MODIFY COLUMN ${column.fieldName} ${column.dataType}
+        <if test="column.dataLength > 0">
+            (${column.dataLength})
+        </if>
+    </update>
+
+    <!-- 为超级表添加标签 -->
+    <update id="addTagForSuperTable">
+        ALTER STABLE ${dataBaseName}.${superTableName} ADD TAG ${tag.fieldName} ${tag.dataType}
+        <if test="tag.dataLength > 0">
+            (${tag.dataLength})
+        </if>
+    </update>
+
+    <!-- 为超级表删除标签 -->
+    <update id="dropTagForSuperTable">
+        ALTER STABLE ${dataBaseName}.${superTableName} DROP TAG ${tag.fieldName}
+    </update>
+
+</mapper>

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

@@ -0,0 +1,33 @@
+<?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>