Commit da60e649dfd068519ca2f040b9579fe23ff07b10
1 parent
fd00fb29
feat:【IoT 物联网】物模型数据使用 NVARCHAR 存储,并兼容 struct、array 等数据结构
Showing
23 changed files
with
109 additions
and
93 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDevicePropertyController.java
| @@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | @@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 6 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyDetailRespVO; | 6 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyDetailRespVO; |
| 7 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyHistoryListReqVO; | 7 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyHistoryListReqVO; |
| 8 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO; | 8 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO; |
| 9 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty; | 9 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty; |
| 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 11 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; | 11 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; |
| 12 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | 12 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/property/IotDevicePropertyDetailRespVO.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.device.vo.property; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.device.vo.property; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDataSpecs; | 3 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType.ThingModelDataSpecs; |
| 4 | import io.swagger.v3.oas.annotations.media.Schema; | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 5 | import lombok.Data; | 5 | import lombok.Data; |
| 6 | 6 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotThingModelController.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.collection.CollUtil; | ||
| 4 | -import cn.hutool.core.util.ObjUtil; | ||
| 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 8 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.*; | 6 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.*; |
| 7 | +import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | ||
| 9 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 10 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; | 9 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; |
| 10 | +import cn.iocoder.yudao.module.iot.service.product.IotProductService; | ||
| 11 | import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; | 11 | import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; |
| 12 | +import com.google.common.base.Objects; | ||
| 12 | import io.swagger.v3.oas.annotations.Operation; | 13 | import io.swagger.v3.oas.annotations.Operation; |
| 13 | import io.swagger.v3.oas.annotations.Parameter; | 14 | import io.swagger.v3.oas.annotations.Parameter; |
| 14 | import io.swagger.v3.oas.annotations.tags.Tag; | 15 | import io.swagger.v3.oas.annotations.tags.Tag; |
| @@ -32,6 +33,8 @@ public class IotThingModelController { | @@ -32,6 +33,8 @@ public class IotThingModelController { | ||
| 32 | 33 | ||
| 33 | @Resource | 34 | @Resource |
| 34 | private IotThingModelService thingModelService; | 35 | private IotThingModelService thingModelService; |
| 36 | + @Resource | ||
| 37 | + private IotProductService productService; | ||
| 35 | 38 | ||
| 36 | @PostMapping("/create") | 39 | @PostMapping("/create") |
| 37 | @Operation(summary = "创建产品物模型") | 40 | @Operation(summary = "创建产品物模型") |
| @@ -71,23 +74,21 @@ public class IotThingModelController { | @@ -71,23 +74,21 @@ public class IotThingModelController { | ||
| 71 | @Parameter(name = "productId", description = "产品 ID", required = true, example = "1024") | 74 | @Parameter(name = "productId", description = "产品 ID", required = true, example = "1024") |
| 72 | @PreAuthorize("@ss.hasPermission('iot:thing-model:query')") | 75 | @PreAuthorize("@ss.hasPermission('iot:thing-model:query')") |
| 73 | public CommonResult<IotThingModelTSLRespVO> getThingModelTsl(@RequestParam("productId") Long productId) { | 76 | public CommonResult<IotThingModelTSLRespVO> getThingModelTsl(@RequestParam("productId") Long productId) { |
| 74 | - IotThingModelTSLRespVO tslRespVO = new IotThingModelTSLRespVO(); | ||
| 75 | - // TODO @puhui999:是不是要先查询产品哈?原因是,万一没配置物模型,但是产品已经有了! | ||
| 76 | - // 1. 获得产品所有物模型定义 | ||
| 77 | - List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductId(productId); | ||
| 78 | - if (CollUtil.isEmpty(thingModels)) { | ||
| 79 | - return success(tslRespVO); | 77 | + // 1. 获得产品 |
| 78 | + IotProductDO product = productService.getProduct(productId); | ||
| 79 | + if (product == null) { | ||
| 80 | + return success(null); | ||
| 80 | } | 81 | } |
| 81 | - | ||
| 82 | - // 2. 设置公共部分参数 | ||
| 83 | - IotThingModelDO thingModel = thingModels.get(0); | ||
| 84 | - tslRespVO.setProductId(thingModel.getProductId()).setProductKey(thingModel.getProductKey()); | 82 | + IotThingModelTSLRespVO tslRespVO = new IotThingModelTSLRespVO() |
| 83 | + .setProductId(product.getId()).setProductKey(product.getProductKey()); | ||
| 84 | + // 2. 获得物模型定义 | ||
| 85 | + List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductId(productId); | ||
| 85 | tslRespVO.setProperties(convertList(filterList(thingModels, item -> | 86 | tslRespVO.setProperties(convertList(filterList(thingModels, item -> |
| 86 | - ObjUtil.equal(IotThingModelTypeEnum.PROPERTY.getType(), item.getType())), IotThingModelDO::getProperty)); | ||
| 87 | - tslRespVO.setServices(convertList(filterList(thingModels, item -> | ||
| 88 | - ObjUtil.equal(IotThingModelTypeEnum.SERVICE.getType(), item.getType())), IotThingModelDO::getService)); | ||
| 89 | - tslRespVO.setEvents(convertList(filterList(thingModels, item -> | ||
| 90 | - ObjUtil.equal(IotThingModelTypeEnum.EVENT.getType(), item.getType())), IotThingModelDO::getEvent)); | 87 | + Objects.equal(IotThingModelTypeEnum.PROPERTY.getType(), item.getType())), IotThingModelDO::getProperty)) |
| 88 | + .setServices(convertList(filterList(thingModels, item -> | ||
| 89 | + Objects.equal(IotThingModelTypeEnum.SERVICE.getType(), item.getType())), IotThingModelDO::getService)) | ||
| 90 | + .setEvents(convertList(filterList(thingModels, item -> | ||
| 91 | + Objects.equal(IotThingModelTypeEnum.EVENT.getType(), item.getType())), IotThingModelDO::getEvent)); | ||
| 91 | return success(tslRespVO); | 92 | return success(tslRespVO); |
| 92 | } | 93 | } |
| 93 | 94 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelRespVO.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent; | ||
| 4 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty; | ||
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; | 3 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent; |
| 4 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty; | ||
| 5 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelService; | ||
| 6 | import io.swagger.v3.oas.annotations.media.Schema; | 6 | import io.swagger.v3.oas.annotations.media.Schema; |
| 7 | import lombok.Data; | 7 | import lombok.Data; |
| 8 | 8 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelSaveReqVO.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; | 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 4 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent; | ||
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty; | ||
| 6 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; | 4 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent; |
| 5 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty; | ||
| 6 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelService; | ||
| 7 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; | 7 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; |
| 8 | import io.swagger.v3.oas.annotations.media.Schema; | 8 | import io.swagger.v3.oas.annotations.media.Schema; |
| 9 | import jakarta.validation.Valid; | 9 | import jakarta.validation.Valid; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelTSLRespVO.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent; | ||
| 4 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty; | ||
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; | 3 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent; |
| 4 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty; | ||
| 5 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelService; | ||
| 6 | import io.swagger.v3.oas.annotations.media.Schema; | 6 | import io.swagger.v3.oas.annotations.media.Schema; |
| 7 | import lombok.Data; | 7 | import lombok.Data; |
| 8 | 8 | ||
| @@ -12,7 +12,7 @@ import java.util.List; | @@ -12,7 +12,7 @@ import java.util.List; | ||
| 12 | @Data | 12 | @Data |
| 13 | public class IotThingModelTSLRespVO { | 13 | public class IotThingModelTSLRespVO { |
| 14 | 14 | ||
| 15 | - @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | 15 | + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 16 | private Long productId; | 16 | private Long productId; |
| 17 | 17 | ||
| 18 | @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_sensor") | 18 | @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_sensor") |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/convert/thingmodel/IotThingModelConvert.java
| 1 | package cn.iocoder.yudao.module.iot.convert.thingmodel; | 1 | package cn.iocoder.yudao.module.iot.convert.thingmodel; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent; | ||
| 4 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty; | ||
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; | 3 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent; |
| 4 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty; | ||
| 5 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelService; | ||
| 6 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; | 6 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; |
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 8 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; | 8 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/IotThingModelDO.java
| 1 | package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel; | 1 | package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent; | ||
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty; | ||
| 6 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; | 4 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent; |
| 5 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty; | ||
| 6 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelService; | ||
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 8 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; | 8 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; |
| 9 | import com.baomidou.mybatisplus.annotation.KeySequence; | 9 | import com.baomidou.mybatisplus.annotation.KeySequence; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelEvent.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/model/ThingModelEvent.java
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; | 1 | +package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; | 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 4 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelServiceEventTypeEnum; | 4 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelServiceEventTypeEnum; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelParam.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/model/ThingModelParam.java
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; | 1 | +package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; | 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 4 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDataSpecs; | 4 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType.ThingModelDataSpecs; |
| 5 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum; | 5 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum; |
| 6 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelParamDirectionEnum; | 6 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelParamDirectionEnum; |
| 7 | import jakarta.validation.constraints.NotEmpty; | 7 | import jakarta.validation.constraints.NotEmpty; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelProperty.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/model/ThingModelProperty.java
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; | 1 | +package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; | 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 4 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDataSpecs; | 4 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType.ThingModelDataSpecs; |
| 5 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum; | 5 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum; |
| 6 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelAccessModeEnum; | 6 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelAccessModeEnum; |
| 7 | import jakarta.validation.constraints.NotEmpty; | 7 | import jakarta.validation.constraints.NotEmpty; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelService.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/model/ThingModelService.java
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; | 1 | +package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; | 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 4 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelServiceCallTypeEnum; | 4 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelServiceCallTypeEnum; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelArrayDataSpecs.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/model/dataType/ThingModelArrayDataSpecs.java
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; | 1 | +package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType; |
| 2 | 2 | ||
| 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| 4 | import jakarta.validation.Valid; | 4 | import jakarta.validation.Valid; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelBoolOrEnumDataSpecs.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/model/dataType/ThingModelBoolOrEnumDataSpecs.java
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; | 1 | +package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType; |
| 2 | 2 | ||
| 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| 4 | import jakarta.validation.constraints.NotEmpty; | 4 | import jakarta.validation.constraints.NotEmpty; |
| @@ -10,7 +10,7 @@ import lombok.EqualsAndHashCode; | @@ -10,7 +10,7 @@ import lombok.EqualsAndHashCode; | ||
| 10 | /** | 10 | /** |
| 11 | * IoT 物模型数据类型为布尔型或枚举型的 DataSpec 定义 | 11 | * IoT 物模型数据类型为布尔型或枚举型的 DataSpec 定义 |
| 12 | * | 12 | * |
| 13 | - * 数据类型,取值为 bool 或 enum。 | 13 | + * 数据类型,取值为 bool 或 enum |
| 14 | * | 14 | * |
| 15 | * @author HUIHUI | 15 | * @author HUIHUI |
| 16 | */ | 16 | */ |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelDataSpecs.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/model/dataType/ThingModelDataSpecs.java
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; | 1 | +package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType; |
| 2 | 2 | ||
| 3 | import com.fasterxml.jackson.annotation.JsonSubTypes; | 3 | import com.fasterxml.jackson.annotation.JsonSubTypes; |
| 4 | import com.fasterxml.jackson.annotation.JsonTypeInfo; | 4 | import com.fasterxml.jackson.annotation.JsonTypeInfo; |
| @@ -7,8 +7,8 @@ import lombok.Data; | @@ -7,8 +7,8 @@ import lombok.Data; | ||
| 7 | /** | 7 | /** |
| 8 | * IoT ThingModelDataSpecs 抽象类 | 8 | * IoT ThingModelDataSpecs 抽象类 |
| 9 | * | 9 | * |
| 10 | - * 用于表示物模型数据的通用类型,根据具体的 "dataType" 字段动态映射到对应的子类。 | ||
| 11 | - * 提供多态支持,适用于不同类型的数据结构序列化和反序列化场景。 | 10 | + * 用于表示物模型数据的通用类型,根据具体的 "dataType" 字段动态映射到对应的子类 |
| 11 | + * 提供多态支持,适用于不同类型的数据结构序列化和反序列化场景 | ||
| 12 | * | 12 | * |
| 13 | * @author HUIHUI | 13 | * @author HUIHUI |
| 14 | */ | 14 | */ |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelDateOrTextDataSpecs.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/model/dataType/ThingModelDateOrTextDataSpecs.java
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; | 1 | +package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType; |
| 2 | 2 | ||
| 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| 4 | import jakarta.validation.constraints.Max; | 4 | import jakarta.validation.constraints.Max; |
| @@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode; | @@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode; | ||
| 8 | /** | 8 | /** |
| 9 | * IoT 物模型数据类型为时间型或文本型的 DataSpec 定义 | 9 | * IoT 物模型数据类型为时间型或文本型的 DataSpec 定义 |
| 10 | * | 10 | * |
| 11 | - * 数据类型,取值为 date 或 text。 | 11 | + * 数据类型,取值为 date 或 text |
| 12 | * | 12 | * |
| 13 | * @author HUIHUI | 13 | * @author HUIHUI |
| 14 | */ | 14 | */ |
| @@ -18,13 +18,14 @@ import lombok.EqualsAndHashCode; | @@ -18,13 +18,14 @@ import lombok.EqualsAndHashCode; | ||
| 18 | public class ThingModelDateOrTextDataSpecs extends ThingModelDataSpecs { | 18 | public class ThingModelDateOrTextDataSpecs extends ThingModelDataSpecs { |
| 19 | 19 | ||
| 20 | /** | 20 | /** |
| 21 | - * 数据长度,单位为字节。取值不能超过 2048。 | ||
| 22 | - * 当 dataType 为 text 时,需传入该参数。 | 21 | + * 数据长度,单位为字节。取值不能超过 2048 |
| 22 | + * | ||
| 23 | + * 当 dataType 为 text 时,需传入该参数 | ||
| 23 | */ | 24 | */ |
| 24 | @Max(value = 2048, message = "数据长度不能超过 2048") | 25 | @Max(value = 2048, message = "数据长度不能超过 2048") |
| 25 | private Integer length; | 26 | private Integer length; |
| 26 | /** | 27 | /** |
| 27 | - * 默认值,可选参数,用于存储默认值。 | 28 | + * 默认值,可选参数,用于存储默认值 |
| 28 | */ | 29 | */ |
| 29 | private String defaultValue; | 30 | private String defaultValue; |
| 30 | 31 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelNumericDataSpec.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/model/dataType/ThingModelNumericDataSpec.java
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; | 1 | +package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType; |
| 2 | 2 | ||
| 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| 4 | import jakarta.validation.constraints.NotEmpty; | 4 | import jakarta.validation.constraints.NotEmpty; |
| @@ -9,7 +9,7 @@ import lombok.EqualsAndHashCode; | @@ -9,7 +9,7 @@ import lombok.EqualsAndHashCode; | ||
| 9 | /** | 9 | /** |
| 10 | * IoT 物模型数据类型为数值的 DataSpec 定义 | 10 | * IoT 物模型数据类型为数值的 DataSpec 定义 |
| 11 | * | 11 | * |
| 12 | - * 数据类型,取值为 int、float 或 double。 | 12 | + * 数据类型,取值为 int、float 或 double |
| 13 | * | 13 | * |
| 14 | * @author HUIHUI | 14 | * @author HUIHUI |
| 15 | */ | 15 | */ |
| @@ -19,37 +19,37 @@ import lombok.EqualsAndHashCode; | @@ -19,37 +19,37 @@ import lombok.EqualsAndHashCode; | ||
| 19 | public class ThingModelNumericDataSpec extends ThingModelDataSpecs { | 19 | public class ThingModelNumericDataSpec extends ThingModelDataSpecs { |
| 20 | 20 | ||
| 21 | /** | 21 | /** |
| 22 | - * 最大值,需转为字符串类型。值必须与 dataType 类型一致。 | 22 | + * 最大值,需转为字符串类型。值必须与 dataType 类型一致 |
| 23 | */ | 23 | */ |
| 24 | @NotEmpty(message = "最大值不能为空") | 24 | @NotEmpty(message = "最大值不能为空") |
| 25 | @Pattern(regexp = "^-?\\d+(\\.\\d+)?$", message = "最大值必须为数值类型") | 25 | @Pattern(regexp = "^-?\\d+(\\.\\d+)?$", message = "最大值必须为数值类型") |
| 26 | private String max; | 26 | private String max; |
| 27 | /** | 27 | /** |
| 28 | - * 最小值,需转为字符串类型。值必须与 dataType 类型一致。 | 28 | + * 最小值,需转为字符串类型。值必须与 dataType 类型一致 |
| 29 | */ | 29 | */ |
| 30 | @NotEmpty(message = "最小值不能为空") | 30 | @NotEmpty(message = "最小值不能为空") |
| 31 | @Pattern(regexp = "^-?\\d+(\\.\\d+)?$", message = "最小值必须为数值类型") | 31 | @Pattern(regexp = "^-?\\d+(\\.\\d+)?$", message = "最小值必须为数值类型") |
| 32 | private String min; | 32 | private String min; |
| 33 | /** | 33 | /** |
| 34 | - * 步长,需转为字符串类型。值必须与 dataType 类型一致。 | 34 | + * 步长,需转为字符串类型。值必须与 dataType 类型一致 |
| 35 | */ | 35 | */ |
| 36 | @NotEmpty(message = "步长不能为空") | 36 | @NotEmpty(message = "步长不能为空") |
| 37 | @Pattern(regexp = "^-?\\d+(\\.\\d+)?$", message = "步长必须为数值类型") | 37 | @Pattern(regexp = "^-?\\d+(\\.\\d+)?$", message = "步长必须为数值类型") |
| 38 | private String step; | 38 | private String step; |
| 39 | /** | 39 | /** |
| 40 | - * 精度。当 dataType 为 float 或 double 时可选传入。 | 40 | + * 精度。当 dataType 为 float 或 double 时可选传入 |
| 41 | */ | 41 | */ |
| 42 | private String precise; | 42 | private String precise; |
| 43 | /** | 43 | /** |
| 44 | - * 默认值,可传入用于存储的默认值。 | 44 | + * 默认值,可传入用于存储的默认值 |
| 45 | */ | 45 | */ |
| 46 | private String defaultValue; | 46 | private String defaultValue; |
| 47 | /** | 47 | /** |
| 48 | - * 单位的符号。 | 48 | + * 单位的符号 |
| 49 | */ | 49 | */ |
| 50 | private String unit; | 50 | private String unit; |
| 51 | /** | 51 | /** |
| 52 | - * 单位的名称。 | 52 | + * 单位的名称 |
| 53 | */ | 53 | */ |
| 54 | private String unitName; | 54 | private String unitName; |
| 55 | 55 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelStructDataSpecs.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/model/dataType/ThingModelStructDataSpecs.java
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; | 1 | +package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; | 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 4 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelAccessModeEnum; | 4 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelAccessModeEnum; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/core/TDengineTableField.java
| @@ -23,9 +23,15 @@ public class TDengineTableField { | @@ -23,9 +23,15 @@ public class TDengineTableField { | ||
| 23 | public static final String TYPE_DOUBLE = "DOUBLE"; | 23 | public static final String TYPE_DOUBLE = "DOUBLE"; |
| 24 | public static final String TYPE_BOOL = "BOOL"; | 24 | public static final String TYPE_BOOL = "BOOL"; |
| 25 | public static final String TYPE_NCHAR = "NCHAR"; | 25 | public static final String TYPE_NCHAR = "NCHAR"; |
| 26 | + public static final String TYPE_VARCHAR = "VARCHAR"; | ||
| 26 | public static final String TYPE_TIMESTAMP = "TIMESTAMP"; | 27 | public static final String TYPE_TIMESTAMP = "TIMESTAMP"; |
| 27 | 28 | ||
| 28 | /** | 29 | /** |
| 30 | + * 字段长度 - VARCHAR 默认长度 | ||
| 31 | + */ | ||
| 32 | + public static final int LENGTH_VARCHAR = 1024; | ||
| 33 | + | ||
| 34 | + /** | ||
| 29 | * 注释 - TAG 字段 | 35 | * 注释 - TAG 字段 |
| 30 | */ | 36 | */ |
| 31 | public static final String NOTE_TAG = "TAG"; | 37 | public static final String NOTE_TAG = "TAG"; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/property/IotDevicePropertyServiceImpl.java
| @@ -4,14 +4,16 @@ import cn.hutool.core.collection.CollUtil; | @@ -4,14 +4,16 @@ import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.hutool.core.date.LocalDateTimeUtil; | 4 | import cn.hutool.core.date.LocalDateTimeUtil; |
| 5 | import cn.hutool.core.map.MapUtil; | 5 | import cn.hutool.core.map.MapUtil; |
| 6 | import cn.hutool.core.util.StrUtil; | 6 | import cn.hutool.core.util.StrUtil; |
| 7 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||
| 8 | +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | ||
| 7 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyHistoryListReqVO; | 9 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyHistoryListReqVO; |
| 8 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO; | 10 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO; |
| 9 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs; | ||
| 10 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | 11 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| 11 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 12 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 12 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; | 13 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; |
| 13 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | 14 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 14 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | 15 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 16 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs; | ||
| 15 | import cn.iocoder.yudao.module.iot.dal.redis.device.DevicePropertyRedisDAO; | 17 | import cn.iocoder.yudao.module.iot.dal.redis.device.DevicePropertyRedisDAO; |
| 16 | import cn.iocoder.yudao.module.iot.dal.redis.device.DeviceReportTimeRedisDAO; | 18 | import cn.iocoder.yudao.module.iot.dal.redis.device.DeviceReportTimeRedisDAO; |
| 17 | import cn.iocoder.yudao.module.iot.dal.redis.device.DeviceServerIdRedisDAO; | 19 | import cn.iocoder.yudao.module.iot.dal.redis.device.DeviceServerIdRedisDAO; |
| @@ -43,17 +45,19 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | @@ -43,17 +45,19 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | ||
| 43 | 45 | ||
| 44 | /** | 46 | /** |
| 45 | * 物模型的数据类型,与 TDengine 数据类型的映射关系 | 47 | * 物模型的数据类型,与 TDengine 数据类型的映射关系 |
| 48 | + * | ||
| 49 | + * @see <a href="https://docs.taosdata.com/reference/taos-sql/data-type/">TDEngine 数据类型</a> | ||
| 46 | */ | 50 | */ |
| 47 | private static final Map<String, String> TYPE_MAPPING = MapUtil.<String, String>builder() | 51 | private static final Map<String, String> TYPE_MAPPING = MapUtil.<String, String>builder() |
| 48 | .put(IotDataSpecsDataTypeEnum.INT.getDataType(), TDengineTableField.TYPE_INT) | 52 | .put(IotDataSpecsDataTypeEnum.INT.getDataType(), TDengineTableField.TYPE_INT) |
| 49 | .put(IotDataSpecsDataTypeEnum.FLOAT.getDataType(), TDengineTableField.TYPE_FLOAT) | 53 | .put(IotDataSpecsDataTypeEnum.FLOAT.getDataType(), TDengineTableField.TYPE_FLOAT) |
| 50 | .put(IotDataSpecsDataTypeEnum.DOUBLE.getDataType(), TDengineTableField.TYPE_DOUBLE) | 54 | .put(IotDataSpecsDataTypeEnum.DOUBLE.getDataType(), TDengineTableField.TYPE_DOUBLE) |
| 51 | - .put(IotDataSpecsDataTypeEnum.ENUM.getDataType(), TDengineTableField.TYPE_TINYINT) // TODO 芋艿:为什么要映射为 TINYINT 的说明? | ||
| 52 | - .put(IotDataSpecsDataTypeEnum.BOOL.getDataType(), TDengineTableField.TYPE_TINYINT) // TODO 芋艿:为什么要映射为 TINYINT 的说明? | ||
| 53 | - .put(IotDataSpecsDataTypeEnum.TEXT.getDataType(), TDengineTableField.TYPE_NCHAR) | 55 | + .put(IotDataSpecsDataTypeEnum.ENUM.getDataType(), TDengineTableField.TYPE_TINYINT) |
| 56 | + .put(IotDataSpecsDataTypeEnum.BOOL.getDataType(), TDengineTableField.TYPE_TINYINT) | ||
| 57 | + .put(IotDataSpecsDataTypeEnum.TEXT.getDataType(), TDengineTableField.TYPE_VARCHAR) | ||
| 54 | .put(IotDataSpecsDataTypeEnum.DATE.getDataType(), TDengineTableField.TYPE_TIMESTAMP) | 58 | .put(IotDataSpecsDataTypeEnum.DATE.getDataType(), TDengineTableField.TYPE_TIMESTAMP) |
| 55 | - .put(IotDataSpecsDataTypeEnum.STRUCT.getDataType(), TDengineTableField.TYPE_NCHAR) // TODO 芋艿:怎么映射!!!! | ||
| 56 | - .put(IotDataSpecsDataTypeEnum.ARRAY.getDataType(), TDengineTableField.TYPE_NCHAR) // TODO 芋艿:怎么映射!!!! | 59 | + .put(IotDataSpecsDataTypeEnum.STRUCT.getDataType(), TDengineTableField.TYPE_VARCHAR) |
| 60 | + .put(IotDataSpecsDataTypeEnum.ARRAY.getDataType(), TDengineTableField.TYPE_VARCHAR) | ||
| 57 | .build(); | 61 | .build(); |
| 58 | 62 | ||
| 59 | @Resource | 63 | @Resource |
| @@ -109,8 +113,12 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | @@ -109,8 +113,12 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | ||
| 109 | TDengineTableField field = new TDengineTableField( | 113 | TDengineTableField field = new TDengineTableField( |
| 110 | StrUtil.toUnderlineCase(thingModel.getIdentifier()), // TDengine 字段默认都是小写 | 114 | StrUtil.toUnderlineCase(thingModel.getIdentifier()), // TDengine 字段默认都是小写 |
| 111 | TYPE_MAPPING.get(thingModel.getProperty().getDataType())); | 115 | TYPE_MAPPING.get(thingModel.getProperty().getDataType())); |
| 112 | - if (thingModel.getProperty().getDataType().equals(IotDataSpecsDataTypeEnum.TEXT.getDataType())) { | 116 | + String dataType = thingModel.getProperty().getDataType(); |
| 117 | + if (Objects.equals(dataType, IotDataSpecsDataTypeEnum.TEXT.getDataType())) { | ||
| 113 | field.setLength(((ThingModelDateOrTextDataSpecs) thingModel.getProperty().getDataSpecs()).getLength()); | 118 | field.setLength(((ThingModelDateOrTextDataSpecs) thingModel.getProperty().getDataSpecs()).getLength()); |
| 119 | + } else if (ObjectUtils.equalsAny(dataType, IotDataSpecsDataTypeEnum.STRUCT.getDataType(), | ||
| 120 | + IotDataSpecsDataTypeEnum.ARRAY.getDataType())) { | ||
| 121 | + field.setLength(TDengineTableField.LENGTH_VARCHAR); | ||
| 114 | } | 122 | } |
| 115 | return field; | 123 | return field; |
| 116 | }); | 124 | }); |
| @@ -118,7 +126,6 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | @@ -118,7 +126,6 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | ||
| 118 | 126 | ||
| 119 | @Override | 127 | @Override |
| 120 | public void saveDeviceProperty(IotDeviceDO device, IotDeviceMessage message) { | 128 | public void saveDeviceProperty(IotDeviceDO device, IotDeviceMessage message) { |
| 121 | - // TODO @芋艿:这里要改下协议! | ||
| 122 | if (!(message.getParams() instanceof Map)) { | 129 | if (!(message.getParams() instanceof Map)) { |
| 123 | log.error("[saveDeviceProperty][消息内容({}) 的 data 类型不正确]", message); | 130 | log.error("[saveDeviceProperty][消息内容({}) 的 data 类型不正确]", message); |
| 124 | return; | 131 | return; |
| @@ -129,11 +136,18 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | @@ -129,11 +136,18 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | ||
| 129 | List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductIdFromCache(device.getProductId()); | 136 | List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductIdFromCache(device.getProductId()); |
| 130 | Map<String, Object> properties = new HashMap<>(); | 137 | Map<String, Object> properties = new HashMap<>(); |
| 131 | ((Map<?, ?>) message.getParams()).forEach((key, value) -> { | 138 | ((Map<?, ?>) message.getParams()).forEach((key, value) -> { |
| 132 | - if (CollUtil.findOne(thingModels, thingModel -> thingModel.getIdentifier().equals(key)) == null) { | 139 | + IotThingModelDO thingModel = CollUtil.findOne(thingModels, o -> o.getIdentifier().equals(key)); |
| 140 | + if (thingModel == null || thingModel.getProperty() == null) { | ||
| 133 | log.error("[saveDeviceProperty][消息({}) 的属性({}) 不存在]", message, key); | 141 | log.error("[saveDeviceProperty][消息({}) 的属性({}) 不存在]", message, key); |
| 134 | return; | 142 | return; |
| 135 | } | 143 | } |
| 136 | - properties.put((String) key, value); | 144 | + if (ObjectUtils.equalsAny(thingModel.getProperty().getDataType(), |
| 145 | + IotDataSpecsDataTypeEnum.STRUCT.getDataType(), IotDataSpecsDataTypeEnum.ARRAY.getDataType())) { | ||
| 146 | + // 特殊:STRUCT 和 ARRAY 类型,在 TDengine 里,有没对应数据类型,只能通过 JSON 来存储 | ||
| 147 | + properties.put((String) key, JsonUtils.toJsonString(value)); | ||
| 148 | + } else { | ||
| 149 | + properties.put((String) key, value); | ||
| 150 | + } | ||
| 137 | }); | 151 | }); |
| 138 | if (CollUtil.isEmpty(properties)) { | 152 | if (CollUtil.isEmpty(properties)) { |
| 139 | log.error("[saveDeviceProperty][消息({}) 没有合法的属性]", message); | 153 | log.error("[saveDeviceProperty][消息({}) 没有合法的属性]", message); |
| @@ -141,8 +155,7 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | @@ -141,8 +155,7 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | ||
| 141 | } | 155 | } |
| 142 | 156 | ||
| 143 | // 2.1 保存设备属性【数据】 | 157 | // 2.1 保存设备属性【数据】 |
| 144 | - devicePropertyMapper.insert(device, properties, | ||
| 145 | - LocalDateTimeUtil.toEpochMilli(message.getReportTime())); | 158 | + devicePropertyMapper.insert(device, properties, LocalDateTimeUtil.toEpochMilli(message.getReportTime())); |
| 146 | 159 | ||
| 147 | // 2.2 保存设备属性【日志】 | 160 | // 2.2 保存设备属性【日志】 |
| 148 | Map<String, IotDevicePropertyDO> properties2 = convertMap(properties.entrySet(), Map.Entry::getKey, entry -> | 161 | Map<String, IotDevicePropertyDO> properties2 = convertMap(properties.entrySet(), Map.Entry::getKey, entry -> |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataRuleServiceImpl.java
| @@ -143,7 +143,7 @@ public class IotDataRuleServiceImpl implements IotDataRuleService { | @@ -143,7 +143,7 @@ public class IotDataRuleServiceImpl implements IotDataRuleService { | ||
| 143 | productId -> new HashSet<>()).add(config.getIdentifier()); | 143 | productId -> new HashSet<>()).add(config.getIdentifier()); |
| 144 | } | 144 | } |
| 145 | for (Map.Entry<Long, Set<String>> entry : productIdIdentifiers.entrySet()) { | 145 | for (Map.Entry<Long, Set<String>> entry : productIdIdentifiers.entrySet()) { |
| 146 | - thingModelService.validateThingModelsExist(entry.getKey(), entry.getValue()); | 146 | + thingModelService.validateThingModelListExists(entry.getKey(), entry.getValue()); |
| 147 | } | 147 | } |
| 148 | } | 148 | } |
| 149 | 149 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java
| @@ -106,6 +106,6 @@ public interface IotThingModelService { | @@ -106,6 +106,6 @@ public interface IotThingModelService { | ||
| 106 | * @param productId 产品编号 | 106 | * @param productId 产品编号 |
| 107 | * @param identifiers 标识符集合 | 107 | * @param identifiers 标识符集合 |
| 108 | */ | 108 | */ |
| 109 | - void validateThingModelsExist(Long productId, Set<String> identifiers); | 109 | + void validateThingModelListExists(Long productId, Set<String> identifiers); |
| 110 | 110 | ||
| 111 | } | 111 | } |
| 112 | \ No newline at end of file | 112 | \ 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
| @@ -66,7 +66,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -66,7 +66,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 66 | thingModelMapper.insert(thingModel); | 66 | thingModelMapper.insert(thingModel); |
| 67 | 67 | ||
| 68 | // 3. 删除缓存 | 68 | // 3. 删除缓存 |
| 69 | - deleteThingModelListCache(createReqVO.getProductKey()); | 69 | + deleteThingModelListCache(createReqVO.getProductId()); |
| 70 | return thingModel.getId(); | 70 | return thingModel.getId(); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| @@ -85,7 +85,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -85,7 +85,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 85 | thingModelMapper.updateById(thingModel); | 85 | thingModelMapper.updateById(thingModel); |
| 86 | 86 | ||
| 87 | // 3. 删除缓存 | 87 | // 3. 删除缓存 |
| 88 | - deleteThingModelListCache(updateReqVO.getProductKey()); | 88 | + deleteThingModelListCache(updateReqVO.getProductId()); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | @Override | 91 | @Override |
| @@ -103,7 +103,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -103,7 +103,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 103 | thingModelMapper.deleteById(id); | 103 | thingModelMapper.deleteById(id); |
| 104 | 104 | ||
| 105 | // 3. 删除缓存 | 105 | // 3. 删除缓存 |
| 106 | - deleteThingModelListCache(thingModel.getProductKey()); | 106 | + deleteThingModelListCache(thingModel.getProductId()); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | @Override | 109 | @Override |
| @@ -128,7 +128,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -128,7 +128,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 128 | 128 | ||
| 129 | @Override | 129 | @Override |
| 130 | @Cacheable(value = RedisKeyConstants.THING_MODEL_LIST, key = "#productId") | 130 | @Cacheable(value = RedisKeyConstants.THING_MODEL_LIST, key = "#productId") |
| 131 | - @TenantIgnore // 忽略租户信息,跨租户 productKey 是唯一的 | 131 | + @TenantIgnore // 忽略租户信息 |
| 132 | public List<IotThingModelDO> getThingModelListByProductIdFromCache(Long productId) { | 132 | public List<IotThingModelDO> getThingModelListByProductIdFromCache(Long productId) { |
| 133 | return thingModelMapper.selectListByProductId(productId); | 133 | return thingModelMapper.selectListByProductId(productId); |
| 134 | } | 134 | } |
| @@ -144,7 +144,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -144,7 +144,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | @Override | 146 | @Override |
| 147 | - public void validateThingModelsExist(Long productId, Set<String> identifiers) { | 147 | + public void validateThingModelListExists(Long productId, Set<String> identifiers) { |
| 148 | if (CollUtil.isEmpty(identifiers)) { | 148 | if (CollUtil.isEmpty(identifiers)) { |
| 149 | return; | 149 | return; |
| 150 | } | 150 | } |
| @@ -158,11 +158,6 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -158,11 +158,6 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 158 | } | 158 | } |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | - /** | ||
| 162 | - * 校验功能是否存在 | ||
| 163 | - * | ||
| 164 | - * @param id 功能编号 | ||
| 165 | - */ | ||
| 166 | private void validateProductThingModelMapperExists(Long id) { | 161 | private void validateProductThingModelMapperExists(Long id) { |
| 167 | if (thingModelMapper.selectById(id) == null) { | 162 | if (thingModelMapper.selectById(id) == null) { |
| 168 | throw exception(THING_MODEL_NOT_EXISTS); | 163 | throw exception(THING_MODEL_NOT_EXISTS); |
| @@ -170,13 +165,12 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -170,13 +165,12 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 170 | } | 165 | } |
| 171 | 166 | ||
| 172 | private void validateIdentifierUnique(Long id, Long productId, String identifier) { | 167 | private void validateIdentifierUnique(Long id, Long productId, String identifier) { |
| 173 | - // 1.0 情况一:创建时校验 | 168 | + // 1. 情况一:创建时校验 |
| 174 | if (id == null) { | 169 | if (id == null) { |
| 175 | // 1.1 系统保留字段,不能用于标识符定义 | 170 | // 1.1 系统保留字段,不能用于标识符定义 |
| 176 | if (StrUtil.equalsAny(identifier, "set", "get", "post", "property", "event", "time", "value")) { | 171 | if (StrUtil.equalsAny(identifier, "set", "get", "post", "property", "event", "time", "value")) { |
| 177 | throw exception(THING_MODEL_IDENTIFIER_INVALID); | 172 | throw exception(THING_MODEL_IDENTIFIER_INVALID); |
| 178 | } | 173 | } |
| 179 | - | ||
| 180 | // 1.2 校验唯一 | 174 | // 1.2 校验唯一 |
| 181 | IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier); | 175 | IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier); |
| 182 | if (thingModel != null) { | 176 | if (thingModel != null) { |
| @@ -185,7 +179,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -185,7 +179,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 185 | return; | 179 | return; |
| 186 | } | 180 | } |
| 187 | 181 | ||
| 188 | - // 2.0 情况二:更新时校验 | 182 | + // 2. 情况二:更新时校验 |
| 189 | IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier); | 183 | IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier); |
| 190 | if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) { | 184 | if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) { |
| 191 | throw exception(THING_MODEL_IDENTIFIER_EXISTS); | 185 | throw exception(THING_MODEL_IDENTIFIER_EXISTS); |
| @@ -206,13 +200,14 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -206,13 +200,14 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 206 | } | 200 | } |
| 207 | } | 201 | } |
| 208 | 202 | ||
| 209 | - private void deleteThingModelListCache(String productKey) { | 203 | + private void deleteThingModelListCache(Long productId) { |
| 210 | // 保证 Spring AOP 触发 | 204 | // 保证 Spring AOP 触发 |
| 211 | - getSelf().deleteThingModelListCache0(productKey); | 205 | + getSelf().deleteThingModelListCache0(productId); |
| 212 | } | 206 | } |
| 213 | 207 | ||
| 214 | - @CacheEvict(value = RedisKeyConstants.THING_MODEL_LIST, key = "#productKey") | ||
| 215 | - public void deleteThingModelListCache0(String productKey) { | 208 | + @CacheEvict(value = RedisKeyConstants.THING_MODEL_LIST, key = "#productId") |
| 209 | + @TenantIgnore // 忽略租户信息 | ||
| 210 | + public void deleteThingModelListCache0(Long productId) { | ||
| 216 | } | 211 | } |
| 217 | 212 | ||
| 218 | private IotThingModelServiceImpl getSelf() { | 213 | private IotThingModelServiceImpl getSelf() { |