!1167 【代码优化】IOT:物模型日志评审优化

Merge pull request !1167 from alwayssuper/feature/iot
This commit is contained in:
芋道源码 2024-12-21 08:29:40 +00:00 committed by Gitee
commit f580383267
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
7 changed files with 59 additions and 39 deletions

View File

@ -14,6 +14,7 @@ public interface ErrorCodeConstants {
ErrorCode PRODUCT_KEY_EXISTS = new ErrorCode(1_050_001_001, "产品标识已经存在"); ErrorCode PRODUCT_KEY_EXISTS = new ErrorCode(1_050_001_001, "产品标识已经存在");
ErrorCode PRODUCT_STATUS_NOT_DELETE = new ErrorCode(1_050_001_002, "产品状是发布状态,不允许删除"); ErrorCode PRODUCT_STATUS_NOT_DELETE = new ErrorCode(1_050_001_002, "产品状是发布状态,不允许删除");
ErrorCode PRODUCT_STATUS_NOT_ALLOW_THING_MODEL = new ErrorCode(1_050_001_003, "产品状是发布状态,不允许操作物模型"); ErrorCode PRODUCT_STATUS_NOT_ALLOW_THING_MODEL = new ErrorCode(1_050_001_003, "产品状是发布状态,不允许操作物模型");
ErrorCode PRODUCT_DEVICE_NOT_EXISTS = new ErrorCode(1_050_001_004, "产品设备类型不存在");
// ========== 产品物模型 1-050-002-000 ============ // ========== 产品物模型 1-050-002-000 ============
ErrorCode THING_MODEL_NOT_EXISTS = new ErrorCode(1_050_002_000, "产品物模型不存在"); ErrorCode THING_MODEL_NOT_EXISTS = new ErrorCode(1_050_002_000, "产品物模型不存在");

View File

@ -16,7 +16,7 @@ import java.util.Arrays;
public enum IotProductDeviceTypeEnum implements IntArrayValuable { public enum IotProductDeviceTypeEnum implements IntArrayValuable {
DIRECT(0, "直连设备"), DIRECT(0, "直连设备"),
GATEWAY_CHILD(1, "网关子设备"), GATEWAY_SUB(1, "网关子设备"),
GATEWAY(2, "网关设备"); GATEWAY(2, "网关设备");
/** /**

View File

@ -10,7 +10,7 @@ import org.apache.ibatis.annotations.Mapper;
*/ */
@Mapper @Mapper
@DS("tdengine") @DS("tdengine")
public interface TdThinkModelMessageMapper { public interface TdThingModelMessageMapper {
/** /**
* 创建物模型消息日志超级表超级表 * 创建物模型消息日志超级表超级表

View File

@ -0,0 +1,8 @@
package cn.iocoder.yudao.module.iot.mq.consumer.simulatesend;
/**
* @author alwayssuper
* @date 2024/12/20 8:04
*/
public class SimulateSendConsumer {
}

View File

@ -13,11 +13,9 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotProductThingModelDO; import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotProductThingModelDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.*;
import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO; import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDDLMapper; import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDDLMapper;
import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper; import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper;
import cn.iocoder.yudao.module.iot.dal.tdengine.TdThinkModelMessageMapper;
import cn.iocoder.yudao.module.iot.enums.IotConstants; import cn.iocoder.yudao.module.iot.enums.IotConstants;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotProductThingModelTypeEnum; import cn.iocoder.yudao.module.iot.enums.thingmodel.IotProductThingModelTypeEnum;
@ -68,11 +66,6 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
@Resource @Resource
private DeviceDataRedisDAO deviceDataRedisDAO; private DeviceDataRedisDAO deviceDataRedisDAO;
@Resource
private IotTdDatabaseUtils iotTdDatabaseUtils;
@Resource
private TdThinkModelMessageMapper tdThinkModelMessageMapper;
// TODO @haohao这个方法可以考虑加下 1. 2. 3. 更有层次感 // TODO @haohao这个方法可以考虑加下 1. 2. 3. 更有层次感
@Override @Override
@ -85,7 +78,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
iotDeviceService.updateDeviceStatus(new IotDeviceStatusUpdateReqVO() iotDeviceService.updateDeviceStatus(new IotDeviceStatusUpdateReqVO()
.setId(device.getId()).setStatus(IotDeviceStatusEnum.ONLINE.getStatus())); .setId(device.getId()).setStatus(IotDeviceStatusEnum.ONLINE.getStatus()));
// 1.2 创建物模型日志设备表 // 1.2 创建物模型日志设备表
createThinkModelMessageDeviceTable(device.getProductKey(), device.getDeviceName(), device.getDeviceKey()); createThingModelMessageDeviceTable(device.getProductKey(), device.getDeviceName(), device.getDeviceKey());
} }
// 2. 获取设备属性并进行物模型校验过滤非物模型属性 // 2. 获取设备属性并进行物模型校验过滤非物模型属性
@ -122,13 +115,23 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
// 2. 获取超级表的名称和数据库名称 // 2. 获取超级表的名称和数据库名称
// TODO @alwayssuper最好 databaseNamesuperTableName 的处理放到 tdThinkModelMessageMapper 可以考虑弄个 default 方法 // TODO @alwayssuper最好 databaseNamesuperTableName 的处理放到 tdThinkModelMessageMapper 可以考虑弄个 default 方法
String databaseName = iotTdDatabaseUtils.getDatabaseName(); String databaseName = IotTdDatabaseUtils.getDatabaseName(url);
String superTableName = IotTdDatabaseUtils.getThingModelMessageSuperTableName(product.getProductKey()); String superTableName = IotTdDatabaseUtils.getThingModelMessageSuperTableName(product.getProductKey());
// 解析物模型获取字段列表
List<TdFieldDO> schemaFields = List.of(
TdFieldDO.builder().fieldName("time").dataType("TIMESTAMP").build(),
TdFieldDO.builder().fieldName("id").dataType("NCHAR").dataLength(64).build(),
TdFieldDO.builder().fieldName("sys").dataType("NCHAR").dataLength(2048).build(),
TdFieldDO.builder().fieldName("method").dataType("NCHAR").dataLength(256).build(),
TdFieldDO.builder().fieldName("params").dataType("NCHAR").dataLength(2048).build()
);
// 设置超级表的标签
List<TdFieldDO> tagsFields = List.of(
TdFieldDO.builder().fieldName("device_key").dataType("NCHAR").dataLength(64).build()
);
// 3. 创建超级表 // 3. 创建超级表
tdThinkModelMessageMapper.createSuperTable(ThingModelMessageDO.builder().build() tdEngineDDLMapper.createSuperTable(new TdTableDO(databaseName, superTableName, schemaFields, tagsFields));
.setDataBaseName(databaseName)
.setSuperTableName(superTableName));
} }
private List<IotProductThingModelDO> getValidFunctionList(String productKey) { private List<IotProductThingModelDO> getValidFunctionList(String productKey) {
@ -237,20 +240,20 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
* @param deviceKey 设备 Key * @param deviceKey 设备 Key
* *
*/ */
private void createThinkModelMessageDeviceTable(String productKey, String deviceName, String deviceKey){ private void createThingModelMessageDeviceTable(String productKey, String deviceName, String deviceKey){
// 1. 获取超级表的名称数据库名称设备日志表名称 // 1. 获取超级表的名称数据库名称设备日志表名称
String databaseName = iotTdDatabaseUtils.getDatabaseName(); String databaseName = IotTdDatabaseUtils.getDatabaseName(url);
String superTableName = IotTdDatabaseUtils.getThingModelMessageSuperTableName(productKey); String superTableName = IotTdDatabaseUtils.getThingModelMessageSuperTableName(productKey);
// TODO @alwayssuper最好 databaseNamesuperTableNamethinkModelMessageDeviceTableName 的处理放到 tdThinkModelMessageMapper 可以考虑弄个 default 方法 // TODO @alwayssuper最好 databaseNamesuperTableNamethinkModelMessageDeviceTableName 的处理放到 tdThinkModelMessageMapper 可以考虑弄个 default 方法
String thinkModelMessageDeviceTableName = IotTdDatabaseUtils.getThinkModelMessageDeviceTableName(productKey, deviceName); String thinkModelMessageDeviceTableName = IotTdDatabaseUtils.getThingModelMessageDeviceTableName(productKey, deviceName);
// 2. 创建物模型日志设备数据表 // 2. 创建物模型日志设备数据表
tdThinkModelMessageMapper.createTableWithTag(ThingModelMessageDO.builder().build() // tdThingModelMessageMapper.createTableWithTag(ThingModelMessageDO.builder().build()
.setDataBaseName(databaseName) // .setDataBaseName(databaseName)
.setSuperTableName(superTableName) // .setSuperTableName(superTableName)
.setTableName(thinkModelMessageDeviceTableName) // .setTableName(thinkModelMessageDeviceTableName)
.setDeviceKey(deviceKey)); // .setDeviceKey(deviceKey));
} }
/** /**

View File

@ -1,9 +1,14 @@
package cn.iocoder.yudao.module.iot.util; package cn.iocoder.yudao.module.iot.util;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.iot.enums.IotConstants; import cn.iocoder.yudao.module.iot.enums.IotConstants;
import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.PRODUCT_DEVICE_NOT_EXISTS;
// TODO @芋艿可能要思索下有没更好的处理方式 // TODO @芋艿可能要思索下有没更好的处理方式
// TODO @芋艿怎么改成无状态 // TODO @芋艿怎么改成无状态
/** /**
@ -11,19 +16,14 @@ import org.springframework.stereotype.Component;
* *
* @author AlwaysSuper * @author AlwaysSuper
*/ */
@Component
public class IotTdDatabaseUtils { public class IotTdDatabaseUtils {
@Value("${spring.datasource.dynamic.datasource.tdengine.url}")
private String url;
/** /**
* 获取数据库名称 * 获取数据库名称
*/ */
public String getDatabaseName() { public static String getDatabaseName(String url) {
// TODO @alwayssuper:StrUtil.subAfter("/") // TODO @alwayssuper:StrUtil.subAfter("/")
int index = url.lastIndexOf("/"); return StrUtil.subAfter(url, "/", true);
return index != -1 ? url.substring(index + 1) : url;
} }
/** /**
@ -35,11 +35,19 @@ public class IotTdDatabaseUtils {
*/ */
public static String getProductSuperTableName(Integer deviceType, String productKey) { public static String getProductSuperTableName(Integer deviceType, String productKey) {
// TODO @alwayssuper枚举字段不要 123不符合预期抛出异常 // TODO @alwayssuper枚举字段不要 123不符合预期抛出异常
return switch (deviceType) { if (deviceType == null) {
case 1 -> String.format(IotConstants.GATEWAY_SUB_STABLE_NAME_FORMAT, productKey).toLowerCase(); throw exception(PRODUCT_DEVICE_NOT_EXISTS);
case 2 -> String.format(IotConstants.GATEWAY_STABLE_NAME_FORMAT, productKey).toLowerCase(); }
default -> String.format(IotConstants.DEVICE_STABLE_NAME_FORMAT, productKey).toLowerCase(); if (IotProductDeviceTypeEnum.GATEWAY_SUB.getType().equals(deviceType)) {
}; return String.format(IotConstants.GATEWAY_SUB_STABLE_NAME_FORMAT, productKey).toLowerCase();
} else if (IotProductDeviceTypeEnum.GATEWAY.getType().equals(deviceType)) {
return String.format(IotConstants.GATEWAY_STABLE_NAME_FORMAT, productKey).toLowerCase();
} else if (IotProductDeviceTypeEnum.DIRECT.getType().equals(deviceType)){
return String.format(IotConstants.DEVICE_STABLE_NAME_FORMAT, productKey).toLowerCase();
}
else{
throw exception(PRODUCT_DEVICE_NOT_EXISTS);
}
} }
/** /**
@ -51,7 +59,7 @@ public class IotTdDatabaseUtils {
*/ */
public static String getThingModelMessageSuperTableName(String productKey) { public static String getThingModelMessageSuperTableName(String productKey) {
// TODO @alwayssuper是不是应该 + 拼接就好不用 format // TODO @alwayssuper是不是应该 + 拼接就好不用 format
return String.format("thing_model_message_", productKey).toLowerCase(); return "thing_model_message_" + productKey.toLowerCase();
} }
/** /**
@ -61,7 +69,7 @@ public class IotTdDatabaseUtils {
* @param deviceName 设备名称 * @param deviceName 设备名称
* @return 物模型日志设备表名 * @return 物模型日志设备表名
*/ */
public static String getThinkModelMessageDeviceTableName(String productKey, String deviceName) { public static String getThingModelMessageDeviceTableName(String productKey, String deviceName) {
return String.format(IotConstants.THING_MODEL_MESSAGE_TABLE_NAME_FORMAT, productKey.toLowerCase(), deviceName.toLowerCase()); return String.format(IotConstants.THING_MODEL_MESSAGE_TABLE_NAME_FORMAT, productKey.toLowerCase(), deviceName.toLowerCase());
} }

View File

@ -2,7 +2,7 @@
<!DOCTYPE mapper <!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdThinkModelMessageMapper"> <mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdThingModelMessageMapper">
<!-- 创建物模型消息日志超级表 --> <!-- 创建物模型消息日志超级表 -->
<!-- TODO @芋艿:捉摸下字段,特别是 sys、ts 这种缩写 --> <!-- TODO @芋艿:捉摸下字段,特别是 sys、ts 这种缩写 -->
@ -14,7 +14,7 @@
method VARCHAR(255), method VARCHAR(255),
params VARCHAR(2048) params VARCHAR(2048)
)TAGS ( )TAGS (
deviceKey VARCHAR(255) device_key VARCHAR(255)
) )
</update> </update>
@ -28,7 +28,7 @@
method , method ,
params params
)TAGS( )TAGS(
#{deviceKey} #{device_key}
) )
</update> </update>
</mapper> </mapper>