Commit 8ff09fea018acc63b107430fe4a5c7ca1ffbed5c

Authored by alwayssuper
1 parent b2434b7b

[代码优化]:物模型日志评审优化

yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
... ... @@ -14,6 +14,7 @@ public interface ErrorCodeConstants {
14 14 ErrorCode PRODUCT_KEY_EXISTS = new ErrorCode(1_050_001_001, "产品标识已经存在");
15 15 ErrorCode PRODUCT_STATUS_NOT_DELETE = new ErrorCode(1_050_001_002, "产品状是发布状态,不允许删除");
16 16 ErrorCode PRODUCT_STATUS_NOT_ALLOW_THING_MODEL = new ErrorCode(1_050_001_003, "产品状是发布状态,不允许操作物模型");
  17 + ErrorCode PRODUCT_DEVICE_NOT_EXISTS = new ErrorCode(1_050_001_004, "产品设备类型不存在");
17 18  
18 19 // ========== 产品物模型 1-050-002-000 ============
19 20 ErrorCode THING_MODEL_NOT_EXISTS = new ErrorCode(1_050_002_000, "产品物模型不存在");
... ...
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/product/IotProductDeviceTypeEnum.java
... ... @@ -16,7 +16,7 @@ import java.util.Arrays;
16 16 public enum IotProductDeviceTypeEnum implements IntArrayValuable {
17 17  
18 18 DIRECT(0, "直连设备"),
19   - GATEWAY_CHILD(1, "网关子设备"),
  19 + GATEWAY_SUB(1, "网关子设备"),
20 20 GATEWAY(2, "网关设备");
21 21  
22 22 /**
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdThinkModelMessageMapper.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdThingModelMessageMapper.java
... ... @@ -10,7 +10,7 @@ import org.apache.ibatis.annotations.Mapper;
10 10 */
11 11 @Mapper
12 12 @DS("tdengine")
13   -public interface TdThinkModelMessageMapper {
  13 +public interface TdThingModelMessageMapper {
14 14  
15 15 /**
16 16 * 创建物模型消息日志超级表超级表
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.mq.consumer.simulatesend;
  2 +
  3 +/**
  4 + * @author alwayssuper
  5 + * @date 2024/12/20 8:04
  6 + */
  7 +public class SimulateSendConsumer {
  8 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java
... ... @@ -13,11 +13,9 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.TdTableDO;
13 13 import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage;
14 14 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotProductThingModelDO;
15 15 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
16   -import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.*;
17 16 import cn.iocoder.yudao.module.iot.dal.redis.deviceData.DeviceDataRedisDAO;
18 17 import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDDLMapper;
19 18 import cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineDMLMapper;
20   -import cn.iocoder.yudao.module.iot.dal.tdengine.TdThinkModelMessageMapper;
21 19 import cn.iocoder.yudao.module.iot.enums.IotConstants;
22 20 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
23 21 import cn.iocoder.yudao.module.iot.enums.thingmodel.IotProductThingModelTypeEnum;
... ... @@ -68,11 +66,6 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
68 66 @Resource
69 67 private DeviceDataRedisDAO deviceDataRedisDAO;
70 68  
71   - @Resource
72   - private IotTdDatabaseUtils iotTdDatabaseUtils;
73   -
74   - @Resource
75   - private TdThinkModelMessageMapper tdThinkModelMessageMapper;
76 69  
77 70 // TODO @haohao:这个方法,可以考虑加下 1. 2. 3. 更有层次感
78 71 @Override
... ... @@ -85,7 +78,7 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
85 78 iotDeviceService.updateDeviceStatus(new IotDeviceStatusUpdateReqVO()
86 79 .setId(device.getId()).setStatus(IotDeviceStatusEnum.ONLINE.getStatus()));
87 80 // 1.2 创建物模型日志设备表
88   - createThinkModelMessageDeviceTable(device.getProductKey(), device.getDeviceName(), device.getDeviceKey());
  81 + createThingModelMessageDeviceTable(device.getProductKey(), device.getDeviceName(), device.getDeviceKey());
89 82 }
90 83  
91 84 // 2. 获取设备属性并进行物模型校验,过滤非物模型属性
... ... @@ -122,13 +115,23 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
122 115  
123 116 // 2. 获取超级表的名称和数据库名称
124 117 // TODO @alwayssuper:最好 databaseName、superTableName 的处理,放到 tdThinkModelMessageMapper 里。可以考虑,弄个 default 方法
125   - String databaseName = iotTdDatabaseUtils.getDatabaseName();
  118 + String databaseName = IotTdDatabaseUtils.getDatabaseName(url);
126 119 String superTableName = IotTdDatabaseUtils.getThingModelMessageSuperTableName(product.getProductKey());
127 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 + );
128 133 // 3. 创建超级表
129   - tdThinkModelMessageMapper.createSuperTable(ThingModelMessageDO.builder().build()
130   - .setDataBaseName(databaseName)
131   - .setSuperTableName(superTableName));
  134 + tdEngineDDLMapper.createSuperTable(new TdTableDO(databaseName, superTableName, schemaFields, tagsFields));
132 135 }
133 136  
134 137 private List<IotProductThingModelDO> getValidFunctionList(String productKey) {
... ... @@ -237,20 +240,20 @@ public class IotThingModelMessageServiceImpl implements IotThingModelMessageServ
237 240 * @param deviceKey 设备 Key
238 241 *
239 242 */
240   - private void createThinkModelMessageDeviceTable(String productKey, String deviceName, String deviceKey){
  243 + private void createThingModelMessageDeviceTable(String productKey, String deviceName, String deviceKey){
241 244  
242 245 // 1. 获取超级表的名称、数据库名称、设备日志表名称
243   - String databaseName = iotTdDatabaseUtils.getDatabaseName();
  246 + String databaseName = IotTdDatabaseUtils.getDatabaseName(url);
244 247 String superTableName = IotTdDatabaseUtils.getThingModelMessageSuperTableName(productKey);
245 248 // TODO @alwayssuper:最好 databaseName、superTableName、thinkModelMessageDeviceTableName 的处理,放到 tdThinkModelMessageMapper 里。可以考虑,弄个 default 方法
246   - String thinkModelMessageDeviceTableName = IotTdDatabaseUtils.getThinkModelMessageDeviceTableName(productKey, deviceName);
  249 + String thinkModelMessageDeviceTableName = IotTdDatabaseUtils.getThingModelMessageDeviceTableName(productKey, deviceName);
247 250  
248 251 // 2. 创建物模型日志设备数据表
249   - tdThinkModelMessageMapper.createTableWithTag(ThingModelMessageDO.builder().build()
250   - .setDataBaseName(databaseName)
251   - .setSuperTableName(superTableName)
252   - .setTableName(thinkModelMessageDeviceTableName)
253   - .setDeviceKey(deviceKey));
  252 +// tdThingModelMessageMapper.createTableWithTag(ThingModelMessageDO.builder().build()
  253 +// .setDataBaseName(databaseName)
  254 +// .setSuperTableName(superTableName)
  255 +// .setTableName(thinkModelMessageDeviceTableName)
  256 +// .setDeviceKey(deviceKey));
254 257 }
255 258  
256 259 /**
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/util/IotTdDatabaseUtils.java
1 1 package cn.iocoder.yudao.module.iot.util;
2 2  
  3 +import cn.hutool.core.util.StrUtil;
3 4 import cn.iocoder.yudao.module.iot.enums.IotConstants;
  5 +import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum;
4 6 import org.springframework.beans.factory.annotation.Value;
5 7 import org.springframework.stereotype.Component;
6 8  
  9 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  10 +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.PRODUCT_DEVICE_NOT_EXISTS;
  11 +
7 12 // TODO @芋艿:可能要思索下,有没更好的处理方式
8 13 // TODO @芋艿:怎么改成无状态
9 14 /**
... ... @@ -11,19 +16,14 @@ import org.springframework.stereotype.Component;
11 16 *
12 17 * @author AlwaysSuper
13 18 */
14   -@Component
15 19 public class IotTdDatabaseUtils {
16 20  
17   - @Value("${spring.datasource.dynamic.datasource.tdengine.url}")
18   - private String url;
19   -
20 21 /**
21 22 * 获取数据库名称
22 23 */
23   - public String getDatabaseName() {
  24 + public static String getDatabaseName(String url) {
24 25 // TODO @alwayssuper:StrUtil.subAfter("/")
25   - int index = url.lastIndexOf("/");
26   - return index != -1 ? url.substring(index + 1) : url;
  26 + return StrUtil.subAfter(url, "/", true);
27 27 }
28 28  
29 29 /**
... ... @@ -35,11 +35,19 @@ public class IotTdDatabaseUtils {
35 35 */
36 36 public static String getProductSuperTableName(Integer deviceType, String productKey) {
37 37 // TODO @alwayssuper:枚举字段,不要 1、2、3;不符合预期,抛出异常
38   - return switch (deviceType) {
39   - case 1 -> String.format(IotConstants.GATEWAY_SUB_STABLE_NAME_FORMAT, productKey).toLowerCase();
40   - case 2 -> String.format(IotConstants.GATEWAY_STABLE_NAME_FORMAT, productKey).toLowerCase();
41   - default -> String.format(IotConstants.DEVICE_STABLE_NAME_FORMAT, productKey).toLowerCase();
42   - };
  38 + if (deviceType == null) {
  39 + throw exception(PRODUCT_DEVICE_NOT_EXISTS);
  40 + }
  41 + if (IotProductDeviceTypeEnum.GATEWAY_SUB.getType().equals(deviceType)) {
  42 + return String.format(IotConstants.GATEWAY_SUB_STABLE_NAME_FORMAT, productKey).toLowerCase();
  43 + } else if (IotProductDeviceTypeEnum.GATEWAY.getType().equals(deviceType)) {
  44 + return String.format(IotConstants.GATEWAY_STABLE_NAME_FORMAT, productKey).toLowerCase();
  45 + } else if (IotProductDeviceTypeEnum.DIRECT.getType().equals(deviceType)){
  46 + return String.format(IotConstants.DEVICE_STABLE_NAME_FORMAT, productKey).toLowerCase();
  47 + }
  48 + else{
  49 + throw exception(PRODUCT_DEVICE_NOT_EXISTS);
  50 + }
43 51 }
44 52  
45 53 /**
... ... @@ -51,7 +59,7 @@ public class IotTdDatabaseUtils {
51 59 */
52 60 public static String getThingModelMessageSuperTableName(String productKey) {
53 61 // TODO @alwayssuper:是不是应该 + 拼接就好,不用 format
54   - return String.format("thing_model_message_", productKey).toLowerCase();
  62 + return "thing_model_message_" + productKey.toLowerCase();
55 63 }
56 64  
57 65 /**
... ... @@ -61,7 +69,7 @@ public class IotTdDatabaseUtils {
61 69 * @param deviceName 设备名称
62 70 * @return 物模型日志设备表名
63 71 */
64   - public static String getThinkModelMessageDeviceTableName(String productKey, String deviceName) {
  72 + public static String getThingModelMessageDeviceTableName(String productKey, String deviceName) {
65 73 return String.format(IotConstants.THING_MODEL_MESSAGE_TABLE_NAME_FORMAT, productKey.toLowerCase(), deviceName.toLowerCase());
66 74 }
67 75  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdThinkModelMessageMapper.xml
... ... @@ -2,7 +2,7 @@
2 2 <!DOCTYPE mapper
3 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5   -<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdThinkModelMessageMapper">
  5 +<mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdThingModelMessageMapper">
6 6  
7 7 <!-- 创建物模型消息日志超级表 -->
8 8 <!-- TODO @芋艿:捉摸下字段,特别是 sys、ts 这种缩写 -->
... ... @@ -14,7 +14,7 @@
14 14 method VARCHAR(255),
15 15 params VARCHAR(2048)
16 16 )TAGS (
17   - deviceKey VARCHAR(255)
  17 + device_key VARCHAR(255)
18 18 )
19 19 </update>
20 20  
... ... @@ -28,7 +28,7 @@
28 28 method ,
29 29 params
30 30 )TAGS(
31   - #{deviceKey}
  31 + #{device_key}
32 32 )
33 33 </update>
34 34 </mapper>
35 35 \ No newline at end of file
... ...