Commit 53693529e1d06a417f7e1d8f9f68e0478cdb4fca

Authored by YunaiV
1 parent 8bcfd408

【代码评审】IoT:首页统计

Showing 13 changed files with 46 additions and 90 deletions
... ... @@ -16,7 +16,7 @@
16 16 <module>yudao-module-system</module>
17 17 <module>yudao-module-infra</module>
18 18 <!-- <module>yudao-module-member</module>-->
19   -<!-- <module>yudao-module-bpm</module>-->
  19 + <module>yudao-module-bpm</module>
20 20 <!-- <module>yudao-module-report</module>-->
21 21 <!-- <module>yudao-module-mp</module>-->
22 22 <!-- <module>yudao-module-pay</module>-->
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/statistics/IotStatisticsController.java
... ... @@ -36,43 +36,42 @@ public class IotStatisticsController {
36 36 @Resource
37 37 private IotDeviceLogService deviceLogService;
38 38  
39   - // TODO @super:description 非必要,可以不写哈
40 39 @GetMapping("/get-summary")
41   - @Operation(summary = "获取IOT数据统计")
  40 + @Operation(summary = "获取 IoT 数据统计")
42 41 public CommonResult<IotStatisticsSummaryRespVO> getIotStatisticsSummary(){
43 42 IotStatisticsSummaryRespVO respVO = new IotStatisticsSummaryRespVO();
44   - // 获取总数
  43 + // 1.1 获取总数
45 44 respVO.setProductCategoryCount(productCategoryService.getProductCategoryCount(null));
46 45 respVO.setProductCount(productService.getProductCount(null));
47 46 respVO.setDeviceCount(deviceService.getDeviceCount(null));
48 47 respVO.setDeviceMessageCount(deviceLogService.getDeviceLogCount(null));
49   -
50   - // 获取今日新增数量
  48 + // 1.2 获取今日新增数量
  49 + // TODO @super:使用 LocalDateTimeUtils.getToday()
51 50 LocalDateTime todayStart = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
52 51 respVO.setProductCategoryTodayCount(productCategoryService.getProductCategoryCount(todayStart));
53 52 respVO.setProductTodayCount(productService.getProductCount(todayStart));
54 53 respVO.setDeviceTodayCount(deviceService.getDeviceCount(todayStart));
55 54 respVO.setDeviceMessageTodayCount(deviceLogService.getDeviceLogCount(todayStart));
56 55  
57   - // 获取各个品类下设备数量统计
  56 + // 2. 获取各个品类下设备数量统计
58 57 respVO.setProductCategoryDeviceCounts(productCategoryService.getProductCategoryDeviceCountMap());
59 58  
60   - // 获取设备状态数量统计
  59 + // 3. 获取设备状态数量统计
61 60 Map<Integer, Long> deviceCountMap = deviceService.getDeviceCountMapByState();
62 61 respVO.setDeviceOnlineCount(deviceCountMap.getOrDefault(IotDeviceStateEnum.ONLINE.getState(), 0L));
63 62 respVO.setDeviceOfflineCount(deviceCountMap.getOrDefault(IotDeviceStateEnum.OFFLINE.getState(), 0L));
64 63 respVO.setDeviceInactiveCount(deviceCountMap.getOrDefault(IotDeviceStateEnum.INACTIVE.getState(), 0L));
65   -
66 64 return CommonResult.success(respVO);
67 65 }
68   - @GetMapping("/get-log-summary")
69   - @Operation(summary = "获取IOT上下行消息数据统计")
70   - public CommonResult<IotStatisticsDeviceMessageSummaryRespVO> getIotStatisticsDeviceMessageSummary(@Valid IotStatisticsReqVO reqVO){
71   - // 根据传入时间范围获取设备上下行消息数量统计
72   - IotStatisticsDeviceMessageSummaryRespVO iotStatisticsRespVO = new IotStatisticsDeviceMessageSummaryRespVO();
73   - iotStatisticsRespVO.setUpstreamCounts(deviceLogService.getDeviceLogUpCountByHour(null, reqVO.getStartTime(), reqVO.getEndTime()));
74   - iotStatisticsRespVO.setDownstreamCounts(deviceLogService.getDeviceLogDownCountByHour(null, reqVO.getStartTime(), reqVO.getEndTime()));
75 66  
76   - return CommonResult.success(iotStatisticsRespVO);
  67 + // TODO @super:要不干掉 IotStatisticsReqVO 参数,直接使用 @RequestParam 接收,简单一些。
  68 + @GetMapping("/get-log-summary")
  69 + @Operation(summary = "获取 IoT 设备上下行消息数据统计")
  70 + public CommonResult<IotStatisticsDeviceMessageSummaryRespVO> getIotStatisticsDeviceMessageSummary(
  71 + @Valid IotStatisticsReqVO reqVO) {
  72 + return CommonResult.success(new IotStatisticsDeviceMessageSummaryRespVO()
  73 + .setDownstreamCounts(deviceLogService.getDeviceLogUpCountByHour(null, reqVO.getStartTime(), reqVO.getEndTime()))
  74 + .setDownstreamCounts((deviceLogService.getDeviceLogDownCountByHour(null, reqVO.getStartTime(), reqVO.getEndTime()))));
77 75 }
  76 +
78 77 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/statistics/vo/IotStatisticsDeviceMessageSummaryRespVO.java
... ... @@ -6,14 +6,14 @@ import lombok.Data;
6 6 import java.util.List;
7 7 import java.util.Map;
8 8  
9   -@Schema(description = "管理后台 - Iot 上下行消息数量统计 Response VO")
  9 +@Schema(description = "管理后台 - IoT 设备上下行消息数量统计 Response VO")
10 10 @Data
11 11 public class IotStatisticsDeviceMessageSummaryRespVO {
  12 +
12 13 @Schema(description = "每小时上行数据数量统计")
13 14 private List<Map<Long, Integer>> upstreamCounts;
14 15  
15 16 @Schema(description = "每小时下行数据数量统计")
16 17 private List<Map<Long, Integer>> downstreamCounts;
17 18  
18   - // TODO @super:如果只有这两个字段,使用 KeyValue 这个键值对
19 19 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/statistics/vo/IotStatisticsReqVO.java
... ... @@ -4,12 +4,11 @@ import io.swagger.v3.oas.annotations.media.Schema;
4 4 import jakarta.validation.constraints.NotNull;
5 5 import lombok.Data;
6 6  
7   -@Schema(description = "管理后台 - Iot统计 Request VO")
  7 +@Schema(description = "管理后台 - IoT 统计 Request VO")
8 8 @Data
9 9 public class IotStatisticsReqVO {
10 10  
11   - // TODO @supper:times 直接传递哈;
12   - // TODO 2super:private 不要丢了
  11 + // TODO @super:前端传递的时候,还是通过 startTime 和 endTime 传递。后端转成 Long
13 12  
14 13 @Schema(description = "查询起始时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "1658486600000")
15 14 @NotNull(message = "查询起始时间不能为空")
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/statistics/vo/IotStatisticsSummaryRespVO.java
... ... @@ -5,8 +5,6 @@ import lombok.Data;
5 5  
6 6 import java.util.Map;
7 7  
8   -// TODO @super:Total 全部改成 Count
9   -// TODO @super:IotStatisticsSummaryRespVO
10 8 /**
11 9 * 管理后台 - Iot 统计 Response VO
12 10 */
... ... @@ -14,56 +12,40 @@ import java.util.Map;
14 12 @Data
15 13 public class IotStatisticsSummaryRespVO {
16 14  
17   - // TODO @super:productCategory 哈
18 15 @Schema(description = "品类数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
19   - private long productCategoryCount;
  16 + private Long productCategoryCount;
20 17  
21 18 @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
22   - private long productCount;
  19 + private Long productCount;
23 20  
24 21 @Schema(description = "设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
25   - private long deviceCount;
  22 + private Long deviceCount;
26 23  
27   - // TODO @super:deviceMessageCount;设备消息数量
28 24 @Schema(description = "上报数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
29   - private long deviceMessageCount;
  25 + private Long deviceMessageCount;
30 26  
31   - // TODO @super:productCategory 哈
32 27 @Schema(description = "今日新增品类数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
33   - private long productCategoryTodayCount;
  28 + private Long productCategoryTodayCount;
34 29  
35 30 @Schema(description = "今日新增产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
36   - private long productTodayCount;
  31 + private Long productTodayCount;
37 32  
38 33 @Schema(description = "今日新增设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
39   - private long deviceTodayCount;
  34 + private Long deviceTodayCount;
40 35  
41   - // TODO @super:deviceMessageCount;今日设备消息数量
42 36 @Schema(description = "今日新增上报数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
43   - private long deviceMessageTodayCount;
44   -
45   - // TODO @super:deviceOnlineCount
  37 + private Long deviceMessageTodayCount;
46 38  
47 39 @Schema(description = "在线数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "80")
48   - private long deviceOnlineCount;
49   -
50   - // TODO @super:deviceOfflineCount
  40 + private Long deviceOnlineCount;
51 41  
52 42 @Schema(description = "离线数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15")
53   - private long deviceOfflineCount;
54   -
55   - // TODO @super:deviceInactivECount
  43 + private Long deviceOfflineCount;
56 44  
57 45 @Schema(description = "待激活设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
58   - private long deviceInactiveCount;
  46 + private Long deviceInactiveCount;
59 47  
60   - // TODO @super:1)类型改成 Map,key 分类名、value 设备数量;2)deviceStatsOfCategory => productCategoryDeviceCounts
61 48 @Schema(description = "按品类统计的设备数量")
62 49 private Map<String, Integer> productCategoryDeviceCounts;
63 50  
64   - // TODO @super:貌似界面里,用不到这个字段???
65   -
66   -
67   - // TODO @super:deviceUpMessageStats、deviceDownMessageStats 单独抽到 IotStatisticsDeviceMessageSummaryRespVO,然后里面属性就是 upstreamCounts、downstreamCounts
68   -
69 51 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceMapper.java
... ... @@ -8,13 +8,11 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePa
8 8 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
9 9 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
10 10 import org.apache.ibatis.annotations.Mapper;
11   -import org.apache.ibatis.annotations.Param;
12 11  
13 12 import javax.annotation.Nullable;
14 13 import java.time.LocalDateTime;
15 14 import java.util.List;
16 15 import java.util.Map;
17   -import java.util.stream.Collectors;
18 16  
19 17 /**
20 18 * IoT 设备 Mapper
... ... @@ -79,18 +77,15 @@ public interface IotDeviceMapper extends BaseMapperX&lt;IotDeviceDO&gt; {
79 77 .geIfPresent(IotDeviceDO::getCreateTime, createTime));
80 78 }
81 79  
82   - default Long selectCountByState(@Nullable Integer state) {
83   - return selectCount(new LambdaQueryWrapperX<IotDeviceDO>()
84   - .eqIfPresent(IotDeviceDO::getState, state));
85   - }
86   -
87 80 /**
88 81 * 查询指定产品下各状态的设备数量
89 82 *
90 83 * @return 设备数量统计列表
91 84 */
  85 + // TODO @super:通过 mybatis-plus 来写哈,然后返回 Map 貌似就行了?!
92 86 List<Map<String, Object>> selectDeviceCountMapByProductId();
93 87  
  88 + // TODO @super:通过 mybatis-plus 来写哈,然后返回 Map 貌似就行了?!
94 89 /**
95 90 * 查询各个状态下的设备数量
96 91 *
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogMapper.java
... ... @@ -63,14 +63,14 @@ public interface IotDeviceLogMapper {
63 63 * 查询每个小时设备上行消息数量
64 64 */
65 65 List<Map<String, Object>> selectDeviceLogUpCountByHour(@Param("deviceKey") String deviceKey,
66   - @Param("startTime") Long startTime,
67   - @Param("endTime") Long endTime);
  66 + @Param("startTime") Long startTime,
  67 + @Param("endTime") Long endTime);
68 68  
69 69 /**
70 70 * 查询每个小时设备下行消息数量
71 71 */
72 72 List<Map<String, Object>> selectDeviceLogDownCountByHour(@Param("deviceKey") String deviceKey,
73   - @Param("startTime") Long startTime,
74   - @Param("endTime") Long endTime);
  73 + @Param("startTime") Long startTime,
  74 + @Param("endTime") Long endTime);
75 75  
76 76 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
... ... @@ -196,14 +196,6 @@ public interface IotDeviceService {
196 196 */
197 197 Long getDeviceCount(@Nullable LocalDateTime createTime);
198 198  
199   -
200   - /**
201   - * 获得所有设备列表
202   - *
203   - * @return 设备列表
204   - */
205   - List<IotDeviceDO> getDeviceList();
206   -
207 199 /**
208 200 * 获取 MQTT 连接参数
209 201 *
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java
... ... @@ -430,13 +430,7 @@ public class IotDeviceServiceImpl implements IotDeviceService {
430 430 return deviceMapper.selectCountByCreateTime(createTime);
431 431 }
432 432  
433   - // TODO @super:是不是 groupby 查询,更高效;不过 controller,还是要考虑 null 的情况;不过可以直接枚举 foreach 处理下
434   -
435   - @Override
436   - public List<IotDeviceDO> getDeviceList() {
437   - return deviceMapper.selectList();
438   - }
439   -
  433 + // TODO @super:简化
440 434 @Override
441 435 public Map<Long, Integer> getDeviceCountMapByProductId() {
442 436 // 查询结果转换成Map
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/data/IotDeviceLogService.java
... ... @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.iot.service.device.data;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO;
5   -import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageSummaryRespVO;
6 5 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO;
7 6 import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
8 7  
... ... @@ -57,8 +56,8 @@ public interface IotDeviceLogService {
57 56 * @return key: 时间戳, value: 消息数量
58 57 */
59 58 List<Map<Long, Integer>> getDeviceLogUpCountByHour(@Nullable String deviceKey,
60   - @Nullable Long startTime,
61   - @Nullable Long endTime);
  59 + @Nullable Long startTime,
  60 + @Nullable Long endTime);
62 61  
63 62 /**
64 63 * 获得每个小时设备下行消息数量统计
... ... @@ -69,7 +68,7 @@ public interface IotDeviceLogService {
69 68 * @return key: 时间戳, value: 消息数量
70 69 */
71 70 List<Map<Long, Integer>> getDeviceLogDownCountByHour(@Nullable String deviceKey,
72   - @Nullable Long startTime,
73   - @Nullable Long endTime);
  71 + @Nullable Long startTime,
  72 + @Nullable Long endTime);
74 73  
75 74 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/data/IotDeviceLogServiceImpl.java
... ... @@ -7,7 +7,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 7 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
8 8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
9 9 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO;
10   -import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageSummaryRespVO;
11 10 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO;
12 11 import cn.iocoder.yudao.module.iot.dal.tdengine.IotDeviceLogMapper;
13 12 import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
... ... @@ -73,13 +72,13 @@ public class IotDeviceLogServiceImpl implements IotDeviceLogService {
73 72  
74 73 @Override
75 74 public Long getDeviceLogCount(LocalDateTime createTime) {
76   - // todo @super:1)LocalDateTimeUtil.toEpochMilli(createTime);2)直接表达式,更简洁 time != null ? createTime.toInstant(ZoneOffset.UTC).toEpochMilli() : null;
77 75 return deviceLogMapper.selectCountByCreateTime(createTime != null ? LocalDateTimeUtil.toEpochMilli(createTime) : null);
78 76 }
79 77  
80 78 // TODO @super:加一个参数,Boolean upstream:true 上行,false 下行,null 不过滤
81 79 @Override
82 80 public List<Map<Long, Integer>> getDeviceLogUpCountByHour(String deviceKey, Long startTime, Long endTime) {
  81 + // TODO @super:不能只基于数据库统计。因为有一些小时,可能出现没数据的情况,导致前端展示的图是不全的。可以参考 CrmStatisticsCustomerService 来实现
83 82 List<Map<String, Object>> list = deviceLogMapper.selectDeviceLogUpCountByHour(deviceKey, startTime, endTime);
84 83 return list.stream()
85 84 .map(map -> {
... ... @@ -93,6 +92,7 @@ public class IotDeviceLogServiceImpl implements IotDeviceLogService {
93 92 .collect(Collectors.toList());
94 93 }
95 94  
  95 + // TODO @super:getDeviceLogDownCountByHour 融合到 getDeviceLogUpCountByHour
96 96 @Override
97 97 public List<Map<Long, Integer>> getDeviceLogDownCountByHour(String deviceKey, Long startTime, Long endTime) {
98 98 List<Map<String, Object>> list = deviceLogMapper.selectDeviceLogDownCountByHour(deviceKey, startTime, endTime);
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductCategoryService.java
... ... @@ -93,9 +93,8 @@ public interface IotProductCategoryService {
93 93 */
94 94 Long getProductCategoryCount(@Nullable LocalDateTime createTime);
95 95  
96   - // TODO @super:1)Map<ProductCategory, Count> 虽然有点怪哈,然后 Controller 按需转换成 Map<String, Integer> ;2)名字 getProductCategoryDeviceCountMap 方法
97 96 /**
98   - * 获得各个品类下设备数量统计
  97 + * 获得各个品类下设备数量统计,其中 key 是产品分类名
99 98 *
100 99 * @return 品类设备统计列表
101 100 */
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductCategoryServiceImpl.java
... ... @@ -106,11 +106,9 @@ public class IotProductCategoryServiceImpl implements IotProductCategoryService
106 106  
107 107 // 2. 统计每个分类下的设备数量
108 108 Map<String, Integer> categoryDeviceCountMap = new HashMap<>();
109   -
110   - // 2.1 初始化所有分类的计数为0
111 109 for (IotProductCategoryDO category : categoryList) {
112 110 categoryDeviceCountMap.put(category.getName(), 0);
113   -
  111 + // TODO @super:CollectionUtils.getSumValue(),看看能不能简化下
114 112 // 2.2 找到该分类下的所有产品,累加设备数量
115 113 for (IotProductDO product : productList) {
116 114 if (Objects.equals(product.getCategoryId(), category.getId())) {
... ... @@ -119,7 +117,6 @@ public class IotProductCategoryServiceImpl implements IotProductCategoryService
119 117 }
120 118 }
121 119 }
122   -
123 120 return categoryDeviceCountMap;
124 121 }
125 122  
... ...