From 08c2a39100db6501c6d457e6eb1509779b51e0f3 Mon Sep 17 00:00:00 2001 From: xins Date: Tue, 29 Aug 2023 17:46:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8B=A5=E4=BE=9D=E5=BE=AE=E6=9C=8D=E5=8A=A11.?= =?UTF-8?q?04=E7=89=88=E6=9C=AC=EF=BC=8C=E4=B8=BB=E8=A6=81=E6=94=AF?= =?UTF-8?q?=E6=8C=81tdengine=E6=9C=8D=E5=8A=A1=201=E3=80=81=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E6=95=B0=E6=8D=AE=E5=BA=93=202=E3=80=81=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E8=B6=85=E7=BA=A7=E8=A1=A8=203=E3=80=81=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E5=AD=90=E8=A1=A8=204=E3=80=81=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=B6=85=E7=BA=A7=E8=A1=A8column=205=E3=80=81=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E8=B6=85=E7=BA=A7=E8=A1=A8column=206=E3=80=81?= =?UTF-8?q?=E6=8F=92=E5=85=A5=E6=95=B0=E6=8D=AE=207=E3=80=81=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=AD=90=E8=A1=A8=E6=9C=80=E6=96=B0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=208=E3=80=81=E6=A0=B9=E6=8D=AEtags=E8=8E=B7=E5=8F=96=E8=B6=85?= =?UTF-8?q?=E7=BA=A7=E8=A1=A8=E6=9C=80=E6=96=B0=E6=95=B0=E6=8D=AE=209?= =?UTF-8?q?=E3=80=81=E8=8E=B7=E5=8F=96=E5=8E=86=E5=8F=B2=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=2010=E3=80=81=E8=8E=B7=E5=8F=96=E5=8E=86=E5=8F=B2=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-api/hw-api-tdengine/pom.xml | 28 ++ .../tdengine/api/RemoteTdEngineService.java | 55 +++ .../ruoyi/tdengine/api/domain/TdField.java | 40 +++ .../ruoyi/tdengine/api/domain/TdFieldVo.java | 68 ++++ .../api/domain/TdHistorySelectDto.java | 40 +++ .../tdengine/api/domain/TdSelectDto.java | 33 ++ .../tdengine/api/domain/TdSuperTableVo.java | 57 +++ .../ruoyi/tdengine/api/domain/TdTableVo.java | 42 +++ .../RemoteTdEngineFallbackFactory.java | 76 ++++ ruoyi-api/pom.xml | 1 + .../MyLocaleChangeInterceptor.java | 6 +- .../main/resources/i18n/messages.properties | 11 + .../resources/i18n/messages_en_US.properties | 4 +- .../resources/i18n/messages_zh_CN.properties | 3 + ruoyi-common/ruoyi-common-core/pom.xml | 5 + .../core/constant/ServiceNameConstants.java | 5 + .../core/constant/TdEngineConstants.java | 8 + .../common/core/enums/DataTypeEnums.java | 115 ++++++ .../validated/tdengine/AddTdSTableColumn.java | 4 + .../hw/validated/tdengine/InsertTdTable.java | 4 + .../ruoyi/common/core/utils/ip/IpUtils.java | 2 +- ruoyi-modules/hw-tdengine/pom.xml | 106 ++++++ .../ruoyi/tdengine/HwTdengineApplication.java | 34 ++ .../controller/TdEngineController.java | 339 ++++++++++++++++++ .../ruoyi/tdengine/mapper/TdEngineMapper.java | 154 ++++++++ .../tdengine/service/ITdEngineService.java | 125 +++++++ .../service/impl/TdEngineServiceImpl.java | 289 +++++++++++++++ .../hw-tdengine/src/main/resources/banner.txt | 10 + .../src/main/resources/bootstrap.yml | 25 ++ .../src/main/resources/logback.xml | 74 ++++ .../mapper/tdengine/TdEngineMapper.xml | 251 +++++++++++++ ruoyi-modules/pom.xml | 1 + 32 files changed, 2010 insertions(+), 5 deletions(-) create mode 100644 ruoyi-api/hw-api-tdengine/pom.xml create mode 100644 ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/RemoteTdEngineService.java create mode 100644 ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdField.java create mode 100644 ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdFieldVo.java create mode 100644 ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdHistorySelectDto.java create mode 100644 ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdSelectDto.java create mode 100644 ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdSuperTableVo.java create mode 100644 ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdTableVo.java create mode 100644 ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/factory/RemoteTdEngineFallbackFactory.java create mode 100644 ruoyi-common/hw-common-i18n/src/main/resources/i18n/messages.properties create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TdEngineConstants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/DataTypeEnums.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/hw/validated/tdengine/AddTdSTableColumn.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/hw/validated/tdengine/InsertTdTable.java create mode 100644 ruoyi-modules/hw-tdengine/pom.xml create mode 100644 ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/HwTdengineApplication.java create mode 100644 ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/controller/TdEngineController.java create mode 100644 ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/mapper/TdEngineMapper.java create mode 100644 ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/ITdEngineService.java create mode 100644 ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/impl/TdEngineServiceImpl.java create mode 100644 ruoyi-modules/hw-tdengine/src/main/resources/banner.txt create mode 100644 ruoyi-modules/hw-tdengine/src/main/resources/bootstrap.yml create mode 100644 ruoyi-modules/hw-tdengine/src/main/resources/logback.xml create mode 100644 ruoyi-modules/hw-tdengine/src/main/resources/mapper/tdengine/TdEngineMapper.xml diff --git a/ruoyi-api/hw-api-tdengine/pom.xml b/ruoyi-api/hw-api-tdengine/pom.xml new file mode 100644 index 0000000..699bd7f --- /dev/null +++ b/ruoyi-api/hw-api-tdengine/pom.xml @@ -0,0 +1,28 @@ + + + + com.ruoyi + ruoyi-api + 3.6.3 + + 4.0.0 + + hw-api-tdengine + + + hw-api-tdengine时序数据库接口模块 + + + + + + + com.ruoyi + ruoyi-common-core + + + + + \ No newline at end of file diff --git a/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/RemoteTdEngineService.java b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/RemoteTdEngineService.java new file mode 100644 index 0000000..b7172c3 --- /dev/null +++ b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/RemoteTdEngineService.java @@ -0,0 +1,55 @@ +package com.ruoyi.tdengine.api; + + +import com.ruoyi.common.core.constant.ServiceNameConstants; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.hw.validated.tdengine.AddTdSTableColumn; +import com.ruoyi.common.core.hw.validated.tdengine.InsertTdTable; +import com.ruoyi.tdengine.api.domain.TdHistorySelectDto; +import com.ruoyi.tdengine.api.domain.TdSelectDto; +import com.ruoyi.tdengine.api.domain.TdSuperTableVo; +import com.ruoyi.tdengine.api.domain.TdTableVo; +import com.ruoyi.tdengine.api.factory.RemoteTdEngineFallbackFactory; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.Map; + +@FeignClient(contextId = "remoteTdEngineService", value = ServiceNameConstants.TDENGINE_SERVICE, fallbackFactory = RemoteTdEngineFallbackFactory.class) +public interface RemoteTdEngineService { + + @PostMapping("/tdengine/createDatabase") + R createDataBase(@RequestParam("databaseName") String databaseName); + + @PostMapping("/tdengine/createSuperTable") + R createSuperTable(@Validated @RequestBody TdSuperTableVo tdSuperTableVo); + + @PostMapping("/tdengine/createTable") + R createTable(@Validated @RequestBody TdTableVo tdTableVo); + + @PostMapping("/tdengine/addSuperTableColumn") + R addSuperTableColumn(@Validated(AddTdSTableColumn.class) @RequestBody TdSuperTableVo tdSuperTableVo); + + @PostMapping("/tdengine/dropSuperTableColumn") + R dropColumnForSuperTable(@Validated(AddTdSTableColumn.class) @RequestBody TdSuperTableVo tdSuperTableVo); + + @PostMapping("/tdengine/insertTable") + R insertTable(@Validated(InsertTdTable.class) @RequestBody TdTableVo tdTableVo); + + @PostMapping("/tdengine/getLatestData") + R getLatestData(@Validated @RequestBody TdSelectDto tdSelectDto); + + @PostMapping("/tdengine/getLatestDataByTags") + R>> getLatestDataByTags(@RequestBody TdSelectDto tdSelectDto); + + @PostMapping("/tdengine/getHistoryData") + R getHistoryData(@Validated @RequestBody TdHistorySelectDto tdHistorySelectDto); + + @PostMapping("/tdengine/getCountOfHistoryData") + R getCountOfHistoryData(@Validated @RequestBody TdHistorySelectDto tdHistorySelectDto); + + +} diff --git a/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdField.java b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdField.java new file mode 100644 index 0000000..b9f9ac0 --- /dev/null +++ b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdField.java @@ -0,0 +1,40 @@ +package com.ruoyi.tdengine.api.domain; + +import com.ruoyi.common.core.enums.DataTypeEnums; +import lombok.Data; + +/** + * @ClassName: TdField + * @Author : xins + * @Date :2023-08-28 9:47 + * @Description: TDengine filed,建表的字段实体类 + * @Version :1.0 + */ +@Data +public class TdField { + + //字段名称 + private String fieldName; + + //字段值 + private Object fieldValue; + + //字段数据类型code + private Integer dataTypeCode; + + //字段数据类型 + private String dataType; + + //字段字节大小 + private Integer size; + + public TdField() { + } + + public TdField(String fieldName, Integer dataTypeCode, Integer size) { + this.fieldName = fieldName; + this.dataTypeCode = dataTypeCode; + this.dataType = DataTypeEnums.dataCodeTypeMap.get(dataTypeCode); + this.size = size; + } +} diff --git a/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdFieldVo.java b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdFieldVo.java new file mode 100644 index 0000000..a695adc --- /dev/null +++ b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdFieldVo.java @@ -0,0 +1,68 @@ +package com.ruoyi.tdengine.api.domain; + +import com.ruoyi.common.core.enums.DataTypeEnums; +import org.apache.commons.lang3.StringUtils; +import org.springframework.validation.annotation.Validated; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * @Description: Tdengine 创建表的字段实体类 + * @ClassName: TdFieldsVo + * @Author : xins + * @Date :2023-08-28 14:34 + * @Version :1.0 + */ +public class TdFieldVo { + private static final long serialVersionUID = 1L; + + private String fieldName; + + private String dataType; + + private Integer size; + + + public TdFieldVo(String fieldName, Integer dataTypeCode, Integer size) { + this.fieldName = fieldName; + this.dataType = DataTypeEnums.dataCodeTypeMap.get(dataTypeCode); + this.size = size; + } + + /** + * @description 将TdFields转换为创建表的实体类TdFieldsVo,主要是datatype转换 + * @author xins + * @date 2023-08-28 14:40 + * @param field + * @return TdFieldsVo + */ + public static TdFieldVo convertField(@Validated TdField field) throws SQLException { + String fieldName = field.getFieldName(); + Integer datatypeCode = field.getDataTypeCode(); + Integer size = field.getSize(); + if(StringUtils.isBlank(fieldName) || datatypeCode == null){ + throw new SQLException("fieldname and datatype cannot be null"); + } + TdFieldVo tdFieldsVo = new TdFieldVo(fieldName, datatypeCode, size); + return tdFieldsVo; + } + + + /** + * @description 批量转换创建表的字段 + * @author xins + * @date 2023-08-28 14:58 + * @param fieldList + * @return List + */ + public static List batchConvertFields(List fieldList) throws SQLException{ + List tdFieldsVoList = new ArrayList<>(); + for(TdField tdField:fieldList){ + tdFieldsVoList.add(convertField(tdField)); + } + return tdFieldsVoList; + } + +} diff --git a/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdHistorySelectDto.java b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdHistorySelectDto.java new file mode 100644 index 0000000..a712eed --- /dev/null +++ b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdHistorySelectDto.java @@ -0,0 +1,40 @@ +package com.ruoyi.tdengine.api.domain; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class TdHistorySelectDto { + + //数据库名称 + @NotBlank(message="databaseName cannot be empty") + private String databaseName; + + //子表名称 + @NotBlank(message="tableName cannot be empty") + private String tableName; + + //控制输出条数 + private int limit; + + //指定从第几条之后输出(例如:limit 2,5,输出第3行到第7行的数据) + private int offset; + + /** + * 第一个字段,数据类型必须是timestamp + */ + private String firstFieldName; + + //过滤条件:开始时间 + private long startTime; + + //过滤条件:结束时间 + private long endTime; + + //排序字段 + private String orderByFieldName; + + //排序方式 + private String orderByMode; +} diff --git a/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdSelectDto.java b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdSelectDto.java new file mode 100644 index 0000000..f985526 --- /dev/null +++ b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdSelectDto.java @@ -0,0 +1,33 @@ +package com.ruoyi.tdengine.api.domain; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; + +/** + * @Description: TDengine查询数据入参数据传输对象 + * @ClassName: TdSelectDto + * @Author : xins + * @Date :2023-08-29 10:39 + * @Version :1.0 + */ +@Data +public class TdSelectDto { + + //数据库名称 + @NotBlank(message="databaseName cannot be empty") + private String databaseName; + + //子表名称 + @NotBlank(message="tableName cannot be empty") + private String tableName; + + //超级表名称 + private String superTableName; + + //tags名称 + private String tagsName; + + +} diff --git a/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdSuperTableVo.java b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdSuperTableVo.java new file mode 100644 index 0000000..2ed1f8f --- /dev/null +++ b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdSuperTableVo.java @@ -0,0 +1,57 @@ +package com.ruoyi.tdengine.api.domain; + +import com.ruoyi.common.core.hw.validated.tdengine.AddTdSTableColumn; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * @ClassDescription: 创建超级表需要的入参的实体类 + * @ClassName: TdSuperTableVo + * @Author: xins + * @Date: 2023-08-28 09:30:45 + * @Version 1.0 + */ +@Data +public class TdSuperTableVo { + + //数据库名称 + @NotEmpty(message="databaseName cannot be empty",groups = AddTdSTableColumn.class) + private String databaseName; + + //超级表名称 + @NotEmpty(message="supertableName cannot be empty",groups = AddTdSTableColumn.class) + private String superTableName; + + /** + * 第一个字段,数据类型必须是timestamp + */ + private String firstFieldName; + + /** + * 超级表的表结构Schema,根据物模型创建 + * 第一列必须为时间戳timestamp,也就是第一个字段的数据类型必须是timestamp + * 字符相关数据类型必须指定大小 + * 字段名称和字段数据类型不能为空 + */ + @NotEmpty(message="schemeFields cannot be empty") + private List schemaFields; + + + /** + * 超级表的标签字段Schema,采集点的静态属性,可以作为子表在超级表里的标识 + * TAGS 列名不能与其他列名相同。 + * TAGS 列名不能为预留关键字。 + * TAGS 最多允许 128 个,至少 1 个,总长度不超过 16 KB。 + */ + @NotEmpty(message="tagsFields cannot be empty") + private List tagsFields; + + + /** + * 字段信息对象,超级表添加列时使用该属性 + */ + private TdField field; + +} diff --git a/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdTableVo.java b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdTableVo.java new file mode 100644 index 0000000..76bd658 --- /dev/null +++ b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/TdTableVo.java @@ -0,0 +1,42 @@ +package com.ruoyi.tdengine.api.domain; + +import com.ruoyi.common.core.hw.validated.tdengine.InsertTdTable; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * @Description: 子表实体类 + * @ClassName: TdTableVo + * @Author : xins + * @Date :2023-08-28 15:45 + * @Version :1.0 + */ +@Data +public class TdTableVo { + + //数据库名称 + @NotEmpty(message="databaseName cannot be empty",groups = InsertTdTable.class) + private String databaseName; + + //超级表名称 + @NotEmpty(message="supertableName cannot be empty") + private String superTableName; + + //子表名称 + @NotEmpty(message="tableName cannot be empty",groups = InsertTdTable.class) + private String tableName; + + /** + * 子表的标签字段的值,创建子表时标签字段值的数据类型要与超级表的对应上 + */ + private List tagsFieldValues; + + /** + * 子表的schema字段的值,掺入子表时schema字段值的数据类型要与超级表的对应上 + */ + @NotEmpty(message="schemaFields cannot be empty",groups = InsertTdTable.class) + private List schemaFields; + +} diff --git a/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/factory/RemoteTdEngineFallbackFactory.java b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/factory/RemoteTdEngineFallbackFactory.java new file mode 100644 index 0000000..5d9e794 --- /dev/null +++ b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/factory/RemoteTdEngineFallbackFactory.java @@ -0,0 +1,76 @@ +package com.ruoyi.tdengine.api.factory; + +import com.ruoyi.common.core.domain.R; +import com.ruoyi.tdengine.api.RemoteTdEngineService; +import com.ruoyi.tdengine.api.domain.TdHistorySelectDto; +import com.ruoyi.tdengine.api.domain.TdSelectDto; +import com.ruoyi.tdengine.api.domain.TdSuperTableVo; +import com.ruoyi.tdengine.api.domain.TdTableVo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +public class RemoteTdEngineFallbackFactory implements FallbackFactory { + + private static final Logger log = LoggerFactory.getLogger(RemoteTdEngineFallbackFactory.class); + @Override + public RemoteTdEngineService create(Throwable throwable) { + return new RemoteTdEngineService() + { + @Override + public R createDataBase(String databaseName) { + return R.fail("创建数据库失败:" + throwable.getMessage()); + } + + @Override + public R createSuperTable(TdSuperTableVo tdSuperTableVo) { + return R.fail("创建超级表失败:" + throwable.getMessage()); + } + + @Override + public R createTable(TdTableVo tdTableVo) { + return R.fail("创建子表失败:" + throwable.getMessage()); + } + + @Override + public R addSuperTableColumn(TdSuperTableVo tdSuperTableVo) { + return R.fail("添加超级表Column失败:" + throwable.getMessage()); + } + + @Override + public R dropColumnForSuperTable(TdSuperTableVo tdSuperTableVo) { + return R.fail("删除超级表Column失败:" + throwable.getMessage()); + } + + @Override + public R insertTable(TdTableVo tdTableVo) { + return R.fail("插入数据失败:" + throwable.getMessage()); + } + + @Override + public R getLatestData(TdSelectDto tdSelectDto) { + return R.fail("获取子表最新数据失败:" + throwable.getMessage()); + } + + @Override + public R>> getLatestDataByTags(TdSelectDto tdSelectDto) { + return R.fail("根据tags获取超级表最新数据失败:" + throwable.getMessage()); + } + + @Override + public R getHistoryData(TdHistorySelectDto tdHistorySelectDto) { + return R.fail("获取历史数据失败:" + throwable.getMessage()); + } + + @Override + public R getCountOfHistoryData(TdHistorySelectDto tdHistorySelectDto) { + return R.fail("获取历史数据数量失败:" + throwable.getMessage()); + } + + }; + } +} diff --git a/ruoyi-api/pom.xml b/ruoyi-api/pom.xml index a57a127..965d90a 100644 --- a/ruoyi-api/pom.xml +++ b/ruoyi-api/pom.xml @@ -10,6 +10,7 @@ ruoyi-api-system + hw-api-tdengine ruoyi-api diff --git a/ruoyi-common/hw-common-i18n/src/main/java/com/ruoyi/i18n/interceptor/MyLocaleChangeInterceptor.java b/ruoyi-common/hw-common-i18n/src/main/java/com/ruoyi/i18n/interceptor/MyLocaleChangeInterceptor.java index 00e3f7b..3a3e85e 100644 --- a/ruoyi-common/hw-common-i18n/src/main/java/com/ruoyi/i18n/interceptor/MyLocaleChangeInterceptor.java +++ b/ruoyi-common/hw-common-i18n/src/main/java/com/ruoyi/i18n/interceptor/MyLocaleChangeInterceptor.java @@ -31,7 +31,7 @@ public class MyLocaleChangeInterceptor implements HandlerInterceptor { // Proceed in cookie cookieLocale=cookie.getValue(); } - if(cookieLocale!=null&& !cookieLocale.trim().equals("")){ + if(cookieLocale!=null&& !"".equals(cookieLocale.trim())){ locale=cookieLocale; } @@ -41,12 +41,12 @@ public class MyLocaleChangeInterceptor implements HandlerInterceptor { // System.out.println((request.getHeader("accept-language"))); // System.out.println(request.getHeader("cookie")); - if(headerLocale!=null && !headerLocale.trim().equals("")){ + if(headerLocale!=null && !"".equals(headerLocale.trim())){ locale=headerLocale; } // 3、从get 参数数据获取 language=zh_CN String parameterLocale=request.getParameter(paramName); - if(parameterLocale!=null && !parameterLocale.trim().equals("")){ + if(parameterLocale!=null && !"".equals(parameterLocale.trim())){ locale=parameterLocale; } //4 语言信息写入线程变量 diff --git a/ruoyi-common/hw-common-i18n/src/main/resources/i18n/messages.properties b/ruoyi-common/hw-common-i18n/src/main/resources/i18n/messages.properties new file mode 100644 index 0000000..3a8ef58 --- /dev/null +++ b/ruoyi-common/hw-common-i18n/src/main/resources/i18n/messages.properties @@ -0,0 +1,11 @@ +user.login.username=\u7528\u6237\u540D +user.login.password=\u5BC6\u7801 +user.login.code=\u9A8C\u8BC1\u7801 +user.login.remember=\u8BB0\u4F4F\u6211 +user.login.submit=\u767B\u5F55 + + +menu.system.management=\u7CFB\u7EDF\u7BA1\u7406 + + +tdengine.supertable1.pressure=yali diff --git a/ruoyi-common/hw-common-i18n/src/main/resources/i18n/messages_en_US.properties b/ruoyi-common/hw-common-i18n/src/main/resources/i18n/messages_en_US.properties index a8e2116..50fb610 100644 --- a/ruoyi-common/hw-common-i18n/src/main/resources/i18n/messages_en_US.properties +++ b/ruoyi-common/hw-common-i18n/src/main/resources/i18n/messages_en_US.properties @@ -2,4 +2,6 @@ user.login.username=User name user.login.password=Password user.login.code=Security code user.login.remember=Remember me -user.login.submit=Sign In \ No newline at end of file +user.login.submit=Sign In + +menu.system.management=System Management diff --git a/ruoyi-common/hw-common-i18n/src/main/resources/i18n/messages_zh_CN.properties b/ruoyi-common/hw-common-i18n/src/main/resources/i18n/messages_zh_CN.properties index 95a9a1c..b24f57a 100644 --- a/ruoyi-common/hw-common-i18n/src/main/resources/i18n/messages_zh_CN.properties +++ b/ruoyi-common/hw-common-i18n/src/main/resources/i18n/messages_zh_CN.properties @@ -4,3 +4,6 @@ user.login.code=\u9A8C\u8BC1\u7801 user.login.remember=\u8BB0\u4F4F\u6211 user.login.submit=\u767B\u5F55 + +menu.system.management=\u7CFB\u7EDF\u7BA1\u7406 + diff --git a/ruoyi-common/ruoyi-common-core/pom.xml b/ruoyi-common/ruoyi-common-core/pom.xml index b394ea9..e2f468b 100644 --- a/ruoyi-common/ruoyi-common-core/pom.xml +++ b/ruoyi-common/ruoyi-common-core/pom.xml @@ -113,6 +113,11 @@ swagger-annotations + + org.projectlombok + lombok + + diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ServiceNameConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ServiceNameConstants.java index 421a322..8a0f1e6 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ServiceNameConstants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ServiceNameConstants.java @@ -21,4 +21,9 @@ public class ServiceNameConstants * 文件服务的serviceid */ public static final String FILE_SERVICE = "ruoyi-file"; + + /** + * Tdengine服务的serviceid + */ + public static final String TDENGINE_SERVICE = "hw-tdengine"; } diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TdEngineConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TdEngineConstants.java new file mode 100644 index 0000000..e5c87b8 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TdEngineConstants.java @@ -0,0 +1,8 @@ +package com.ruoyi.common.core.constant; + +public class TdEngineConstants { + + public static final String DEFAULT_FIRST_FIELD_NAME = "ts"; + + public static final String DEFAULT_ORDER_BY_MODE = "desc"; +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/DataTypeEnums.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/DataTypeEnums.java new file mode 100644 index 0000000..7fb824e --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/DataTypeEnums.java @@ -0,0 +1,115 @@ +package com.ruoyi.common.core.enums; + + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public enum DataTypeEnums{ + + /** + * 时间戳。缺省精度毫秒,可支持微秒和纳秒 + */ + TIMESTAMP(1,"timestamp"), + + /** + * 整型,范围 [-2^31, 2^31-1] + */ + INT(2, "int"), + + /** + * 长整型,范围 [-2^63, 2^63-1] + */ + BIGINT(3, "bigint"), + + /** + * 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] + */ + FLOAT(4, "float"), + + /** + * 双精度浮点型,有效位数 15-16,范围 [-1.7E308, 1.7E308] + */ + DOUBLE(5, "double"), + + /** + * 记录单字节字符串,建议只用于处理 ASCII 可见字符,最大长度16000,中文等多字节字符需使用 NCHAR + */ + BINARY(6, "binary"), + + /** + * 短整型, 范围 [-32768, 32767] + */ + SMALLINT(7, "smallint"), + + /** + * 单字节整型,范围 [-128, 127] + */ + TINYINT(8, "tinyint"), + + /** + * 布尔型,{true, false} + */ + BOOL(9, "bool"), + + /** + * 记录包含多字节字符在内的字符串,如中文字符。 + * 每个 NCHAR 字符占用 4 字节的存储空间。字符串两端使用单引号引用,字符串内的单引号需用转义字符 \'。 + * NCHAR 使用时须指定字符串大小,类型为 NCHAR(10) 的列表示此列的字符串最多存储 10 个 NCHAR 字符。 + * 如果用户字符串长度超出声明长度,将会报错。最大长度4093 + */ + NCHAR(10, "nchar"), + + + /** + * json数据类型 只有tag类型可以是json格式 + */ + JSON(11, "json"); + + // 性别值数组 + public static final List genderValueList = Arrays.stream(values()).map(DataTypeEnums::getDataCode).collect(Collectors.toList()); + + // 性别名数组 + public static final List genderNameList = Arrays.stream(values()).map(DataTypeEnums::getDataType).collect(Collectors.toList()); + + // 属性值与属性名Map + public static final Map dataCodeTypeMap = Arrays.stream(values()).collect( + Collectors.toMap( + DataTypeEnums::getDataCode, + DataTypeEnums::getDataType + ) + ); + + // 属性名与属性值Map + public static final Map dataTypeCodeMap = Arrays.stream(values()).collect( + Collectors.toMap( + DataTypeEnums::getDataType, + DataTypeEnums::getDataCode + ) + ); + + // 性别值 + private final Integer dataCode; + + // 性别名 + private final String dataType; + + DataTypeEnums(Integer dataCode, String dataType) { + this.dataCode = dataCode; + this.dataType = dataType; + } + + public Integer getDataCode() { + return dataCode; + } + + public String getDataType() { + return dataType; + } + + + public static void main(String[] args) { + System.out.println(dataCodeTypeMap.get(1)); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/hw/validated/tdengine/AddTdSTableColumn.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/hw/validated/tdengine/AddTdSTableColumn.java new file mode 100644 index 0000000..8c04ee9 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/hw/validated/tdengine/AddTdSTableColumn.java @@ -0,0 +1,4 @@ +package com.ruoyi.common.core.hw.validated.tdengine; + +public interface AddTdSTableColumn { +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/hw/validated/tdengine/InsertTdTable.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/hw/validated/tdengine/InsertTdTable.java new file mode 100644 index 0000000..226caba --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/hw/validated/tdengine/InsertTdTable.java @@ -0,0 +1,4 @@ +package com.ruoyi.common.core.hw.validated.tdengine; + +public interface InsertTdTable { +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java index cf5108b..7b7c315 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java @@ -304,7 +304,7 @@ public class IpUtils String[] s1 = ipWildCard.split("\\."); String[] s2 = ip.split("\\."); boolean isMatchedSeg = true; - for (int i = 0; i < s1.length && !s1[i].equals("*"); i++) + for (int i = 0; i < s1.length && !"*".equals(s1[i]); i++) { if (!s1[i].equals(s2[i])) { diff --git a/ruoyi-modules/hw-tdengine/pom.xml b/ruoyi-modules/hw-tdengine/pom.xml new file mode 100644 index 0000000..b4e8934 --- /dev/null +++ b/ruoyi-modules/hw-tdengine/pom.xml @@ -0,0 +1,106 @@ + + + + com.ruoyi + ruoyi-modules + 3.6.3 + + 4.0.0 + + ruoyi-modules-tdengine + + + ruoyi-modules-tdengine 时序数据库处理模块 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + io.springfox + springfox-swagger-ui + ${swagger.fox.version} + + + + + com.ruoyi + ruoyi-common-datasource + + + + + com.ruoyi + ruoyi-common-datascope + + + + + com.ruoyi + ruoyi-common-log + + + + + com.ruoyi + ruoyi-common-swagger + + + + + com.taosdata.jdbc + taos-jdbcdriver + 3.1.0 + + + com.ruoyi + hw-api-tdengine + 3.6.3 + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + \ No newline at end of file diff --git a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/HwTdengineApplication.java b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/HwTdengineApplication.java new file mode 100644 index 0000000..c7fafc9 --- /dev/null +++ b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/HwTdengineApplication.java @@ -0,0 +1,34 @@ +package com.ruoyi.tdengine; + +import com.ruoyi.common.security.annotation.EnableCustomConfig; +import com.ruoyi.common.security.annotation.EnableRyFeignClients; +import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * 系统模块 + * + * @author ruoyi + */ +@EnableCustomConfig +@EnableCustomSwagger2 +@EnableRyFeignClients +@SpringBootApplication +public class HwTdengineApplication +{ + public static void main(String[] args) + { + SpringApplication.run(HwTdengineApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 时序数据库模块启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/controller/TdEngineController.java b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/controller/TdEngineController.java new file mode 100644 index 0000000..f3832f5 --- /dev/null +++ b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/controller/TdEngineController.java @@ -0,0 +1,339 @@ +package com.ruoyi.tdengine.controller; + +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.hw.validated.tdengine.AddTdSTableColumn; +import com.ruoyi.common.core.hw.validated.tdengine.InsertTdTable; +import com.ruoyi.tdengine.api.domain.*; +import com.ruoyi.tdengine.service.ITdEngineService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.UncategorizedSQLException; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Map; + +/** + * @ClassDescription: TdEngine Controller + * @ClassName: TdEngineController + * @Author: xins + * @Date: 2023-08-25 16:38:44 + * @Version 1.0 + */ +@RestController +@RequestMapping("/tdengine") +public class TdEngineController { + + @Autowired + private ITdEngineService tdEngineService; + + private static final Logger log = LoggerFactory.getLogger(TdEngineController.class); + + /* @description 创建数据库 + * @author xins + * @date 2023-08-28 11:38 + * @param databaseName + * @return R + */ + @PostMapping("/createDatabase") + public R createDataBase(@RequestBody() String databaseName) { + try { + //调用创建数据库方法 + this.tdEngineService.createDatabase(databaseName); + log.info("success for create database " + databaseName); + return R.ok(); + } catch (UncategorizedSQLException e) { + String message = e.getCause().getMessage(); + try { + message = message.substring(message.lastIndexOf("invalid operation")); + } catch (Exception ex) { + } + log.error(message); + return R.fail(message); + } catch (Exception e) { + log.error(e.getMessage()); + return R.fail(e.getMessage()); + } + } + + /* * @description:创建超级表 + * @author xins + * @date 2023-08-28 11:41 + * @param tdSuperTableVo + * @return R + */ + @PostMapping("/createSuperTable") + public R createSuperTable(@Validated @RequestBody TdSuperTableVo tdSuperTableVo) { + //数据库名称 + String databaseName = tdSuperTableVo.getDatabaseName(); + //超级表名称 + String superTableName = tdSuperTableVo.getSuperTableName(); + //第一个字段名称 + String firstFieldName = tdSuperTableVo.getFirstFieldName(); + //schema列字段(超级表结构)对象集合 + List schemaFields = tdSuperTableVo.getSchemaFields(); + //标签字段对象集合 + List tagsFields = tdSuperTableVo.getTagsFields(); + + try { + //将Schema字段对象和标签字段对象转换为创建表的字段Vo类对象集合 + List schemaFieldsVos = TdFieldVo.batchConvertFields(schemaFields); + List tagsFieldsVos = TdFieldVo.batchConvertFields(tagsFields); + this.tdEngineService.createSuperTable(databaseName, superTableName, firstFieldName, schemaFieldsVos, tagsFieldsVos); + log.info("success for create superTable " + superTableName); + return R.ok("created superTable '" + superTableName + "' success"); + } catch (UncategorizedSQLException e) { + String message = e.getCause().getMessage(); + try { + message = message.substring(message.lastIndexOf("invalid operation")); + } catch (Exception ex) { + } + log.error(message); + return R.fail(message); + } catch (Exception e) { + log.error(e.getMessage()); + return R.fail(e.getMessage()); + } + } + + /** + * @return R + * @param: tableDto + * @description 创建子表 + * @author xins + * @date 2023-08-28 16:17 + */ + @PostMapping("/createTable") + public R createTable(@Validated @RequestBody TdTableVo tdTableVo) { + try { + String databaseName = tdTableVo.getDatabaseName(); + String superTableName = tdTableVo.getSuperTableName(); + String tableName = tdTableVo.getTableName(); + List tagsFieldValues = tdTableVo.getTagsFieldValues(); + this.tdEngineService.createTable(databaseName, superTableName, tableName, tagsFieldValues); + log.info("success for create table " + tableName); + return R.ok("created table '" + tableName + "' success"); + } catch (Exception e) { + String message = e.getCause().getMessage(); + try { + message = message.substring(message.lastIndexOf("invalid operation")); + } catch (Exception ex) { + log.error(ex.getMessage()); + } + log.error(message); + return R.fail(message); + } + } + + + /** + * @return R + * @param: tdSuperTableVo + * @description 超级表增加列 + * @author xins + * @date 2023-08-28 17:55 + */ + @PostMapping("/addSuperTableColumn") + public R addSuperTableColumn(@Validated(AddTdSTableColumn.class) @RequestBody TdSuperTableVo tdSuperTableVo) { + String databaseName = tdSuperTableVo.getDatabaseName(); + String superTableName = tdSuperTableVo.getSuperTableName(); + TdField addTdField = tdSuperTableVo.getField(); + try { + TdFieldVo addFieldVo = TdFieldVo.convertField(addTdField); + this.tdEngineService.addSuperTableColumn(databaseName, superTableName, addFieldVo); + log.info("success for add column for superTable " + superTableName + ""); + return R.ok(); + } catch (UncategorizedSQLException e) { + String message = e.getCause().getMessage(); + try { + message = message.substring(message.lastIndexOf("invalid operation")); + } catch (Exception ex) { + } + log.error(message); + return R.fail(message); + } catch (Exception e) { + log.error(e.getMessage()); + return R.fail(e.getMessage()); + } + } + + /** + * @return R + * @param: tdSuperTableVo + * @description 超级表删除列 + * @author xins + * @date 2023-08-28 17:56 + */ + @PostMapping("/dropSuperTableColumn") + public R dropColumnForSuperTable(@Validated(AddTdSTableColumn.class) @RequestBody TdSuperTableVo tdSuperTableVo) { + String databaseName = tdSuperTableVo.getDatabaseName(); + String superTableName = tdSuperTableVo.getSuperTableName(); + TdField dropField = tdSuperTableVo.getField(); + + try { + TdFieldVo dropFieldVo = TdFieldVo.convertField(dropField); + this.tdEngineService.dropSuperTableColumn(databaseName, superTableName, dropFieldVo); + log.info("successful operation: drop column for superTable '" + superTableName + "' success"); + return R.ok(); + } catch (UncategorizedSQLException e) { + String message = e.getCause().getMessage(); + try { + message = message.substring(message.lastIndexOf("invalid operation")); + } catch (Exception ex) { + } + log.error(message); + return R.fail(message); + } catch (Exception e) { + log.error(e.getMessage()); + return R.fail(e.getMessage()); + } + } + + /** + * @return R + * @param: tdTableVo + * @description 插入数据 + * @author xins + * @date 2023-08-29 10:04 + */ + @PostMapping("/insertTable") + public R insertTable(@Validated(InsertTdTable.class) @RequestBody TdTableVo tdTableVo) { + try { + String databaseName = tdTableVo.getDatabaseName(); + String tableName = tdTableVo.getTableName(); + List schemaFields = tdTableVo.getSchemaFields(); + + this.tdEngineService.insertTable(databaseName, tableName, schemaFields); + log.info("success for insert table " + databaseName + "." + tableName); + return R.ok(); + } catch (UncategorizedSQLException e) { + String message = e.getCause().getMessage(); + try { + message = message.substring(message.lastIndexOf("invalid operation")); + } catch (Exception ex) { + } + log.error(message); + return R.fail(message); + } catch (Exception e) { + log.error(e.getMessage()); + return R.fail(e.getMessage()); + } + } + + + /** + * @return R + * @param: tdSelectDto + * @description 获取某个子表最新一条数据 + * @author xins + * @date 2023-08-29 11:26 + */ + @PostMapping("/getLatestData") + public R getLatestData(@Validated @RequestBody TdSelectDto tdSelectDto) { + try { + return R.ok(this.tdEngineService.getLatestData(tdSelectDto)); + } catch (UncategorizedSQLException e) { + String message = e.getCause().getMessage(); + try { + message = message.substring(message.lastIndexOf("invalid operation")); + } catch (Exception ex) { + } + log.error(message); + return R.fail(message); + } catch (Exception e) { + log.error(e.getMessage()); + return R.fail(e.getMessage()); + } + } + + /** + * @return R>> + * @param: tdSelectDto + * @description 根据tagsname获取超级表最新信息 + * @author xins + * @date 2023-08-29 14:51 + */ + @PostMapping("/getLatestDataByTags") + public R>> getLatestDataByTags(@RequestBody TdSelectDto tdSelectDto) { + try { + return R.ok(this.tdEngineService.getLatestDataByTags(tdSelectDto)); + } catch (UncategorizedSQLException e) { + String message = e.getCause().getMessage(); + try { + message = message.substring(message.lastIndexOf("invalid operation")); + } catch (Exception ex) { + } + log.error(message); + return R.fail(message); + } catch (Exception e) { + log.error(e.getMessage()); + return R.fail(e.getMessage()); + } + } + + + /** + * @param tdHistorySelectDto + * @return R + * @MethodDescription 可视化数据 返回格式,时间,数值列 + * 历史数据 SELECT voltage ,ts FROM test.meters where ts between '2017-07-14 02:40:00.000' and '2017-07-14 02:40:00.001' LIMIT [topnums] + * ts > now - 24h; + * 实时数据 select col from table LIMIT [topnums] + * 聚合数据 select [avg/max/sum/count..](col) from table where ts between '2017-07-14 02:40:00.000' and '2017-07-14 02:40:00.001' group by col LIMIT [topnums] + */ + @PostMapping("/getHistoryData") + public R getHistoryData(@Validated @RequestBody TdHistorySelectDto tdHistorySelectDto) { + try { +// if (selectVisualDto.getType() == 0) {//查询历史 +// return R.ok(this.tdEngineService.getHistoryData(selectVisualDto)); +// }else if(selectVisualDto.getType() == 1) {//查询实时 +// return R.ok(this.tdEngineService.getRealtimeData(selectVisualDto)); +// }else {//查询聚合 +// return R.ok(this.tdEngineService.getAggregateData(selectVisualDto)); +// } + return R.ok(this.tdEngineService.getHistoryData(tdHistorySelectDto)); + } catch (UncategorizedSQLException e) { + String message = e.getCause().getMessage(); + try { + message = message.substring(message.lastIndexOf("invalid operation")); + } catch (Exception ex) { + } + log.error(message); + return R.fail(message); + } catch (Exception e) { + log.error(e.getMessage()); + return R.fail(e.getMessage()); + } + } + + /** + * @param: tdHistorySelectDto + * @description 获取历史数据数量 + * @author xins + * @date 2023-08-29 17:29 + * @return R + */ + @PostMapping("/getCountOfHistoryData") + public R getCountOfHistoryData(@Validated @RequestBody TdHistorySelectDto tdHistorySelectDto) { + try { + return R.ok(this.tdEngineService.getCountOfHistoryData(tdHistorySelectDto)); + } catch (UncategorizedSQLException e) { + String message = e.getCause().getMessage(); + try { + message = message.substring(message.lastIndexOf("invalid operation")); + } catch (Exception ex) { + } + log.error(message); + return R.fail(message); + } catch (Exception e) { + log.error(e.getMessage()); + return R.fail(e.getMessage()); + } + } + +} diff --git a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/mapper/TdEngineMapper.java b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/mapper/TdEngineMapper.java new file mode 100644 index 0000000..ab04823 --- /dev/null +++ b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/mapper/TdEngineMapper.java @@ -0,0 +1,154 @@ +package com.ruoyi.tdengine.mapper; + +import com.ruoyi.tdengine.api.domain.TdField; +import com.ruoyi.tdengine.api.domain.TdFieldVo; +import com.ruoyi.tdengine.api.domain.TdHistorySelectDto; +import com.ruoyi.tdengine.api.domain.TdSelectDto; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassDescription: + * @ClassName: TdEngineMapper + * @Author: thinglinks + * @Date: 2021-12-27 14:52:34 + * @Version 1.0 + */ +public interface TdEngineMapper { + + /** + * @param databaseName + * @description 创建数据库 + * @author xins + * @date 2023-08-28 13:16 + */ + void createDatabase(String databaseName); + + /** + * @param databaseName + * @param superTableName + * @param firstFieldName + * @param schemaFields + * @param tagsFields + * @description 创建超级表 + * @author xins + * @date 2023-08-28 11:09 + */ + void createSuperTable(@Param("databaseName") String databaseName, + @Param("superTableName") String superTableName, + @Param("firstFieldName") String firstFieldName, + @Param("schemaFields") List schemaFields, + @Param("tagsFields") List tagsFields + ); + + /** + * @param: databaseName + * @param: superTableName + * @param: tableName + * @param: tagsFieldValues + * @description 创建子表 + * @author xins + * @date 2023-08-28 15:58 + */ + void createTable(@Param("databaseName") String databaseName, + @Param("superTableName") String superTableName, + @Param("tableName") String tableName, + @Param("tagsFieldValues") List tagsFieldValues); + + + /** + * @param: databaseName + * @param: superTableName + * @param: addFieldsVo + * @description 增加超级表的列 + * @author xins + * @date 2023-08-28 17:11 + */ + void addSuperTableColumn(@Param("databaseName") String databaseName, + @Param("superTableName") String superTableName, + @Param("addFieldsVo") TdFieldVo addFieldsVo); + + /** + * @param: databaseName + * @param: superTableName + * @param: dropFieldsVo + * @description 删除超级表的列 + * @author xins + * @date 2023-08-28 17:11 + */ + void dropSuperTableColumn(@Param("databaseName") String databaseName, + @Param("superTableName") String superTableName, + @Param("dropFieldsVo") TdFieldVo dropFieldsVo); + + + /** + * @param: databaseName + * @param: tableName + * @param: schemaFields + * @description 插入数据 + * @author xins + * @date 2023-08-29 10:03 + */ + void insertTable(@Param("databaseName") String databaseName, + @Param("tableName") String tableName, + @Param("schemaFields") List schemaFields); + + + /** + * @return List> + * @param: tdSelectDto + * @description 查询具体某个子表最新数据,适用于设备监测页面,先根据监控单元获取设备信息,再根据设备来获取最新的数据 + * @author xins + * @date 2023-08-29 10:43 + */ + List> getLatestData(TdSelectDto tdSelectDto); + + /** + * @return List> + * @param: tdSelectDto + * @description 根据tagsname获取超级表最新信息,适用于设备汇总页面,先分页获取设备信息,再获取所有此物模型下的最新信息(冗余,但每页只获取一次,不需要每个设备都获取一次 + * 如果需要根据时间周期获取最新的数据,则需要用select last_row() + * @author xins + * @date 2023-08-29 14:42 + */ + List> getLatestDataByTags(TdSelectDto tdSelectDto); + + + /** + * @return List> + * @param: tdSelectDto + * @description 获取历史数据 + * @author xins + * @date 2023-08-29 15:50 + */ + List> getHistoryData(TdHistorySelectDto tdHistorySelectDto); + + Map getCountOfHistoryData(TdHistorySelectDto tdHistorySelectDto); + + + + +// /** +// * 检查表是否存在 +// * @param dataBaseName +// * @param tableName 可以为超级表名或普通表名 +// * @return +// */ +// Integer checkTableExists(@Param("dataBaseName") String dataBaseName, @Param("tableName")String tableName); + + +// +// List> getRealtimeData(SelectVisualDto selectVisualDto); +// +// List> getAggregateData(SelectVisualDto selectVisualDto); + + + // void addTagForSuperTable(@Param("superTableName") String superTableName, +// @Param("fieldsVo") FieldsVo fieldsVo); +// +// void dropTagForSuperTable(@Param("superTableName") String superTableName, +// @Param("fieldsVo") FieldsVo fieldsVo); + +} diff --git a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/ITdEngineService.java b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/ITdEngineService.java new file mode 100644 index 0000000..c25c29e --- /dev/null +++ b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/ITdEngineService.java @@ -0,0 +1,125 @@ +package com.ruoyi.tdengine.service; + +import com.ruoyi.tdengine.api.domain.TdField; +import com.ruoyi.tdengine.api.domain.TdFieldVo; +import com.ruoyi.tdengine.api.domain.TdHistorySelectDto; +import com.ruoyi.tdengine.api.domain.TdSelectDto; + +import java.util.List; +import java.util.Map; + +/** + * @InterfaceName: ITdEngineService + * @Author : xins + * @Date :2023-08-28 13:14 + * @Description: TdEngineService接口 + * @Version :1.0 + */ +public interface ITdEngineService { + + /** + * @param databaseName + * @description:创建数据库 + * @author xins + * @date 2023-08-28 11:32 + */ + public void createDatabase(String databaseName) throws Exception; + + /** + * @param databaseName + * @param superTableName + * @param firstFieldName + * @param schemaFields + * @param tagsFields + * @description 创建超级表 + * @author xins + * @date 2023-08-28 13:18 + */ + public void createSuperTable(String databaseName, String superTableName, String firstFieldName, List schemaFields, List tagsFields) throws Exception; + + /** + * @param: databaseName + * @param: superTableName + * @param: tableName + * @param: tagsFieldValues + * @description 创建子表 + * @author xins + * @date 2023-08-28 16:16 + */ + public void createTable(String databaseName, String superTableName, String tableName, List tagsFieldValues) throws Exception; + + /** + * @param: databaseName + * @param: superTableName + * @param: addFieldsVo + * @description 增加超级表的列 + * @author xins + * @date 2023-08-28 17:12 + */ + + public void addSuperTableColumn(String databaseName,String superTableName, TdFieldVo addFieldsVo) throws Exception; + + /** + * @param: databaseName + * @param: superTableName + * @param: dropFieldsVo + * @description 删除超级表的列 + * @author xins + * @date 2023-08-28 17:13 + */ + public void dropSuperTableColumn(String databaseName,String superTableName, TdFieldVo dropFieldsVo) throws Exception; + + /** + * @param: databaseName + * @param: tableName + * @param: schemaFields + * @description 插入数据 + * @author xins + * @date 2023-08-29 10:10 + */ + public void insertTable(String databaseName,String tableName,List schemaFields) throws Exception; + + /** + * @param: tdSelectDto + * @description 获取某个子表最新一条数据 + * @author xins + * @date 2023-08-29 11:28 + * @return List> + */ + public List> getLatestData(TdSelectDto tdSelectDto) throws Exception; + + /** + * @return Map> + * @param: tdSelectDto + * @description 根据tagsname获取超级表最新信息,适用于设备汇总页面,先分页获取设备信息,再获取所有此物模型下的最新信息(冗余,但每页只获取一次,不需要每个设备都获取一次 + * * 如果需要根据时间周期获取最新的数据,则需要用select last_row() + * @author xins + * @date 2023-08-29 14:47 + */ + public Map> getLatestDataByTags(TdSelectDto tdSelectDto); + + /** + * @param: tdHistorySelectDto + * @description 获取历史数据 + * @author xins + * @date 2023-08-29 15:52 + * @return List> + */ + public List> getHistoryData(TdHistorySelectDto tdHistorySelectDto); + + /** + * @param: tdHistorySelectDto + * @description 获取历史记录的数量 + * @author xins + * @date 2023-08-29 16:54 + * @return Long + */ + public Long getCountOfHistoryData(TdHistorySelectDto tdHistorySelectDto) throws Exception; + + +// void initSTableFrame(String msg) throws Exception; + +// List> getRealtimeData(SelectVisualDto selectVisualDto); +// +// List> getAggregateData(SelectVisualDto selectVisualDto); +} diff --git a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/impl/TdEngineServiceImpl.java b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/impl/TdEngineServiceImpl.java new file mode 100644 index 0000000..3b4ebbe --- /dev/null +++ b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/impl/TdEngineServiceImpl.java @@ -0,0 +1,289 @@ +package com.ruoyi.tdengine.service.impl; + +import com.ruoyi.common.core.constant.TdEngineConstants; +import com.ruoyi.tdengine.api.domain.TdField; +import com.ruoyi.tdengine.api.domain.TdFieldVo; +import com.ruoyi.tdengine.api.domain.TdHistorySelectDto; +import com.ruoyi.tdengine.api.domain.TdSelectDto; +import com.ruoyi.tdengine.mapper.TdEngineMapper; +import com.ruoyi.tdengine.service.ITdEngineService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @ClassDescription: TdEngine业务实现逻辑 + * @ClassName: TdEngineServiceImpl + * @Author: xins + * @Date: 2023-08-25 15:55:50 + * @Version 1.0 + */ +@Service +//@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) +public class TdEngineServiceImpl implements ITdEngineService { + private static final String DEFAULT_FIRST_FIELD_NAME = "ts"; + + @Autowired + private TdEngineMapper tdEngineMapper; +// @Autowired +// private RedisService redisService; + + /** + * @param databaseName + * @description:创建数据库 + * @author xins + * @date 2023-08-28 11:32 + */ + @Override + public void createDatabase(String databaseName) throws Exception { + this.tdEngineMapper.createDatabase(databaseName); + } + + /** + * @param databaseName + * @param superTableName + * @param firstFieldName + * @param schemaFields + * @param tagsFields + * @description 创建超级表 + * @author xins + * @date 2023-08-28 13:18 + */ + @Override + public void createSuperTable(String databaseName, String superTableName, String firstFieldName, List schemaFields, List tagsFields) throws Exception { + if (StringUtils.isBlank(firstFieldName)) { + firstFieldName = DEFAULT_FIRST_FIELD_NAME; + } + this.tdEngineMapper.createSuperTable(databaseName, superTableName, firstFieldName, schemaFields, tagsFields); + } + + /** + * @param: databaseName + * @param: superTableName + * @param: tableName + * @param: tagsFieldValues + * @description 创建子表 + * @author xins + * @date 2023-08-28 16:16 + */ + @Override + public void createTable(String databaseName, String superTableName, String tableName, List tagsFieldValues) throws Exception { + this.tdEngineMapper.createTable(databaseName, superTableName, tableName, tagsFieldValues); + + } + + /** + * @param: databaseName + * @param: superTableName + * @param: addFieldsVo + * @description 增加超级表的列 + * @author xins + * @date 2023-08-28 17:12 + */ + @Override + public void addSuperTableColumn(String databaseName, String superTableName, TdFieldVo addFieldsVo) throws Exception { + this.tdEngineMapper.addSuperTableColumn(databaseName, superTableName, addFieldsVo); + } + + /** + * @param: databaseName + * @param: superTableName + * @param: dropFieldsVo + * @description 删除超级表的列 + * @author xins + * @date 2023-08-28 17:13 + */ + public void dropSuperTableColumn(String databaseName, String superTableName, TdFieldVo dropFieldsVo) throws Exception { + this.tdEngineMapper.dropSuperTableColumn(databaseName, superTableName, dropFieldsVo); + } + + + /** + * @param: databaseName + * @param: tableName + * @param: schemaFields + * @description 插入数据 + * @author xins + * @date 2023-08-29 10:10 + */ + @Override + public void insertTable(String databaseName, String tableName, List schemaFields) throws Exception { + this.tdEngineMapper.insertTable(databaseName, tableName, schemaFields); + } + + /** + * @return List> + * @param: tdSelectDto + * @description 查询具体某个子表最新数据,适用于设备监测页面,先根据监控单元获取设备信息,再根据设备来获取最新的数据 + * @author xins + * @date 2023-08-29 11:28 + */ + @Override + public List> getLatestData(TdSelectDto tdSelectDto) throws Exception { + List> latestMaps = this.tdEngineMapper.getLatestData(tdSelectDto); + + List> filterMaps = new ArrayList<>(); + +// String i18nKey = "tdengine_supertable1_"; + String i18nKey = "";//todo:国际化看在哪处理 + /** + * 由于通过last(*)获取则获取的key为last(key),所以需要以下过滤,需要获取括号中间的真正key + */ + for (Map latestMap : latestMaps) { + Map filterMap = latestMap.entrySet() + .stream() + .filter(entry -> entry.getValue() != null) + .collect(HashMap::new, (m, v) -> + m.put(i18nKey + v.getKey().substring(v.getKey().indexOf("(") + 1, + v.getKey().indexOf(")")), v.getValue()), HashMap::putAll); + filterMaps.add(filterMap); + } + return filterMaps; + } + + /** + * @return Map> + * @param: tdSelectDto + * @description 根据tagsname获取超级表最新信息,适用于设备汇总页面,先分页获取设备信息,再获取所有此物模型下的最新信息(冗余,但每页只获取一次,不需要每个设备都获取一次 + * * 如果需要根据时间周期获取最新的数据,则需要用select last_row() + * @author xins + * @date 2023-08-29 14:47 + */ + @Override + public Map> getLatestDataByTags(TdSelectDto tdSelectDto) { + List> latestMaps = this.tdEngineMapper.getLatestDataByTags(tdSelectDto); + Map> tagsMap = new HashMap<>(); + for (Map latestMap : latestMaps) { + Map filterMap = latestMap.entrySet() + .stream() + .filter(entry -> entry.getValue() != null) + .collect(HashMap::new, (m, v) -> + m.put(v.getKey().substring(v.getKey().indexOf("(") + 1, + v.getKey().indexOf(")")), v.getValue()), HashMap::putAll); + tagsMap.put(filterMap.get(tdSelectDto.getTagsName()).toString(), filterMap); + } + return tagsMap; + } + + + /** + * @return List> + * @param: tdHistorySelectDto + * @description 获取历史数据 + * @author xins + * @date 2023-08-29 15:52 + */ + @Override + public List> getHistoryData(TdHistorySelectDto tdHistorySelectDto) { + if (StringUtils.isBlank(tdHistorySelectDto.getOrderByFieldName())) { + tdHistorySelectDto.setOrderByFieldName(TdEngineConstants.DEFAULT_FIRST_FIELD_NAME); + } + if (StringUtils.isBlank(tdHistorySelectDto.getOrderByMode())) { + tdHistorySelectDto.setOrderByMode(TdEngineConstants.DEFAULT_ORDER_BY_MODE); + } + + List> historyDataMaps = this.tdEngineMapper.getHistoryData(tdHistorySelectDto); + return historyDataMaps; + } + + + /** + * @param: tdHistorySelectDto + * @description 获取历史记录的数量 + * @author xins + * @date 2023-08-29 16:54 + * @return Long + */ + @Override + public Long getCountOfHistoryData(TdHistorySelectDto tdHistorySelectDto) throws Exception { + Map countMap = this.tdEngineMapper.getCountOfHistoryData(tdHistorySelectDto); + if (countMap == null) { + return 0L; + } + return countMap.get("dataCount"); + } + + + + +// +// /** +// * 检查数据库表是否存在 +// * +// * @param dataBaseName 数据库名 +// * @param tableName tableName 可以为超级表名或普通表名 +// * @return +// */ +// public boolean checkTableExists(String dataBaseName, String tableName) throws Exception { +// try { +// Integer count = tdEngineMapper.checkTableExists(dataBaseName, tableName); +// return count == 1; +// } catch (Exception e) { +// log.warn("{},{} 数据库表不存在", dataBaseName, tableName); +// return false; +// } +// } +// +// @Override +// public void initSTableFrame(String msg) throws Exception { +// final SuperTableDto superTableDto = JSONObject.toJavaObject(JSONObject.parseObject(msg), SuperTableDto.class); +// //从入参对象获取列字段(超级表结构)对象集合 +// List schemaFields = superTableDto.getSchemaFields(); +// //从入参对象获取标签字段对象集合 +// List tagsFields = superTableDto.getTagsFields(); +// //从入参获取数据库名称 +// String dataBaseName = superTableDto.getDataBaseName(); +// //从入参获取超级表名称 +// String superTableName = superTableDto.getSuperTableName(); +// final boolean tableExists = this.checkTableExists(dataBaseName, superTableName); +// if (tableExists) { +// log.info("超级表{}已存在", superTableName); +// return; +// } +// //获取列字段对象集合的第一个对象的字段数据类型 +// DataTypeEnum dataType = schemaFields.get(0).getDataType(); +// //如果该数据类型不是时间戳,打印和返回报错信息 +// if (dataType == null || !"timestamp".equals(dataType.getDataType())) { +// log.error("invalid operation: first column must be timestamp"); +// return; +// } +// //将列字段对象集合和标签字段对象集合转码为字段Vo类对象集合 +// List schemaFieldsVoList = FieldsVo.fieldsTranscoding(schemaFields); +// List tagsFieldsVoList = FieldsVo.fieldsTranscoding(tagsFields); +// //创建超级表 +// this.createSuperTable(schemaFieldsVoList, tagsFieldsVoList, dataBaseName, superTableName); +// log.info("create {} super table success", superTableName); +// } +// + +// +// /** +// * @param tagsSelectDao +// * @return +// */ +// @Override + +// +// + +// +// @Override +// public List> getRealtimeData(SelectVisualDto selectVisualDto) { +// List> maps = this.tdEngineMapper.getRealtimeData(selectVisualDto); +// return maps; +// } +// +// @Override +// public List> getAggregateData(SelectVisualDto selectVisualDto) { +// List> maps = this.tdEngineMapper.getAggregateData(selectVisualDto); +// return maps; +// } + +} diff --git a/ruoyi-modules/hw-tdengine/src/main/resources/banner.txt b/ruoyi-modules/hw-tdengine/src/main/resources/banner.txt new file mode 100644 index 0000000..fbd45f5 --- /dev/null +++ b/ruoyi-modules/hw-tdengine/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ _ + (_) | | + _ __ _ _ ___ _ _ _ ______ ___ _ _ ___ | |_ ___ _ __ ___ +| '__|| | | | / _ \ | | | || ||______|/ __|| | | |/ __|| __| / _ \| '_ ` _ \ +| | | |_| || (_) || |_| || | \__ \| |_| |\__ \| |_ | __/| | | | | | +|_| \__,_| \___/ \__, ||_| |___/ \__, ||___/ \__| \___||_| |_| |_| + __/ | __/ | + |___/ |___/ \ No newline at end of file diff --git a/ruoyi-modules/hw-tdengine/src/main/resources/bootstrap.yml b/ruoyi-modules/hw-tdengine/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..5c55aa3 --- /dev/null +++ b/ruoyi-modules/hw-tdengine/src/main/resources/bootstrap.yml @@ -0,0 +1,25 @@ +# Tomcat +server: + port: 9602 + +# Spring +spring: + application: + # 应用名称 + name: hw-tdengine + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/ruoyi-modules/hw-tdengine/src/main/resources/logback.xml b/ruoyi-modules/hw-tdengine/src/main/resources/logback.xml new file mode 100644 index 0000000..27d1aec --- /dev/null +++ b/ruoyi-modules/hw-tdengine/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-modules/hw-tdengine/src/main/resources/mapper/tdengine/TdEngineMapper.xml b/ruoyi-modules/hw-tdengine/src/main/resources/mapper/tdengine/TdEngineMapper.xml new file mode 100644 index 0000000..1b1570c --- /dev/null +++ b/ruoyi-modules/hw-tdengine/src/main/resources/mapper/tdengine/TdEngineMapper.xml @@ -0,0 +1,251 @@ + + + + + + create database if not exists #{databaseName} + + + + create table if not exists #{databaseName}.#{superTableName} + (${firstFieldName} timestamp, + + + + ${item.fieldName} + + + + + timestamp + + + tinyint + + + smallint + + + int + + + bigint + + + float + + + double + + + binary + + + nchar + + + bool + + + json + + + + + + (#{item.size}) + + + ) tags + + + + ${item.fieldName} + + + + + timestamp + + + int + + + bigint + + + float + + + double + + + binary + + + smallint + + + tinyint + + + bool + + + nchar + + + json + + + + + (#{item.size}) + + + + + + create table if not exists #{databaseName}.#{tableName} + using #{databaseName}.#{superTableName} + tags + + ${item.fieldValue} + + + + + + + ALTER STABLE #{databaseName}.#{superTableName} ADD COLUMN + + ${addFieldsVo.fieldName} + + + + + timestamp + + + int + + + bigint + + + float + + + double + + + binary + + + smallint + + + tinyint + + + bool + + + nchar + + + json + + + + + (#{addFieldsVo.size}) + + + + + ALTER STABLE #{databaseName}.#{superTableName} DROP COLUMN + + ${dropFieldsVo.fieldName} + + + + + + + insert into #{databaseName}.#{tableName} + + ${item.fieldName} + + values + + #{item.fieldValue} + + + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-modules/pom.xml b/ruoyi-modules/pom.xml index a5f5c70..b5a5a35 100644 --- a/ruoyi-modules/pom.xml +++ b/ruoyi-modules/pom.xml @@ -26,6 +26,7 @@ hw-mqtt-broker hw-business hw-basic + hw-tdengine ruoyi-modules