Commit 9f3730d5d943e4bd30acfcc21223a43791cb995a
1 parent
495ae452
[fix]:code review
Showing
6 changed files
with
77 additions
and
55 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/deviceData/IotDeviceDataSimulatorSaveReqVO.java
| @@ -14,16 +14,18 @@ public class IotDeviceDataSimulatorSaveReqVO { | @@ -14,16 +14,18 @@ public class IotDeviceDataSimulatorSaveReqVO { | ||
| 14 | private String id; | 14 | private String id; |
| 15 | 15 | ||
| 16 | // TODO @super:不用传递 productKey,因为 deviceKey 可以推导出来 | 16 | // TODO @super:不用传递 productKey,因为 deviceKey 可以推导出来 |
| 17 | - @Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "product123") | ||
| 18 | - @NotEmpty(message = "产品ID不能为空") | 17 | + // TODO 讨论: 日志记录的时候要记录一下productKey,目前是前端已经有productKey了,所以前端传入,如果不传入的话,后端要根据deviceKey查询productKey,感觉直传是不是效率高一些 |
| 18 | + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "product123") | ||
| 19 | + @NotEmpty(message = "产品标识不能为空") | ||
| 19 | private String productKey; | 20 | private String productKey; |
| 20 | 21 | ||
| 21 | // TODO @super:中文写作规范,中英文之间,要有空格。例如说,设备 ID。ps:这里应该是设备标识 | 22 | // TODO @super:中文写作规范,中英文之间,要有空格。例如说,设备 ID。ps:这里应该是设备标识 |
| 22 | - @Schema(description = "设备ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "device123") | ||
| 23 | - @NotEmpty(message = "设备ID不能为空") | 23 | + @Schema(description = "设备标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "device123") |
| 24 | + @NotEmpty(message = "设备标识不能为空") | ||
| 24 | private String deviceKey; | 25 | private String deviceKey; |
| 25 | 26 | ||
| 26 | // TODO @super:type、subType,是不是不用传递,因为模拟只有属性??? | 27 | // TODO @super:type、subType,是不是不用传递,因为模拟只有属性??? |
| 28 | + // TODO 讨论: 不只模拟属性 | ||
| 27 | @Schema(description = "消息/日志类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "property") | 29 | @Schema(description = "消息/日志类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "property") |
| 28 | @NotEmpty(message = "消息类型不能为空") | 30 | @NotEmpty(message = "消息类型不能为空") |
| 29 | private String type; | 31 | private String type; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceLogDO.java
| 1 | package cn.iocoder.yudao.module.iot.dal.dataobject.device; | 1 | package cn.iocoder.yudao.module.iot.dal.dataobject.device; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | ||
| 3 | import lombok.AllArgsConstructor; | 4 | import lombok.AllArgsConstructor; |
| 4 | import lombok.Builder; | 5 | import lombok.Builder; |
| 5 | import lombok.Data; | 6 | import lombok.Data; |
| @@ -27,12 +28,16 @@ public class IotDeviceLogDO { | @@ -27,12 +28,16 @@ public class IotDeviceLogDO { | ||
| 27 | // TODO @super:关联要 @下 | 28 | // TODO @super:关联要 @下 |
| 28 | /** | 29 | /** |
| 29 | * 产品标识 | 30 | * 产品标识 |
| 31 | + * <p> | ||
| 32 | + * 关联 {@link IotProductDO#getProductKey()} | ||
| 30 | */ | 33 | */ |
| 31 | private String productKey; | 34 | private String productKey; |
| 32 | 35 | ||
| 33 | // TODO @super:关联要 @下 | 36 | // TODO @super:关联要 @下 |
| 34 | /** | 37 | /** |
| 35 | * 设备标识 | 38 | * 设备标识 |
| 39 | + * <p> | ||
| 40 | + * 关联 {@link IotDeviceDO#getDeviceKey()}} | ||
| 36 | */ | 41 | */ |
| 37 | private String deviceKey; | 42 | private String deviceKey; |
| 38 | 43 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogDataMapper.java
| @@ -27,6 +27,19 @@ public interface IotDeviceLogDataMapper { | @@ -27,6 +27,19 @@ public interface IotDeviceLogDataMapper { | ||
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | // TODO @super:单个参数,不用加 @Param | 29 | // TODO @super:单个参数,不用加 @Param |
| 30 | + //讨论:艿菇这里有些特殊情况,我也学习了一下这块知识: | ||
| 31 | + // 如果使用的是Java 8及以上版本,并且编译器保留了参数名(通过编译器选项-parameters启用),则可以去掉@Param注解。MyBatis会自动使用参数的实际名称 | ||
| 32 | + // 但在TDengine中 @Param去掉后TDengine会报错,以下是大模型的回答: | ||
| 33 | + // 不用加 @Param在普通的 MySQL 场景下是正确的 - 对于 MyBatis,当方法只有一个参数时,确实可以不用添加 @Param 注解。 | ||
| 34 | + //但是在 TDengine 的场景下,情况不同: | ||
| 35 | + //TDengine 的特殊性: | ||
| 36 | + //TDengine 使用特殊的 SQL 语法 | ||
| 37 | + //需要处理超级表(STable)和子表的概念 | ||
| 38 | + //参数绑定的方式与普通 MySQL 不同 | ||
| 39 | + //为什么这里必须要 @Param: | ||
| 40 | + //XML 中使用了 ${log.deviceKey} 这样的参数引用方式 | ||
| 41 | + //需要在 SQL 中动态构建表名(device_log_${log.deviceKey}) | ||
| 42 | + //没有 @Param("log") 的话,MyBatis 无法正确解析参数 | ||
| 30 | /** | 43 | /** |
| 31 | * 插入设备日志数据 | 44 | * 插入设备日志数据 |
| 32 | * | 45 | * |
| @@ -34,7 +47,7 @@ public interface IotDeviceLogDataMapper { | @@ -34,7 +47,7 @@ public interface IotDeviceLogDataMapper { | ||
| 34 | * | 47 | * |
| 35 | * @param log 设备日志数据 | 48 | * @param log 设备日志数据 |
| 36 | */ | 49 | */ |
| 37 | - void insert(IotDeviceLogDO log); | 50 | + void insert(@Param("log") IotDeviceLogDO log); |
| 38 | 51 | ||
| 39 | /** | 52 | /** |
| 40 | * 获得设备日志分页 | 53 | * 获得设备日志分页 |
| @@ -42,7 +55,7 @@ public interface IotDeviceLogDataMapper { | @@ -42,7 +55,7 @@ public interface IotDeviceLogDataMapper { | ||
| 42 | * @param reqVO 分页查询条件 | 55 | * @param reqVO 分页查询条件 |
| 43 | * @return 设备日志列表 | 56 | * @return 设备日志列表 |
| 44 | */ | 57 | */ |
| 45 | - List<IotDeviceLogDO> selectPage(IotDeviceLogPageReqVO reqVO); | 58 | + List<IotDeviceLogDO> selectPage(@Param("reqVO") IotDeviceLogPageReqVO reqVO); |
| 46 | 59 | ||
| 47 | /** | 60 | /** |
| 48 | * 获得设备日志总数 | 61 | * 获得设备日志总数 |
| @@ -50,7 +63,7 @@ public interface IotDeviceLogDataMapper { | @@ -50,7 +63,7 @@ public interface IotDeviceLogDataMapper { | ||
| 50 | * @param reqVO 查询条件 | 63 | * @param reqVO 查询条件 |
| 51 | * @return 日志总数 | 64 | * @return 日志总数 |
| 52 | */ | 65 | */ |
| 53 | - Long selectCount(IotDeviceLogPageReqVO reqVO); | 66 | + Long selectCount(@Param("reqVO") IotDeviceLogPageReqVO reqVO); |
| 54 | 67 | ||
| 55 | /** | 68 | /** |
| 56 | * 查询设备日志表是否存在 | 69 | * 查询设备日志表是否存在 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceLogDataServiceImpl.java
| @@ -55,16 +55,18 @@ public class IotDeviceLogDataServiceImpl implements IotDeviceLogDataService{ | @@ -55,16 +55,18 @@ public class IotDeviceLogDataServiceImpl implements IotDeviceLogDataService{ | ||
| 55 | 55 | ||
| 56 | // 2. 处理时间字段 | 56 | // 2. 处理时间字段 |
| 57 | // TODO @super:一次性的字段,不用单独给个变量 | 57 | // TODO @super:一次性的字段,不用单独给个变量 |
| 58 | - long currentTime = System.currentTimeMillis(); | 58 | +// long currentTime = System.currentTimeMillis(); |
| 59 | // 2.1 设置时序时间为当前时间 | 59 | // 2.1 设置时序时间为当前时间 |
| 60 | - iotDeviceLogDO.setTs(currentTime); // TODO @super:TS在SQL中直接NOW 咱们的TS数据获取是走哪一种;走 now() | 60 | +// iotDeviceLogDO.setTs(currentTime); // TODO @super:TS在SQL中直接NOW 咱们的TS数据获取是走哪一种;走 now() |
| 61 | 61 | ||
| 62 | // 3. 插入数据 | 62 | // 3. 插入数据 |
| 63 | // TODO @super:不要直接调用对方的 IotDeviceLogDataMapper,通过 service 哈! | 63 | // TODO @super:不要直接调用对方的 IotDeviceLogDataMapper,通过 service 哈! |
| 64 | + // 讨论:艿菇 这就是iotDeviceLogDataService的Impl | ||
| 64 | iotDeviceLogDataMapper.insert(iotDeviceLogDO); | 65 | iotDeviceLogDataMapper.insert(iotDeviceLogDO); |
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | // TODO @super:在 iotDeviceLogDataService 写 | 68 | // TODO @super:在 iotDeviceLogDataService 写 |
| 69 | + // 讨论:艿菇 这就是iotDeviceLogDataService的Impl | ||
| 68 | @Override | 70 | @Override |
| 69 | public PageResult<IotDeviceLogDO> getDeviceLogPage(IotDeviceLogPageReqVO pageReqVO) { | 71 | public PageResult<IotDeviceLogDO> getDeviceLogPage(IotDeviceLogPageReqVO pageReqVO) { |
| 70 | // 查询数据 | 72 | // 查询数据 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/ExampleService.java
| 1 | -package cn.iocoder.yudao.module.iot.service.plugin; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.iot.mqttrpc.server.RpcServer; | ||
| 4 | -import lombok.RequiredArgsConstructor; | ||
| 5 | -import org.springframework.stereotype.Service; | ||
| 6 | - | ||
| 7 | -import javax.annotation.PostConstruct; | ||
| 8 | - | ||
| 9 | -@Service | ||
| 10 | -@RequiredArgsConstructor | ||
| 11 | -public class ExampleService { | ||
| 12 | - | ||
| 13 | - private final RpcServer rpcServer; | ||
| 14 | - | ||
| 15 | - @PostConstruct | ||
| 16 | - public void registerMethods() { | ||
| 17 | - rpcServer.registerMethod("add", params -> { | ||
| 18 | - if (params.length != 2) { | ||
| 19 | - throw new IllegalArgumentException("add方法需要两个参数"); | ||
| 20 | - } | ||
| 21 | - int a = ((Number) params[0]).intValue(); | ||
| 22 | - int b = ((Number) params[1]).intValue(); | ||
| 23 | - return add(a, b); | ||
| 24 | - }); | ||
| 25 | - | ||
| 26 | - rpcServer.registerMethod("concat", params -> { | ||
| 27 | - if (params.length != 2) { | ||
| 28 | - throw new IllegalArgumentException("concat方法需要两个参数"); | ||
| 29 | - } | ||
| 30 | - String str1 = params[0].toString(); | ||
| 31 | - String str2 = params[1].toString(); | ||
| 32 | - return concat(str1, str2); | ||
| 33 | - }); | ||
| 34 | - } | ||
| 35 | - | ||
| 36 | - private int add(int a, int b) { | ||
| 37 | - return a + b; | ||
| 38 | - } | ||
| 39 | - | ||
| 40 | - private String concat(String a, String b) { | ||
| 41 | - return a + b; | ||
| 42 | - } | ||
| 43 | -} | ||
| 44 | \ No newline at end of file | 1 | \ No newline at end of file |
| 2 | +//package cn.iocoder.yudao.module.iot.service.plugin; | ||
| 3 | +// | ||
| 4 | +//import cn.iocoder.yudao.module.iot.mqttrpc.server.RpcServer; | ||
| 5 | +//import lombok.RequiredArgsConstructor; | ||
| 6 | +//import org.springframework.stereotype.Service; | ||
| 7 | +// | ||
| 8 | +//import javax.annotation.PostConstruct; | ||
| 9 | +// | ||
| 10 | +//@Service | ||
| 11 | +//@RequiredArgsConstructor | ||
| 12 | +//public class ExampleService { | ||
| 13 | +// | ||
| 14 | +// private final RpcServer rpcServer; | ||
| 15 | +// | ||
| 16 | +// @PostConstruct | ||
| 17 | +// public void registerMethods() { | ||
| 18 | +// rpcServer.registerMethod("add", params -> { | ||
| 19 | +// if (params.length != 2) { | ||
| 20 | +// throw new IllegalArgumentException("add方法需要两个参数"); | ||
| 21 | +// } | ||
| 22 | +// int a = ((Number) params[0]).intValue(); | ||
| 23 | +// int b = ((Number) params[1]).intValue(); | ||
| 24 | +// return add(a, b); | ||
| 25 | +// }); | ||
| 26 | +// | ||
| 27 | +// rpcServer.registerMethod("concat", params -> { | ||
| 28 | +// if (params.length != 2) { | ||
| 29 | +// throw new IllegalArgumentException("concat方法需要两个参数"); | ||
| 30 | +// } | ||
| 31 | +// String str1 = params[0].toString(); | ||
| 32 | +// String str2 = params[1].toString(); | ||
| 33 | +// return concat(str1, str2); | ||
| 34 | +// }); | ||
| 35 | +// } | ||
| 36 | +// | ||
| 37 | +// private int add(int a, int b) { | ||
| 38 | +// return a + b; | ||
| 39 | +// } | ||
| 40 | +// | ||
| 41 | +// private String concat(String a, String b) { | ||
| 42 | +// return a + b; | ||
| 43 | +// } | ||
| 44 | +//} | ||
| 45 | \ No newline at end of file | 45 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogDataMapper.xml
| @@ -27,11 +27,11 @@ | @@ -27,11 +27,11 @@ | ||
| 27 | 27 | ||
| 28 | <!-- 插入设备日志数据 在子表不存在的情况下 可在数据插入时 自动建表 --> | 28 | <!-- 插入设备日志数据 在子表不存在的情况下 可在数据插入时 自动建表 --> |
| 29 | <insert id="insert"> | 29 | <insert id="insert"> |
| 30 | - INSERT INTO device_log_${log.deviceKey} (ts, id, product_key, type, subType, content, report_time) | 30 | + INSERT INTO device_log_${log.deviceKey} (id, product_key, type, subType, content, report_time) |
| 31 | USING device_log | 31 | USING device_log |
| 32 | TAGS ('${log.deviceKey}') | 32 | TAGS ('${log.deviceKey}') |
| 33 | VALUES ( | 33 | VALUES ( |
| 34 | - #{log.ts}, | 34 | + NOW, |
| 35 | #{log.id}, | 35 | #{log.id}, |
| 36 | #{log.productKey}, | 36 | #{log.productKey}, |
| 37 | #{log.type}, | 37 | #{log.type}, |
| @@ -77,7 +77,7 @@ | @@ -77,7 +77,7 @@ | ||
| 77 | 77 | ||
| 78 | <!-- 检查设备日志超级表是否存在 --> | 78 | <!-- 检查设备日志超级表是否存在 --> |
| 79 | <select id="checkDeviceLogTableExists" resultType="Object"> | 79 | <select id="checkDeviceLogTableExists" resultType="Object"> |
| 80 | - SHOW TABLES LIKE 'device_log'; | 80 | + SHOW STABLES LIKE 'device_log' |
| 81 | </select> | 81 | </select> |
| 82 | 82 | ||
| 83 | </mapper> | 83 | </mapper> |
| 84 | \ No newline at end of file | 84 | \ No newline at end of file |