From ba743c9a26b5ec45cb9f76527f6e23774b761cff Mon Sep 17 00:00:00 2001 From: HuangHuiKang Date: Wed, 31 Dec 2025 17:53:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=96=B0=E5=A2=9E=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=9B=91=E6=8E=A7=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-dependencies/pom.xml | 8 ++ .../module/iot/enums/ErrorCodeConstants.java | 1 + yudao-module-iot/yudao-module-iot-biz/pom.xml | 5 ++ .../admin/device/DeviceController.java | 20 ++++- .../admin/device/config/TDengineConfig.java | 17 ++++ .../admin/device/vo/LineDeviceRequestVO.java | 34 ++++++++ .../admin/device/vo/LineDeviceRespVO.java | 35 ++++++++ .../devicemodel/vo/DeviceModelRespVO.java | 8 +- .../iot/dal/mysql/device/DeviceMapper.java | 8 ++ .../mysql/devicemodel/DeviceModelMapper.java | 25 +++++- .../iot/service/device/DeviceService.java | 4 + .../iot/service/device/DeviceServiceImpl.java | 80 ++++++++++++++++++- .../iot/service/device/TDengineService.java | 48 +++++++++++ .../resources/mapper/device/DeviceMapper.xml | 35 ++++++++ .../service/device/DeviceServiceImplTest.java | 11 +++ .../src/main/resources/application-dev.yaml | 14 ++++ 16 files changed, 342 insertions(+), 11 deletions(-) create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/config/TDengineConfig.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/LineDeviceRequestVO.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/LineDeviceRespVO.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/TDengineService.java 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: