Commit 16120820a0094ecc74e5197e7497c10d485c9668
Merge branch 'feature/iot' of https://gitee.com/alwayssuper/ruoyi-vue-pro into feature/iot
# Conflicts: # yudao-server/src/main/resources/application-local.yaml
Showing
24 changed files
with
618 additions
and
103 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceDataController.java
| ... | ... | @@ -3,19 +3,19 @@ package cn.iocoder.yudao.module.iot.controller.admin.device; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataPageReqVO; | |
| 7 | -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataRespVO; | |
| 6 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceSaveReqVO; | |
| 7 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.*; | |
| 8 | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO; |
| 9 | -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotTimeDataRespVO; | |
| 9 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; | |
| 10 | +import cn.iocoder.yudao.module.iot.service.device.IotDeviceLogDataService; | |
| 10 | 11 | import cn.iocoder.yudao.module.iot.service.device.IotDevicePropertyDataService; |
| 11 | 12 | import io.swagger.v3.oas.annotations.Operation; |
| 12 | 13 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 13 | 14 | import jakarta.annotation.Resource; |
| 14 | 15 | import jakarta.validation.Valid; |
| 16 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 15 | 17 | import org.springframework.validation.annotation.Validated; |
| 16 | -import org.springframework.web.bind.annotation.GetMapping; | |
| 17 | -import org.springframework.web.bind.annotation.RequestMapping; | |
| 18 | -import org.springframework.web.bind.annotation.RestController; | |
| 18 | +import org.springframework.web.bind.annotation.*; | |
| 19 | 19 | |
| 20 | 20 | import java.util.List; |
| 21 | 21 | import java.util.Map; |
| ... | ... | @@ -31,6 +31,12 @@ public class IotDeviceDataController { |
| 31 | 31 | @Resource |
| 32 | 32 | private IotDevicePropertyDataService deviceDataService; |
| 33 | 33 | |
| 34 | + @Resource | |
| 35 | + private IotDeviceLogDataService iotDeviceLogDataService; | |
| 36 | + | |
| 37 | + @Resource | |
| 38 | + private IotDeviceLogDataService deviceLogDataService; | |
| 39 | + | |
| 34 | 40 | // TODO @浩浩:这里的 /latest-list,包括方法名。 |
| 35 | 41 | @GetMapping("/latest") |
| 36 | 42 | @Operation(summary = "获取设备属性最新数据") |
| ... | ... | @@ -46,5 +52,20 @@ public class IotDeviceDataController { |
| 46 | 52 | PageResult<Map<String, Object>> list = deviceDataService.getHistoryDeviceProperties(deviceDataReqVO); |
| 47 | 53 | return success(BeanUtils.toBean(list, IotTimeDataRespVO.class)); |
| 48 | 54 | } |
| 55 | + // TODO:数据权限 | |
| 56 | + @PostMapping("/simulator") | |
| 57 | + @Operation(summary = "模拟设备") | |
| 58 | + public CommonResult<Boolean> simulatorDevice(@Valid @RequestBody IotDeviceDataSimulatorSaveReqVO simulatorReqVO) { | |
| 59 | + //TODO:先生成一下设备日志 后续完善模拟设备代码逻辑 | |
| 60 | + iotDeviceLogDataService.createDeviceLog(simulatorReqVO); | |
| 61 | + return success(true); | |
| 62 | + } | |
| 63 | + // TODO:数据权限 | |
| 64 | + @GetMapping("/log/page") | |
| 65 | + @Operation(summary = "获得设备日志分页") | |
| 66 | + public CommonResult<PageResult<IotDeviceLogRespVO>> getDeviceLogPage(@Valid IotDeviceLogPageReqVO pageReqVO) { | |
| 67 | + PageResult<IotDeviceLogDO> pageResult = deviceLogDataService.getDeviceLogPage(pageReqVO); | |
| 68 | + return success(BeanUtils.toBean(pageResult, IotDeviceLogRespVO.class)); | |
| 69 | + } | |
| 49 | 70 | |
| 50 | 71 | } |
| 51 | 72 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceSaveReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device; |
| 2 | 2 | |
| 3 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | +import jakarta.validation.constraints.Size; | |
| 4 | 5 | import lombok.Data; |
| 5 | 6 | |
| 6 | 7 | import java.util.Set; |
| ... | ... | @@ -13,6 +14,7 @@ public class IotDeviceSaveReqVO { |
| 13 | 14 | private Long id; |
| 14 | 15 | |
| 15 | 16 | @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.AUTO, example = "177") |
| 17 | + @Size(max = 50, message = "设备编号长度不能超过50个字符") | |
| 16 | 18 | private String deviceKey; |
| 17 | 19 | |
| 18 | 20 | @Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataSimulatorSaveReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData; | |
| 2 | + | |
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | +import jakarta.validation.constraints.NotEmpty; | |
| 5 | +import lombok.Data; | |
| 6 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 7 | + | |
| 8 | +import java.time.LocalDateTime; | |
| 9 | + | |
| 10 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 11 | + | |
| 12 | +@Schema(description = "管理后台 - IoT 模拟设备数据 Request VO") | |
| 13 | +@Data | |
| 14 | +public class IotDeviceDataSimulatorSaveReqVO { | |
| 15 | + | |
| 16 | + @Schema(description = "消息ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "msg123") | |
| 17 | + private String id; | |
| 18 | + | |
| 19 | + @Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "product123") | |
| 20 | + @NotEmpty(message = "产品ID不能为空") | |
| 21 | + private String productKey; | |
| 22 | + | |
| 23 | + @Schema(description = "设备ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "device123") | |
| 24 | + @NotEmpty(message = "设备ID不能为空") | |
| 25 | + private String deviceKey; | |
| 26 | + | |
| 27 | + @Schema(description = "消息/日志类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "property") | |
| 28 | + @NotEmpty(message = "消息类型不能为空") | |
| 29 | + private String type; | |
| 30 | + | |
| 31 | + @Schema(description = "标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature") | |
| 32 | + @NotEmpty(message = "标识符不能为空") | |
| 33 | + private String subType; | |
| 34 | + | |
| 35 | + @Schema(description = "数据内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "{\"value\": 25.6}") | |
| 36 | + @NotEmpty(message = "数据内容不能为空") | |
| 37 | + private String content; | |
| 38 | + | |
| 39 | + @Schema(description = "上报时间", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 40 | + private Long reportTime; | |
| 41 | + | |
| 42 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceLogPageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 5 | +import jakarta.validation.constraints.NotEmpty; | |
| 6 | +import lombok.Data; | |
| 7 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 8 | + | |
| 9 | +import java.time.LocalDateTime; | |
| 10 | + | |
| 11 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 12 | + | |
| 13 | +@Schema(description = "管理后台 - IoT 设备日志分页查询 Request VO") | |
| 14 | +@Data | |
| 15 | +public class IotDeviceLogPageReqVO extends PageParam { | |
| 16 | + | |
| 17 | + @Schema(description = "设备标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "device123") | |
| 18 | + @NotEmpty(message = "设备标识不能为空") | |
| 19 | + private String deviceKey; | |
| 20 | + | |
| 21 | + @Schema(description = "消息类型", example = "property") | |
| 22 | + private String type; | |
| 23 | + | |
| 24 | + @Schema(description = "标识符", example = "temperature") | |
| 25 | + private String subType; | |
| 26 | + | |
| 27 | + @Schema(description = "创建时间") | |
| 28 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 29 | + private LocalDateTime[] createTime; | |
| 30 | +} | |
| 0 | 31 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceLogRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData; | |
| 2 | + | |
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | +import lombok.Data; | |
| 5 | + | |
| 6 | +import java.time.LocalDateTime; | |
| 7 | + | |
| 8 | +@Schema(description = "管理后台 - IoT 设备日志 Response VO") | |
| 9 | +@Data | |
| 10 | +public class IotDeviceLogRespVO { | |
| 11 | + | |
| 12 | + @Schema(description = "日志编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 13 | + private String id; | |
| 14 | + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "product123") | |
| 15 | + private String productKey; | |
| 16 | + @Schema(description = "设备标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "device123") | |
| 17 | + private String deviceKey; | |
| 18 | + | |
| 19 | + @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "property") | |
| 20 | + private String type; | |
| 21 | + | |
| 22 | + @Schema(description = "标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature") | |
| 23 | + private String subType; | |
| 24 | + | |
| 25 | + @Schema(description = "日志内容", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 26 | + private String content; | |
| 27 | + | |
| 28 | + @Schema(description = "上报时间", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 29 | + private LocalDateTime reportTime; | |
| 30 | + | |
| 31 | + @Schema(description = "记录时间戳", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 32 | + private LocalDateTime ts; | |
| 33 | +} | |
| 0 | 34 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotThingModelController.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.thingmodel; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; | |
| 6 | 7 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; |
| 7 | 8 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelRespVO; |
| 8 | 9 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; |
| ... | ... | @@ -73,6 +74,14 @@ public class IotThingModelController { |
| 73 | 74 | return success(IotThingModelConvert.INSTANCE.convertList(list)); |
| 74 | 75 | } |
| 75 | 76 | |
| 77 | + @GetMapping("/list") | |
| 78 | + @Operation(summary = "获得产品物模型列表") | |
| 79 | + @PreAuthorize("@ss.hasPermission('iot:thing-model:query')") | |
| 80 | + public CommonResult<List<IotThingModelRespVO>> getThingModelListByProductId(@Valid IotThingModelListReqVO reqVO) { | |
| 81 | + List<IotThingModelDO> list = thingModelService.getThingModelList(reqVO); | |
| 82 | + return success(IotThingModelConvert.INSTANCE.convertList(list)); | |
| 83 | + } | |
| 84 | + | |
| 76 | 85 | @GetMapping("/page") |
| 77 | 86 | @Operation(summary = "获得产品物模型分页") |
| 78 | 87 | @PreAuthorize("@ss.hasPermission('iot:thing-model:query')") | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelListReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 4 | +import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; | |
| 5 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 6 | +import jakarta.validation.constraints.NotNull; | |
| 7 | +import lombok.Data; | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | +@Schema(description = "管理后台 - IoT 产品物模型List Request VO") | |
| 12 | +@Data | |
| 13 | +public class IotThingModelListReqVO { | |
| 14 | + @Schema(description = "功能标识") | |
| 15 | + private String identifier; | |
| 16 | + | |
| 17 | + @Schema(description = "功能名称", example = "张三") | |
| 18 | + private String name; | |
| 19 | + | |
| 20 | + @Schema(description = "功能类型", example = "1") | |
| 21 | + @InEnum(IotThingModelTypeEnum.class) | |
| 22 | + private Integer type; | |
| 23 | + | |
| 24 | + @Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 25 | + @NotNull(message = "产品ID不能为空") | |
| 26 | + private Long productId; | |
| 27 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceLogDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.dal.dataobject.device; | |
| 2 | + | |
| 3 | +import cn.hutool.core.date.DateTime; | |
| 4 | +import lombok.AllArgsConstructor; | |
| 5 | +import lombok.Builder; | |
| 6 | +import lombok.Data; | |
| 7 | +import lombok.NoArgsConstructor; | |
| 8 | + | |
| 9 | +import java.time.LocalDateTime; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * IoT 设备日志数据 DO | |
| 13 | + * | |
| 14 | + * @author alwayssuper | |
| 15 | + */ | |
| 16 | +@Data | |
| 17 | +@Builder | |
| 18 | +@NoArgsConstructor | |
| 19 | +@AllArgsConstructor | |
| 20 | +public class IotDeviceLogDO { | |
| 21 | + /** | |
| 22 | + * 消息ID | |
| 23 | + */ | |
| 24 | + private String id; | |
| 25 | + | |
| 26 | + /** | |
| 27 | + * 产品ID | |
| 28 | + */ | |
| 29 | + private String productKey; | |
| 30 | + | |
| 31 | + /** | |
| 32 | + * 设备ID | |
| 33 | + */ | |
| 34 | + private String deviceKey; | |
| 35 | + | |
| 36 | + /** | |
| 37 | + * 消息/日志类型 | |
| 38 | + */ | |
| 39 | + private String type; | |
| 40 | + | |
| 41 | + /** | |
| 42 | + * 标识符:用于标识具体的属性、事件或服务 | |
| 43 | + */ | |
| 44 | + private String subType; | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * 数据内容:存储具体的消息数据内容,通常是JSON格式 | |
| 48 | + */ | |
| 49 | + private String content; | |
| 50 | + | |
| 51 | + /** | |
| 52 | + * 上报时间戳 | |
| 53 | + */ | |
| 54 | + private Long reportTime; | |
| 55 | + | |
| 56 | + /** | |
| 57 | + * 时序时间 | |
| 58 | + */ | |
| 59 | + private Long ts; | |
| 60 | + | |
| 61 | + | |
| 62 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/ThingModelMessageDO.java
| ... | ... | @@ -6,6 +6,7 @@ import lombok.Data; |
| 6 | 6 | import lombok.NoArgsConstructor; |
| 7 | 7 | |
| 8 | 8 | // TODO @芋艿:纠结下字段 |
| 9 | +@Deprecated | |
| 9 | 10 | /** |
| 10 | 11 | * TD 物模型消息日志的数据库 |
| 11 | 12 | */ |
| ... | ... | @@ -15,21 +16,7 @@ import lombok.NoArgsConstructor; |
| 15 | 16 | @AllArgsConstructor |
| 16 | 17 | public class ThingModelMessageDO { |
| 17 | 18 | |
| 18 | - /** | |
| 19 | - * 数据库名称 | |
| 20 | - */ | |
| 21 | - private String dataBaseName; | |
| 22 | 19 | |
| 23 | - // TODO @haohao:superTableName 和 tableName 是不是合并。因为每个 mapper 操作的时候,有且只会使用到其中一个。 | |
| 24 | - /** | |
| 25 | - * 超级表名称 | |
| 26 | - */ | |
| 27 | - private String superTableName; | |
| 28 | - | |
| 29 | - /** | |
| 30 | - * 表名称 | |
| 31 | - */ | |
| 32 | - private String tableName; | |
| 33 | 20 | |
| 34 | 21 | /** |
| 35 | 22 | * 消息 ID |
| ... | ... | @@ -37,9 +24,11 @@ public class ThingModelMessageDO { |
| 37 | 24 | private String id; |
| 38 | 25 | |
| 39 | 26 | /** |
| 40 | - * 扩展功能的参数 | |
| 27 | + * 系统扩展参数 | |
| 28 | + * | |
| 29 | + * 例如:设备状态、系统时间、固件版本等系统级信息 | |
| 41 | 30 | */ |
| 42 | - private Object sys; | |
| 31 | + private Object system; | |
| 43 | 32 | |
| 44 | 33 | /** |
| 45 | 34 | * 请求方法 |
| ... | ... | @@ -59,6 +48,12 @@ public class ThingModelMessageDO { |
| 59 | 48 | private Long time; |
| 60 | 49 | |
| 61 | 50 | /** |
| 51 | + * 设备信息 | |
| 52 | + */ | |
| 53 | + private String productKey; | |
| 54 | + | |
| 55 | + | |
| 56 | + /** | |
| 62 | 57 | * 设备 key |
| 63 | 58 | */ |
| 64 | 59 | private String deviceKey; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotThingModelMapper.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.dal.mysql.thingmodel; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; | |
| 6 | 7 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; |
| 7 | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 8 | 9 | import org.apache.ibatis.annotations.Mapper; |
| ... | ... | @@ -28,6 +29,17 @@ public interface IotThingModelMapper extends BaseMapperX<IotThingModelDO> { |
| 28 | 29 | .orderByDesc(IotThingModelDO::getId)); |
| 29 | 30 | } |
| 30 | 31 | |
| 32 | + default List<IotThingModelDO> selectList(IotThingModelListReqVO reqVO) { | |
| 33 | + return selectList(new LambdaQueryWrapperX<IotThingModelDO>() | |
| 34 | + .eqIfPresent(IotThingModelDO::getIdentifier, reqVO.getIdentifier()) | |
| 35 | + .likeIfPresent(IotThingModelDO::getName, reqVO.getName()) | |
| 36 | + .eqIfPresent(IotThingModelDO::getType, reqVO.getType()) | |
| 37 | + .eqIfPresent(IotThingModelDO::getProductId, reqVO.getProductId()) | |
| 38 | + // TODO @芋艿:看看要不要加枚举 | |
| 39 | + .notIn(IotThingModelDO::getIdentifier, "get", "set", "post") | |
| 40 | + .orderByDesc(IotThingModelDO::getId)); | |
| 41 | + } | |
| 42 | + | |
| 31 | 43 | default IotThingModelDO selectByProductIdAndIdentifier(Long productId, String identifier) { |
| 32 | 44 | return selectOne(IotThingModelDO::getProductId, productId, |
| 33 | 45 | IotThingModelDO::getIdentifier, identifier); | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.dal.tdengine; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceLogPageReqVO; | |
| 5 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; | |
| 6 | +import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS; | |
| 7 | +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; | |
| 8 | +import org.apache.ibatis.annotations.Mapper; | |
| 9 | +import org.apache.ibatis.annotations.Param; | |
| 10 | + | |
| 11 | +import java.util.List; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * IOT 设备日志数据 Mapper 接口 | |
| 15 | + * | |
| 16 | + * 基于 TDengine 实现设备日志的存储 | |
| 17 | + */ | |
| 18 | +@Mapper | |
| 19 | +@TDengineDS | |
| 20 | +@InterceptorIgnore(tenantLine = "true") // 避免 SQL 解析,因为 JSqlParser 对 TDengine 的 SQL 解析会报错 | |
| 21 | +public interface IotDeviceLogDataMapper { | |
| 22 | + | |
| 23 | + /** | |
| 24 | + * 创建设备日志超级表 | |
| 25 | + * | |
| 26 | + * 注意:初始化时只需创建一次 | |
| 27 | + */ | |
| 28 | + void createDeviceLogSTable(); | |
| 29 | + | |
| 30 | + /** | |
| 31 | + * 创建设备日志子表 | |
| 32 | + * | |
| 33 | + * @param deviceKey 设备标识 | |
| 34 | + */ | |
| 35 | + void createDeviceLogTable(@Param("deviceKey") String deviceKey); | |
| 36 | + | |
| 37 | + /** | |
| 38 | + * 插入设备日志数据 | |
| 39 | + * | |
| 40 | + * 如果子表不存在,会自动创建子表 | |
| 41 | + * | |
| 42 | + * @param log 设备日志数据 | |
| 43 | + */ | |
| 44 | + void insert(@Param("log") IotDeviceLogDO log); | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * 获得设备日志分页 | |
| 48 | + * | |
| 49 | + * @param reqVO 分页查询条件 | |
| 50 | + * @return 设备日志列表 | |
| 51 | + */ | |
| 52 | + List<IotDeviceLogDO> selectPage(@Param("reqVO") IotDeviceLogPageReqVO reqVO); | |
| 53 | + | |
| 54 | + /** | |
| 55 | + * 获得设备日志总数 | |
| 56 | + * | |
| 57 | + * @param reqVO 查询条件 | |
| 58 | + * @return 日志总数 | |
| 59 | + */ | |
| 60 | + Long selectCount(@Param("reqVO") IotDeviceLogPageReqVO reqVO); | |
| 61 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdThingModelMessageMapper.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.dal.tdengine; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; |
| 4 | +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; | |
| 4 | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessageDO; |
| 6 | +import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS; | |
| 5 | 7 | import com.baomidou.dynamic.datasource.annotation.DS; |
| 8 | +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; | |
| 6 | 9 | import org.apache.ibatis.annotations.Mapper; |
| 10 | +import org.apache.ibatis.annotations.Param; | |
| 7 | 11 | |
| 8 | 12 | /** |
| 9 | 13 | * 处理 TD 中物模型消息日志的操作 |
| 10 | 14 | */ |
| 11 | 15 | @Mapper |
| 12 | -@DS("tdengine") | |
| 16 | +@Deprecated | |
| 17 | +@TDengineDS | |
| 18 | +@InterceptorIgnore(tenantLine = "true") // 避免 SQL 解析,因为 JSqlParser 对 TDengine 的 SQL 解析会报错 | |
| 13 | 19 | public interface TdThingModelMessageMapper { |
| 14 | 20 | |
| 15 | 21 | /** |
| 16 | 22 | * 创建物模型消息日志超级表超级表 |
| 17 | 23 | * |
| 18 | 24 | */ |
| 19 | - @TenantIgnore | |
| 20 | - void createSuperTable(ThingModelMessageDO superTable); | |
| 25 | + | |
| 26 | + void createSuperTable(@Param("productKey") String productKey); | |
| 21 | 27 | |
| 22 | 28 | /** |
| 23 | 29 | * 创建子表 |
| 24 | 30 | * |
| 25 | 31 | */ |
| 26 | - @TenantIgnore | |
| 27 | - void createTableWithTag(ThingModelMessageDO table); | |
| 32 | + | |
| 33 | + void createTableWithTag(@Param("productKey") String productKey,@Param("deviceKey") String deviceKey); | |
| 28 | 34 | |
| 29 | 35 | } | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/config/TDengineTableInitConfiguration.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.framework.tdengine.config; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.iot.service.device.IotDeviceLogDataService; | |
| 4 | +import lombok.RequiredArgsConstructor; | |
| 5 | +import lombok.extern.slf4j.Slf4j; | |
| 6 | +import org.springframework.boot.ApplicationArguments; | |
| 7 | +import org.springframework.boot.ApplicationRunner; | |
| 8 | +import org.springframework.context.annotation.Configuration; | |
| 9 | +import org.springframework.core.annotation.Order; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * TDengine 表初始化的 Configuration | |
| 13 | + * | |
| 14 | + * @author alwayssuper | |
| 15 | + */ | |
| 16 | +@Slf4j | |
| 17 | +@RequiredArgsConstructor | |
| 18 | +@Configuration | |
| 19 | +@Order(Integer.MAX_VALUE) // 保证在最后执行 | |
| 20 | +public class TDengineTableInitConfiguration implements ApplicationRunner { | |
| 21 | + | |
| 22 | + private final IotDeviceLogDataService deviceLogService; | |
| 23 | + | |
| 24 | + @Override | |
| 25 | + public void run(ApplicationArguments args) { | |
| 26 | + try { | |
| 27 | + // 初始化设备日志表 | |
| 28 | + deviceLogService.initTDengineSTable(); | |
| 29 | + log.info("初始化 设备日志表 TDengine 表结构成功"); | |
| 30 | + } catch (Exception ex) { | |
| 31 | + if (ex.getMessage().contains("Table already exists")) { | |
| 32 | + log.info("TDengine 设备日志超级表已存在,跳过创建"); | |
| 33 | + return; | |
| 34 | + }else{ | |
| 35 | + log.error("初始化 设备日志表 TDengine 表结构失败", ex); | |
| 36 | + } | |
| 37 | + throw ex; | |
| 38 | + } | |
| 39 | + } | |
| 40 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.service.device; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataSimulatorSaveReqVO; | |
| 5 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceLogPageReqVO; | |
| 6 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; | |
| 7 | + | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * IoT 设备日志数据 Service 接口 | |
| 11 | + * | |
| 12 | + * @author alwayssuper | |
| 13 | + */ | |
| 14 | +public interface IotDeviceLogDataService { | |
| 15 | + | |
| 16 | + /** | |
| 17 | + * 初始化 TDengine 超级表 | |
| 18 | + * | |
| 19 | + *系统启动时,会自动初始化一次 | |
| 20 | + */ | |
| 21 | + void initTDengineSTable(); | |
| 22 | + | |
| 23 | + /** | |
| 24 | + * 插入设备日志 | |
| 25 | + * | |
| 26 | + * 当该设备第一次插入日志时,自动创建该设备的设备日志子表 | |
| 27 | + * | |
| 28 | + * @param simulatorReqVO 设备日志模拟数据 | |
| 29 | + */ | |
| 30 | + void createDeviceLog(IotDeviceDataSimulatorSaveReqVO simulatorReqVO); | |
| 31 | + | |
| 32 | + /** | |
| 33 | + * 获得设备日志分页 | |
| 34 | + * | |
| 35 | + * @param pageReqVO 分页查询 | |
| 36 | + * @return 设备日志分页 | |
| 37 | + */ | |
| 38 | + PageResult<IotDeviceLogDO> getDeviceLogPage(IotDeviceLogPageReqVO pageReqVO); | |
| 39 | + | |
| 40 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.service.device; | |
| 2 | + | |
| 3 | +import cn.hutool.core.date.DateTime; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | |
| 6 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceDataSimulatorSaveReqVO; | |
| 7 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.deviceData.IotDeviceLogPageReqVO; | |
| 8 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; | |
| 9 | +import cn.iocoder.yudao.module.iot.dal.tdengine.IotDeviceLogDataMapper; | |
| 10 | +import jakarta.annotation.Resource; | |
| 11 | +import lombok.extern.slf4j.Slf4j; | |
| 12 | +import org.springframework.stereotype.Service; | |
| 13 | +import org.springframework.validation.annotation.Validated; | |
| 14 | + | |
| 15 | +import java.time.LocalDateTime; | |
| 16 | +import java.time.ZoneId; | |
| 17 | +import java.util.List; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * IoT 设备日志数据 Service 实现了 | |
| 21 | + * | |
| 22 | + * @author alwayssuper | |
| 23 | + */ | |
| 24 | +@Service | |
| 25 | +@Slf4j | |
| 26 | +@Validated | |
| 27 | +public class IotDeviceLogDataServiceImpl implements IotDeviceLogDataService{ | |
| 28 | + | |
| 29 | + @Resource | |
| 30 | + private IotDeviceLogDataMapper iotDeviceLogDataMapper; | |
| 31 | + | |
| 32 | + | |
| 33 | + @Override | |
| 34 | + public void initTDengineSTable() { | |
| 35 | + try { | |
| 36 | + // 创建设备日志超级表 | |
| 37 | + iotDeviceLogDataMapper.createDeviceLogSTable(); | |
| 38 | + log.info("创建设备日志超级表成功"); | |
| 39 | + } catch (Exception ex) { | |
| 40 | + throw ex; | |
| 41 | + } | |
| 42 | + } | |
| 43 | + | |
| 44 | + @Override | |
| 45 | + public void createDeviceLog(IotDeviceDataSimulatorSaveReqVO simulatorReqVO) { | |
| 46 | + //TODO:讨论一下,iotkit这块TS和上报时间都是外部传入的 但是看TDengine文档 他是建议对TS在SQL中直接NOW 咱们的TS数据获取是走哪一种 | |
| 47 | + | |
| 48 | + // 1. 转换请求对象为 DO | |
| 49 | + IotDeviceLogDO iotDeviceLogDO = BeanUtils.toBean(simulatorReqVO, IotDeviceLogDO.class); | |
| 50 | + | |
| 51 | + // 2. 处理时间字段 | |
| 52 | + long currentTime = System.currentTimeMillis(); | |
| 53 | + // 2.1 设置时序时间为当前时间 | |
| 54 | + iotDeviceLogDO.setTs(currentTime); | |
| 55 | + | |
| 56 | + // 3. 插入数据 | |
| 57 | + iotDeviceLogDataMapper.insert(iotDeviceLogDO); | |
| 58 | + } | |
| 59 | + | |
| 60 | + @Override | |
| 61 | + public PageResult<IotDeviceLogDO> getDeviceLogPage(IotDeviceLogPageReqVO pageReqVO) { | |
| 62 | + // 查询数据 | |
| 63 | + List<IotDeviceLogDO> list = iotDeviceLogDataMapper.selectPage(pageReqVO); | |
| 64 | + Long total = iotDeviceLogDataMapper.selectCount(pageReqVO); | |
| 65 | + // 构造分页结果 | |
| 66 | + return new PageResult<>(list, total); | |
| 67 | + } | |
| 68 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataServiceImpl.java
| ... | ... | @@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 18 | 18 | import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO; |
| 19 | 19 | import cn.iocoder.yudao.module.iot.dal.tdengine.IotDevicePropertyDataMapper; |
| 20 | 20 | import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper; |
| 21 | +import cn.iocoder.yudao.module.iot.dal.tdengine.TdThingModelMessageMapper; | |
| 21 | 22 | import cn.iocoder.yudao.module.iot.enums.IotConstants; |
| 22 | 23 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum; |
| 23 | 24 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; |
| ... | ... | @@ -85,6 +86,7 @@ public class IotDevicePropertyDataServiceImpl implements IotDevicePropertyDataSe |
| 85 | 86 | @Resource |
| 86 | 87 | private IotDevicePropertyDataMapper devicePropertyDataMapper; |
| 87 | 88 | |
| 89 | + | |
| 88 | 90 | @Override |
| 89 | 91 | public void defineDevicePropertyData(Long productId) { |
| 90 | 92 | // 1.1 查询产品和物模型 |
| ... | ... | @@ -109,6 +111,7 @@ public class IotDevicePropertyDataServiceImpl implements IotDevicePropertyDataSe |
| 109 | 111 | return; |
| 110 | 112 | } |
| 111 | 113 | newFields.add(0, new TDengineTableField(TDengineTableField.FIELD_TS, TDengineTableField.TYPE_TIMESTAMP)); |
| 114 | + // 2.1.1 创建产品超级表 | |
| 112 | 115 | devicePropertyDataMapper.createProductPropertySTable(product.getProductKey(), newFields); |
| 113 | 116 | return; |
| 114 | 117 | } | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductServiceImpl.java
| ... | ... | @@ -36,9 +36,6 @@ public class IotProductServiceImpl implements IotProductService { |
| 36 | 36 | |
| 37 | 37 | @Resource |
| 38 | 38 | @Lazy // 延迟加载,解决循环依赖 |
| 39 | - private IotThingModelMessageService thingModelMessageService; | |
| 40 | - @Resource | |
| 41 | - @Lazy // 延迟加载,解决循环依赖 | |
| 42 | 39 | private IotDevicePropertyDataService devicePropertyDataService; |
| 43 | 40 | |
| 44 | 41 | @Override |
| ... | ... | @@ -125,8 +122,7 @@ public class IotProductServiceImpl implements IotProductService { |
| 125 | 122 | if (Objects.equals(status, IotProductStatusEnum.PUBLISHED.getStatus())) { |
| 126 | 123 | // 3.1 创建产品超级表数据模型 |
| 127 | 124 | devicePropertyDataService.defineDevicePropertyData(id); |
| 128 | - // 3.2 创建物模型日志超级表数据模型 TODO 待定:message 要不要分; | |
| 129 | - thingModelMessageService.createSuperTable(id); | |
| 125 | + | |
| 130 | 126 | } |
| 131 | 127 | productMapper.updateById(updateObj); |
| 132 | 128 | } | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageService.java
| ... | ... | @@ -16,11 +16,6 @@ public interface IotThingModelMessageService { |
| 16 | 16 | */ |
| 17 | 17 | void saveThingModelMessage(IotDeviceDO device, ThingModelMessage thingModelMessage); |
| 18 | 18 | |
| 19 | - /** | |
| 20 | - * 创建物模型消息日志超级表 | |
| 21 | - * | |
| 22 | - * @param productId 产品编号 | |
| 23 | - */ | |
| 24 | - void createSuperTable(Long productId); | |
| 19 | + | |
| 25 | 20 | |
| 26 | 21 | } |
| 27 | 22 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java
| ... | ... | @@ -7,15 +7,13 @@ import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; |
| 7 | 7 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO; |
| 8 | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 9 | 9 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDataDO; |
| 10 | -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.FieldParser; | |
| 11 | -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdFieldDO; | |
| 12 | -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO; | |
| 13 | -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; | |
| 10 | +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.*; | |
| 14 | 11 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 15 | 12 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 16 | 13 | import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO; |
| 17 | 14 | import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDDLMapper; |
| 18 | 15 | import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper; |
| 16 | +import cn.iocoder.yudao.module.iot.dal.tdengine.TdThingModelMessageMapper; | |
| 19 | 17 | import cn.iocoder.yudao.module.iot.enums.IotConstants; |
| 20 | 18 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; |
| 21 | 19 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; |
| ... | ... | @@ -64,6 +62,9 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ |
| 64 | 62 | private TdEngineDMLMapper tdEngineDMLMapper; |
| 65 | 63 | |
| 66 | 64 | @Resource |
| 65 | + private TdThingModelMessageMapper tdThingModelMessageMapper; | |
| 66 | + | |
| 67 | + @Resource | |
| 67 | 68 | private DeviceDataRedisDAO deviceDataRedisDAO; |
| 68 | 69 | |
| 69 | 70 | |
| ... | ... | @@ -77,8 +78,6 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ |
| 77 | 78 | createDeviceTable(device.getDeviceType(), device.getProductKey(), device.getDeviceName(), device.getDeviceKey()); |
| 78 | 79 | iotDeviceService.updateDeviceStatus(new IotDeviceStatusUpdateReqVO() |
| 79 | 80 | .setId(device.getId()).setStatus(IotDeviceStatusEnum.ONLINE.getStatus())); |
| 80 | - // 1.2 创建物模型日志设备表 | |
| 81 | - createThingModelMessageDeviceTable(device.getProductKey(), device.getDeviceName(), device.getDeviceKey()); | |
| 82 | 81 | } |
| 83 | 82 | |
| 84 | 83 | // 2. 获取设备属性并进行物模型校验,过滤非物模型属性 |
| ... | ... | @@ -107,32 +106,34 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ |
| 107 | 106 | thingModel -> IotThingModelTypeEnum.PROPERTY.getType().equals(thingModel.getType())); |
| 108 | 107 | } |
| 109 | 108 | |
| 110 | - @Override | |
| 111 | - @TenantIgnore | |
| 112 | - public void createSuperTable(Long productId) { | |
| 113 | - // 1. 查询产品 | |
| 114 | - IotProductDO product = productService.getProduct(productId); | |
| 115 | - | |
| 116 | - // 2. 获取超级表的名称和数据库名称 | |
| 117 | - // TODO @alwayssuper:最好 databaseName、superTableName 的处理,放到 tdThinkModelMessageMapper 里。可以考虑,弄个 default 方法 | |
| 118 | - String databaseName = IotTdDatabaseUtils.getDatabaseName(url); | |
| 119 | - String superTableName = IotTdDatabaseUtils.getThingModelMessageSuperTableName(product.getProductKey()); | |
| 120 | - | |
| 121 | - // 解析物模型,获取字段列表 | |
| 122 | - List<TdFieldDO> schemaFields = List.of( | |
| 123 | - TdFieldDO.builder().fieldName("time").dataType("TIMESTAMP").build(), | |
| 124 | - TdFieldDO.builder().fieldName("id").dataType("NCHAR").dataLength(64).build(), | |
| 125 | - TdFieldDO.builder().fieldName("sys").dataType("NCHAR").dataLength(2048).build(), | |
| 126 | - TdFieldDO.builder().fieldName("method").dataType("NCHAR").dataLength(256).build(), | |
| 127 | - TdFieldDO.builder().fieldName("params").dataType("NCHAR").dataLength(2048).build() | |
| 128 | - ); | |
| 129 | - // 设置超级表的标签 | |
| 130 | - List<TdFieldDO> tagsFields = List.of( | |
| 131 | - TdFieldDO.builder().fieldName("device_key").dataType("NCHAR").dataLength(64).build() | |
| 132 | - ); | |
| 133 | - // 3. 创建超级表 | |
| 134 | - tdEngineDDLMapper.createSuperTable(new TdTableDO(databaseName, superTableName, schemaFields, tagsFields)); | |
| 135 | - } | |
| 109 | +// @Override | |
| 110 | +// @TenantIgnore | |
| 111 | +// public void createSuperTable(Long productId) { | |
| 112 | +// // 1. 查询产品 | |
| 113 | +// IotProductDO product = productService.getProduct(productId); | |
| 114 | +// // 2. 创建日志超级表 | |
| 115 | +// tdThingModelMessageMapper.createSuperTable(product.getProductKey()); | |
| 116 | +// | |
| 117 | +// // 2. 获取超级表的名称和数据库名称 | |
| 118 | +// // TODO @alwayssuper:最好 databaseName、superTableName 的处理,放到 tdThinkModelMessageMapper 里。可以考虑,弄个 default 方法 | |
| 119 | +//// String databaseName = IotTdDatabaseUtils.getDatabaseName(url); | |
| 120 | +//// String superTableName = IotTdDatabaseUtils.getThingModelMessageSuperTableName(product.getProductKey()); | |
| 121 | +//// | |
| 122 | +//// // 解析物模型,获取字段列表 | |
| 123 | +//// List<TdFieldDO> schemaFields = List.of( | |
| 124 | +//// TdFieldDO.builder().fieldName("time").dataType("TIMESTAMP").build(), | |
| 125 | +//// TdFieldDO.builder().fieldName("id").dataType("NCHAR").dataLength(64).build(), | |
| 126 | +//// TdFieldDO.builder().fieldName("sys").dataType("NCHAR").dataLength(2048).build(), | |
| 127 | +//// TdFieldDO.builder().fieldName("method").dataType("NCHAR").dataLength(256).build(), | |
| 128 | +//// TdFieldDO.builder().fieldName("params").dataType("NCHAR").dataLength(2048).build() | |
| 129 | +//// ); | |
| 130 | +//// // 设置超级表的标签 | |
| 131 | +//// List<TdFieldDO> tagsFields = List.of( | |
| 132 | +//// TdFieldDO.builder().fieldName("device_key").dataType("NCHAR").dataLength(64).build() | |
| 133 | +//// ); | |
| 134 | +//// // 3. 创建超级表 | |
| 135 | +//// tdEngineDDLMapper.createSuperTable(new TdTableDO(databaseName, superTableName, schemaFields, tagsFields)); | |
| 136 | +// } | |
| 136 | 137 | |
| 137 | 138 | private List<IotThingModelDO> getValidFunctionList(String productKey) { |
| 138 | 139 | return filterList(iotThingModelService.getProductThingModelListByProductKey(productKey), |
| ... | ... | @@ -228,29 +229,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ |
| 228 | 229 | .setTags(tagsFieldValues)); |
| 229 | 230 | } |
| 230 | 231 | |
| 231 | - /** | |
| 232 | - * 创建物模型日志设备数据表 | |
| 233 | - * | |
| 234 | - * @param productKey 产品 Key | |
| 235 | - * @param deviceName 设备名称 | |
| 236 | - * @param deviceKey 设备 Key | |
| 237 | - * | |
| 238 | - */ | |
| 239 | - private void createThingModelMessageDeviceTable(String productKey, String deviceName, String deviceKey){ | |
| 240 | - | |
| 241 | - // 1. 获取超级表的名称、数据库名称、设备日志表名称 | |
| 242 | - String databaseName = IotTdDatabaseUtils.getDatabaseName(url); | |
| 243 | - String superTableName = IotTdDatabaseUtils.getThingModelMessageSuperTableName(productKey); | |
| 244 | - // TODO @alwayssuper:最好 databaseName、superTableName、thinkModelMessageDeviceTableName 的处理,放到 tdThinkModelMessageMapper 里。可以考虑,弄个 default 方法 | |
| 245 | - String thinkModelMessageDeviceTableName = IotTdDatabaseUtils.getThingModelMessageDeviceTableName(productKey, deviceName); | |
| 246 | - | |
| 247 | - // 2. 创建物模型日志设备数据表 | |
| 248 | -// tdThingModelMessageMapper.createTableWithTag(ThingModelMessageDO.builder().build() | |
| 249 | -// .setDataBaseName(databaseName) | |
| 250 | -// .setSuperTableName(superTableName) | |
| 251 | -// .setTableName(thinkModelMessageDeviceTableName) | |
| 252 | -// .setDeviceKey(deviceKey)); | |
| 253 | - } | |
| 232 | + | |
| 254 | 233 | |
| 255 | 234 | /** |
| 256 | 235 | * 获取数据库名称 | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.thingmodel; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; | |
| 4 | 5 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; |
| 6 | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| ... | ... | @@ -69,4 +70,11 @@ public interface IotThingModelService { |
| 69 | 70 | */ |
| 70 | 71 | List<IotThingModelDO> getProductThingModelListByProductKey(String productKey); |
| 71 | 72 | |
| 73 | + /** | |
| 74 | + * 获得产品物模型列表 | |
| 75 | + * | |
| 76 | + * @param reqVO 列表查询 | |
| 77 | + * @return 产品物模型列表 | |
| 78 | + */ | |
| 79 | + List<IotThingModelDO> getThingModelList(IotThingModelListReqVO reqVO); | |
| 72 | 80 | } |
| 73 | 81 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java
| ... | ... | @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | 7 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent; |
| 8 | 8 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelParam; |
| 9 | 9 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; |
| 10 | +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; | |
| 10 | 11 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; |
| 11 | 12 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; |
| 12 | 13 | import cn.iocoder.yudao.module.iot.convert.thingmodel.IotThingModelConvert; |
| ... | ... | @@ -134,6 +135,11 @@ public class IotThingModelServiceImpl implements IotThingModelService { |
| 134 | 135 | return thingModelMapper.selectListByProductKey(productKey); |
| 135 | 136 | } |
| 136 | 137 | |
| 138 | + @Override | |
| 139 | + public List<IotThingModelDO> getThingModelList(IotThingModelListReqVO reqVO) { | |
| 140 | + return thingModelMapper.selectList(reqVO); | |
| 141 | + } | |
| 142 | + | |
| 137 | 143 | /** |
| 138 | 144 | * 校验功能是否存在 |
| 139 | 145 | * | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<!DOCTYPE mapper | |
| 3 | + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |
| 4 | + "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |
| 5 | +<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.IotDeviceLogDataMapper"> | |
| 6 | + | |
| 7 | + <!-- 创建设备日志超级表 初始化只创建一次--> | |
| 8 | + <update id="createDeviceLogSTable"> | |
| 9 | + CREATE STABLE device_log ( | |
| 10 | + ts TIMESTAMP, | |
| 11 | + id NCHAR(50), | |
| 12 | + product_key NCHAR(50), | |
| 13 | + type NCHAR(50), | |
| 14 | + subType NCHAR(50), | |
| 15 | + content NCHAR(1024), | |
| 16 | + report_time TIMESTAMP | |
| 17 | + )TAGS ( | |
| 18 | + device_key NCHAR(50) | |
| 19 | + ) | |
| 20 | + </update> | |
| 21 | + | |
| 22 | + | |
| 23 | + <!-- 创建设备日志子表 讨论:TDengine 在子表不存在的情况下 可在数据插入时 自动建表 要不要去掉创建子表的逻辑 由第一次插入数据时自动创建--> | |
| 24 | + <update id="createDeviceLogTable"> | |
| 25 | + CREATE TABLE device_log_${deviceKey} USING device_log TAGS('${deviceKey}') | |
| 26 | + </update> | |
| 27 | + | |
| 28 | + <!-- 插入设备日志数据 在子表不存在的情况下 可在数据插入时 自动建表 --> | |
| 29 | + <insert id="insert"> | |
| 30 | + INSERT INTO device_log_${log.deviceKey} (ts, id, product_key, type, subType, content, report_time) | |
| 31 | + USING device_log | |
| 32 | + TAGS ('${log.deviceKey}') | |
| 33 | + VALUES ( | |
| 34 | + #{log.ts}, | |
| 35 | + #{log.id}, | |
| 36 | + #{log.productKey}, | |
| 37 | + #{log.type}, | |
| 38 | + #{log.subType}, | |
| 39 | + #{log.content}, | |
| 40 | + #{log.reportTime} | |
| 41 | + ) | |
| 42 | + </insert> | |
| 43 | + | |
| 44 | + <select id="selectPage" resultType="cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO"> | |
| 45 | + SELECT ts, id, device_key, product_key, type, subType, content, report_time | |
| 46 | + FROM device_log_${reqVO.deviceKey} | |
| 47 | + <where> | |
| 48 | + <if test="reqVO.type != null and reqVO.type != ''"> | |
| 49 | + AND type = #{reqVO.type} | |
| 50 | + </if> | |
| 51 | + <if test="reqVO.subType != null and reqVO.subType != ''"> | |
| 52 | + AND subType = #{reqVO.subType} | |
| 53 | + </if> | |
| 54 | + <if test="reqVO.createTime != null"> | |
| 55 | + AND ts BETWEEN #{reqVO.createTime[0]} AND #{reqVO.createTime[1]} | |
| 56 | + </if> | |
| 57 | + </where> | |
| 58 | + ORDER BY ts DESC | |
| 59 | + LIMIT #{reqVO.pageSize} OFFSET #{reqVO.pageNo} | |
| 60 | + </select> | |
| 61 | + | |
| 62 | + <select id="selectCount" resultType="Long"> | |
| 63 | + SELECT COUNT(*) | |
| 64 | + FROM device_log_${reqVO.deviceKey} | |
| 65 | + <where> | |
| 66 | + <if test="reqVO.type != null and reqVO.type != ''"> | |
| 67 | + AND type = #{reqVO.type} | |
| 68 | + </if> | |
| 69 | + <if test="reqVO.subType != null and reqVO.subType != ''"> | |
| 70 | + AND subType = #{reqVO.subType} | |
| 71 | + </if> | |
| 72 | + <if test="reqVO.createTime != null"> | |
| 73 | + AND ts BETWEEN #{reqVO.createTime[0]} AND #{reqVO.createTime[1]} | |
| 74 | + </if> | |
| 75 | + </where> | |
| 76 | + </select> | |
| 77 | + | |
| 78 | +</mapper> | |
| 0 | 79 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineDMLMapper.xml
| ... | ... | @@ -42,7 +42,7 @@ |
| 42 | 42 | |
| 43 | 43 | <!-- 根据标签获取最新数据 --> |
| 44 | 44 | <select id="selectLastDataListByTags" parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TagsSelectDO" |
| 45 | - resultType="Map"> | |
| 45 | + resultType="java.util.Map"> | |
| 46 | 46 | SELECT LAST(*) |
| 47 | 47 | FROM ${dataBaseName}.${stableName} |
| 48 | 48 | GROUP BY ${tagsName} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdThinkModelMessageMapper.xml
| ... | ... | @@ -6,26 +6,28 @@ |
| 6 | 6 | |
| 7 | 7 | <!-- 创建物模型消息日志超级表 --> |
| 8 | 8 | <update id="createSuperTable"> |
| 9 | - CREATE STABLE ${dataBaseName}.${superTableName}( | |
| 9 | + CREATE STABLE thing_model_message_${productKey}( | |
| 10 | 10 | ts TIMESTAMP, |
| 11 | - id VARCHAR(255), | |
| 12 | - sys VARCHAR(2048), | |
| 13 | - method VARCHAR(255), | |
| 14 | - params VARCHAR(2048) | |
| 11 | + id NCHAR(64), | |
| 12 | + sys NCHAR(2048), | |
| 13 | + method NCHAR(255), | |
| 14 | + params NCHAR(2048), | |
| 15 | + device_name NCHAR(64) | |
| 15 | 16 | )TAGS ( |
| 16 | - device_key VARCHAR(255) | |
| 17 | + device_key NCHAR(50) | |
| 17 | 18 | ) |
| 18 | 19 | </update> |
| 19 | 20 | |
| 20 | 21 | <!-- 创建物模型消息日志子表,带有deviceKey的TAG --> |
| 21 | 22 | <update id="createTableWithTag"> |
| 22 | - CREATE TABLE IF NOT EXISTS ${dataBaseName}.${tableName} | |
| 23 | - USING ${dataBaseName}.${superTableName}( | |
| 23 | + CREATE STABLE ${deviceKey} | |
| 24 | + USING thing_model_message_${productKey}( | |
| 24 | 25 | ts, |
| 25 | 26 | id , |
| 26 | 27 | sys , |
| 27 | 28 | method , |
| 28 | - params | |
| 29 | + params , | |
| 30 | + device_name | |
| 29 | 31 | )TAGS( |
| 30 | 32 | #{device_key} |
| 31 | 33 | ) | ... | ... |