Commit e3dcea9cb3792bfebb489c3ccfb568bcec6bf7da

Authored by 安浩浩
1 parent d7b8cf54

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

Showing 50 changed files with 1289 additions and 1469 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/BaseEntity.java deleted
1   -package cn.iocoder.yudao.module.iot.domain;
2   -
3   -import lombok.Data;
4   -
5   -@Data
6   -public class BaseEntity {
7   - private static final long serialVersionUID = 1L;
8   -
9   - /**
10   - * 数据库名称
11   - */
12   - private String dataBaseName;
13   -
14   - /**
15   - * 超级表名称
16   - */
17   - private String superTableName;
18   -}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/DeviceDataVo.java deleted
1   -package cn.iocoder.yudao.module.iot.domain;
2   -
3   -import lombok.Data;
4   -
5   -/**
6   - * @ClassDescription: 查询可视化所需入参对象
7   - * @ClassName: SelectDto
8   - * @Author: andyz
9   - * @Date: 2022-07-29 14:12:26
10   - * @Version 1.0
11   - */
12   -@Data
13   -public class DeviceDataVo {
14   -
15   -
16   - private String deviceId;
17   -
18   - private Long lastTime;
19   -}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/Fields.java deleted
1   -package cn.iocoder.yudao.module.iot.domain;
2   -
3   -import lombok.Data;
4   -
5   -@Data
6   -public class Fields {
7   - private static final long serialVersionUID = 1L;
8   -
9   - /**
10   - * 字段名称
11   - */
12   - private String fieldName;
13   -
14   - /**
15   - * 字段值
16   - */
17   - private Object fieldValue;
18   -
19   - /**
20   - * 字段数据类型
21   - */
22   -// private DataTypeEnum dataType;
23   -
24   - /**
25   - * 字段字节大小
26   - */
27   - private Integer size;
28   -
29   - public Fields() {
30   - }
31   -
32   - public Fields(String fieldName, String dataType, Integer size) {
33   -// this.fieldName = fieldName;
34   -// //根据规则匹配字段数据类型
35   -// switch (dataType.toLowerCase()) {
36   -// case ("json"):
37   -// this.dataType = DataTypeEnum.JSON;
38   -// this.size = size;
39   -// break;
40   -// case ("string"):
41   -// this.dataType = DataTypeEnum.NCHAR;
42   -// this.size = size;
43   -// break;
44   -// case ("binary"):
45   -// this.dataType = DataTypeEnum.BINARY;
46   -// this.size = size;
47   -// break;
48   -// case ("int"):
49   -// this.dataType = DataTypeEnum.INT;
50   -// break;
51   -// case ("bool"):
52   -// this.dataType = DataTypeEnum.BOOL;
53   -// break;
54   -// case ("decimal"):
55   -// this.dataType = DataTypeEnum.DOUBLE;
56   -// break;
57   -// case ("timestamp"):
58   -// if ("eventTime".equals(fieldName)) {
59   -// this.fieldName = "eventTime";
60   -// }
61   -// this.dataType = DataTypeEnum.TIMESTAMP;
62   -// break;
63   -// }
64   - }
65   -}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/FieldsVo.java deleted
1   -package cn.iocoder.yudao.module.iot.domain;
2   -
3   -import lombok.Builder;
4   -import lombok.Data;
5   -
6   -import java.sql.SQLException;
7   -import java.util.ArrayList;
8   -import java.util.List;
9   -
10   -/**
11   - * 字段信息 VO
12   - */
13   -@Data
14   -@Builder
15   -public class FieldsVo {
16   -
17   - /**
18   - * 字段名称
19   - */
20   - private String fieldName;
21   -
22   - /**
23   - * 字段数据类型
24   - */
25   - private String dataType;
26   -
27   - /**
28   - * 字段字节大小
29   - */
30   - private Integer size;
31   -}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/IotSequential.java deleted
1   -package cn.iocoder.yudao.module.iot.domain;
2   -
3   -import com.fasterxml.jackson.annotation.JsonFormat;
4   -
5   -import java.sql.Timestamp;
6   -
7   -public class IotSequential extends BaseEntity {
8   - private static final long serialVersionUID = 1L;
9   -
10   - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS" , timezone = "GMT+8")
11   - private Timestamp statetime;
12   -
13   - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS" , timezone = "GMT+8")
14   - private Timestamp endtime;
15   -
16   - private String deviceid;
17   -
18   - private String eventtime;
19   -
20   - private String serviceid;
21   -
22   - private String devices;
23   -
24   - public String getDeviceid() {
25   - return deviceid;
26   - }
27   -
28   - public void setDeviceid(String deviceid) {
29   - this.deviceid = deviceid;
30   - }
31   -
32   - public String getEventtime() {
33   - return eventtime;
34   - }
35   -
36   - public void setEventtime(String eventtime) {
37   - this.eventtime = eventtime;
38   - }
39   -
40   - public String getServiceid() {
41   - return serviceid;
42   - }
43   -
44   - public void setServiceid(String serviceid) {
45   - this.serviceid = serviceid;
46   - }
47   -
48   - public String getDevices() {
49   - return devices;
50   - }
51   -
52   - public void setDevices(String devices) {
53   - this.devices = devices;
54   - }
55   -
56   - public Timestamp getStatetime() {
57   - return statetime;
58   - }
59   -
60   - public void setStatetime(Timestamp statetime) {
61   - this.statetime = statetime;
62   - }
63   -
64   - public Timestamp getEndtime() {
65   - return endtime;
66   - }
67   -
68   - public void setEndtime(Timestamp endtime) {
69   - this.endtime = endtime;
70   - }
71   -}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/MessageCountVo.java deleted
1   -package cn.iocoder.yudao.module.iot.domain;
2   -
3   -import lombok.AllArgsConstructor;
4   -import lombok.Data;
5   -import lombok.NoArgsConstructor;
6   -
7   -/**
8   - * 统计的时间数据
9   - */
10   -@Data
11   -@NoArgsConstructor
12   -@AllArgsConstructor
13   -public class MessageCountVo {
14   -
15   - /**
16   - * 时间
17   - */
18   - private String time;
19   -
20   - /**
21   - * 数据值
22   - */
23   - private Object data;
24   -
25   -}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/ProductSuperTableModel.java deleted
1   -package cn.iocoder.yudao.module.iot.domain;
2   -
3   -import com.fasterxml.jackson.annotation.JsonFormat;
4   -import lombok.Data;
5   -
6   -import java.sql.Timestamp;
7   -import java.util.HashMap;
8   -import java.util.Optional;
9   -
10   -@Data
11   -public class ProductSuperTableModel {
12   - private static final long serialVersionUID = 1L;
13   -
14   - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+8")
15   - private Timestamp ts;
16   -
17   - private String superTableName;
18   -
19   - /**
20   - * columnsName,columnsProperty
21   - */
22   - private HashMap<Optional, Optional> columns;
23   -
24   - /**
25   - * tagsName,tagsProperty
26   - */
27   - private HashMap<Optional, Optional> tags;
28   -
29   -}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/SelectDto.java deleted
1   -package cn.iocoder.yudao.module.iot.domain;
2   -
3   -import lombok.Data;
4   -
5   -import java.util.Set;
6   -
7   -@Data
8   -public class SelectDto {
9   -
10   - // @NotBlank(message = "invalid operation: dataBaseName can not be empty")
11   - private String dataBaseName;
12   -
13   -// @NotBlank(message = "invalid operation: tableName can not be empty")
14   - private String tableName;
15   -
16   - // @NotBlank(message = "invalid operation: fieldName can not be empty")
17   - private String fieldName;
18   -
19   - // @NotNull(message = "invalid operation: startTime can not be null")
20   - private Long startTime;
21   -
22   - // @NotNull(message = "invalid operation: endTime can not be null")
23   - private Long endTime;
24   -
25   - private String type;
26   -
27   - private Set<Integer> orgIds;
28   -
29   - private String deviceId;
30   -}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/SuperTableDto.java deleted
1   -package cn.iocoder.yudao.module.iot.domain;
2   -
3   -import lombok.Data;
4   -
5   -import java.util.List;
6   -
7   -@Data
8   -public class SuperTableDto extends BaseEntity {
9   -
10   - /**
11   - * 超级表的表结构(业务相关)
12   - * 第一个字段的数据类型必须为timestamp
13   - * 字符相关数据类型必须指定大小
14   - * 字段名称和字段数据类型不能为空
15   - */
16   -// @NotEmpty(message = "invalid operation: schemaFields can not be empty")
17   - private List<Fields> schemaFields;
18   -
19   - /**
20   - * 超级表的标签字段,可以作为子表在超级表里的标识
21   - * 字符相关数据类型必须指定大小
22   - * 字段名称和字段数据类型不能为空
23   - */
24   -// @NotEmpty(message = "invalid operation: tagsFields can not be empty")
25   - private List<Fields> tagsFields;
26   -
27   - /**
28   - * 字段信息对象,超级表添加列时使用该属性
29   - */
30   - private Fields fields;
31   -}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/TableDto.java deleted
1   -package cn.iocoder.yudao.module.iot.domain;
2   -
3   -import lombok.Data;
4   -
5   -import java.util.List;
6   -
7   -@Data
8   -public class TableDto extends BaseEntity {
9   -
10   - /**
11   - * 超级表普通列字段的值
12   - * 值需要与创建超级表时普通列字段的数据类型对应上
13   - */
14   - private List<Fields> schemaFieldValues;
15   -
16   - /**
17   - * 超级表标签字段的值
18   - * 值需要与创建超级表时标签字段的数据类型对应上
19   - */
20   - private List<Fields> tagsFieldValues;
21   -
22   - /**
23   - * 表名称
24   - */
25   - private String tableName;
26   -}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/TagsSelectDao.java deleted
1   -package cn.iocoder.yudao.module.iot.domain;
2   -
3   -import lombok.Data;
4   -
5   -
6   -@Data
7   -public class TagsSelectDao {
8   -
9   - // @NotBlank(message = "invalid operation: dataBaseName can not be empty")
10   - private String dataBaseName;
11   -
12   - // @NotBlank(message = "invalid operation: stableName can not be empty")
13   - private String stableName;
14   -
15   - // @NotBlank(message = "invalid operation: tagsName can not be empty")
16   - private String tagsName;
17   -
18   - // @NotNull(message = "invalid operation: startTime can not be null")
19   - private Long startTime;
20   -
21   - // @NotNull(message = "invalid operation: endTime can not be null")
22   - private Long endTime;
23   -
24   -
25   -}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/Weather.java deleted
1   -package cn.iocoder.yudao.module.iot.domain;
2   -
3   -import com.fasterxml.jackson.annotation.JsonFormat;
4   -
5   -import java.sql.Timestamp;
6   -
7   -public class Weather {
8   -
9   - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS" , timezone = "GMT+8")
10   - private Timestamp ts;
11   - private Float temperature;
12   - private Float humidity;
13   - private String location;
14   - private String note;
15   - private int groupId;
16   -
17   - public Weather() {
18   - }
19   -
20   - public Weather(Timestamp ts, float temperature, float humidity) {
21   - this.ts = ts;
22   - this.temperature = temperature;
23   - this.humidity = humidity;
24   - }
25   -
26   - public Timestamp getTs() {
27   - return ts;
28   - }
29   -
30   - public void setTs(Timestamp ts) {
31   - this.ts = ts;
32   - }
33   -
34   - public Float getTemperature() {
35   - return temperature;
36   - }
37   -
38   - public void setTemperature(Float temperature) {
39   - this.temperature = temperature;
40   - }
41   -
42   - public Float getHumidity() {
43   - return humidity;
44   - }
45   -
46   - public void setHumidity(Float humidity) {
47   - this.humidity = humidity;
48   - }
49   -
50   - public String getLocation() {
51   - return location;
52   - }
53   -
54   - public void setLocation(String location) {
55   - this.location = location;
56   - }
57   -
58   - public int getGroupId() {
59   - return groupId;
60   - }
61   -
62   - public void setGroupId(int groupId) {
63   - this.groupId = groupId;
64   - }
65   -
66   - public String getNote() {
67   - return note;
68   - }
69   -
70   - public void setNote(String note) {
71   - this.note = note;
72   - }
73   -}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TableData.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectDO.java
... ... @@ -2,43 +2,50 @@ package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
2 2  
3 3 import lombok.Data;
4 4  
5   -import java.util.List;
6   -
  5 +import java.util.Set;
7 6 /**
8   - * TableData 类用于存储和操作 TDengine 表数据
  7 + * 查询DO
9 8 */
10 9 @Data
11   -public class TableData {
  10 +public class SelectDO {
12 11  
13 12 /**
14   - * 超级表普通列字段的名称
  13 + * 数据库名称
15 14 */
16   - private List<String> schemaFieldList;
  15 + private String dataBaseName;
17 16  
18 17 /**
19   - * 超级表普通列字段的值
20   - * 值需要与创建超级表时普通列字段的数据类型对应上
  18 + * 超级表名称
21 19 */
22   - private List<Object> schemaValueList;
  20 + private String tableName;
23 21  
24 22 /**
25   - * 超级表标签字段的名称
  23 + * 查询字段
26 24 */
27   - private List<String> tagsFieldList;
  25 + private String fieldName;
28 26  
29 27 /**
30   - * 超级表标签字段的值
31   - * 值需要与创建超级表时标签字段的数据类型对应上
  28 + * 开始时间
32 29 */
33   - private List<Object> tagsValueList;
  30 + private Long startTime;
34 31  
35 32 /**
36   - * 表名称
  33 + * 结束时间
37 34 */
38   - private String tableName;
  35 + private Long endTime;
39 36  
40 37 /**
41   - * 超级表名称
  38 + * 查询类型
  39 + */
  40 + private String type;
  41 +
  42 + /**
  43 + * 查询条件
  44 + */
  45 + private Set<Integer> orgIds;
  46 +
  47 + /**
  48 + * 设备ID
42 49 */
43   - private String superTableName;
44   -}
45 50 \ No newline at end of file
  51 + private String deviceId;
  52 +}
... ...
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/visual/SelectVisualDto.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java
1   -package cn.iocoder.yudao.module.iot.domain.visual;
  1 +package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
2 2  
3 3 import lombok.Data;
4 4  
5 5 import java.util.Map;
6 6  
7 7 @Data
8   -public class SelectVisualDto {
  8 +public class SelectVisualDO {
9 9  
10 10 /**
11 11 * 数据库名称
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TableDO.java deleted
1   -package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
2   -
3   -import cn.iocoder.yudao.module.iot.domain.BaseEntity;
4   -import lombok.Data;
5   -
6   -import java.util.List;
7   -
8   -@Data
9   -public class TableDO extends BaseEntity {
10   -
11   - /**
12   - * 超级表普通列字段的值
13   - * 值需要与创建超级表时普通列字段的数据类型对应上
14   - */
15   - private List<TdFieldDO> schemaFieldValues;
16   -
17   - /**
18   - * 超级表标签字段的值
19   - * 值需要与创建超级表时标签字段的数据类型对应上
20   - */
21   - private List<TdFieldDO> tagsFieldValues;
22   -
23   - /**
24   - * 表名称
25   - */
26   - private String tableName;
27   -}
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/domain/DeviceDataExportExcelDto.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TagsSelectDO.java
1   -package cn.iocoder.yudao.module.iot.domain;
  1 +package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
2 2  
3 3 import lombok.Data;
4 4  
5 5 /**
6   - * 设备数据导出 excel DTO
  6 + * tags查询DO
7 7 */
8 8 @Data
9   -public class DeviceDataExportExcelDto {
  9 +public class TagsSelectDO {
10 10  
11 11 /**
12   - * 设备标识
  12 + * 数据库名称
13 13 */
14   - private String deviceKey;
  14 + private String dataBaseName;
15 15  
16 16 /**
17   - * 导出形式 1 单个参数导出 2 全部参数导出
  17 + * 超级表名称
18 18 */
19   - private String exportType;
  19 + private String stableName;
20 20  
21 21 /**
22   - * 导出开始时间
  22 + * tags名称
23 23 */
24   - private String exportBeginTime;
  24 + private String tagsName;
25 25  
26 26 /**
27   - * 导出结束时间
  27 + * tags值
28 28 */
29   - private String exportEndTime;
  29 + private Long startTime;
30 30  
31 31 /**
32   - * 导出参数,空则导出全部
  32 + * tags值
33 33 */
34   - private String exportParameter;
  34 + private Long endTime;
  35 +
35 36 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdFieldDO.java
... ... @@ -20,11 +20,6 @@ public class TdFieldDO {
20 20 private String fieldName;
21 21  
22 22 /**
23   - * 字段值
24   - */
25   - private Object fieldValue;
26   -
27   - /**
28 23 * 字段类型
29 24 */
30 25 private String dataType;
... ... @@ -34,6 +29,11 @@ public class TdFieldDO {
34 29 */
35 30 private Integer dataLength = 0;
36 31  
  32 + /**
  33 + * 字段值
  34 + */
  35 + private Object fieldValue;
  36 +
37 37 public TdFieldDO(String fieldName, String dataType, Integer dataLength) {
38 38 this.fieldName = fieldName;
39 39 this.dataType = dataType;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Builder;
  5 +import lombok.Data;
  6 +import lombok.NoArgsConstructor;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * TD 引擎的数据库
  12 + */
  13 +@Data
  14 +@Builder
  15 +@NoArgsConstructor
  16 +@AllArgsConstructor
  17 +public class TdTableDO {
  18 +
  19 + /**
  20 + * 数据库名称
  21 + */
  22 + private String dataBaseName;
  23 +
  24 + /**
  25 + * 超级表名称
  26 + */
  27 + private String superTableName;
  28 +
  29 + /**
  30 + * 表名称
  31 + */
  32 + private String tableName;
  33 +
  34 + /**
  35 + * COLUMN 字段
  36 + */
  37 + private TdFieldDO column;
  38 +
  39 + /**
  40 + * TAG 字段
  41 + */
  42 + private TdFieldDO tag;
  43 +
  44 + /**
  45 + * COLUMN 字段 - 列表
  46 + */
  47 + private List<TdFieldDO> columns;
  48 +
  49 + /**
  50 + * TAG 字段 - 列表
  51 + */
  52 + private List<TdFieldDO> tags;
  53 +
  54 + public TdTableDO(String dataBaseName, String superTableName, List<TdFieldDO> columns, List<TdFieldDO> tags) {
  55 + this.dataBaseName = dataBaseName;
  56 + this.superTableName = superTableName;
  57 + this.columns = columns;
  58 + this.tags = tags;
  59 + }
  60 +
  61 + public TdTableDO(String dataBaseName, String superTableName) {
  62 + this.dataBaseName = dataBaseName;
  63 + this.superTableName = superTableName;
  64 + }
  65 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDataWriterMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
  4 +import com.baomidou.dynamic.datasource.annotation.DS;
  5 +import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +/**
  9 + * TD 引擎的数据写入 Mapper
  10 + */
  11 +@Mapper
  12 +@DS("tdengine")
  13 +public interface TdEngineDataWriterMapper {
  14 +
  15 + /**
  16 + * 插入数据 - 指定列插入数据
  17 + *
  18 + * @param table 数据
  19 + * dataBaseName 数据库名
  20 + * tableName 表名
  21 + * columns 列
  22 + */
  23 + @InterceptorIgnore(tenantLine = "true")
  24 + void insertData(TdTableDO table);
  25 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDatabaseMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.tdengine;
  2 +
  3 +import com.baomidou.dynamic.datasource.annotation.DS;
  4 +import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +import org.apache.ibatis.annotations.Param;
  7 +
  8 +/**
  9 + * TD 引擎的数据库 Mapper
  10 + */
  11 +@Mapper
  12 +@DS("tdengine")
  13 +public interface TdEngineDatabaseMapper {
  14 +
  15 + /**
  16 + * 创建数据库
  17 + * SQL:CREATE DATABASE [IF NOT EXISTS] db_name [database_options];
  18 + *
  19 + * @param dataBaseName 数据库名称
  20 + */
  21 + @InterceptorIgnore(tenantLine = "true")
  22 + void createDatabase(@Param("dataBaseName") String dataBaseName);
  23 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineMapper.java deleted
1   -package cn.iocoder.yudao.module.iot.dal.tdengine;
2   -
3   -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO;
4   -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
5   -import cn.iocoder.yudao.module.iot.domain.FieldsVo;
6   -import cn.iocoder.yudao.module.iot.domain.SelectDto;
7   -import cn.iocoder.yudao.module.iot.domain.TagsSelectDao;
8   -import cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto;
9   -import com.baomidou.dynamic.datasource.annotation.DS;
10   -import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
11   -import org.apache.ibatis.annotations.Mapper;
12   -import org.apache.ibatis.annotations.Param;
13   -
14   -import java.util.List;
15   -import java.util.Map;
16   -
17   -@Mapper
18   -@DS("tdengine")
19   -public interface TdEngineMapper {
20   -
21   - /**
22   - * 创建数据库
23   - *
24   - * @param dataBaseName 数据库名称
25   - */
26   - @InterceptorIgnore(tenantLine = "true")
27   - void createDatabase(@Param("dataBaseName") String dataBaseName);
28   -
29   - /**
30   - * 创建超级表
31   - *
32   - * @param schemaFields schema字段
33   - * @param tagsFields tags字段
34   - * @param dataBaseName 数据库名称
35   - * @param superTableName 超级表名称
36   - */
37   - @InterceptorIgnore(tenantLine = "true")
38   - void createSuperTable(@Param("schemaFields") List<TdFieldDO> schemaFields,
39   - @Param("tagsFields") List<TdFieldDO> tagsFields,
40   - @Param("dataBaseName") String dataBaseName,
41   - @Param("superTableName") String superTableName);
42   -
43   - /**
44   - * 查看超级表 - 显示当前数据库下的所有超级表信息
45   - * SQL:SHOW STABLES [LIKE tb_name_wildcard];
46   - *
47   - * @param dataBaseName 数据库名称
48   - * @param superTableName 超级表名称
49   - */
50   - @InterceptorIgnore(tenantLine = "true")
51   - List<Map<String, Object>> showSuperTables(@Param("dataBaseName") String dataBaseName,
52   - @Param("superTableName") String superTableName);
53   -
54   - /**
55   - * 查看超级表 - 获取超级表的结构信息
56   - * SQL:DESCRIBE [db_name.]stb_name;
57   - * <p>
58   - * * @param dataBaseName 数据库名称
59   - * * @param superTableName 超级表名称
60   - */
61   - @InterceptorIgnore(tenantLine = "true")
62   - List<Map<String, Object>> describeSuperTable(@Param("dataBaseName") String dataBaseName,
63   - @Param("superTableName") String superTableName);
64   -
65   - /**
66   - * 为超级表添加列
67   - *
68   - * @param dataBaseName 数据库名称
69   - * @param superTableName 超级表名称
70   - * @param field 字段信息
71   - */
72   - @InterceptorIgnore(tenantLine = "true")
73   - void addColumnForSuperTable(@Param("dataBaseName") String dataBaseName,
74   - @Param("superTableName") String superTableName,
75   - @Param("field") TdFieldDO field);
76   -
77   - /**
78   - * 为超级表删除列
79   - *
80   - * @param dataBaseName 数据库名称
81   - * @param superTableName 超级表名称
82   - * @param field 字段信息
83   - */
84   - @InterceptorIgnore(tenantLine = "true")
85   - void dropColumnForSuperTable(@Param("dataBaseName") String dataBaseName,
86   - @Param("superTableName") String superTableName,
87   - @Param("field") TdFieldDO field);
88   -
89   - /**
90   - * 创建表 - 创建超级表的子表
91   - *
92   - * @param tableDO 表信息
93   - */
94   - @InterceptorIgnore(tenantLine = "true")
95   - void createTable(TableDO tableDO);
96   -
97   - /**
98   - * 插入数据 - 指定列插入数据
99   - *
100   - * @param tableDto 数据
101   - */
102   - @InterceptorIgnore(tenantLine = "true")
103   - void insertData(TableDO tableDto);
104   -
105   - List<Map<String, Object>> selectByTimestamp(SelectDto selectDto);
106   -
107   -
108   - void addTagForSuperTable(@Param("superTableName") String superTableName,
109   - @Param("fieldsVo") FieldsVo fieldsVo);
110   -
111   - void dropTagForSuperTable(@Param("superTableName") String superTableName,
112   - @Param("fieldsVo") FieldsVo fieldsVo);
113   -
114   - Map<String, Long> getCountByTimestamp(SelectDto selectDto);
115   -
116   - Map<String, Object> getLastData(SelectDto selectDto);
117   -
118   - @InterceptorIgnore(tenantLine = "true")
119   - List<Map<String, Object>> getHistoryData(SelectVisualDto selectVisualDto);
120   -
121   - List<Map<String, Object>> getRealtimeData(SelectVisualDto selectVisualDto);
122   -
123   - List<Map<String, Object>> getAggregateData(SelectVisualDto selectVisualDto);
124   -
125   - List<Map<String, Object>> getLastDataByTags(TagsSelectDao tagsSelectDao);
126   -
127   - @InterceptorIgnore(tenantLine = "true")
128   - Long getHistoryCount(SelectVisualDto selectVisualDto);
129   -}
130 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineQueryMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO;
  4 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
  5 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO;
  6 +import com.baomidou.dynamic.datasource.annotation.DS;
  7 +import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +/**
  14 + * TD 引擎的查询 Mapper
  15 + */
  16 +@Mapper
  17 +@DS("tdengine")
  18 +public interface TdEngineQueryMapper {
  19 +
  20 + /**
  21 + * 根据时间戳查询数据
  22 + *
  23 + * @param selectDO 查询条件
  24 + * @return 查询结果
  25 + */
  26 + List<Map<String, Object>> selectByTimestamp(SelectDO selectDO);
  27 +
  28 + /**
  29 + * 根据时间戳获取数据条数
  30 + *
  31 + * @param selectDO 查询条件
  32 + * @return 数据条数
  33 + */
  34 + Map<String, Long> getCountByTimestamp(SelectDO selectDO);
  35 +
  36 + /**
  37 + * 获取最新数据
  38 + *
  39 + * @param selectDO 查询条件
  40 + * @return 最新数据
  41 + */
  42 + Map<String, Object> getLastData(SelectDO selectDO);
  43 +
  44 + /**
  45 + * 获取历史数据
  46 + *
  47 + * @param selectVisualDO 查询条件
  48 + * @return 历史数据列表
  49 + */
  50 + @InterceptorIgnore(tenantLine = "true")
  51 + List<Map<String, Object>> getHistoryData(SelectVisualDO selectVisualDO);
  52 +
  53 + /**
  54 + * 获取实时数据
  55 + *
  56 + * @param selectVisualDO 查询条件
  57 + * @return 实时数据列表
  58 + */
  59 + List<Map<String, Object>> getRealtimeData(SelectVisualDO selectVisualDO);
  60 +
  61 + /**
  62 + * 获取聚合数据
  63 + *
  64 + * @param selectVisualDO 查询条件
  65 + * @return 聚合数据列表
  66 + */
  67 + List<Map<String, Object>> getAggregateData(SelectVisualDO selectVisualDO);
  68 +
  69 + /**
  70 + * 根据标签获取最新数据
  71 + *
  72 + * @param tagsSelectDO 查询条件
  73 + * @return 最新数据列表
  74 + */
  75 + List<Map<String, Object>> getLastDataByTags(TagsSelectDO tagsSelectDO);
  76 +
  77 + /**
  78 + * 获取历史数据条数
  79 + *
  80 + * @param selectVisualDO 查询条件
  81 + * @return 数据条数
  82 + */
  83 + @InterceptorIgnore(tenantLine = "true")
  84 + Long getHistoryCount(SelectVisualDO selectVisualDO);
  85 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineSuperTableMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
  4 +import com.baomidou.dynamic.datasource.annotation.DS;
  5 +import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +import java.util.List;
  9 +import java.util.Map;
  10 +
  11 +/**
  12 + * TD 引擎的超级表 Mapper
  13 + */
  14 +@Mapper
  15 +@DS("tdengine")
  16 +public interface TdEngineSuperTableMapper {
  17 +
  18 + /**
  19 + * 创建超级表
  20 + * SQL:CREATE STABLE [IF NOT EXISTS] stb_name (create_definition [, create_definition] ...) TAGS (create_definition [, create_definition] ...) [table_options];
  21 + *
  22 + * @param superTable 超级表信息
  23 + * dataBaseName 数据库名称
  24 + * superTableName 超级表名称
  25 + * columns 列信息
  26 + * tags 标签信息
  27 + */
  28 + @InterceptorIgnore(tenantLine = "true")
  29 + void createSuperTable(TdTableDO superTable);
  30 +
  31 + /**
  32 + * 查看超级表 - 显示当前数据库下的所有超级表信息
  33 + * SQL:SHOW STABLES [LIKE tb_name_wildcard];
  34 + *
  35 + * @param superTable 超级表信息
  36 + * dataBaseName 数据库名称
  37 + * superTableName 超级表名称
  38 + */
  39 + @InterceptorIgnore(tenantLine = "true")
  40 + List<Map<String, Object>> showSuperTables(TdTableDO superTable);
  41 +
  42 + /**
  43 + * 查看超级表 - 获取超级表的结构信息
  44 + * SQL:DESCRIBE [db_name.]stb_name;
  45 + *
  46 + * @param superTable 超级表信息
  47 + * dataBaseName 数据库名称
  48 + * superTableName 超级表名称
  49 + */
  50 + @InterceptorIgnore(tenantLine = "true")
  51 + List<Map<String, Object>> describeSuperTable(TdTableDO superTable);
  52 +
  53 + /**
  54 + * 修改超级表 - 增加列
  55 + * SQL:ALTER STABLE stb_name ADD COLUMN col_name column_type;
  56 + *
  57 + * @param superTable 超级表信息
  58 + * dataBaseName 数据库名称
  59 + * superTableName 超级表名称
  60 + * column 列信息
  61 + */
  62 + @InterceptorIgnore(tenantLine = "true")
  63 + void addColumnForSuperTable(TdTableDO superTable);
  64 +
  65 + /**
  66 + * 修改超级表 - 删除列
  67 + * SQL:ALTER STABLE stb_name DROP COLUMN col_name;
  68 + *
  69 + * @param superTable 超级表信息
  70 + * dataBaseName 数据库名称
  71 + * superTableName 超级表名称
  72 + * column 列信息
  73 + */
  74 + @InterceptorIgnore(tenantLine = "true")
  75 + void dropColumnForSuperTable(TdTableDO superTable);
  76 +
  77 + /**
  78 + * 修改超级表 - 修改列宽
  79 + * SQL:ALTER STABLE stb_name MODIFY COLUMN col_name data_type(length);
  80 + *
  81 + * @param superTable 超级表信息
  82 + * dataBaseName 数据库名称
  83 + * superTableName 超级表名称
  84 + * column 列信息
  85 + */
  86 + @InterceptorIgnore(tenantLine = "true")
  87 + void modifyColumnWidthForSuperTable(TdTableDO superTable);
  88 +
  89 +
  90 + /**
  91 + * 修改超级表 - 为超级表添加标签
  92 + *
  93 + * @param superTable 超级表信息
  94 + * dataBaseName 数据库名称
  95 + * superTableName 超级表名称
  96 + * tag 标签信息
  97 + */
  98 + @InterceptorIgnore(tenantLine = "true")
  99 + void addTagForSuperTable(TdTableDO superTable);
  100 +
  101 + /**
  102 + * 修改超级表 - 为超级表删除标签
  103 + *
  104 + * @param superTable 超级表信息
  105 + * dataBaseName 数据库名称
  106 + * superTableName 超级表名称
  107 + * tag 标签信息
  108 + */
  109 + @InterceptorIgnore(tenantLine = "true")
  110 + void dropTagForSuperTable(TdTableDO superTable);
  111 +}
0 112 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineTableMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
  4 +import com.baomidou.dynamic.datasource.annotation.DS;
  5 +import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +/**
  9 + * TD 引擎的表 Mapper
  10 + */
  11 +@Mapper
  12 +@DS("tdengine")
  13 +public interface TdEngineTableMapper {
  14 +
  15 + /**
  16 + * 创建子表 - 创建子表
  17 + * SQL:CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);
  18 + *
  19 + * @param table 表信息
  20 + * dataBaseName 数据库名称
  21 + * superTableName 超级表名称
  22 + * tableName 子表名称
  23 + * tags TAG 字段
  24 + */
  25 + @InterceptorIgnore(tenantLine = "true")
  26 + void createTable(TdTableDO table);
  27 +
  28 + /**
  29 + * 创建子表 - 创建子表并指定标签的值
  30 + * SQL:CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...);
  31 + *
  32 + * @param table 表信息
  33 + * dataBaseName 数据库名称
  34 + * superTableName 超级表名称
  35 + * tableName 子表名称
  36 + * tags TAG 字段
  37 + */
  38 + @InterceptorIgnore(tenantLine = "true")
  39 + void createTableWithTags(TdTableDO table);
  40 +
  41 +}
... ...
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;
6 6 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataReqVO;
7 7 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
8 8 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
  9 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
9 10 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage;
10 11 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
11 12 import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
12   -import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineMapper;
13   -import cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto;
14 13 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
15 14 import cn.iocoder.yudao.module.iot.service.tdengine.IotThingModelMessageService;
  15 +import cn.iocoder.yudao.module.iot.service.tdengine.TdEngineQueryService;
16 16 import cn.iocoder.yudao.module.iot.service.thinkmodelfunction.IotThinkModelFunctionService;
17 17 import jakarta.annotation.Resource;
18 18 import jakarta.validation.Valid;
... ... @@ -39,12 +39,11 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
39 39 private IotThingModelMessageService thingModelMessageService;
40 40 @Resource
41 41 private IotThinkModelFunctionService thinkModelFunctionService;
42   -
43 42 @Resource
44   - private DeviceDataRedisDAO deviceDataRedisDAO;
  43 + private TdEngineQueryService tdEngineQueryService;
45 44  
46 45 @Resource
47   - private TdEngineMapper tdEngineMapper;
  46 + private DeviceDataRedisDAO deviceDataRedisDAO;
48 47  
49 48 @Override
50 49 public void saveDeviceData(String productKey, String deviceName, String message) {
... ... @@ -112,18 +111,18 @@ public class IotDeviceDataServiceImpl implements IotDeviceDataService {
112 111 // 1. 获取设备信息
113 112 IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
114 113 // 2. 获取设备属性历史数据
115   - SelectVisualDto selectVisualDto = new SelectVisualDto();
116   - selectVisualDto.setDataBaseName(getDatabaseName());
117   - selectVisualDto.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()));
118   - selectVisualDto.setFieldName(deviceDataReqVO.getIdentifier());
119   - selectVisualDto.setStartTime(DateUtil.date(deviceDataReqVO.getTimes()[0].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime());
120   - selectVisualDto.setEndTime(DateUtil.date(deviceDataReqVO.getTimes()[1].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime());
  114 + SelectVisualDO selectVisualDO = new SelectVisualDO();
  115 + selectVisualDO.setDataBaseName(getDatabaseName());
  116 + selectVisualDO.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()));
  117 + selectVisualDO.setFieldName(deviceDataReqVO.getIdentifier());
  118 + selectVisualDO.setStartTime(DateUtil.date(deviceDataReqVO.getTimes()[0].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime());
  119 + selectVisualDO.setEndTime(DateUtil.date(deviceDataReqVO.getTimes()[1].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime());
121 120 Map<String, Object> params = new HashMap<>();
122 121 params.put("rows", deviceDataReqVO.getPageSize());
123 122 params.put("page", (deviceDataReqVO.getPageNo() - 1) * deviceDataReqVO.getPageSize());
124   - selectVisualDto.setParams(params);
125   - pageResult.setList(tdEngineMapper.getHistoryData(selectVisualDto));
126   - pageResult.setTotal(tdEngineMapper.getHistoryCount(selectVisualDto));
  123 + selectVisualDO.setParams(params);
  124 + pageResult.setList(tdEngineQueryService.getHistoryData(selectVisualDO));
  125 + pageResult.setTotal(tdEngineQueryService.getHistoryCount(selectVisualDO));
127 126 return pageResult;
128 127 }
129 128  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotDbStructureDataServiceImpl.java deleted
1   -package cn.iocoder.yudao.module.iot.service.tdengine;
2   -
3   -import cn.hutool.core.bean.BeanUtil;
4   -import cn.hutool.core.collection.CollUtil;
5   -import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty;
6   -import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelRespVO;
7   -import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
8   -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser;
9   -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
10   -import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
11   -import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
12   -import jakarta.annotation.Resource;
13   -import lombok.extern.slf4j.Slf4j;
14   -import org.springframework.beans.factory.annotation.Value;
15   -import org.springframework.stereotype.Service;
16   -
17   -import java.util.*;
18   -import java.util.stream.Collectors;
19   -
20   -@Service
21   -@Slf4j
22   -public class IotDbStructureDataServiceImpl implements IotDbStructureDataService {
23   -
24   - @Resource
25   - private IotTdEngineService iotTdEngineService;
26   -
27   - @Value("${spring.datasource.dynamic.datasource.tdengine.url}")
28   - private String url;
29   -
30   - @Override
31   - public void createSuperTable(ThingModelRespVO thingModel, Integer deviceType) {
32   - // 1. 解析物模型,获得字段列表
33   - List<TdFieldDO> schemaFields = new ArrayList<>();
34   - schemaFields.add(TdFieldDO.builder()
35   - .fieldName("time")
36   - .dataType("TIMESTAMP")
37   - .build());
38   - schemaFields.addAll(FieldParser.parse(thingModel));
39   -
40   - // 3. 设置超级表的标签
41   - List<TdFieldDO> tagsFields = Arrays.asList(
42   - TdFieldDO.builder().fieldName("product_key").dataType("NCHAR").dataLength(64).build(),
43   - TdFieldDO.builder().fieldName("device_key").dataType("NCHAR").dataLength(64).build(),
44   - TdFieldDO.builder().fieldName("device_name").dataType("NCHAR").dataLength(64).build(),
45   - TdFieldDO.builder().fieldName("device_type").dataType("INT").build()
46   - );
47   -
48   - // 4. 获取超级表的名称
49   - String superTableName = getProductPropertySTableName(deviceType, thingModel.getProductKey());
50   -
51   - // 5. 创建超级表
52   - String dataBaseName = getDatabaseName();
53   - iotTdEngineService.createSuperTable(schemaFields, tagsFields, dataBaseName, superTableName);
54   - }
55   -
56   - @Override
57   - public void updateSuperTable(ThingModelRespVO thingModel, Integer deviceType) {
58   - try {
59   - String tbName = getProductPropertySTableName(deviceType, thingModel.getProductKey());
60   - List<TdFieldDO> oldFields = getTableFields(tbName);
61   - List<TdFieldDO> newFields = FieldParser.parse(thingModel);
62   -
63   - updateTableFields(tbName, oldFields, newFields);
64   - } catch (Exception e) {
65   - log.error("更新物模型超级表失败", e);
66   - }
67   - }
68   -
69   - // 获取表字段
70   - private List<TdFieldDO> getTableFields(String tableName) {
71   - List<TdFieldDO> fields = new ArrayList<>();
72   - // 获取超级表的描述信息
73   - List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(getDatabaseName(), tableName);
74   - if (maps != null) {
75   - // 过滤掉 note 字段为 TAG 的记录和 time 字段
76   - List<Map<String, Object>> filteredMaps = maps.stream()
77   - .filter(map -> !"TAG".equals(map.get("note")))
78   - .filter(map -> !"time".equals(map.get("field")))
79   - .toList();
80   - // 解析字段信息
81   - fields = FieldParser.parse(filteredMaps.stream()
82   - .map(map -> List.of(map.get("field"), map.get("type"), map.get("length")))
83   - .collect(Collectors.toList()));
84   - }
85   - return fields;
86   - }
87   -
88   - // 更新表字段
89   - private void updateTableFields(String tableName, List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
90   - // 获取新增字段
91   - List<TdFieldDO> addFields = getAddFields(oldFields, newFields);
92   - // 获取修改字段
93   - List<TdFieldDO> modifyFields = getModifyFields(oldFields, newFields);
94   - // 获取删除字段
95   - List<TdFieldDO> dropFields = getDropFields(oldFields, newFields);
96   -
97   - String dataBaseName = getDatabaseName();
98   - // 添加新增字段
99   - if (CollUtil.isNotEmpty(addFields)) {
100   - iotTdEngineService.addColumnForSuperTable(dataBaseName, tableName, addFields);
101   - }
102   - // 删除旧字段
103   - if (CollUtil.isNotEmpty(dropFields)) {
104   - iotTdEngineService.dropColumnForSuperTable(dataBaseName, tableName, dropFields);
105   - }
106   - // 修改字段(先删除再添加)
107   - if (CollUtil.isNotEmpty(modifyFields)) {
108   - iotTdEngineService.dropColumnForSuperTable(dataBaseName, tableName, modifyFields);
109   - iotTdEngineService.addColumnForSuperTable(dataBaseName, tableName, modifyFields);
110   - }
111   - }
112   -
113   - // 获取新增字段
114   - private List<TdFieldDO> getAddFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
115   - Set<String> oldFieldNames = oldFields.stream()
116   - .map(TdFieldDO::getFieldName)
117   - .collect(Collectors.toSet());
118   - return newFields.stream()
119   - .filter(f -> !oldFieldNames.contains(f.getFieldName()))
120   - .collect(Collectors.toList());
121   - }
122   -
123   - // 获取修改字段
124   - private List<TdFieldDO> getModifyFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
125   - Map<String, TdFieldDO> oldFieldMap = oldFields.stream()
126   - .collect(Collectors.toMap(TdFieldDO::getFieldName, f -> f));
127   -
128   - return newFields.stream()
129   - .filter(f -> {
130   - TdFieldDO oldField = oldFieldMap.get(f.getFieldName());
131   - return oldField != null &&
132   - (!oldField.getDataType().equals(f.getDataType()) ||
133   - !Objects.equals(oldField.getDataLength(), f.getDataLength()));
134   - })
135   - .collect(Collectors.toList());
136   - }
137   -
138   - // 获取删除字段
139   - private List<TdFieldDO> getDropFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
140   - Set<String> newFieldNames = newFields.stream()
141   - .map(TdFieldDO::getFieldName)
142   - .collect(Collectors.toSet());
143   - return oldFields.stream()
144   - .filter(f -> !"time".equals(f.getFieldName()) && !"device_id".equals(f.getFieldName()))
145   - .filter(f -> !newFieldNames.contains(f.getFieldName()))
146   - .collect(Collectors.toList());
147   - }
148   -
149   - @Override
150   - public void createSuperTableDataModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList) {
151   - ThingModelRespVO thingModel = buildThingModel(product, functionList);
152   -
153   - if (thingModel.getModel() == null || CollUtil.isEmpty(thingModel.getModel().getProperties())) {
154   - log.warn("物模型属性列表为空,不创建超级表");
155   - return;
156   - }
157   -
158   - String superTableName = getProductPropertySTableName(product.getDeviceType(), product.getProductKey());
159   - String dataBaseName = getDatabaseName();
160   - Integer tableExists = iotTdEngineService.checkSuperTableExists(dataBaseName, superTableName);
161   -
162   - if (tableExists != null && tableExists > 0) {
163   - updateSuperTable(thingModel, product.getDeviceType());
164   - } else {
165   - createSuperTable(thingModel, product.getDeviceType());
166   - }
167   - }
168   -
169   - private ThingModelRespVO buildThingModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList) {
170   - ThingModelRespVO thingModel = new ThingModelRespVO();
171   - thingModel.setId(product.getId());
172   - thingModel.setProductKey(product.getProductKey());
173   -
174   - ThingModelRespVO.Model model = new ThingModelRespVO.Model();
175   - List<ThingModelProperty> properties = functionList.stream()
176   - .filter(function -> IotProductFunctionTypeEnum.PROPERTY.equals(
177   - IotProductFunctionTypeEnum.valueOfType(function.getType())))
178   - .map(this::buildThingModelProperty)
179   - .collect(Collectors.toList());
180   -
181   - model.setProperties(properties);
182   - thingModel.setModel(model);
183   -
184   - return thingModel;
185   - }
186   -
187   - private ThingModelProperty buildThingModelProperty(IotThinkModelFunctionDO function) {
188   - ThingModelProperty property = BeanUtil.copyProperties(function, ThingModelProperty.class);
189   - property.setDataType(function.getProperty().getDataType());
190   - return property;
191   - }
192   -
193   - private String getDatabaseName() {
194   - return url.substring(url.lastIndexOf("/") + 1);
195   - }
196   -
197   - static String getProductPropertySTableName(Integer deviceType, String productKey) {
198   - return switch (deviceType) {
199   - case 1 -> String.format("gateway_sub_%s", productKey).toLowerCase();
200   - case 2 -> String.format("gateway_%s", productKey).toLowerCase();
201   - default -> String.format("device_%s", productKey).toLowerCase();
202   - };
203   - }
204   -
205   -}
206 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotDbStructureDataService.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotSuperTableService.java
1 1 package cn.iocoder.yudao.module.iot.service.tdengine;
2 2  
3 3  
4   -import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelRespVO;
5 4 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
6 5 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
7 6  
8 7 import java.util.List;
9 8  
10 9 /**
11   - * 数据结构接口
  10 + * IoT 超级表服务,负责根据物模型创建和更新超级表,以及创建超级表的子表等操作。
12 11 */
13   -public interface IotDbStructureDataService {
14   -
15   - /**
16   - * 创建物模型定义
17   - */
18   - void createSuperTable(ThingModelRespVO thingModel, Integer deviceType);
19   -
20   - /**
21   - * 更新物模型定义
22   - */
23   - void updateSuperTable(ThingModelRespVO thingModel, Integer deviceType);
  12 +public interface IotSuperTableService {
24 13  
25 14 /**
26 15 * 创建超级表数据模型
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotSuperTableServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.tdengine;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.hutool.core.collection.CollUtil;
  5 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelRespVO;
  7 +import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
  8 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser;
  9 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
  10 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
  11 +import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
  12 +import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
  13 +import jakarta.annotation.Resource;
  14 +import lombok.extern.slf4j.Slf4j;
  15 +import org.springframework.beans.factory.annotation.Value;
  16 +import org.springframework.stereotype.Service;
  17 +
  18 +import java.util.*;
  19 +import java.util.stream.Collectors;
  20 +
  21 +/**
  22 + * IoT 超级表服务实现类,负责根据物模型创建和更新超级表,以及创建超级表的子表等操作。
  23 + */
  24 +@Service
  25 +@Slf4j
  26 +public class IotSuperTableServiceImpl implements IotSuperTableService {
  27 +
  28 + @Resource
  29 + private TdEngineSuperTableService tdEngineSuperTableService;
  30 +
  31 + @Value("${spring.datasource.dynamic.datasource.tdengine.url}")
  32 + private String url;
  33 +
  34 + @Override
  35 + public void createSuperTableDataModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList) {
  36 + ThingModelRespVO thingModel = buildThingModel(product, functionList);
  37 +
  38 + if (thingModel.getModel() == null || CollUtil.isEmpty(thingModel.getModel().getProperties())) {
  39 + log.warn("物模型属性列表为空,不创建超级表");
  40 + return;
  41 + }
  42 +
  43 + String superTableName = getSuperTableName(product.getDeviceType(), product.getProductKey());
  44 + String databaseName = getDatabaseName();
  45 + Integer tableExists = tdEngineSuperTableService.checkSuperTableExists(new TdTableDO(databaseName, superTableName));
  46 +
  47 + if (tableExists != null && tableExists > 0) {
  48 + updateSuperTable(thingModel, product.getDeviceType());
  49 + } else {
  50 + createSuperTable(thingModel, product.getDeviceType());
  51 + }
  52 + }
  53 +
  54 + /**
  55 + * 创建超级表
  56 + */
  57 + private void createSuperTable(ThingModelRespVO thingModel, Integer deviceType) {
  58 + // 解析物模型,获取字段列表
  59 + List<TdFieldDO> schemaFields = new ArrayList<>();
  60 + schemaFields.add(TdFieldDO.builder()
  61 + .fieldName("time")
  62 + .dataType("TIMESTAMP")
  63 + .build());
  64 + schemaFields.addAll(FieldParser.parse(thingModel));
  65 +
  66 + // 设置超级表的标签
  67 + List<TdFieldDO> tagsFields = List.of(
  68 + TdFieldDO.builder().fieldName("product_key").dataType("NCHAR").dataLength(64).build(),
  69 + TdFieldDO.builder().fieldName("device_key").dataType("NCHAR").dataLength(64).build(),
  70 + TdFieldDO.builder().fieldName("device_name").dataType("NCHAR").dataLength(64).build(),
  71 + TdFieldDO.builder().fieldName("device_type").dataType("INT").build()
  72 + );
  73 +
  74 + // 获取超级表的名称和数据库名称
  75 + String superTableName = getSuperTableName(deviceType, thingModel.getProductKey());
  76 + String databaseName = getDatabaseName();
  77 +
  78 + // 创建超级表
  79 + tdEngineSuperTableService.createSuperTable(new TdTableDO(databaseName, superTableName, schemaFields, tagsFields));
  80 + }
  81 +
  82 + /**
  83 + * 更新超级表
  84 + */
  85 + private void updateSuperTable(ThingModelRespVO thingModel, Integer deviceType) {
  86 + String superTableName = getSuperTableName(deviceType, thingModel.getProductKey());
  87 + try {
  88 + List<TdFieldDO> oldFields = getTableFields(superTableName);
  89 + List<TdFieldDO> newFields = FieldParser.parse(thingModel);
  90 +
  91 + updateTableFields(superTableName, oldFields, newFields);
  92 + } catch (Exception e) {
  93 + log.error("更新物模型超级表失败: {}", e.getMessage(), e);
  94 + }
  95 + }
  96 +
  97 + /**
  98 + * 获取表的字段信息
  99 + */
  100 + private List<TdFieldDO> getTableFields(String tableName) {
  101 + List<Map<String, Object>> tableDescription = tdEngineSuperTableService.describeSuperTable(new TdTableDO(getDatabaseName(), tableName));
  102 + if (CollUtil.isEmpty(tableDescription)) {
  103 + return Collections.emptyList();
  104 + }
  105 +
  106 + return tableDescription.stream()
  107 + .filter(map -> !"TAG".equals(map.get("note")))
  108 + .filter(map -> !"time".equals(map.get("field")))
  109 + .map(map -> TdFieldDO.builder()
  110 + .fieldName((String) map.get("field"))
  111 + .dataType((String) map.get("type"))
  112 + .dataLength((Integer) map.get("length"))
  113 + .build())
  114 + .collect(Collectors.toList());
  115 + }
  116 +
  117 + /**
  118 + * 更新表的字段,包括新增、修改和删除字段
  119 + */
  120 + private void updateTableFields(String tableName, List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
  121 + String databaseName = getDatabaseName();
  122 +
  123 + // 获取新增、修改、删除的字段
  124 + List<TdFieldDO> addFields = getAddFields(oldFields, newFields);
  125 + List<TdFieldDO> modifyFields = getModifyFields(oldFields, newFields);
  126 + List<TdFieldDO> dropFields = getDropFields(oldFields, newFields);
  127 +
  128 + // 添加新增字段
  129 + if (CollUtil.isNotEmpty(addFields)) {
  130 + tdEngineSuperTableService.addColumnsForSuperTable(TdTableDO.builder()
  131 + .dataBaseName(databaseName)
  132 + .superTableName(tableName)
  133 + .columns(addFields)
  134 + .build());
  135 + }
  136 + // 删除旧字段
  137 + if (CollUtil.isNotEmpty(dropFields)) {
  138 + tdEngineSuperTableService.dropColumnsForSuperTable(TdTableDO.builder()
  139 + .dataBaseName(databaseName)
  140 + .superTableName(tableName)
  141 + .columns(dropFields)
  142 + .build());
  143 + }
  144 + // 修改字段(先删除再添加)
  145 + if (CollUtil.isNotEmpty(modifyFields)) {
  146 + tdEngineSuperTableService.dropColumnsForSuperTable(TdTableDO.builder()
  147 + .dataBaseName(databaseName)
  148 + .superTableName(tableName)
  149 + .columns(modifyFields)
  150 + .build());
  151 + tdEngineSuperTableService.addColumnsForSuperTable(TdTableDO.builder()
  152 + .dataBaseName(databaseName)
  153 + .superTableName(tableName)
  154 + .columns(addFields)
  155 + .build());
  156 + }
  157 + }
  158 +
  159 + /**
  160 + * 获取需要新增的字段
  161 + */
  162 + private List<TdFieldDO> getAddFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
  163 + Set<String> oldFieldNames = oldFields.stream()
  164 + .map(TdFieldDO::getFieldName)
  165 + .collect(Collectors.toSet());
  166 + return newFields.stream()
  167 + .filter(f -> !oldFieldNames.contains(f.getFieldName()))
  168 + .collect(Collectors.toList());
  169 + }
  170 +
  171 + /**
  172 + * 获取需要修改的字段
  173 + */
  174 + private List<TdFieldDO> getModifyFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
  175 + Map<String, TdFieldDO> oldFieldMap = oldFields.stream()
  176 + .collect(Collectors.toMap(TdFieldDO::getFieldName, f -> f));
  177 +
  178 + return newFields.stream()
  179 + .filter(f -> {
  180 + TdFieldDO oldField = oldFieldMap.get(f.getFieldName());
  181 + return oldField != null && (
  182 + !oldField.getDataType().equals(f.getDataType()) ||
  183 + !Objects.equals(oldField.getDataLength(), f.getDataLength())
  184 + );
  185 + })
  186 + .collect(Collectors.toList());
  187 + }
  188 +
  189 + /**
  190 + * 获取需要删除的字段
  191 + */
  192 + private List<TdFieldDO> getDropFields(List<TdFieldDO> oldFields, List<TdFieldDO> newFields) {
  193 + Set<String> newFieldNames = newFields.stream()
  194 + .map(TdFieldDO::getFieldName)
  195 + .collect(Collectors.toSet());
  196 + return oldFields.stream()
  197 + .filter(f -> !"time".equals(f.getFieldName()))
  198 + .filter(f -> !newFieldNames.contains(f.getFieldName()))
  199 + .collect(Collectors.toList());
  200 + }
  201 +
  202 + /**
  203 + * 构建物模型
  204 + */
  205 + private ThingModelRespVO buildThingModel(IotProductDO product, List<IotThinkModelFunctionDO> functionList) {
  206 + ThingModelRespVO thingModel = new ThingModelRespVO();
  207 + thingModel.setId(product.getId());
  208 + thingModel.setProductKey(product.getProductKey());
  209 +
  210 + List<ThingModelProperty> properties = functionList.stream()
  211 + .filter(function -> IotProductFunctionTypeEnum.PROPERTY.equals(
  212 + IotProductFunctionTypeEnum.valueOfType(function.getType())))
  213 + .map(this::buildThingModelProperty)
  214 + .collect(Collectors.toList());
  215 +
  216 + ThingModelRespVO.Model model = new ThingModelRespVO.Model();
  217 + model.setProperties(properties);
  218 + thingModel.setModel(model);
  219 +
  220 + return thingModel;
  221 + }
  222 +
  223 + /**
  224 + * 构建物模型属性
  225 + */
  226 + private ThingModelProperty buildThingModelProperty(IotThinkModelFunctionDO function) {
  227 + ThingModelProperty property = BeanUtil.copyProperties(function, ThingModelProperty.class);
  228 + property.setDataType(function.getProperty().getDataType());
  229 + return property;
  230 + }
  231 +
  232 + /**
  233 + * 获取数据库名称
  234 + */
  235 + private String getDatabaseName() {
  236 + int index = url.lastIndexOf("/");
  237 + return index != -1 ? url.substring(index + 1) : url;
  238 + }
  239 +
  240 + /**
  241 + * 获取超级表名称
  242 + */
  243 + private String getSuperTableName(Integer deviceType, String productKey) {
  244 + String prefix = switch (deviceType) {
  245 + case 1 -> "gateway_sub_";
  246 + case 2 -> "gateway_";
  247 + default -> "device_";
  248 + };
  249 + return (prefix + productKey).toLowerCase();
  250 + }
  251 +
  252 +}
0 253 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotTdEngineService.java deleted
1   -package cn.iocoder.yudao.module.iot.service.tdengine;
2   -
3   -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO;
4   -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
5   -import cn.iocoder.yudao.module.iot.domain.SelectDto;
6   -import cn.iocoder.yudao.module.iot.domain.TagsSelectDao;
7   -import cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto;
8   -
9   -import java.util.List;
10   -import java.util.Map;
11   -
12   -/**
13   - * TdEngineService
14   - */
15   -public interface IotTdEngineService {
16   -
17   - /**
18   - * 创建数据库
19   - *
20   - * @param dataBaseName 数据库名称
21   - * @throws Exception 异常
22   - */
23   - void createDateBase(String dataBaseName) throws Exception;
24   -
25   - /**
26   - * 创建超级表
27   - *
28   - * @param schemaFields schema字段
29   - * @param tagsFields tags字段
30   - * @param superTableName 超级表名称
31   - */
32   - void createSuperTable(List<TdFieldDO> schemaFields, List<TdFieldDO> tagsFields, String dataBaseName, String superTableName);
33   -
34   - /**
35   - * 检查超级表是否存在
36   - */
37   - Integer checkSuperTableExists(String dataBaseName, String superTableName);
38   -
39   -
40   - /**
41   - * 获取超级表的结构信息
42   - */
43   - List<Map<String, Object>> describeSuperTable(String dataBaseName, String superTableName);
44   -
45   - /**
46   - * 为超级表添加列
47   - *
48   - * @param dataBaseName 数据库名称
49   - * @param superTableName 超级表名称
50   - * @param fieldsVo 字段信息
51   - */
52   - void addColumnForSuperTable(String dataBaseName, String superTableName, List<TdFieldDO> fieldsVo);
53   -
54   - /**
55   - * 为超级表删除列
56   - *
57   - * @param dataBaseName 数据库名称
58   - * @param superTableName 超级表名称
59   - * @param fieldsVo 字段信息
60   - */
61   - void dropColumnForSuperTable(String dataBaseName, String superTableName, List<TdFieldDO> fieldsVo);
62   -
63   - /**
64   - * 为超级表添加tag
65   - */
66   - Long getCountByTimesTamp(SelectDto selectDto) throws Exception;
67   -
68   -
69   - /**
70   - * 创建表
71   - *
72   - * @param tableDto 表信息
73   - */
74   - void createTable(TableDO tableDto);
75   -
76   - /**
77   - * 插入数据
78   - *
79   - * @param tableDto 表信息
80   - */
81   - void insertData(TableDO tableDto);
82   -
83   - /**
84   - * 根据时间戳查询数据
85   - *
86   - * @param selectDto 查询条件
87   - * @return 数据
88   - * @throws Exception 异常
89   - */
90   - List<Map<String, Object>> selectByTimesTamp(SelectDto selectDto) throws Exception;
91   -
92   - /**
93   - * 初始化超级表
94   - *
95   - * @param msg 消息
96   - * @throws Exception 异常
97   - */
98   - void initSTableFrame(String msg) throws Exception;
99   -
100   - /**
101   - * 获取最新数据
102   - *
103   - * @param selectDto 查询条件
104   - * @return 数据
105   - * @throws Exception 异常
106   - */
107   - Map<String, Object> getLastData(SelectDto selectDto) throws Exception;
108   -
109   - /**
110   - * 根据tag查询最新数据
111   - *
112   - * @param tagsSelectDao 查询条件
113   - * @return 数据
114   - */
115   - Map<String, Map<String, Object>> getLastDataByTags(TagsSelectDao tagsSelectDao);
116   -
117   - /**
118   - * 获取历史数据
119   - *
120   - * @param selectVisualDto 查询条件
121   - * @return 数据
122   - */
123   - List<Map<String, Object>> getHistoryData(SelectVisualDto selectVisualDto);
124   -
125   - /**
126   - * 获取实时数据
127   - *
128   - * @param selectVisualDto 查询条件
129   - * @return 数据
130   - */
131   - List<Map<String, Object>> getRealtimeData(SelectVisualDto selectVisualDto);
132   -
133   - /**
134   - * 获取聚合数据
135   - *
136   - * @param selectVisualDto 查询条件
137   - * @return 数据
138   - */
139   - List<Map<String, Object>> getAggregateData(SelectVisualDto selectVisualDto);
140   -
141   -
142   -}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotTdEngineServiceImpl.java deleted
1   -package cn.iocoder.yudao.module.iot.service.tdengine;
2   -
3   -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO;
4   -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
5   -import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineMapper;
6   -import cn.iocoder.yudao.module.iot.domain.SelectDto;
7   -import cn.iocoder.yudao.module.iot.domain.TagsSelectDao;
8   -import cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto;
9   -import jakarta.annotation.Resource;
10   -import lombok.extern.slf4j.Slf4j;
11   -import org.springframework.stereotype.Service;
12   -
13   -import java.util.List;
14   -import java.util.Map;
15   -
16   -@Service
17   -@Slf4j
18   -public class IotTdEngineServiceImpl implements IotTdEngineService {
19   -
20   - @Resource
21   - private TdEngineMapper tdEngineMapper;
22   -
23   - @Override
24   - public void createDateBase(String dataBaseName) {
25   - tdEngineMapper.createDatabase(dataBaseName);
26   - }
27   -
28   - @Override
29   - public void createSuperTable(List<TdFieldDO> schemaFields, List<TdFieldDO> tagsFields, String dataBaseName, String superTableName) {
30   - tdEngineMapper.createSuperTable(schemaFields, tagsFields, dataBaseName, superTableName);
31   - }
32   -
33   - @Override
34   - public void createTable(TableDO tableDto) {
35   - tdEngineMapper.createTable(tableDto);
36   - }
37   -
38   - @Override
39   - public void insertData(TableDO tableDto) {
40   - tdEngineMapper.insertData(tableDto);
41   - }
42   -
43   - @Override
44   - public List<Map<String, Object>> selectByTimesTamp(SelectDto selectDto) {
45   - return List.of();
46   - }
47   -
48   - @Override
49   - public void addColumnForSuperTable(String dataBaseName,String superTableName, List<TdFieldDO> fields) {
50   - for (TdFieldDO field : fields) {
51   - tdEngineMapper.addColumnForSuperTable(dataBaseName,superTableName, field);
52   - }
53   - }
54   -
55   - @Override
56   - public void dropColumnForSuperTable(String dataBaseName,String superTableName, List<TdFieldDO> fields) {
57   - for (TdFieldDO field : fields) {
58   - tdEngineMapper.dropColumnForSuperTable(dataBaseName,superTableName, field);
59   - }
60   - }
61   -
62   - @Override
63   - public Long getCountByTimesTamp(SelectDto selectDto) {
64   - return 0L;
65   - }
66   -
67   - @Override
68   - public void initSTableFrame(String msg) {
69   -
70   - }
71   -
72   - @Override
73   - public Map<String, Object> getLastData(SelectDto selectDto) {
74   - return Map.of();
75   - }
76   -
77   - @Override
78   - public Map<String, Map<String, Object>> getLastDataByTags(TagsSelectDao tagsSelectDao) {
79   - return Map.of();
80   - }
81   -
82   - @Override
83   - public List<Map<String, Object>> getHistoryData(SelectVisualDto selectVisualDto) {
84   - return List.of();
85   - }
86   -
87   - @Override
88   - public List<Map<String, Object>> getRealtimeData(SelectVisualDto selectVisualDto) {
89   - return List.of();
90   - }
91   -
92   - @Override
93   - public List<Map<String, Object>> getAggregateData(SelectVisualDto selectVisualDto) {
94   - return List.of();
95   - }
96   -
97   - @Override
98   - public Integer checkSuperTableExists(String dataBaseName, String superTableName) {
99   - List<Map<String, Object>> results = tdEngineMapper.showSuperTables(dataBaseName, superTableName);
100   - return results == null || results.isEmpty() ? 0 : results.size();
101   - }
102   -
103   - @Override
104   - public List<Map<String, Object>> describeSuperTable(String dataBaseName, String superTableName) {
105   - return tdEngineMapper.describeSuperTable(dataBaseName, superTableName);
106   - }
107   -}
108 0 \ No newline at end of file
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 {
11 11 /**
12 12 * 保存物模型消息
13 13 *
14   - * @param device 设备
  14 + * @param device 设备
15 15 * @param thingModelMessage 物模型消息
16 16 */
17   - void saveThingModelMessage(IotDeviceDO device,ThingModelMessage thingModelMessage);
  17 + void saveThingModelMessage(IotDeviceDO device, ThingModelMessage thingModelMessage);
18 18 }
19 19 \ No newline at end of file
... ...
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
6 6 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
7 7 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO;
8 8 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser;
9   -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TableDO;
10 9 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
  10 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
11 11 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage;
12 12 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
13 13 import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
... ... @@ -23,6 +23,9 @@ import org.springframework.stereotype.Service;
23 23 import java.util.*;
24 24 import java.util.stream.Collectors;
25 25  
  26 +/**
  27 + * 物模型消息 Service 实现类
  28 + */
26 29 @Slf4j
27 30 @Service
28 31 public class IotThingModelMessageServiceImpl implements IotThingModelMessageService {
... ... @@ -35,7 +38,11 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
35 38 @Resource
36 39 private IotDeviceService iotDeviceService;
37 40 @Resource
38   - private IotTdEngineService iotTdEngineService;
  41 + private TdEngineTableService tdEngineTableService;
  42 + @Resource
  43 + private TdEngineSuperTableService tdEngineSuperTableService;
  44 + @Resource
  45 + private TdEngineDataWriterService tdEngineDataWriterService;
39 46  
40 47 @Resource
41 48 private DeviceDataRedisDAO deviceDataRedisDAO;
... ... @@ -90,14 +97,11 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
90 97 return;
91 98 }
92 99  
93   - // 构建并保存设备属性
94   - TableDO tableData = new TableDO();
95   - tableData.setDataBaseName(getDatabaseName());
96   - tableData.setSuperTableName(getProductPropertySTableName(device.getDeviceType(), device.getProductKey()));
97   - tableData.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()));
98   - tableData.setSchemaFieldValues(schemaFieldValues);
99   -
100   - iotTdEngineService.insertData(tableData);
  100 + // 构建并保存设备属性数据
  101 + tdEngineDataWriterService.insertData(TdTableDO.builder().build()
  102 + .setDataBaseName(getDatabaseName())
  103 + .setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()))
  104 + .setColumns(schemaFieldValues));
101 105 }
102 106  
103 107 /**
... ... @@ -135,7 +139,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
135 139 String superTableName = getProductPropertySTableName(deviceType, productKey);
136 140 String dataBaseName = getDatabaseName();
137 141  
138   - List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(dataBaseName, superTableName);
  142 + List<Map<String, Object>> maps = tdEngineSuperTableService.describeSuperTable(new TdTableDO(dataBaseName, superTableName));
139 143 List<TdFieldDO> tagsFieldValues = new ArrayList<>();
140 144  
141 145 if (maps != null) {
... ... @@ -159,13 +163,11 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
159 163  
160 164 // 创建设备数据表
161 165 String tableName = getDeviceTableName(productKey, deviceName);
162   - TableDO tableDto = new TableDO();
163   - tableDto.setDataBaseName(dataBaseName);
164   - tableDto.setSuperTableName(superTableName);
165   - tableDto.setTableName(tableName);
166   - tableDto.setTagsFieldValues(tagsFieldValues);
167   -
168   - iotTdEngineService.createTable(tableDto);
  166 + tdEngineTableService.createTable(TdTableDO.builder().build()
  167 + .setDataBaseName(dataBaseName)
  168 + .setSuperTableName(superTableName)
  169 + .setTableName(tableName)
  170 + .setTags(tagsFieldValues));
169 171 }
170 172  
171 173 /**
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDataWriterService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
  4 +
  5 +/**
  6 + * TD 引擎的数据写入 Service 接口
  7 + */
  8 +public interface TdEngineDataWriterService {
  9 +
  10 + /**
  11 + * 插入数据 - 指定列插入数据
  12 + *
  13 + * @param table 数据
  14 + * dataBaseName 数据库名
  15 + * tableName 表名
  16 + * columns 列
  17 + */
  18 + void insertData(TdTableDO table);
  19 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDataWriterServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
  4 +import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDataWriterMapper;
  5 +import jakarta.annotation.Resource;
  6 +import org.springframework.stereotype.Service;
  7 +
  8 +/**
  9 + * TD 引擎的数据写入 Service 实现类
  10 + */
  11 +@Service
  12 +public class TdEngineDataWriterServiceImpl implements TdEngineDataWriterService {
  13 +
  14 + @Resource
  15 + private TdEngineDataWriterMapper tdEngineDataWriterMapper;
  16 +
  17 + @Override
  18 + public void insertData(TdTableDO table) {
  19 + tdEngineDataWriterMapper.insertData(table);
  20 + }
  21 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDatabaseService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.tdengine;
  2 +
  3 +/**
  4 + * TD 引擎的数据库 Service 接口
  5 + */
  6 +public interface TdEngineDatabaseService {
  7 +
  8 + /**
  9 + * 创建数据库
  10 + *
  11 + * @param dataBaseName 数据库名称
  12 + */
  13 + void createDatabase(String dataBaseName);
  14 +}
0 15 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineDatabaseServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDatabaseMapper;
  4 +import jakarta.annotation.Resource;
  5 +import lombok.extern.slf4j.Slf4j;
  6 +import org.springframework.stereotype.Service;
  7 +
  8 +/**
  9 + * TD 引擎的数据库 Service 实现类
  10 + */
  11 +@Service
  12 +@Slf4j
  13 +public class TdEngineDatabaseServiceImpl implements TdEngineDatabaseService {
  14 +
  15 + @Resource
  16 + private TdEngineDatabaseMapper tdEngineDatabaseMapper;
  17 +
  18 + @Override
  19 + public void createDatabase(String dataBaseName) {
  20 + tdEngineDatabaseMapper.createDatabase(dataBaseName);
  21 + }
  22 +}
0 23 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineQueryService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
  4 +
  5 +import java.util.List;
  6 +import java.util.Map;
  7 +
  8 +/**
  9 + * TD 引擎的查询 Service 接口
  10 + */
  11 +public interface TdEngineQueryService {
  12 +
  13 + /**
  14 + * 获取历史数据
  15 + *
  16 + * @param selectVisualDO 查询条件
  17 + * @return 历史数据列表
  18 + */
  19 + List<Map<String, Object>> getHistoryData(SelectVisualDO selectVisualDO);
  20 +
  21 + /**
  22 + * 获取历史数据条数
  23 + *
  24 + * @param selectVisualDO 查询条件
  25 + * @return 数据条数
  26 + */
  27 + Long getHistoryCount(SelectVisualDO selectVisualDO);
  28 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineQueryServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
  4 +import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineQueryMapper;
  5 +import jakarta.annotation.Resource;
  6 +import org.springframework.stereotype.Service;
  7 +
  8 +import java.util.List;
  9 +import java.util.Map;
  10 +
  11 +@Service
  12 +public class TdEngineQueryServiceImpl implements TdEngineQueryService {
  13 +
  14 + @Resource
  15 + private TdEngineQueryMapper tdEngineQueryMapper;
  16 +
  17 + @Override
  18 + public List<Map<String, Object>> getHistoryData(SelectVisualDO selectVisualDO) {
  19 + return tdEngineQueryMapper.getHistoryData(selectVisualDO);
  20 + }
  21 +
  22 + @Override
  23 + public Long getHistoryCount(SelectVisualDO selectVisualDO) {
  24 + return tdEngineQueryMapper.getHistoryCount(selectVisualDO);
  25 + }
  26 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineSuperTableService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
  4 +
  5 +import java.util.List;
  6 +import java.util.Map;
  7 +
  8 +/**
  9 + * TD 引擎的超级表 Service 接口
  10 + */
  11 +public interface TdEngineSuperTableService {
  12 +
  13 + /**
  14 + * 创建超级表
  15 + *
  16 + * @param superTable 超级表信息
  17 + * dataBaseName 数据库名称
  18 + * superTableName 超级表名称
  19 + * columns 列信息
  20 + * tags 标签信息
  21 + */
  22 + void createSuperTable(TdTableDO superTable);
  23 +
  24 + /**
  25 + * 查看超级表 - 显示当前数据库下的所有超级表信息
  26 + *
  27 + * @param superTable 超级表信息
  28 + * dataBaseName 数据库名称
  29 + * superTableName 超级表名称
  30 + */
  31 +
  32 + List<Map<String, Object>> showSuperTables(TdTableDO superTable);
  33 +
  34 + /**
  35 + * 查看超级表 - 获取超级表的结构信息
  36 + *
  37 + * @param superTable 超级表信息
  38 + * dataBaseName 数据库名称
  39 + * superTableName 超级表名称
  40 + */
  41 + List<Map<String, Object>> describeSuperTable(TdTableDO superTable);
  42 +
  43 + /**
  44 + * 修改超级表 - 增加列
  45 + *
  46 + * @param superTable 超级表信息
  47 + * dataBaseName 数据库名称
  48 + * superTableName 超级表名称
  49 + * column 列信息
  50 + */
  51 + void addColumnForSuperTable(TdTableDO superTable);
  52 +
  53 + /**
  54 + * 修改超级表 - 删除列
  55 + *
  56 + * @param superTable 超级表信息
  57 + * dataBaseName 数据库名称
  58 + * superTableName 超级表名称
  59 + * column 列信息
  60 + */
  61 + void dropColumnForSuperTable(TdTableDO superTable);
  62 +
  63 + /**
  64 + * 修改超级表 - 修改列宽
  65 + *
  66 + * @param superTable 超级表信息
  67 + * dataBaseName 数据库名称
  68 + * superTableName 超级表名称
  69 + * column 列信息
  70 + */
  71 + void modifyColumnWidthForSuperTable(TdTableDO superTable);
  72 +
  73 +
  74 + /**
  75 + * 修改超级表 - 为超级表添加标签
  76 + *
  77 + * @param superTable 超级表信息
  78 + * dataBaseName 数据库名称
  79 + * superTableName 超级表名称
  80 + * tag 标签信息
  81 + */
  82 + void addTagForSuperTable(TdTableDO superTable);
  83 +
  84 + /**
  85 + * 修改超级表 - 为超级表删除标签
  86 + *
  87 + * @param superTable 超级表信息
  88 + * dataBaseName 数据库名称
  89 + * superTableName 超级表名称
  90 + * tag 标签信息
  91 + */
  92 + void dropTagForSuperTable(TdTableDO superTable);
  93 +
  94 + /**
  95 + * 检查超级表是否存在
  96 + *
  97 + * @param superTable 超级表信息
  98 + * dataBaseName 数据库名称
  99 + * superTableName 超级表名称
  100 + * @return 超级表数量
  101 + */
  102 + Integer checkSuperTableExists(TdTableDO superTable);
  103 +
  104 + /**
  105 + * 为超级表添加列
  106 + *
  107 + * @param superTable 超级表信息
  108 + * dataBaseName 数据库名称
  109 + * superTableName 超级表名称
  110 + * columns 列信息
  111 + */
  112 + void addColumnsForSuperTable(TdTableDO superTable);
  113 +
  114 + /**
  115 + * 为超级表删除列
  116 + *
  117 + * @param superTable 超级表信息
  118 + * dataBaseName 数据库名称
  119 + * superTableName 超级表名称
  120 + * columns 列信息
  121 + */
  122 + void dropColumnsForSuperTable(TdTableDO superTable);
  123 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineSuperTableServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO;
  4 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
  5 +import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineSuperTableMapper;
  6 +import jakarta.annotation.Resource;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.springframework.stereotype.Service;
  9 +
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +/**
  14 + * TD 引擎的超级表 Service 实现类
  15 + */
  16 +@Slf4j
  17 +@Service
  18 +public class TdEngineSuperTableServiceImpl implements TdEngineSuperTableService {
  19 +
  20 + @Resource
  21 + private TdEngineSuperTableMapper tdEngineSuperTableMapper;
  22 +
  23 + @Override
  24 + public void createSuperTable(TdTableDO superTable) {
  25 + tdEngineSuperTableMapper.createSuperTable(superTable);
  26 + }
  27 +
  28 + @Override
  29 + public List<Map<String, Object>> showSuperTables(TdTableDO superTable) {
  30 + return tdEngineSuperTableMapper.showSuperTables(superTable);
  31 + }
  32 +
  33 + @Override
  34 + public List<Map<String, Object>> describeSuperTable(TdTableDO superTable) {
  35 + return tdEngineSuperTableMapper.describeSuperTable(superTable);
  36 + }
  37 +
  38 + @Override
  39 + public void addColumnForSuperTable(TdTableDO superTable) {
  40 + tdEngineSuperTableMapper.addColumnForSuperTable(superTable);
  41 + }
  42 +
  43 + @Override
  44 + public void dropColumnForSuperTable(TdTableDO superTable) {
  45 + tdEngineSuperTableMapper.dropColumnForSuperTable(superTable);
  46 + }
  47 +
  48 + @Override
  49 + public void modifyColumnWidthForSuperTable(TdTableDO superTable) {
  50 + tdEngineSuperTableMapper.modifyColumnWidthForSuperTable(superTable);
  51 + }
  52 +
  53 + @Override
  54 + public void addTagForSuperTable(TdTableDO superTable) {
  55 + tdEngineSuperTableMapper.addTagForSuperTable(superTable);
  56 + }
  57 +
  58 + @Override
  59 + public void dropTagForSuperTable(TdTableDO superTable) {
  60 + tdEngineSuperTableMapper.dropTagForSuperTable(superTable);
  61 + }
  62 +
  63 + @Override
  64 + public Integer checkSuperTableExists(TdTableDO superTable) {
  65 + List<Map<String, Object>> results = tdEngineSuperTableMapper.showSuperTables(superTable);
  66 + return results == null || results.isEmpty() ? 0 : results.size();
  67 + }
  68 +
  69 + @Override
  70 + public void addColumnsForSuperTable(TdTableDO superTable) {
  71 + for (TdFieldDO column : superTable.getColumns()) {
  72 + tdEngineSuperTableMapper.addColumnForSuperTable(TdTableDO.builder()
  73 + .dataBaseName(superTable.getDataBaseName())
  74 + .superTableName(superTable.getSuperTableName())
  75 + .column(column)
  76 + .build());
  77 + }
  78 + }
  79 +
  80 + @Override
  81 + public void dropColumnsForSuperTable(TdTableDO superTable) {
  82 + for (TdFieldDO column : superTable.getColumns()) {
  83 + tdEngineSuperTableMapper.dropColumnForSuperTable(TdTableDO.builder()
  84 + .dataBaseName(superTable.getDataBaseName())
  85 + .superTableName(superTable.getSuperTableName())
  86 + .column(column)
  87 + .build());
  88 + }
  89 + }
  90 +}
0 91 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineTableService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
  4 +
  5 +/**
  6 + * TD 引擎的表 Service 接口
  7 + */
  8 +public interface TdEngineTableService {
  9 +
  10 + /**
  11 + * 创建表 - 创建超级表的子表
  12 + *
  13 + * @param table 表信息
  14 + * dataBaseName 数据库名称
  15 + * superTableName 超级表名称
  16 + * tableName 子表名称
  17 + * tags TAG 字段
  18 + */
  19 + void createTable(TdTableDO table);
  20 +
  21 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineTableServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.tdengine;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
  4 +import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineTableMapper;
  5 +import jakarta.annotation.Resource;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.springframework.stereotype.Service;
  8 +
  9 +/**
  10 + * TD 引擎的表 Service 实现类
  11 + */
  12 +@Slf4j
  13 +@Service
  14 +public class TdEngineTableServiceImpl implements TdEngineTableService {
  15 +
  16 + @Resource
  17 + private TdEngineTableMapper tdEngineTableMapper;
  18 +
  19 + @Override
  20 + public void createTable(TdTableDO table) {
  21 + tdEngineTableMapper.createTable(table);
  22 + }
  23 +}
... ...
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 {
75 75 * @param productKey 产品 Key
76 76 * @return 产品物模型列表
77 77 */
78   - List<IotThinkModelFunctionDO> getThinkModelFunctionListByProductKey(String productKey);
  78 + List<IotThinkModelFunctionDO> getThinkModelFunctionListByProductKey(String productKey);
79 79 }
80 80 \ No newline at end of file
... ...
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;
22 22 import cn.iocoder.yudao.module.iot.enums.product.IotProductFunctionTypeEnum;
23 23 import cn.iocoder.yudao.module.iot.enums.product.IotProductStatusEnum;
24 24 import cn.iocoder.yudao.module.iot.service.product.IotProductService;
25   -import cn.iocoder.yudao.module.iot.service.tdengine.IotDbStructureDataService;
  25 +import cn.iocoder.yudao.module.iot.service.tdengine.IotSuperTableService;
26 26 import jakarta.annotation.Resource;
27 27 import lombok.extern.slf4j.Slf4j;
28 28 import org.springframework.stereotype.Service;
... ... @@ -52,7 +52,7 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
52 52 @Resource
53 53 private IotProductService productService;
54 54 @Resource
55   - private IotDbStructureDataService dbStructureDataService;
  55 + private IotSuperTableService dbStructureDataService;
56 56  
57 57 @Override
58 58 @Transactional(rollbackFor = Exception.class)
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDataWriterMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper
  3 + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4 + "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5 +
  6 +<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDataWriterMapper">
  7 +
  8 + <!-- 插入数据 -->
  9 + <insert id="insertData">
  10 + INSERT INTO ${dataBaseName}.${tableName}
  11 + <foreach item="item" collection="columns" separator=","
  12 + open="(" close=")">
  13 + ${item.fieldName}
  14 + </foreach>
  15 + VALUES
  16 + <foreach item="item" collection="columns" separator=","
  17 + open="(" close=")">
  18 + #{item.fieldValue}
  19 + </foreach>
  20 + </insert>
  21 +
  22 +</mapper>
0 23 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDatabaseMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper
  3 + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4 + "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5 +
  6 +<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDatabaseMapper">
  7 +
  8 + <!-- 创建数据库 -->
  9 + <update id="createDatabase" parameterType="String">
  10 + CREATE DATABASE IF NOT EXISTS ${dataBaseName}
  11 + </update>
  12 +
  13 +</mapper>
0 14 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineMapper.xml deleted
1   -<?xml version="1.0" encoding="UTF-8"?>
2   -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3   -
4   -<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineMapper">
5   - <!-- TODO 对 $ 符号有安全要求的话,后期改为接口方式 -->
6   -
7   - <update id="createDatabase" parameterType="String">
8   - CREATE DATABASE IF NOT EXISTS ${dataBaseName}
9   - </update>
10   -
11   - <update id="createSuperTable">
12   - CREATE STABLE IF NOT EXISTS ${dataBaseName}.${superTableName}
13   - <foreach item="item" collection="schemaFields" separator=","
14   - open="(" close=")" index="">
15   - <if test="item.fieldName != null || item.fieldName != ''">
16   - ${item.fieldName}
17   - </if>
18   - <if test="item.dataType != null || item.dataType != ''">
19   - <choose>
20   - <when test="item.dataType == 'TIMESTAMP'">
21   - TIMESTAMP
22   - </when>
23   - <when test="item.dataType == 'TINYINT'">
24   - TINYINT
25   - </when>
26   - <when test="item.dataType == 'SMALLINT'">
27   - SMALLINT
28   - </when>
29   - <when test="item.dataType == 'INT'">
30   - INT
31   - </when>
32   - <when test="item.dataType == 'BIGINT'">
33   - BIGINT
34   - </when>
35   - <when test="item.dataType == 'FLOAT'">
36   - FLOAT
37   - </when>
38   - <when test="item.dataType == 'DOUBLE'">
39   - DOUBLE
40   - </when>
41   - <when test="item.dataType == 'BINARY'">
42   - BINARY
43   - </when>
44   - <when test="item.dataType == 'NCHAR'">
45   - NCHAR
46   - </when>
47   - <when test="item.dataType == 'BOOL'">
48   - BOOL
49   - </when>
50   - <when test="item.dataType == 'JSON'">
51   - JSON
52   - </when>
53   - </choose>
54   - </if>
55   - <if test="item.dataLength > 0">
56   - (
57   - ${item.dataLength}
58   - )
59   - </if>
60   - </foreach>
61   - TAGS
62   - <!--tdEngine不支持动态tags里的数据类型,只能使用choose标签比对-->
63   - <foreach item="item" collection="tagsFields" separator=","
64   - open="(" close=")" index="">
65   - <if test="item.fieldName != null || item.fieldName != ''">
66   - ${item.fieldName}
67   - </if>
68   - <if test="item.dataType != null || item.dataType != ''">
69   - <choose>
70   - <when test="item.dataType == 'TIMESTAMP'">
71   - TIMESTAMP
72   - </when>
73   - <when test="item.dataType == 'TINYINT'">
74   - TINYINT
75   - </when>
76   - <when test="item.dataType == 'SMALLINT'">
77   - SMALLINT
78   - </when>
79   - <when test="item.dataType == 'INT'">
80   - INT
81   - </when>
82   - <when test="item.dataType == 'BIGINT'">
83   - BIGINT
84   - </when>
85   - <when test="item.dataType == 'FLOAT'">
86   - FLOAT
87   - </when>
88   - <when test="item.dataType == 'DOUBLE'">
89   - DOUBLE
90   - </when>
91   - <when test="item.dataType == 'BINARY'">
92   - BINARY
93   - </when>
94   - <when test="item.dataType == 'NCHAR'">
95   - NCHAR
96   - </when>
97   - <when test="item.dataType == 'BOOL'">
98   - BOOL
99   - </when>
100   - <when test="item.dataType == 'JSON'">
101   - JSON
102   - </when>
103   - </choose>
104   - </if>
105   - <if test="item.dataLength > 0">
106   - (
107   - ${item.dataLength}
108   - )
109   - </if>
110   - </foreach>
111   - </update>
112   -
113   - <!-- CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);-->
114   - <update id="createTable">
115   - CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
116   - USING ${dataBaseName}.${superTableName}
117   - <foreach item="item" collection="tagsFieldValues" separator="," open="(" close=")">
118   - ${item.fieldName}
119   - </foreach>
120   - TAGS
121   - <foreach item="item" collection="tagsFieldValues" separator="," open="(" close=")">
122   - #{item.fieldValue}
123   - </foreach>
124   - </update>
125   -
126   - <!-- insert into d1004 (ts, voltage, phase) values("2018-10-04 14:38:06", 223, 0.29) -->
127   - <insert id="insertData">
128   - INSERT INTO ${dataBaseName}.${tableName}
129   - <foreach item="item" collection="schemaFieldValues" separator=","
130   - open="(" close=")" index="">
131   - ${item.fieldName}
132   - </foreach>
133   - VALUES
134   - <foreach item="item" collection="schemaFieldValues" separator=","
135   - open="(" close=")" index="">
136   - #{item.fieldValue}
137   - </foreach>
138   - </insert>
139   -
140   - <select id="selectByTimestamp" parameterType="cn.iocoder.yudao.module.iot.domain.SelectDto"
141   - resultType="Map">
142   - select * from #{dataBaseName}.#{tableName}
143   - <!--查询这里不能使用#{}占位符的方式,使用这种方式,tdEngine不识别为列名,只能使用${}占位的方式-->
144   - <!--因为tdEngine引擎一次只执行一条sql,所以有效预防了sql的注入,且该服务该接口为内部调用,所以可以使用${}-->
145   - where ${fieldName}
146   - between #{startTime} and #{endTime}
147   - </select>
148   -
149   - <update id="addColumnForSuperTable">
150   - ALTER STABLE ${dataBaseName}.${superTableName} ADD COLUMN
151   - <if test="field.fieldName != null || field.fieldName != ''">
152   - #{field.fieldName}
153   - </if>
154   - <if test="field.dataType != null || field.dataType != ''">
155   - <choose>
156   - <when test="field.dataType == 'TIMESTAMP'">
157   - TIMESTAMP
158   - </when>
159   - <when test="field.dataType == 'TINYINT'">
160   - TINYINT
161   - </when>
162   - <when test="field.dataType == 'SMALLINT'">
163   - SMALLINT
164   - </when>
165   - <when test="field.dataType == 'INT'">
166   - INT
167   - </when>
168   - <when test="field.dataType == 'BIGINT'">
169   - BIGINT
170   - </when>
171   - <when test="field.dataType == 'FLOAT'">
172   - FLOAT
173   - </when>
174   - <when test="field.dataType == 'DOUBLE'">
175   - DOUBLE
176   - </when>
177   - <when test="field.dataType == 'BINARY'">
178   - BINARY
179   - </when>
180   - <when test="field.dataType == 'NCHAR'">
181   - NCHAR
182   - </when>
183   - <when test="field.dataType == 'BOOL'">
184   - BOOL
185   - </when>
186   - <when test="field.dataType == 'JSON'">
187   - JSON
188   - </when>
189   - </choose>
190   - </if>
191   - <if test="field.dataLength > 0">
192   - (
193   - #{field.dataLength}
194   - )
195   - </if>
196   - </update>
197   -
198   - <update id="dropColumnForSuperTable">
199   - ALTER STABLE ${dataBaseName}.${superTableName} DROP COLUMN
200   - <if test="field.fieldName != null || field.fieldName != ''">
201   - #{field.fieldName}
202   - </if>
203   - </update>
204   -
205   - <update id="addTagForSuperTable">
206   - ALTER
207   - STABLE
208   - #{superTableName}
209   - ADD
210   - TAG
211   - <if test="field.fieldName != null || fieldDO.fieldName != ''">
212   - #{fieldDO.fieldName}
213   - </if>
214   - <if test="fieldDO.dataType != null || fieldDO.dataType != ''">
215   - <choose>
216   - <when test="fieldDO.dataType == 'timestamp'">
217   - timestamp
218   - </when>
219   - <when test="fieldDO.dataType == 'tinyint'">
220   - tinyint
221   - </when>
222   - <when test="fieldDO.dataType == 'smallint'">
223   - smallint
224   - </when>
225   - <when test="fieldDO.dataType == 'int'">
226   - int
227   - </when>
228   - <when test="fieldDO.dataType == 'bigint'">
229   - bigint
230   - </when>
231   - <when test="fieldDO.dataType == 'float'">
232   - float
233   - </when>
234   - <when test="fieldDO.dataType == 'double'">
235   - double
236   - </when>
237   - <when test="fieldDO.dataType == 'binary'">
238   - binary
239   - </when>
240   - <when test="fieldDO.dataType == 'nchar'">
241   - nchar
242   - </when>
243   - <when test="fieldDO.dataType == 'bool'">
244   - bool
245   - </when>
246   - <when test="fieldDO.dataType == 'json'">
247   - json
248   - </when>
249   - </choose>
250   - </if>
251   - <if test="fieldDO.dataLength > 0">
252   - (
253   - #{fieldDO.dataLength}
254   - )
255   - </if>
256   - </update>
257   -
258   - <update id="dropTagForSuperTable">
259   - ALTER
260   - STABLE
261   - #{superTableName}
262   - DROP
263   - TAG
264   - <if test="fieldsVo.fieldName != null || fieldsVo.fieldName != ''">
265   - #{fieldsVo.fieldName}
266   - </if>
267   - </update>
268   -
269   - <select id="getCountByTimestamp" parameterType="cn.iocoder.yudao.module.iot.domain.SelectDto"
270   - resultType="java.util.Map">
271   - SELECT count(0) AS count
272   - FROM #{dataBaseName}.#{tableName}
273   - WHERE ${fieldName} BETWEEN #{startTime} AND #{endTime}
274   - </select>
275   -
276   - <select id="showSuperTables" resultType="java.util.Map">
277   - SHOW ${dataBaseName}.STABLES LIKE '${superTableName}'
278   - </select>
279   -
280   - <select id="getLastData" resultType="java.util.Map">
281   - select last(time), *
282   - from #{tableName}
283   - where device_id = #{deviceId}
284   - </select>
285   -
286   - <select id="getLastDataByTags" parameterType="cn.iocoder.yudao.module.iot.domain.TagsSelectDao"
287   - resultType="Map">
288   - select last(*)
289   - from #{dataBaseName}.#{stableName}
290   - group by ${tagsName}
291   - </select>
292   -
293   - <select id="getHistoryData" resultType="java.util.Map"
294   - parameterType="cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto">
295   - SELECT ${fieldName} as data, time
296   - FROM ${dataBaseName}.${tableName}
297   - WHERE time BETWEEN #{startTime} AND #{endTime}
298   - AND ${fieldName} IS NOT NULL
299   - ORDER BY time DESC
300   - LIMIT #{params.rows} offset #{params.page}
301   - </select>
302   -
303   - <select id="getRealtimeData" resultType="java.util.Map"
304   - parameterType="cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto">
305   - SELECT #{fieldName}, time
306   - FROM #{dataBaseName}.#{tableName}
307   - </select>
308   -
309   - <select id="getAggregateData" resultType="java.util.Map"
310   - parameterType="cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto">
311   - SELECT #{aggregate}(${fieldName})
312   - FROM #{dataBaseName}.#{tableName}
313   - WHERE ts BETWEEN #{startTime} AND #{endTime} interval (${interval})
314   - LIMIT #{num}
315   - </select>
316   -
317   - <select id="describeSuperTable" resultType="java.util.Map">
318   - DESCRIBE ${dataBaseName}.${superTableName}
319   - </select>
320   - <select id="getHistoryCount" resultType="java.lang.Long">
321   - SELECT count(time)
322   - FROM ${dataBaseName}.${tableName}
323   - WHERE time BETWEEN #{startTime} AND #{endTime}
324   - AND ${fieldName} IS NOT NULL
325   - </select>
326   -
327   -</mapper>
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineQueryMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper
  3 + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4 + "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5 +
  6 +<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineQueryMapper">
  7 +
  8 + <!-- 根据时间戳查询数据 -->
  9 + <select id="selectByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO"
  10 + resultType="Map">
  11 + SELECT * FROM ${dataBaseName}.${tableName}
  12 + WHERE ${fieldName} BETWEEN #{startTime} AND #{endTime}
  13 + </select>
  14 +
  15 + <!-- 获取时间范围内的数据条数 -->
  16 + <select id="getCountByTimestamp" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectDO"
  17 + resultType="java.util.Map">
  18 + SELECT COUNT(0) AS count
  19 + FROM ${dataBaseName}.${tableName}
  20 + WHERE ${fieldName} BETWEEN #{startTime} AND #{endTime}
  21 + </select>
  22 +
  23 + <!-- 获取最新数据 -->
  24 + <select id="getLastData" resultType="java.util.Map">
  25 + SELECT LAST(time), *
  26 + FROM ${tableName}
  27 + WHERE device_id = #{deviceId}
  28 + </select>
  29 +
  30 + <!-- 根据标签获取最新数据 -->
  31 + <select id="getLastDataByTags" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO"
  32 + resultType="Map">
  33 + SELECT LAST(*)
  34 + FROM ${dataBaseName}.${stableName}
  35 + GROUP BY ${tagsName}
  36 + </select>
  37 +
  38 + <!-- 获取历史数据 -->
  39 + <select id="getHistoryData" resultType="java.util.Map"
  40 + parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
  41 + SELECT ${fieldName} AS data, time
  42 + FROM ${dataBaseName}.${tableName}
  43 + WHERE time BETWEEN #{startTime} AND #{endTime}
  44 + AND ${fieldName} IS NOT NULL
  45 + ORDER BY time DESC
  46 + LIMIT #{params.rows} OFFSET #{params.page}
  47 + </select>
  48 +
  49 + <!-- 获取实时数据 -->
  50 + <select id="getRealtimeData" resultType="java.util.Map"
  51 + parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
  52 + SELECT ${fieldName}, time
  53 + FROM ${dataBaseName}.${tableName}
  54 + </select>
  55 +
  56 + <!-- 获取聚合数据 -->
  57 + <select id="getAggregateData" resultType="java.util.Map"
  58 + parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
  59 + SELECT ${aggregate}(${fieldName})
  60 + FROM ${dataBaseName}.${tableName}
  61 + WHERE ts BETWEEN #{startTime} AND #{endTime} INTERVAL (${interval})
  62 + LIMIT #{num}
  63 + </select>
  64 +
  65 + <!-- 获取历史数据条数 -->
  66 + <select id="getHistoryCount" resultType="java.lang.Long">
  67 + SELECT COUNT(time)
  68 + FROM ${dataBaseName}.${tableName}
  69 + WHERE time BETWEEN #{startTime} AND #{endTime}
  70 + AND ${fieldName} IS NOT NULL
  71 + </select>
  72 +
  73 +</mapper>
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineSuperTableMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper
  3 + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4 + "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5 +
  6 +<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineSuperTableMapper">
  7 +
  8 + <!-- 创建超级表 -->
  9 + <update id="createSuperTable">
  10 + CREATE STABLE IF NOT EXISTS ${dataBaseName}.${superTableName}
  11 + <foreach item="item" collection="columns" separator=","
  12 + open="(" close=")">
  13 + ${item.fieldName} ${item.dataType}
  14 + <if test="item.dataLength > 0">
  15 + (${item.dataLength})
  16 + </if>
  17 + </foreach>
  18 + TAGS
  19 + <foreach item="item" collection="tags" separator=","
  20 + open="(" close=")">
  21 + ${item.fieldName} ${item.dataType}
  22 + <if test="item.dataLength > 0">
  23 + (${item.dataLength})
  24 + </if>
  25 + </foreach>
  26 + </update>
  27 +
  28 + <!-- 查看超级表 -->
  29 + <select id="showSuperTables" resultType="java.util.Map">
  30 + SHOW ${dataBaseName}.STABLES LIKE '${superTableName}'
  31 + </select>
  32 +
  33 + <!-- 描述超级表结构 -->
  34 + <select id="describeSuperTable" resultType="java.util.Map">
  35 + DESCRIBE ${dataBaseName}.${superTableName}
  36 + </select>
  37 +
  38 + <!-- 为超级表添加列 -->
  39 + <update id="addColumnForSuperTable">
  40 + ALTER STABLE ${dataBaseName}.${superTableName} ADD COLUMN ${column.fieldName} ${column.dataType}
  41 + <if test="column.dataLength > 0">
  42 + (${column.dataLength})
  43 + </if>
  44 + </update>
  45 +
  46 + <!-- 为超级表删除列 -->
  47 + <update id="dropColumnForSuperTable">
  48 + ALTER STABLE ${dataBaseName}.${superTableName} DROP COLUMN ${column.fieldName}
  49 + </update>
  50 +
  51 + <!-- 修改列宽 -->
  52 + <update id="modifyColumnWidthForSuperTable">
  53 + ALTER STABLE ${dataBaseName}.${superTableName} MODIFY COLUMN ${column.fieldName} ${column.dataType}
  54 + <if test="column.dataLength > 0">
  55 + (${column.dataLength})
  56 + </if>
  57 + </update>
  58 +
  59 + <!-- 为超级表添加标签 -->
  60 + <update id="addTagForSuperTable">
  61 + ALTER STABLE ${dataBaseName}.${superTableName} ADD TAG ${tag.fieldName} ${tag.dataType}
  62 + <if test="tag.dataLength > 0">
  63 + (${tag.dataLength})
  64 + </if>
  65 + </update>
  66 +
  67 + <!-- 为超级表删除标签 -->
  68 + <update id="dropTagForSuperTable">
  69 + ALTER STABLE ${dataBaseName}.${superTableName} DROP TAG ${tag.fieldName}
  70 + </update>
  71 +
  72 +</mapper>
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineTableMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper
  3 + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4 + "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5 +
  6 +<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineTableMapper">
  7 +
  8 + <!-- 创建子表 -->
  9 + <update id="createTable">
  10 + CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
  11 + USING ${dataBaseName}.${superTableName}
  12 + TAGS
  13 + <foreach item="item" collection="tags" separator=","
  14 + open="(" close=")">
  15 + #{item.fieldValue}
  16 + </foreach>
  17 + </update>
  18 +
  19 + <!-- 创建子表,带有 TAGS -->
  20 + <update id="createTableWithTags">
  21 + CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName}
  22 + USING ${dataBaseName}.${superTableName}
  23 + <foreach item="item" collection="tags" separator="," open="(" close=")">
  24 + #{item.fieldName}
  25 + </foreach>
  26 + TAGS
  27 + <foreach item="item" collection="tags" separator=","
  28 + open="(" close=")">
  29 + #{item.fieldValue}
  30 + </foreach>
  31 + </update>
  32 +
  33 +</mapper>
0 34 \ No newline at end of file
... ...