diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/data/IotDevicePropertyHistoryPageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/data/IotDevicePropertyHistoryPageReqVO.java index dc069b9559..38b891309e 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/data/IotDevicePropertyHistoryPageReqVO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/data/IotDevicePropertyHistoryPageReqVO.java @@ -20,12 +20,6 @@ public class IotDevicePropertyHistoryPageReqVO extends PageParam { @NotNull(message = "设备编号不能为空") private Long deviceId; - @Schema(description = "产品 Key", hidden = true) - private String productKey; // 非前端传递,后端自己查询设置 - - @Schema(description = "设备名称", hidden = true) - private String deviceName; // 非前端传递,后端自己查询设置 - @Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED) @NotEmpty(message = "属性标识符不能为空") private String identifier; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotThingModelMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotThingModelMapper.java index 082386b4e0..2ef95d31fb 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotThingModelMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotThingModelMapper.java @@ -50,10 +50,6 @@ public interface IotThingModelMapper extends BaseMapperX { return selectList(IotThingModelDO::getProductId, productId); } - default List selectListByProductKey(String productKey) { - return selectList(IotThingModelDO::getProductKey, productKey); - } - default List selectListByProductIdAndType(Long productId, Integer type) { return selectList(IotThingModelDO::getProductId, productId, IotThingModelDO::getType, type); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/RedisKeyConstants.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/RedisKeyConstants.java index 99bbf2c4c2..5c4b7429f0 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/RedisKeyConstants.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/RedisKeyConstants.java @@ -9,15 +9,14 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; */ public interface RedisKeyConstants { - // TODO @芋艿:弱化 deviceKey;使用 product_key + device_name 替代 /** * 设备属性的数据缓存,采用 HASH 结构 *

- * KEY 格式:device_property:{deviceKey} + * KEY 格式:device_property:{deviceId} * HASH KEY:identifier 属性标识 * VALUE 数据类型:String(JSON) {@link IotDevicePropertyDO} */ - String DEVICE_PROPERTY = "iot:device_property:%s"; + String DEVICE_PROPERTY = "iot:device_property:%d"; /** * 设备的最后上报时间,采用 ZSET 结构 @@ -31,7 +30,7 @@ public interface RedisKeyConstants { * 设备关联的网关 serverId 缓存,采用 HASH 结构 * * KEY 格式:device_server_id - * HASH KEY:{productKey},{deviceName} + * HASH KEY:{deviceId} * VALUE 数据类型:String serverId */ String DEVICE_SERVER_ID = "iot:device_server_id"; @@ -56,7 +55,7 @@ public interface RedisKeyConstants { /** * 物模型的数据缓存,使用 Spring Cache 操作(忽略租户) * - * KEY 格式:thing_model_${productKey} + * KEY 格式:thing_model_${productId} * VALUE 数据类型:String 数组(JSON),即 {@link cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO} 列表 */ String THING_MODEL_LIST = "iot:thing_model_list"; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/device/DevicePropertyRedisDAO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/device/DevicePropertyRedisDAO.java index f60ddc2d8b..c8833830f2 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/device/DevicePropertyRedisDAO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/device/DevicePropertyRedisDAO.java @@ -22,8 +22,8 @@ public class DevicePropertyRedisDAO { @Resource private StringRedisTemplate stringRedisTemplate; - public Map get(String productKey, String deviceName) { - String redisKey = formatKey(productKey, deviceName); + public Map get(Long id) { + String redisKey = formatKey(id); Map entries = stringRedisTemplate.opsForHash().entries(redisKey); if (CollUtil.isEmpty(entries)) { return Collections.emptyMap(); @@ -33,18 +33,18 @@ public class DevicePropertyRedisDAO { entry -> JsonUtils.parseObject((String) entry.getValue(), IotDevicePropertyDO.class)); } - public void putAll(String productKey, String deviceName, Map properties) { + public void putAll(Long id, Map properties) { if (CollUtil.isEmpty(properties)) { return; } - String redisKey = formatKey(productKey, deviceName); + String redisKey = formatKey(id); stringRedisTemplate.opsForHash().putAll(redisKey, convertMap(properties.entrySet(), Map.Entry::getKey, entry -> JsonUtils.toJsonString(entry.getValue()))); } - private static String formatKey(String productKey, String deviceName) { - return String.format(DEVICE_PROPERTY, productKey, deviceName); + private static String formatKey(Long id) { + return String.format(DEVICE_PROPERTY, id); } } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyMapper.java index 4045320289..af619cf650 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyMapper.java @@ -23,17 +23,17 @@ import java.util.stream.Collectors; @InterceptorIgnore(tenantLine = "true") // 避免 SQL 解析,因为 JSqlParser 对 TDengine 的 SQL 解析会报错 public interface IotDevicePropertyMapper { - List getProductPropertySTableFieldList(@Param("productKey") String productKey); + List getProductPropertySTableFieldList(@Param("productId") Long productId); - void createProductPropertySTable(@Param("productKey") String productKey, + void createProductPropertySTable(@Param("productId") Long productId, @Param("fields") List fields); @SuppressWarnings("SimplifyStreamApiCallChains") // 保持 JDK8 兼容性 - default void alterProductPropertySTable(String productKey, + default void alterProductPropertySTable(Long productId, List oldFields, List newFields) { oldFields.removeIf(field -> StrUtil.equalsAny(field.getField(), - TDengineTableField.FIELD_TS, "report_time", "device_name")); + TDengineTableField.FIELD_TS, "report_time")); List addFields = newFields.stream().filter( // 新增的字段 newField -> oldFields.stream().noneMatch(oldField -> oldField.getField().equals(newField.getField()))) .collect(Collectors.toList()); @@ -62,22 +62,22 @@ public interface IotDevicePropertyMapper { }); // 执行 - addFields.forEach(field -> alterProductPropertySTableAddField(productKey, field)); - dropFields.forEach(field -> alterProductPropertySTableDropField(productKey, field)); - modifyLengthFields.forEach(field -> alterProductPropertySTableModifyField(productKey, field)); + addFields.forEach(field -> alterProductPropertySTableAddField(productId, field)); + dropFields.forEach(field -> alterProductPropertySTableDropField(productId, field)); + modifyLengthFields.forEach(field -> alterProductPropertySTableModifyField(productId, field)); modifyTypeFields.forEach(field -> { - alterProductPropertySTableDropField(productKey, field); - alterProductPropertySTableAddField(productKey, field); + alterProductPropertySTableDropField(productId, field); + alterProductPropertySTableAddField(productId, field); }); } - void alterProductPropertySTableAddField(@Param("productKey") String productKey, + void alterProductPropertySTableAddField(@Param("productId") Long productId, @Param("field") TDengineTableField field); - void alterProductPropertySTableModifyField(@Param("productKey") String productKey, + void alterProductPropertySTableModifyField(@Param("productId") Long productId, @Param("field") TDengineTableField field); - void alterProductPropertySTableDropField(@Param("productKey") String productKey, + void alterProductPropertySTableDropField(@Param("productId") Long productId, @Param("field") TDengineTableField field); void insert(@Param("device") IotDeviceDO device, diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/property/IotDevicePropertyServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/property/IotDevicePropertyServiceImpl.java index b15aec82ad..cbe7a6683b 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/property/IotDevicePropertyServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/property/IotDevicePropertyServiceImpl.java @@ -20,7 +20,6 @@ import cn.iocoder.yudao.module.iot.dal.tdengine.IotDevicePropertyMapper; import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum; import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField; -import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; import cn.iocoder.yudao.module.iot.service.product.IotProductService; import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -59,8 +58,6 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { .put(IotDataSpecsDataTypeEnum.ARRAY.getDataType(), TDengineTableField.TYPE_NCHAR) // TODO 芋艿:怎么映射!!!! .build(); - @Resource - private IotDeviceService deviceService; @Resource private IotThingModelService thingModelService; @Resource @@ -87,7 +84,7 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { // 1.2 解析 DB 里的字段 List oldFields = new ArrayList<>(); try { - oldFields.addAll(devicePropertyMapper.getProductPropertySTableFieldList(product.getProductKey())); + oldFields.addAll(devicePropertyMapper.getProductPropertySTableFieldList(product.getId())); } catch (Exception e) { if (!e.getMessage().contains("Table does not exist")) { throw e; @@ -101,11 +98,11 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { log.info("[defineDevicePropertyData][productId({}) 没有需要定义的属性]", productId); return; } - devicePropertyMapper.createProductPropertySTable(product.getProductKey(), newFields); + devicePropertyMapper.createProductPropertySTable(product.getId(), newFields); return; } // 2.2 情况二:如果是修改的时候,需要更新表 - devicePropertyMapper.alterProductPropertySTable(product.getProductKey(), oldFields, newFields); + devicePropertyMapper.alterProductPropertySTable(product.getId(), oldFields, newFields); } private List buildTableFieldList(List thingModels) { @@ -122,16 +119,17 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { @Override public void saveDeviceProperty(IotDeviceDO device, IotDeviceMessage message) { - if (!(message.getData() instanceof Map)) { + // TODO @芋艿:这里要改下协议! + if (!(message.getParams() instanceof Map)) { log.error("[saveDeviceProperty][消息内容({}) 的 data 类型不正确]", message); return; } // 1. 根据物模型,拼接合法的属性 // TODO @芋艿:【待定 004】赋能后,属性到底以 thingModel 为准(ik),还是 db 的表结构为准(tl)? - List thingModels = thingModelService.getThingModelListByProductKeyFromCache(device.getProductKey()); + List thingModels = thingModelService.getThingModelListByProductIdFromCache(device.getProductId()); Map properties = new HashMap<>(); - ((Map) message.getData()).forEach((key, value) -> { + ((Map) message.getParams()).forEach((key, value) -> { if (CollUtil.findOne(thingModels, thingModel -> thingModel.getIdentifier().equals(key)) == null) { log.error("[saveDeviceProperty][消息({}) 的属性({}) 不存在]", message, key); return; @@ -150,25 +148,16 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { // 2.2 保存设备属性【日志】 Map properties2 = convertMap(properties.entrySet(), Map.Entry::getKey, entry -> IotDevicePropertyDO.builder().value(entry.getValue()).updateTime(message.getReportTime()).build()); - deviceDataRedisDAO.putAll(device.getProductKey(), device.getDeviceName(), properties2); + deviceDataRedisDAO.putAll(device.getId(), properties2); } @Override public Map getLatestDeviceProperties(Long deviceId) { - // 获取设备信息 - IotDeviceDO device = deviceService.validateDeviceExists(deviceId); - - // 获得设备属性 - return deviceDataRedisDAO.get(device.getProductKey(), device.getDeviceName()); + return deviceDataRedisDAO.get(deviceId); } @Override public PageResult getHistoryDevicePropertyPage(IotDevicePropertyHistoryPageReqVO pageReqVO) { - // 获取设备信息 - IotDeviceDO device = deviceService.validateDeviceExists(pageReqVO.getDeviceId()); - pageReqVO.setProductKey(device.getProductKey()).setDeviceName(device.getDeviceName()); - - // 分页查询 try { IPage page = devicePropertyMapper.selectPageByHistory( new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java index 8834772d35..875da72664 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java @@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelS import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; import jakarta.validation.Valid; -import java.time.LocalDateTime; import java.util.List; /** @@ -60,10 +59,10 @@ public interface IotThingModelService { * * 注意:该方法会忽略租户信息,所以调用时,需要确认会不会有跨租户访问的风险!!! * - * @param productKey 产品标识 + * @param productId 产品编号 * @return 产品物模型列表 */ - List getThingModelListByProductKeyFromCache(String productKey); + List getThingModelListByProductIdFromCache(Long productId); /** * 获得产品物模型分页 @@ -81,13 +80,4 @@ public interface IotThingModelService { */ List getThingModelList(IotThingModelListReqVO reqVO); - // TODO @super:用不到,删除下哈。 - /** - * 获得物模型数量 - * - * @param createTime 创建时间,如果为空,则统计所有物模型数量 - * @return 物模型数量 - */ - Long getThingModelCount(LocalDateTime createTime); - } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java index 9487ff2de6..edba5e65b4 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java @@ -29,7 +29,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; -import java.time.LocalDateTime; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -133,10 +132,10 @@ public class IotThingModelServiceImpl implements IotThingModelService { } @Override - @Cacheable(value = RedisKeyConstants.THING_MODEL_LIST, key = "#productKey") + @Cacheable(value = RedisKeyConstants.THING_MODEL_LIST, key = "#productId") @TenantIgnore // 忽略租户信息,跨租户 productKey 是唯一的 - public List getThingModelListByProductKeyFromCache(String productKey) { - return thingModelMapper.selectListByProductKey(productKey); + public List getThingModelListByProductIdFromCache(Long productId) { + return thingModelMapper.selectListByProductId(productId); } @Override @@ -364,10 +363,4 @@ public class IotThingModelServiceImpl implements IotThingModelService { return SpringUtil.getBean(getClass()); } - // TODO @super:用不到,删除下; - @Override - public Long getThingModelCount(LocalDateTime createTime) { - return thingModelMapper.selectCountByCreateTime(createTime); - } - } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyMapper.xml b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyMapper.xml index 6ff465162e..bd58b8c168 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyMapper.xml +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyMapper.xml @@ -5,11 +5,11 @@ - CREATE STABLE product_property_${productKey} ( + CREATE STABLE product_property_${productId} ( ts TIMESTAMP, report_time TIMESTAMP, @@ -20,12 +20,12 @@ ) TAGS ( - device_name NCHAR(50) + device_id BIGINT ) - ALTER STABLE product_property_${productKey} + ALTER STABLE product_property_${productId} ADD COLUMN ${field.field} ${field.type} (${field.length}) @@ -33,7 +33,7 @@ - ALTER STABLE product_property_${productKey} + ALTER STABLE product_property_${productId} MODIFY COLUMN ${field.field} ${field.type} (${field.length}) @@ -41,14 +41,14 @@ - ALTER STABLE product_property_${productKey} + ALTER STABLE product_property_${productId} DROP COLUMN ${field.field} - INSERT INTO device_property_${device.productKey}_${device.deviceName} - USING product_property_${device.productKey} - TAGS ('${device.deviceName}') + INSERT INTO device_property_${device.id} + USING product_property_${device.productId} + TAGS ('${device.id}') (ts, report_time, ${@cn.hutool.core.util.StrUtil@toUnderlineCase(key)} @@ -63,13 +63,14 @@ +