diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml
index b9026f6897..3e58c660b1 100644
--- a/yudao-dependencies/pom.xml
+++ b/yudao-dependencies/pom.xml
@@ -35,6 +35,8 @@
8.1.3.140
8.6.0
5.1.0
+ 3.7.8
+
2.3.1
@@ -287,6 +289,12 @@
${kingbase.jdbc.version}
+
+ com.taosdata.jdbc
+ taos-jdbcdriver
+ ${taosdata.version}
+
+
cn.iocoder.boot
diff --git a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
index 472b75ce11..15f3d6296f 100644
--- a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
+++ b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
@@ -48,5 +48,6 @@ public interface ErrorCodeConstants {
ErrorCode OPC_CONNECT_FAILURE_DOES_NOT_EXIST= new ErrorCode(1_003_000_000, "OPC连接失败,请检测url及账号密码是否正确");
ErrorCode OPC_CLOSE_CONNECT_FAILURE= new ErrorCode(1_003_000_000, "OPC断开连接失败");
ErrorCode OPC_PARAMETER_DOES_NOT_EXIST= new ErrorCode(1_003_000_000, "连接关闭参数不存在");
+ ErrorCode CREATE_TDENGINE_FAILURE= new ErrorCode(1_003_000_000, "创建Tdengine子表失败");
}
diff --git a/yudao-module-iot/yudao-module-iot-biz/pom.xml b/yudao-module-iot/yudao-module-iot-biz/pom.xml
index a6b86a4a21..57aa44754a 100644
--- a/yudao-module-iot/yudao-module-iot-biz/pom.xml
+++ b/yudao-module-iot/yudao-module-iot-biz/pom.xml
@@ -58,6 +58,11 @@
yudao-spring-boot-starter-test
+
+ com.taosdata.jdbc
+ taos-jdbcdriver
+
+
cn.iocoder.boot
yudao-spring-boot-starter-excel
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java
index d732e0a583..a03f336f90 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java
@@ -6,9 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DevicePageReqVO;
-import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceRespVO;
-import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceSaveReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.*;
import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.DeviceContactModelPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.devicemodelattribute.vo.DeviceModelAttributePageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceAttributeDO;
@@ -126,6 +124,18 @@ public class DeviceController {
}
+ @GetMapping("/lineDevicePage")
+ @Operation(summary = "获得产线设备分页")
+ @PreAuthorize("@ss.hasPermission('iot:device:query')")
+ public CommonResult> lineDevicePage(@Valid LineDeviceRequestVO pageReqVO) {
+ PageResult pageResult = deviceService.lineDevicePage(pageReqVO);
+ return success(pageResult);
+ }
+
+
+
+
+
// ==================== 子表(设备属性) ====================
@@ -169,4 +179,8 @@ public class DeviceController {
return success(deviceService.getDeviceAttribute(id));
}
+
+
+
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/config/TDengineConfig.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/config/TDengineConfig.java
new file mode 100644
index 0000000000..815e31c9c6
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/config/TDengineConfig.java
@@ -0,0 +1,17 @@
+package cn.iocoder.yudao.module.iot.controller.admin.device.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import javax.sql.DataSource;
+
+@Configuration
+public class TDengineConfig {
+
+ @Bean("tdengineJdbcTemplate")
+ public JdbcTemplate tdengineJdbcTemplate(DataSource dataSource) {
+ // 此处的dataSource会自动注入上面在yml中配置的TDengine数据源
+ return new JdbcTemplate(dataSource);
+ }
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/LineDeviceRequestVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/LineDeviceRequestVO.java
new file mode 100644
index 0000000000..e2967298ed
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/LineDeviceRequestVO.java
@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.time.LocalDateTime;
+
+@Data
+public class LineDeviceRequestVO extends PageParam {
+
+ @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26404")
+ private Long id;
+
+ @Schema(description = "产线编码")
+ private String lineNode;
+
+ @Schema(description = "产线名称")
+ private String lineName;
+
+ @Schema(description = "设备编码")
+ private String deviceCode;
+
+ @Schema(description = "设备名称")
+ private String deviceName;
+
+ @Schema(description = "状态 1-在线 2-离线")
+ private String status;
+
+ @Schema(description = "采集时间")
+ private LocalDateTime collectionTime;
+
+}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/LineDeviceRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/LineDeviceRespVO.java
new file mode 100644
index 0000000000..804fdb346f
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/LineDeviceRespVO.java
@@ -0,0 +1,35 @@
+package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+
+@Schema(description = "管理后台 - 产线设备分页返回 Resq VO")
+@Data
+public class LineDeviceRespVO {
+
+ @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26404")
+ private Long id;
+
+ @Schema(description = "产线编码")
+ private String lineNode;
+
+ @Schema(description = "产线名称")
+ private String lineName;
+
+ @Schema(description = "设备编码")
+ private String deviceCode;
+
+ @Schema(description = "设备名称")
+ private String deviceName;
+
+ @Schema(description = "状态 1-在线 2-离线")
+ private String status;
+
+ @Schema(description = "采集时间")
+ private LocalDateTime collectionTime;
+
+}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/vo/DeviceModelRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/vo/DeviceModelRespVO.java
index ee93cb7fe8..58711a4ad0 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/vo/DeviceModelRespVO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/vo/DeviceModelRespVO.java
@@ -17,12 +17,12 @@ public class DeviceModelRespVO {
// @ExcelProperty("ID")
private Long id;
- @Schema(description = "分类编码", requiredMode = Schema.RequiredMode.REQUIRED)
- @ExcelProperty("分类编码")
+ @Schema(description = "模型编码", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("模型编码")
private String code;
- @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
- @ExcelProperty("分类名称")
+ @Schema(description = "模型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
+ @ExcelProperty("模型名称")
private String name;
@Schema(description = "通讯协议", requiredMode = Schema.RequiredMode.REQUIRED)
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceMapper.java
index 2f23f9c655..bf003757d6 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceMapper.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceMapper.java
@@ -5,9 +5,14 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DevicePageReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.LineDeviceRequestVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.LineDeviceRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import com.alibaba.excel.util.StringUtils;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
import java.util.Arrays;
import java.util.List;
@@ -88,4 +93,7 @@ public interface DeviceMapper extends BaseMapperX {
.eqIfPresent(DeviceDO::getIsEnable, reqVO.getIsEnable())
.orderByDesc(DeviceDO::getId));
}
+
+ IPage lineDevicePage(Page page, @Param("pageReqVO") LineDeviceRequestVO pageReqVO);
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/devicemodel/DeviceModelMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/devicemodel/DeviceModelMapper.java
index 773b0388d2..16ddddfee9 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/devicemodel/DeviceModelMapper.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/devicemodel/DeviceModelMapper.java
@@ -1,11 +1,14 @@
package cn.iocoder.yudao.module.iot.dal.mysql.devicemodel;
import java.util.*;
+import java.util.stream.Collectors;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodel.DeviceModelDO;
+import com.alibaba.excel.util.StringUtils;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.iot.controller.admin.devicemodel.vo.*;
@@ -18,13 +21,29 @@ import cn.iocoder.yudao.module.iot.controller.admin.devicemodel.vo.*;
public interface DeviceModelMapper extends BaseMapperX {
default PageResult selectPage(DeviceModelPageReqVO reqVO) {
- return selectPage(reqVO, new LambdaQueryWrapperX()
- .eqIfPresent(DeviceModelDO::getCode, reqVO.getCode())
+
+ LambdaQueryWrapperX deviceModelDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
+ deviceModelDOLambdaQueryWrapperX.eqIfPresent(DeviceModelDO::getCode, reqVO.getCode())
.likeIfPresent(DeviceModelDO::getName, reqVO.getName())
.eqIfPresent(DeviceModelDO::getProtocol, reqVO.getProtocol())
.eqIfPresent(DeviceModelDO::getRemark, reqVO.getRemark())
.betweenIfPresent(DeviceModelDO::getCreateTime, reqVO.getCreateTime())
- .orderByDesc(DeviceModelDO::getId));
+ .orderByDesc(DeviceModelDO::getCreateTime);
+
+
+ // 单独处理 ids 条件
+ if (StringUtils.isNotBlank(reqVO.getIds())) {
+ List idList = Arrays.stream(reqVO.getIds().split(","))
+ .map(String::trim)
+ .map(Long::valueOf)
+ .collect(Collectors.toList());
+ deviceModelDOLambdaQueryWrapperX.in(DeviceModelDO::getId, idList);
+ }
+
+
+ return selectPage(reqVO, deviceModelDOLambdaQueryWrapperX);
+
+
}
default List select() {
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java
index 2530aa159e..f0dc18551c 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java
@@ -6,6 +6,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DevicePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceSaveReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.LineDeviceRequestVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.LineDeviceRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.DeviceContactModelPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.devicemodelattribute.vo.DeviceModelAttributePageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
@@ -118,4 +120,6 @@ public interface DeviceService {
Boolean connectDevice(DeviceSaveReqVO createReqVO);
Long copyDevice(Long id);
+
+ PageResult lineDevicePage(LineDeviceRequestVO pageReqVO);
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java
index 59d46c7eb3..0c7165faf3 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java
@@ -6,9 +6,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.opc.OpcUtils;
-import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DevicePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceSaveReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.LineDeviceRequestVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.LineDeviceRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.DeviceContactModelPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.devicemodelattribute.vo.DeviceModelAttributePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.mqttdatarecord.vo.MqttDataRecordPageReqVO;
@@ -27,8 +28,13 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceAttributeDO;
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceAttributeMapper;
+import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -66,6 +72,12 @@ public class DeviceServiceImpl implements DeviceService {
@Resource
private MqttDataRecordMapper mqttDataRecordMapper;
+ @Resource
+ @Qualifier("tdengineJdbcTemplate")
+ private JdbcTemplate tdengineJdbcTemplate;
+
+ @Resource
+ private TDengineService tdengineService;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -100,10 +112,60 @@ public class DeviceServiceImpl implements DeviceService {
}
deviceContactModelMapper.insertBatch(contactModelList);
+ //创建时序数据库
+// createTDengine(device.getId());
+
+ tdengineService.initDatabaseAndTable(device.getId());
+
// 返回
return device.getId();
}
+ @DS("tdengine")
+ public void createTDengine(Long id) {
+
+ try {
+ // 测试TDengine连接
+ String testSQL = "SELECT 1";
+ tdengineJdbcTemplate.queryForObject(testSQL, Integer.class);
+ System.out.println("TDengine连接正常");
+ } catch (Exception e) {
+ throw new RuntimeException("无法连接到TDengine,请检查数据源配置", e);
+ }
+
+ try {
+ // 创建数据库 - 使用更兼容的语法[1,6](@ref)
+ String createDbSQL = "CREATE DATABASE IF NOT EXISTS besure KEEP 365 DURATION 30";
+ tdengineJdbcTemplate.execute(createDbSQL);
+
+ // 使用数据库
+ tdengineJdbcTemplate.execute("USE besure");
+
+ // 创建超级表
+ String createSuperTableSQL = "CREATE STABLE IF NOT EXISTS device_data (" +
+ "ts TIMESTAMP, " +
+ "query_data NCHAR(2048)" +
+ ") TAGS (device_id BIGINT)";
+ tdengineJdbcTemplate.execute(createSuperTableSQL);
+
+ // 创建子表
+ String tableName = "d_" + id;
+ String createTableSql = String.format(
+ "CREATE TABLE IF NOT EXISTS %s USING device_data TAGS(%d)",
+ tableName, id);
+ tdengineJdbcTemplate.execute(createTableSql);
+
+ System.out.println("TDengine表创建成功: " + tableName);
+
+ } catch (Exception e) {
+ System.err.println("TDengine操作失败: " + e.getMessage());
+ e.printStackTrace();
+ throw exception(CREATE_TDENGINE_FAILURE);
+ }
+
+
+ }
+
//@Scheduled(cron="0/5 * * * * ? ") //每1秒执行一次
public void updateDeviceStatus(){
List list = deviceMapper.selectList();
@@ -317,6 +379,22 @@ public class DeviceServiceImpl implements DeviceService {
}
+ @Override
+ public PageResult lineDevicePage(LineDeviceRequestVO pageReqVO) {
+
+ Page page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
+
+
+ IPage lineDeviceRespVO = deviceMapper.lineDevicePage(page,pageReqVO);
+ List records = lineDeviceRespVO.getRecords();
+ PageResult lineDeviceRespVOPageResult = new PageResult<>(lineDeviceRespVO.getRecords(), lineDeviceRespVO.getTotal());
+
+
+ return lineDeviceRespVOPageResult;
+
+
+ }
+
private void validateDeviceAttributeExists(Long id) {
if (deviceAttributeMapper.selectById(id) == null) {
throw exception(DEVICE_ATTRIBUTE_NOT_EXISTS);
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/TDengineService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/TDengineService.java
new file mode 100644
index 0000000000..a565f95c65
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/TDengineService.java
@@ -0,0 +1,48 @@
+package cn.iocoder.yudao.module.iot.service.device;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+public class TDengineService {
+
+ @Resource
+ private JdbcTemplate tdengineJdbcTemplate;
+
+ @DS("tdengine")
+ public void testConnection() {
+ String testSQL = "SELECT SERVER_STATUS()";
+ tdengineJdbcTemplate.queryForObject(testSQL, Integer.class);
+ System.out.println("TDengine连接正常");
+ }
+
+ @DS("tdengine")
+ public void initDatabaseAndTable(Long id) {
+ // 1. 创建数据库(使用正确的TDengine语法)
+ // 注意:KEEP 必须大于或等于 3 倍的 DURATION[6](@ref),建议调整
+ String createDbSQL = "CREATE DATABASE IF NOT EXISTS besure KEEP 365 DURATION 30";
+ tdengineJdbcTemplate.execute(createDbSQL);
+
+ // 2. 使用数据库
+ tdengineJdbcTemplate.execute("USE besure");
+
+ // 3. 创建超级表
+ String createSuperTableSQL = "CREATE STABLE IF NOT EXISTS device_data (" +
+ "ts TIMESTAMP, " +
+ "query_data NCHAR(2048)" +
+ ") TAGS (device_id BIGINT)";
+ tdengineJdbcTemplate.execute(createSuperTableSQL);
+
+ // 4. 创建子表
+ String tableName = "d_" + id;
+ String createTableSql = String.format(
+ "CREATE TABLE IF NOT EXISTS %s USING device_data TAGS(%d)",
+ tableName, id);
+ tdengineJdbcTemplate.execute(createTableSql);
+
+ System.out.println("TDengine表创建成功: " + tableName);
+ }
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/DeviceMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/DeviceMapper.xml
index 548b593d61..ebe3310554 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/DeviceMapper.xml
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/DeviceMapper.xml
@@ -9,4 +9,39 @@
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
-->
+
+
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImplTest.java b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImplTest.java
index 8618fc582b..2f8878b3fa 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImplTest.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImplTest.java
@@ -105,6 +105,17 @@ public class DeviceServiceImplTest extends BaseDbUnitTest {
assertServiceException(() -> deviceService.deleteDevice(Collections.singletonList(id)), DEVICE_NOT_EXISTS);
}
+
+ @Test
+ public void testCreateTDengine() {
+ // 准备参数
+ Long id = 12313L;
+ deviceService.createTDengine(id);
+ }
+
+
+
+
@Test
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
public void testGetDevicePage() {
diff --git a/yudao-server/src/main/resources/application-dev.yaml b/yudao-server/src/main/resources/application-dev.yaml
index 1c3a86423e..d92aa9ce1f 100644
--- a/yudao-server/src/main/resources/application-dev.yaml
+++ b/yudao-server/src/main/resources/application-dev.yaml
@@ -55,6 +55,20 @@ spring:
# url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
username: root
password: ngsk0809
+ tdengine:
+ name: tdengine
+ url: jdbc:TAOS-RS://192.168.5.5:6041/besure?charset=UTF-8&locale=en_US.UTF-8
+ username: root
+ password: taosdata
+ driver-class-name: com.taosdata.jdbc.rs.RestfulDriver # TDengine REST驱动
+ # TDengine 专用连接池配置
+ druid:
+ initial-size: 1
+ max-active: 20 # TDengine 连接数不需要太多
+ validation-query: SELECT SERVER_STATUS() # 使用 TDengine 兼容的验证语句[5](@ref)
+ connection-error-retry-attempts: 1 # 减少重试次数
+ break-after-acquire-failure: true
+ fail-fast: true
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis: