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

This commit is contained in:
YunaiV 2025-03-01 23:30:47 +08:00
parent 8bcfd40847
commit 53693529e1
13 changed files with 46 additions and 90 deletions

View File

@ -16,7 +16,7 @@
<module>yudao-module-system</module>
<module>yudao-module-infra</module>
<!-- <module>yudao-module-member</module>-->
<!-- <module>yudao-module-bpm</module>-->
<module>yudao-module-bpm</module>
<!-- <module>yudao-module-report</module>-->
<!-- <module>yudao-module-mp</module>-->
<!-- <module>yudao-module-pay</module>-->

View File

@ -36,43 +36,42 @@ public class IotStatisticsController {
@Resource
private IotDeviceLogService deviceLogService;
// TODO @superdescription 非必要可以不写哈
@GetMapping("/get-summary")
@Operation(summary = "获取IOT数据统计")
@Operation(summary = "获取 IoT 数据统计")
public CommonResult<IotStatisticsSummaryRespVO> getIotStatisticsSummary(){
IotStatisticsSummaryRespVO respVO = new IotStatisticsSummaryRespVO();
// 获取总数
// 1.1 获取总数
respVO.setProductCategoryCount(productCategoryService.getProductCategoryCount(null));
respVO.setProductCount(productService.getProductCount(null));
respVO.setDeviceCount(deviceService.getDeviceCount(null));
respVO.setDeviceMessageCount(deviceLogService.getDeviceLogCount(null));
// 获取今日新增数量
// 1.2 获取今日新增数量
// TODO @super使用 LocalDateTimeUtils.getToday()
LocalDateTime todayStart = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
respVO.setProductCategoryTodayCount(productCategoryService.getProductCategoryCount(todayStart));
respVO.setProductTodayCount(productService.getProductCount(todayStart));
respVO.setDeviceTodayCount(deviceService.getDeviceCount(todayStart));
respVO.setDeviceMessageTodayCount(deviceLogService.getDeviceLogCount(todayStart));
// 获取各个品类下设备数量统计
// 2. 获取各个品类下设备数量统计
respVO.setProductCategoryDeviceCounts(productCategoryService.getProductCategoryDeviceCountMap());
// 获取设备状态数量统计
// 3. 获取设备状态数量统计
Map<Integer, Long> deviceCountMap = deviceService.getDeviceCountMapByState();
respVO.setDeviceOnlineCount(deviceCountMap.getOrDefault(IotDeviceStateEnum.ONLINE.getState(), 0L));
respVO.setDeviceOfflineCount(deviceCountMap.getOrDefault(IotDeviceStateEnum.OFFLINE.getState(), 0L));
respVO.setDeviceInactiveCount(deviceCountMap.getOrDefault(IotDeviceStateEnum.INACTIVE.getState(), 0L));
return CommonResult.success(respVO);
}
@GetMapping("/get-log-summary")
@Operation(summary = "获取IOT上下行消息数据统计")
public CommonResult<IotStatisticsDeviceMessageSummaryRespVO> getIotStatisticsDeviceMessageSummary(@Valid IotStatisticsReqVO reqVO){
// 根据传入时间范围获取设备上下行消息数量统计
IotStatisticsDeviceMessageSummaryRespVO iotStatisticsRespVO = new IotStatisticsDeviceMessageSummaryRespVO();
iotStatisticsRespVO.setUpstreamCounts(deviceLogService.getDeviceLogUpCountByHour(null, reqVO.getStartTime(), reqVO.getEndTime()));
iotStatisticsRespVO.setDownstreamCounts(deviceLogService.getDeviceLogDownCountByHour(null, reqVO.getStartTime(), reqVO.getEndTime()));
return CommonResult.success(iotStatisticsRespVO);
// TODO @super要不干掉 IotStatisticsReqVO 参数直接使用 @RequestParam 接收简单一些
@GetMapping("/get-log-summary")
@Operation(summary = "获取 IoT 设备上下行消息数据统计")
public CommonResult<IotStatisticsDeviceMessageSummaryRespVO> getIotStatisticsDeviceMessageSummary(
@Valid IotStatisticsReqVO reqVO) {
return CommonResult.success(new IotStatisticsDeviceMessageSummaryRespVO()
.setDownstreamCounts(deviceLogService.getDeviceLogUpCountByHour(null, reqVO.getStartTime(), reqVO.getEndTime()))
.setDownstreamCounts((deviceLogService.getDeviceLogDownCountByHour(null, reqVO.getStartTime(), reqVO.getEndTime()))));
}
}

View File

@ -6,14 +6,14 @@ import lombok.Data;
import java.util.List;
import java.util.Map;
@Schema(description = "管理后台 - Iot 上下行消息数量统计 Response VO")
@Schema(description = "管理后台 - IoT 设备上下行消息数量统计 Response VO")
@Data
public class IotStatisticsDeviceMessageSummaryRespVO {
@Schema(description = "每小时上行数据数量统计")
private List<Map<Long, Integer>> upstreamCounts;
@Schema(description = "每小时下行数据数量统计")
private List<Map<Long, Integer>> downstreamCounts;
// TODO @super如果只有这两个字段使用 KeyValue 这个键值对
}

View File

@ -4,12 +4,11 @@ import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - Iot统计 Request VO")
@Schema(description = "管理后台 - IoT 统计 Request VO")
@Data
public class IotStatisticsReqVO {
// TODO @suppertimes 直接传递哈
// TODO 2superprivate 不要丢了
// TODO @super前端传递的时候还是通过 startTime endTime 传递后端转成 Long
@Schema(description = "查询起始时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "1658486600000")
@NotNull(message = "查询起始时间不能为空")

View File

@ -5,8 +5,6 @@ import lombok.Data;
import java.util.Map;
// TODO @superTotal 全部改成 Count
// TODO @superIotStatisticsSummaryRespVO
/**
* 管理后台 - Iot 统计 Response VO
*/
@ -14,56 +12,40 @@ import java.util.Map;
@Data
public class IotStatisticsSummaryRespVO {
// TODO @superproductCategory
@Schema(description = "品类数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
private long productCategoryCount;
private Long productCategoryCount;
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
private long productCount;
private Long productCount;
@Schema(description = "设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private long deviceCount;
private Long deviceCount;
// TODO @superdeviceMessageCount设备消息数量
@Schema(description = "上报数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
private long deviceMessageCount;
private Long deviceMessageCount;
// TODO @superproductCategory
@Schema(description = "今日新增品类数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
private long productCategoryTodayCount;
private Long productCategoryTodayCount;
@Schema(description = "今日新增产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
private long productTodayCount;
private Long productTodayCount;
@Schema(description = "今日新增设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private long deviceTodayCount;
private Long deviceTodayCount;
// TODO @superdeviceMessageCount今日设备消息数量
@Schema(description = "今日新增上报数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
private long deviceMessageTodayCount;
// TODO @superdeviceOnlineCount
private Long deviceMessageTodayCount;
@Schema(description = "在线数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "80")
private long deviceOnlineCount;
// TODO @superdeviceOfflineCount
private Long deviceOnlineCount;
@Schema(description = "离线数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15")
private long deviceOfflineCount;
// TODO @superdeviceInactivECount
private Long deviceOfflineCount;
@Schema(description = "待激活设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
private long deviceInactiveCount;
private Long deviceInactiveCount;
// TODO @super1类型改成 Mapkey 分类名value 设备数量2deviceStatsOfCategory => productCategoryDeviceCounts
@Schema(description = "按品类统计的设备数量")
private Map<String, Integer> productCategoryDeviceCounts;
// TODO @super貌似界面里用不到这个字段
// TODO @superdeviceUpMessageStatsdeviceDownMessageStats 单独抽到 IotStatisticsDeviceMessageSummaryRespVO然后里面属性就是 upstreamCountsdownstreamCounts
}

View File

@ -8,13 +8,11 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePa
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import javax.annotation.Nullable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* IoT 设备 Mapper
@ -79,18 +77,15 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> {
.geIfPresent(IotDeviceDO::getCreateTime, createTime));
}
default Long selectCountByState(@Nullable Integer state) {
return selectCount(new LambdaQueryWrapperX<IotDeviceDO>()
.eqIfPresent(IotDeviceDO::getState, state));
}
/**
* 查询指定产品下各状态的设备数量
*
* @return 设备数量统计列表
*/
// TODO @super通过 mybatis-plus 来写哈然后返回 Map 貌似就行了
List<Map<String, Object>> selectDeviceCountMapByProductId();
// TODO @super通过 mybatis-plus 来写哈然后返回 Map 貌似就行了
/**
* 查询各个状态下的设备数量
*

View File

@ -63,14 +63,14 @@ public interface IotDeviceLogMapper {
* 查询每个小时设备上行消息数量
*/
List<Map<String, Object>> selectDeviceLogUpCountByHour(@Param("deviceKey") String deviceKey,
@Param("startTime") Long startTime,
@Param("endTime") Long endTime);
@Param("startTime") Long startTime,
@Param("endTime") Long endTime);
/**
* 查询每个小时设备下行消息数量
*/
List<Map<String, Object>> selectDeviceLogDownCountByHour(@Param("deviceKey") String deviceKey,
@Param("startTime") Long startTime,
@Param("endTime") Long endTime);
@Param("startTime") Long startTime,
@Param("endTime") Long endTime);
}

View File

@ -196,14 +196,6 @@ public interface IotDeviceService {
*/
Long getDeviceCount(@Nullable LocalDateTime createTime);
/**
* 获得所有设备列表
*
* @return 设备列表
*/
List<IotDeviceDO> getDeviceList();
/**
* 获取 MQTT 连接参数
*

View File

@ -430,13 +430,7 @@ public class IotDeviceServiceImpl implements IotDeviceService {
return deviceMapper.selectCountByCreateTime(createTime);
}
// TODO @super是不是 groupby 查询更高效不过 controller还是要考虑 null 的情况不过可以直接枚举 foreach 处理下
@Override
public List<IotDeviceDO> getDeviceList() {
return deviceMapper.selectList();
}
// TODO @super简化
@Override
public Map<Long, Integer> getDeviceCountMapByProductId() {
// 查询结果转换成Map

View File

@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.iot.service.device.data;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageSummaryRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO;
import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
@ -57,8 +56,8 @@ public interface IotDeviceLogService {
* @return key: 时间戳, value: 消息数量
*/
List<Map<Long, Integer>> getDeviceLogUpCountByHour(@Nullable String deviceKey,
@Nullable Long startTime,
@Nullable Long endTime);
@Nullable Long startTime,
@Nullable Long endTime);
/**
* 获得每个小时设备下行消息数量统计
@ -69,7 +68,7 @@ public interface IotDeviceLogService {
* @return key: 时间戳, value: 消息数量
*/
List<Map<Long, Integer>> getDeviceLogDownCountByHour(@Nullable String deviceKey,
@Nullable Long startTime,
@Nullable Long endTime);
@Nullable Long startTime,
@Nullable Long endTime);
}

View File

@ -7,7 +7,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageSummaryRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO;
import cn.iocoder.yudao.module.iot.dal.tdengine.IotDeviceLogMapper;
import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
@ -73,13 +72,13 @@ public class IotDeviceLogServiceImpl implements IotDeviceLogService {
@Override
public Long getDeviceLogCount(LocalDateTime createTime) {
// todo @super1LocalDateTimeUtil.toEpochMilli(createTime);2直接表达式更简洁 time != null ? createTime.toInstant(ZoneOffset.UTC).toEpochMilli() : null;
return deviceLogMapper.selectCountByCreateTime(createTime != null ? LocalDateTimeUtil.toEpochMilli(createTime) : null);
}
// TODO @super加一个参数Boolean upstreamtrue 上行false 下行null 不过滤
@Override
public List<Map<Long, Integer>> getDeviceLogUpCountByHour(String deviceKey, Long startTime, Long endTime) {
// TODO @super不能只基于数据库统计因为有一些小时可能出现没数据的情况导致前端展示的图是不全的可以参考 CrmStatisticsCustomerService 来实现
List<Map<String, Object>> list = deviceLogMapper.selectDeviceLogUpCountByHour(deviceKey, startTime, endTime);
return list.stream()
.map(map -> {
@ -93,6 +92,7 @@ public class IotDeviceLogServiceImpl implements IotDeviceLogService {
.collect(Collectors.toList());
}
// TODO @supergetDeviceLogDownCountByHour 融合到 getDeviceLogUpCountByHour
@Override
public List<Map<Long, Integer>> getDeviceLogDownCountByHour(String deviceKey, Long startTime, Long endTime) {
List<Map<String, Object>> list = deviceLogMapper.selectDeviceLogDownCountByHour(deviceKey, startTime, endTime);

View File

@ -93,9 +93,8 @@ public interface IotProductCategoryService {
*/
Long getProductCategoryCount(@Nullable LocalDateTime createTime);
// TODO @super1Map<ProductCategory, Count> 虽然有点怪哈然后 Controller 按需转换成 Map<String, Integer> 2名字 getProductCategoryDeviceCountMap 方法
/**
* 获得各个品类下设备数量统计
* 获得各个品类下设备数量统计其中 key 是产品分类名
*
* @return 品类设备统计列表
*/

View File

@ -106,11 +106,9 @@ public class IotProductCategoryServiceImpl implements IotProductCategoryService
// 2. 统计每个分类下的设备数量
Map<String, Integer> categoryDeviceCountMap = new HashMap<>();
// 2.1 初始化所有分类的计数为0
for (IotProductCategoryDO category : categoryList) {
categoryDeviceCountMap.put(category.getName(), 0);
// TODO @superCollectionUtils.getSumValue()看看能不能简化下
// 2.2 找到该分类下的所有产品,累加设备数量
for (IotProductDO product : productList) {
if (Objects.equals(product.getCategoryId(), category.getId())) {
@ -119,7 +117,6 @@ public class IotProductCategoryServiceImpl implements IotProductCategoryService
}
}
}
return categoryDeviceCountMap;
}