Commit 3aef51f8116174222cb3f4f97617f10f3fbc88a2
Committed by
Gitee
!1263 【新增】:IOT首页的数据统计
Merge pull request !1263 from alwayssuper/feature/iot
Showing
20 changed files
with
586 additions
and
4 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/statistics/IotStatisticsController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.statistics; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 4 | +import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsReqVO; | ||
| 5 | +import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsRespVO; | ||
| 6 | +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | ||
| 7 | +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | ||
| 8 | +import cn.iocoder.yudao.module.iot.service.device.data.IotDeviceLogService; | ||
| 9 | +import cn.iocoder.yudao.module.iot.service.product.IotProductCategoryService; | ||
| 10 | +import cn.iocoder.yudao.module.iot.service.product.IotProductService; | ||
| 11 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 12 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 13 | +import jakarta.annotation.Resource; | ||
| 14 | +import jakarta.validation.Valid; | ||
| 15 | +import org.springframework.validation.annotation.Validated; | ||
| 16 | +import org.springframework.web.bind.annotation.GetMapping; | ||
| 17 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
| 18 | +import org.springframework.web.bind.annotation.RestController; | ||
| 19 | + | ||
| 20 | +import java.time.LocalDateTime; | ||
| 21 | + | ||
| 22 | + | ||
| 23 | +@Tag(name = "管理后台 - IoT 数据统计") | ||
| 24 | +@RestController | ||
| 25 | +@RequestMapping("/iot/statistics") | ||
| 26 | +@Validated | ||
| 27 | +public class IotStatisticsController { | ||
| 28 | + | ||
| 29 | + @Resource | ||
| 30 | + private IotDeviceService iotDeviceService; | ||
| 31 | + | ||
| 32 | + @Resource | ||
| 33 | + private IotProductCategoryService iotProductCategoryService; | ||
| 34 | + | ||
| 35 | + @Resource | ||
| 36 | + private IotProductService iotProductService; | ||
| 37 | + | ||
| 38 | + @Resource | ||
| 39 | + private IotDeviceLogService iotDeviceLogService; | ||
| 40 | + | ||
| 41 | + | ||
| 42 | + @GetMapping("/main") | ||
| 43 | + @Operation(summary = "获取IOT首页的数据统计", description = "用于IOT首页的数据统计") | ||
| 44 | + public CommonResult<IotStatisticsRespVO> getIotMainStats(@Valid IotStatisticsReqVO reqVO){ | ||
| 45 | + IotStatisticsRespVO iotStatisticsRespVO = new IotStatisticsRespVO(); | ||
| 46 | + // 获取总数 | ||
| 47 | + iotStatisticsRespVO.setCategoryTotal(iotProductCategoryService.getProductCategoryCount(null)); | ||
| 48 | + iotStatisticsRespVO.setProductTotal(iotProductService.getProductCount(null)); | ||
| 49 | + iotStatisticsRespVO.setDeviceTotal(iotDeviceService.getDeviceCount(null)); | ||
| 50 | + iotStatisticsRespVO.setReportTotal(iotDeviceLogService.getDeviceLogCount(null)); | ||
| 51 | + | ||
| 52 | + // 获取今日新增数量 | ||
| 53 | + LocalDateTime todayStart = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0); | ||
| 54 | + iotStatisticsRespVO.setCategoryTodayTotal(iotProductCategoryService.getProductCategoryCount(todayStart)); | ||
| 55 | + iotStatisticsRespVO.setProductTodayTotal(iotProductService.getProductCount(todayStart)); | ||
| 56 | + iotStatisticsRespVO.setDeviceTodayTotal(iotDeviceService.getDeviceCount(todayStart)); | ||
| 57 | + iotStatisticsRespVO.setReportTodayTotal(iotDeviceLogService.getDeviceLogCount(todayStart)); | ||
| 58 | + | ||
| 59 | + // 获取各个品类下设备数量统计 | ||
| 60 | + iotStatisticsRespVO.setDeviceStatsOfCategory( | ||
| 61 | + iotProductCategoryService.getDeviceCountsOfProductCategory() | ||
| 62 | + ); | ||
| 63 | + | ||
| 64 | + // 获取设备状态数量统计 | ||
| 65 | + iotStatisticsRespVO.setOnlineTotal(iotDeviceService.getDeviceCountByState(IotDeviceStateEnum.ONLINE.getState())); | ||
| 66 | + iotStatisticsRespVO.setOfflineTotal(iotDeviceService.getDeviceCountByState(IotDeviceStateEnum.OFFLINE.getState())); | ||
| 67 | + iotStatisticsRespVO.setNeverOnlineTotal(iotDeviceService.getDeviceCountByState(IotDeviceStateEnum.INACTIVE.getState())); | ||
| 68 | + | ||
| 69 | + // 根据传入时间范围获取设备上下行消息数量统计 | ||
| 70 | + iotStatisticsRespVO.setDeviceUpMessageStats(iotDeviceLogService.getDeviceLogUpCountByHour(null, reqVO.getStartTime(), reqVO.getEndTime())); | ||
| 71 | + iotStatisticsRespVO.setDeviceDownMessageStats(iotDeviceLogService.getDeviceLogDownCountByHour(null, reqVO.getStartTime(), reqVO.getEndTime())); | ||
| 72 | + | ||
| 73 | + return CommonResult.success(iotStatisticsRespVO); | ||
| 74 | + } | ||
| 75 | +} |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/statistics/vo/IotStatisticsReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.statistics.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import jakarta.validation.constraints.NotNull; | ||
| 5 | +import lombok.Data; | ||
| 6 | + | ||
| 7 | +@Schema(description = "管理后台 - Iot统计 Request VO") | ||
| 8 | +@Data | ||
| 9 | +public class IotStatisticsReqVO { | ||
| 10 | + @Schema(description = "查询起始时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "177") | ||
| 11 | + @NotNull(message = "查询起始时间不能为空") | ||
| 12 | + Long startTime; | ||
| 13 | + @Schema(description = "查询结束时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "177") | ||
| 14 | + @NotNull(message = "查询结束时间不能为空") | ||
| 15 | + Long endTime; | ||
| 16 | +} |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/statistics/vo/IotStatisticsRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.statistics.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +import java.util.List; | ||
| 7 | + | ||
| 8 | +@Schema(description = "管理后台 - Iot统计 Response VO") | ||
| 9 | +@Data | ||
| 10 | +public class IotStatisticsRespVO { | ||
| 11 | + | ||
| 12 | + @Schema(description = "品类数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | ||
| 13 | + private long categoryTotal; | ||
| 14 | + | ||
| 15 | + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20") | ||
| 16 | + private long productTotal; | ||
| 17 | + | ||
| 18 | + @Schema(description = "设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | ||
| 19 | + private long deviceTotal; | ||
| 20 | + | ||
| 21 | + @Schema(description = "上报数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") | ||
| 22 | + private long reportTotal; | ||
| 23 | + | ||
| 24 | + @Schema(description = "今日新增品类数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | ||
| 25 | + private long categoryTodayTotal; | ||
| 26 | + | ||
| 27 | + @Schema(description = "今日新增产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20") | ||
| 28 | + private long productTodayTotal; | ||
| 29 | + | ||
| 30 | + @Schema(description = "今日新增设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | ||
| 31 | + private long deviceTodayTotal; | ||
| 32 | + | ||
| 33 | + @Schema(description = "今日新增上报数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") | ||
| 34 | + private long reportTodayTotal; | ||
| 35 | + | ||
| 36 | + @Schema(description = "在线数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "80") | ||
| 37 | + private long onlineTotal; | ||
| 38 | + | ||
| 39 | + @Schema(description = "离线数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15") | ||
| 40 | + private long offlineTotal; | ||
| 41 | + | ||
| 42 | + @Schema(description = "待激活设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") | ||
| 43 | + private long neverOnlineTotal; | ||
| 44 | + | ||
| 45 | + @Schema(description = "上报数据数量统计") | ||
| 46 | + private List<TimeData> reportDataStats; | ||
| 47 | + | ||
| 48 | + @Schema(description = "上行数据数量统计") | ||
| 49 | + private List<TimeData> deviceUpMessageStats; | ||
| 50 | + | ||
| 51 | + @Schema(description = "下行数据数量统计") | ||
| 52 | + private List<TimeData> deviceDownMessageStats; | ||
| 53 | + | ||
| 54 | + @Schema(description = "按品类统计的设备数量") | ||
| 55 | + private List<DataItem> deviceStatsOfCategory; | ||
| 56 | + | ||
| 57 | + @Schema(description = "时间数据") | ||
| 58 | + @Data | ||
| 59 | + public static class TimeData { | ||
| 60 | + | ||
| 61 | + @Schema(description = "时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "1646092800000") | ||
| 62 | + private long time; | ||
| 63 | + | ||
| 64 | + @Schema(description = "数据值", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | ||
| 65 | + private Object data; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + @Schema(description = "数据项") | ||
| 69 | + @Data | ||
| 70 | + public static class DataItem { | ||
| 71 | + | ||
| 72 | + @Schema(description = "数据项名", requiredMode = Schema.RequiredMode.REQUIRED, example = "智能家居") | ||
| 73 | + private String name; | ||
| 74 | + | ||
| 75 | + @Schema(description = "数据项值", requiredMode = Schema.RequiredMode.REQUIRED, example = "50") | ||
| 76 | + private Object value; | ||
| 77 | + } | ||
| 78 | +} |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceMapper.java
| @@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | @@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | ||
| 9 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 9 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| 10 | import org.apache.ibatis.annotations.Mapper; | 10 | import org.apache.ibatis.annotations.Mapper; |
| 11 | 11 | ||
| 12 | +import java.time.LocalDateTime; | ||
| 12 | import java.util.List; | 13 | import java.util.List; |
| 13 | 14 | ||
| 14 | /** | 15 | /** |
| @@ -69,4 +70,26 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> { | @@ -69,4 +70,26 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> { | ||
| 69 | .apply("FIND_IN_SET(" + groupId + ",group_ids) > 0")); | 70 | .apply("FIND_IN_SET(" + groupId + ",group_ids) > 0")); |
| 70 | } | 71 | } |
| 71 | 72 | ||
| 73 | + /** | ||
| 74 | + * 统计设备数量 | ||
| 75 | + * | ||
| 76 | + * @param createTime 创建时间,如果为空,则统计所有设备数量 | ||
| 77 | + * @return 设备数量 | ||
| 78 | + */ | ||
| 79 | + default Long selectCountByCreateTime(LocalDateTime createTime) { | ||
| 80 | + return selectCount(new LambdaQueryWrapperX<IotDeviceDO>() | ||
| 81 | + .geIfPresent(IotDeviceDO::getCreateTime, createTime)); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + /** | ||
| 85 | + * 统计指定状态的设备数量 | ||
| 86 | + * | ||
| 87 | + * @param state 状态 | ||
| 88 | + * @return 设备数量 | ||
| 89 | + */ | ||
| 90 | + default Long selectCountByState(Integer state) { | ||
| 91 | + return selectCount(new LambdaQueryWrapperX<IotDeviceDO>() | ||
| 92 | + .eqIfPresent(IotDeviceDO::getState, state)); | ||
| 93 | + } | ||
| 94 | + | ||
| 72 | } | 95 | } |
| 73 | \ No newline at end of file | 96 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/product/IotProductCategoryMapper.java
| @@ -6,7 +6,9 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | @@ -6,7 +6,9 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||
| 6 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.category.IotProductCategoryPageReqVO; | 6 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.category.IotProductCategoryPageReqVO; |
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductCategoryDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductCategoryDO; |
| 8 | import org.apache.ibatis.annotations.Mapper; | 8 | import org.apache.ibatis.annotations.Mapper; |
| 9 | +import org.apache.ibatis.annotations.Param; | ||
| 9 | 10 | ||
| 11 | +import java.time.LocalDateTime; | ||
| 10 | import java.util.List; | 12 | import java.util.List; |
| 11 | 13 | ||
| 12 | /** | 14 | /** |
| @@ -28,4 +30,15 @@ public interface IotProductCategoryMapper extends BaseMapperX<IotProductCategory | @@ -28,4 +30,15 @@ public interface IotProductCategoryMapper extends BaseMapperX<IotProductCategory | ||
| 28 | return selectList(IotProductCategoryDO::getStatus, status); | 30 | return selectList(IotProductCategoryDO::getStatus, status); |
| 29 | } | 31 | } |
| 30 | 32 | ||
| 33 | + /** | ||
| 34 | + * 统计产品分类数量 | ||
| 35 | + * | ||
| 36 | + * @param createTime 创建时间,如果为空,则统计所有分类数量 | ||
| 37 | + * @return 产品分类数量 | ||
| 38 | + */ | ||
| 39 | + default Long selectCountByCreateTime(LocalDateTime createTime) { | ||
| 40 | + return selectCount(new LambdaQueryWrapperX<IotProductCategoryDO>() | ||
| 41 | + .geIfPresent(IotProductCategoryDO::getCreateTime, createTime)); | ||
| 42 | + } | ||
| 43 | + | ||
| 31 | } | 44 | } |
| 32 | \ No newline at end of file | 45 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/product/IotProductMapper.java
| @@ -8,6 +8,9 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | @@ -8,6 +8,9 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | ||
| 8 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 8 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| 9 | import org.apache.ibatis.annotations.Mapper; | 9 | import org.apache.ibatis.annotations.Mapper; |
| 10 | 10 | ||
| 11 | +import java.time.LocalDateTime; | ||
| 12 | +import java.util.List; | ||
| 13 | + | ||
| 11 | /** | 14 | /** |
| 12 | * IoT 产品 Mapper | 15 | * IoT 产品 Mapper |
| 13 | * | 16 | * |
| @@ -28,4 +31,27 @@ public interface IotProductMapper extends BaseMapperX<IotProductDO> { | @@ -28,4 +31,27 @@ public interface IotProductMapper extends BaseMapperX<IotProductDO> { | ||
| 28 | .apply("LOWER(product_key) = {0}", productKey.toLowerCase())); | 31 | .apply("LOWER(product_key) = {0}", productKey.toLowerCase())); |
| 29 | } | 32 | } |
| 30 | 33 | ||
| 34 | + /** | ||
| 35 | + * 统计产品数量 | ||
| 36 | + * | ||
| 37 | + * @param createTime 创建时间,如果为空,则统计所有产品数量 | ||
| 38 | + * @return 产品数量 | ||
| 39 | + */ | ||
| 40 | + default Long selectCountByCreateTime(LocalDateTime createTime) { | ||
| 41 | + return selectCount(new LambdaQueryWrapperX<IotProductDO>() | ||
| 42 | + .geIfPresent(IotProductDO::getCreateTime, createTime)); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * 获得产品列表,基于分类编号 | ||
| 47 | + * | ||
| 48 | + * @param categoryId 分类编号 | ||
| 49 | + * @return 产品列表 | ||
| 50 | + */ | ||
| 51 | + default List<IotProductDO> selectListByCategoryId(Long categoryId) { | ||
| 52 | + return selectList(new LambdaQueryWrapperX<IotProductDO>() | ||
| 53 | + .eq(IotProductDO::getCategoryId, categoryId) | ||
| 54 | + .orderByDesc(IotProductDO::getId)); | ||
| 55 | + } | ||
| 56 | + | ||
| 31 | } | 57 | } |
| 32 | \ No newline at end of file | 58 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotThingModelMapper.java
| @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelP | @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelP | ||
| 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 9 | import org.apache.ibatis.annotations.Mapper; | 9 | import org.apache.ibatis.annotations.Mapper; |
| 10 | 10 | ||
| 11 | +import java.time.LocalDateTime; | ||
| 11 | import java.util.List; | 12 | import java.util.List; |
| 12 | 13 | ||
| 13 | /** | 14 | /** |
| @@ -72,4 +73,15 @@ public interface IotThingModelMapper extends BaseMapperX<IotThingModelDO> { | @@ -72,4 +73,15 @@ public interface IotThingModelMapper extends BaseMapperX<IotThingModelDO> { | ||
| 72 | IotThingModelDO::getName, name); | 73 | IotThingModelDO::getName, name); |
| 73 | } | 74 | } |
| 74 | 75 | ||
| 76 | + /** | ||
| 77 | + * 统计物模型数量 | ||
| 78 | + * | ||
| 79 | + * @param createTime 创建时间,如果为空,则统计所有物模型数量 | ||
| 80 | + * @return 物模型数量 | ||
| 81 | + */ | ||
| 82 | + default Long selectCountByCreateTime(LocalDateTime createTime) { | ||
| 83 | + return selectCount(new LambdaQueryWrapperX<IotThingModelDO>() | ||
| 84 | + .geIfPresent(IotThingModelDO::getCreateTime, createTime)); | ||
| 85 | + } | ||
| 86 | + | ||
| 75 | } | 87 | } |
| 76 | \ No newline at end of file | 88 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogMapper.java
| 1 | package cn.iocoder.yudao.module.iot.dal.tdengine; | 1 | package cn.iocoder.yudao.module.iot.dal.tdengine; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO; | 3 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO; |
| 4 | +import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsRespVO; | ||
| 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; |
| 5 | import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS; | 6 | import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS; |
| 6 | import com.baomidou.mybatisplus.annotation.InterceptorIgnore; | 7 | import com.baomidou.mybatisplus.annotation.InterceptorIgnore; |
| @@ -8,6 +9,9 @@ import com.baomidou.mybatisplus.core.metadata.IPage; | @@ -8,6 +9,9 @@ import com.baomidou.mybatisplus.core.metadata.IPage; | ||
| 8 | import org.apache.ibatis.annotations.Mapper; | 9 | import org.apache.ibatis.annotations.Mapper; |
| 9 | import org.apache.ibatis.annotations.Param; | 10 | import org.apache.ibatis.annotations.Param; |
| 10 | 11 | ||
| 12 | +import java.time.LocalDateTime; | ||
| 13 | +import java.util.List; | ||
| 14 | + | ||
| 11 | /** | 15 | /** |
| 12 | * 设备日志 {@link IotDeviceLogDO} Mapper 接口 | 16 | * 设备日志 {@link IotDeviceLogDO} Mapper 接口 |
| 13 | */ | 17 | */ |
| @@ -46,4 +50,36 @@ public interface IotDeviceLogMapper { | @@ -46,4 +50,36 @@ public interface IotDeviceLogMapper { | ||
| 46 | IPage<IotDeviceLogDO> selectPage(IPage<IotDeviceLogDO> page, | 50 | IPage<IotDeviceLogDO> selectPage(IPage<IotDeviceLogDO> page, |
| 47 | @Param("reqVO") IotDeviceLogPageReqVO reqVO); | 51 | @Param("reqVO") IotDeviceLogPageReqVO reqVO); |
| 48 | 52 | ||
| 53 | + /** | ||
| 54 | + * 统计设备日志数量 | ||
| 55 | + * | ||
| 56 | + * @param createTime 创建时间,如果为空,则统计所有日志数量 | ||
| 57 | + * @return 日志数量 | ||
| 58 | + */ | ||
| 59 | + Long selectCountByCreateTime(@Param("createTime") Long createTime); | ||
| 60 | + | ||
| 61 | + /** | ||
| 62 | + * 获得每个小时设备上行消息数量统计 | ||
| 63 | + * | ||
| 64 | + * @param deviceKey 设备标识 | ||
| 65 | + * @param startTime 开始时间 | ||
| 66 | + * @param endTime 结束时间 | ||
| 67 | + * @return 每小时消息数量统计 | ||
| 68 | + */ | ||
| 69 | + List<IotStatisticsRespVO.TimeData> selectDeviceLogUpCountByHour(@Param("deviceKey") String deviceKey, | ||
| 70 | + @Param("startTime") Long startTime, | ||
| 71 | + @Param("endTime") Long endTime); | ||
| 72 | + | ||
| 73 | + /** | ||
| 74 | + * 获得每个小时设备下行消息数量统计 | ||
| 75 | + * | ||
| 76 | + * @param deviceKey 设备标识 | ||
| 77 | + * @param startTime 开始时间 | ||
| 78 | + * @param endTime 结束时间 | ||
| 79 | + * @return 每小时消息数量统计 | ||
| 80 | + */ | ||
| 81 | + List<IotStatisticsRespVO.TimeData> selectDeviceLogDownCountByHour(@Param("deviceKey") String deviceKey, | ||
| 82 | + @Param("startTime") Long startTime, | ||
| 83 | + @Param("endTime") Long endTime); | ||
| 84 | + | ||
| 49 | } | 85 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
| @@ -7,6 +7,7 @@ import jakarta.validation.Valid; | @@ -7,6 +7,7 @@ import jakarta.validation.Valid; | ||
| 7 | import jakarta.validation.constraints.NotEmpty; | 7 | import jakarta.validation.constraints.NotEmpty; |
| 8 | 8 | ||
| 9 | import javax.annotation.Nullable; | 9 | import javax.annotation.Nullable; |
| 10 | +import java.time.LocalDateTime; | ||
| 10 | import java.util.Collection; | 11 | import java.util.Collection; |
| 11 | import java.util.List; | 12 | import java.util.List; |
| 12 | 13 | ||
| @@ -186,6 +187,29 @@ public interface IotDeviceService { | @@ -186,6 +187,29 @@ public interface IotDeviceService { | ||
| 186 | IotDeviceImportRespVO importDevice(List<IotDeviceImportExcelVO> importDevices, boolean updateSupport); | 187 | IotDeviceImportRespVO importDevice(List<IotDeviceImportExcelVO> importDevices, boolean updateSupport); |
| 187 | 188 | ||
| 188 | /** | 189 | /** |
| 190 | + * 获得设备数量 | ||
| 191 | + * | ||
| 192 | + * @param createTime 创建时间,如果为空,则统计所有设备数量 | ||
| 193 | + * @return 设备数量 | ||
| 194 | + */ | ||
| 195 | + Long getDeviceCount(LocalDateTime createTime); | ||
| 196 | + | ||
| 197 | + /** | ||
| 198 | + * 获得设备数量,基于状态 | ||
| 199 | + * | ||
| 200 | + * @param state 状态 | ||
| 201 | + * @return 设备数量 | ||
| 202 | + */ | ||
| 203 | + Long getDeviceCountByState(Integer state); | ||
| 204 | + | ||
| 205 | + /** | ||
| 206 | + * 获得所有设备列表 | ||
| 207 | + * | ||
| 208 | + * @return 设备列表 | ||
| 209 | + */ | ||
| 210 | + List<IotDeviceDO> getDeviceList(); | ||
| 211 | + | ||
| 212 | + /** | ||
| 189 | * 获取 MQTT 连接参数 | 213 | * 获取 MQTT 连接参数 |
| 190 | * | 214 | * |
| 191 | * @param deviceId 设备 ID | 215 | * @param deviceId 设备 ID |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java
| @@ -424,4 +424,19 @@ public class IotDeviceServiceImpl implements IotDeviceService { | @@ -424,4 +424,19 @@ public class IotDeviceServiceImpl implements IotDeviceService { | ||
| 424 | return SpringUtil.getBean(getClass()); | 424 | return SpringUtil.getBean(getClass()); |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | + @Override | ||
| 428 | + public Long getDeviceCount(LocalDateTime createTime) { | ||
| 429 | + return deviceMapper.selectCountByCreateTime(createTime); | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + @Override | ||
| 433 | + public Long getDeviceCountByState(Integer state) { | ||
| 434 | + return deviceMapper.selectCountByState(state); | ||
| 435 | + } | ||
| 436 | + | ||
| 437 | + @Override | ||
| 438 | + public List<IotDeviceDO> getDeviceList() { | ||
| 439 | + return deviceMapper.selectList(); | ||
| 440 | + } | ||
| 441 | + | ||
| 427 | } | 442 | } |
| 428 | \ No newline at end of file | 443 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/data/IotDeviceLogService.java
| @@ -2,8 +2,13 @@ package cn.iocoder.yudao.module.iot.service.device.data; | @@ -2,8 +2,13 @@ package cn.iocoder.yudao.module.iot.service.device.data; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO; | 4 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO; |
| 5 | +import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsRespVO; | ||
| 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; |
| 6 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 7 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| 8 | +import org.apache.ibatis.annotations.Param; | ||
| 9 | + | ||
| 10 | +import java.time.LocalDateTime; | ||
| 11 | +import java.util.List; | ||
| 7 | 12 | ||
| 8 | /** | 13 | /** |
| 9 | * IoT 设备日志数据 Service 接口 | 14 | * IoT 设备日志数据 Service 接口 |
| @@ -34,4 +39,32 @@ public interface IotDeviceLogService { | @@ -34,4 +39,32 @@ public interface IotDeviceLogService { | ||
| 34 | */ | 39 | */ |
| 35 | PageResult<IotDeviceLogDO> getDeviceLogPage(IotDeviceLogPageReqVO pageReqVO); | 40 | PageResult<IotDeviceLogDO> getDeviceLogPage(IotDeviceLogPageReqVO pageReqVO); |
| 36 | 41 | ||
| 42 | + /** | ||
| 43 | + * 获得设备日志数量 | ||
| 44 | + * | ||
| 45 | + * @param createTime 创建时间,如果为空,则统计所有日志数量 | ||
| 46 | + * @return 日志数量 | ||
| 47 | + */ | ||
| 48 | + Long getDeviceLogCount(LocalDateTime createTime); | ||
| 49 | + | ||
| 50 | + /** | ||
| 51 | + * 获得每个小时设备上行消息数量统计 | ||
| 52 | + * | ||
| 53 | + * @param deviceKey 设备标识,如果为空,则统计所有设备 | ||
| 54 | + * @param startTime 开始时间,如果为空,则不限制开始时间 | ||
| 55 | + * @param endTime 结束时间,如果为空,则不限制结束时间 | ||
| 56 | + * @return 每小时消息数量统计列表 | ||
| 57 | + */ | ||
| 58 | + List<IotStatisticsRespVO.TimeData> getDeviceLogUpCountByHour(String deviceKey, Long startTime, Long endTime); | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * 获得每个小时设备下行消息数量统计 | ||
| 62 | + * | ||
| 63 | + * @param deviceKey 设备标识,如果为空,则统计所有设备 | ||
| 64 | + * @param startTime 开始时间,如果为空,则不限制开始时间 | ||
| 65 | + * @param endTime 结束时间,如果为空,则不限制结束时间 | ||
| 66 | + * @return 每小时消息数量统计列表 | ||
| 67 | + */ | ||
| 68 | + List<IotStatisticsRespVO.TimeData> getDeviceLogDownCountByHour( String deviceKey, Long startTime, Long endTime); | ||
| 69 | + | ||
| 37 | } | 70 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/data/IotDeviceLogServiceImpl.java
| @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 6 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 6 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 7 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 7 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 8 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO; | 8 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceLogPageReqVO; |
| 9 | +import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsRespVO; | ||
| 9 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; | 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceLogDO; |
| 10 | import cn.iocoder.yudao.module.iot.dal.tdengine.IotDeviceLogMapper; | 11 | import cn.iocoder.yudao.module.iot.dal.tdengine.IotDeviceLogMapper; |
| 11 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 12 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| @@ -16,6 +17,11 @@ import lombok.extern.slf4j.Slf4j; | @@ -16,6 +17,11 @@ import lombok.extern.slf4j.Slf4j; | ||
| 16 | import org.springframework.stereotype.Service; | 17 | import org.springframework.stereotype.Service; |
| 17 | import org.springframework.validation.annotation.Validated; | 18 | import org.springframework.validation.annotation.Validated; |
| 18 | 19 | ||
| 20 | +import java.time.LocalDateTime; | ||
| 21 | +import java.time.ZoneOffset; | ||
| 22 | +import java.util.ArrayList; | ||
| 23 | +import java.util.List; | ||
| 24 | + | ||
| 19 | /** | 25 | /** |
| 20 | * IoT 设备日志数据 Service 实现类 | 26 | * IoT 设备日志数据 Service 实现类 |
| 21 | * | 27 | * |
| @@ -63,4 +69,37 @@ public class IotDeviceLogServiceImpl implements IotDeviceLogService { | @@ -63,4 +69,37 @@ public class IotDeviceLogServiceImpl implements IotDeviceLogService { | ||
| 63 | } | 69 | } |
| 64 | } | 70 | } |
| 65 | 71 | ||
| 72 | + @Override | ||
| 73 | + public Long getDeviceLogCount(LocalDateTime createTime) { | ||
| 74 | + Long time = null; | ||
| 75 | + if (createTime != null) { | ||
| 76 | + time = createTime.toInstant(ZoneOffset.UTC).toEpochMilli(); | ||
| 77 | + } | ||
| 78 | + return deviceLogMapper.selectCountByCreateTime(time); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + @Override | ||
| 82 | + public List<IotStatisticsRespVO.TimeData> getDeviceLogUpCountByHour(String deviceKey, Long startTime, Long endTime) { | ||
| 83 | + try { | ||
| 84 | + return deviceLogMapper.selectDeviceLogUpCountByHour(deviceKey, startTime, endTime); | ||
| 85 | + } catch (Exception exception) { | ||
| 86 | + if (exception.getMessage().contains("Table does not exist")) { | ||
| 87 | + return new ArrayList<>(); | ||
| 88 | + } | ||
| 89 | + throw exception; | ||
| 90 | + } | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + @Override | ||
| 94 | + public List<IotStatisticsRespVO.TimeData> getDeviceLogDownCountByHour(String deviceKey, Long startTime, Long endTime) { | ||
| 95 | + try { | ||
| 96 | + return deviceLogMapper.selectDeviceLogDownCountByHour(deviceKey, startTime, endTime); | ||
| 97 | + } catch (Exception exception) { | ||
| 98 | + if (exception.getMessage().contains("Table does not exist")) { | ||
| 99 | + return new ArrayList<>(); | ||
| 100 | + } | ||
| 101 | + throw exception; | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + | ||
| 66 | } | 105 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductCategoryService.java
| @@ -3,9 +3,11 @@ package cn.iocoder.yudao.module.iot.service.product; | @@ -3,9 +3,11 @@ package cn.iocoder.yudao.module.iot.service.product; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.category.IotProductCategoryPageReqVO; | 4 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.category.IotProductCategoryPageReqVO; |
| 5 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.category.IotProductCategorySaveReqVO; | 5 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.category.IotProductCategorySaveReqVO; |
| 6 | +import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsRespVO; | ||
| 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductCategoryDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductCategoryDO; |
| 7 | import jakarta.validation.Valid; | 8 | import jakarta.validation.Valid; |
| 8 | 9 | ||
| 10 | +import java.time.LocalDateTime; | ||
| 9 | import java.util.Collection; | 11 | import java.util.Collection; |
| 10 | import java.util.List; | 12 | import java.util.List; |
| 11 | import java.util.Map; | 13 | import java.util.Map; |
| @@ -83,4 +85,19 @@ public interface IotProductCategoryService { | @@ -83,4 +85,19 @@ public interface IotProductCategoryService { | ||
| 83 | */ | 85 | */ |
| 84 | List<IotProductCategoryDO> getProductCategoryListByStatus(Integer status); | 86 | List<IotProductCategoryDO> getProductCategoryListByStatus(Integer status); |
| 85 | 87 | ||
| 88 | + /** | ||
| 89 | + * 获得产品分类数量 | ||
| 90 | + * | ||
| 91 | + * @param createTime 创建时间,如果为空,则统计所有分类数量 | ||
| 92 | + * @return 产品分类数量 | ||
| 93 | + */ | ||
| 94 | + Long getProductCategoryCount(LocalDateTime createTime); | ||
| 95 | + | ||
| 96 | + /** | ||
| 97 | + * 获得各个品类下设备数量统计 | ||
| 98 | + * | ||
| 99 | + * @return 品类设备统计列表 | ||
| 100 | + */ | ||
| 101 | + List<IotStatisticsRespVO.DataItem> getDeviceCountsOfProductCategory(); | ||
| 102 | + | ||
| 86 | } | 103 | } |
| 87 | \ No newline at end of file | 104 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductCategoryServiceImpl.java
| @@ -5,14 +5,23 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -5,14 +5,23 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.category.IotProductCategoryPageReqVO; | 6 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.category.IotProductCategoryPageReqVO; |
| 7 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.category.IotProductCategorySaveReqVO; | 7 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.category.IotProductCategorySaveReqVO; |
| 8 | +import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsRespVO; | ||
| 9 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | ||
| 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductCategoryDO; | 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductCategoryDO; |
| 11 | +import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | ||
| 9 | import cn.iocoder.yudao.module.iot.dal.mysql.product.IotProductCategoryMapper; | 12 | import cn.iocoder.yudao.module.iot.dal.mysql.product.IotProductCategoryMapper; |
| 13 | +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | ||
| 14 | +import cn.iocoder.yudao.module.iot.service.product.IotProductCategoryService; | ||
| 10 | import jakarta.annotation.Resource; | 15 | import jakarta.annotation.Resource; |
| 11 | import org.springframework.stereotype.Service; | 16 | import org.springframework.stereotype.Service; |
| 12 | import org.springframework.validation.annotation.Validated; | 17 | import org.springframework.validation.annotation.Validated; |
| 13 | 18 | ||
| 19 | +import java.time.LocalDateTime; | ||
| 14 | import java.util.Collection; | 20 | import java.util.Collection; |
| 21 | +import java.util.HashMap; | ||
| 15 | import java.util.List; | 22 | import java.util.List; |
| 23 | +import java.util.Map; | ||
| 24 | +import java.util.stream.Collectors; | ||
| 16 | 25 | ||
| 17 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 26 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 18 | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.PRODUCT_CATEGORY_NOT_EXISTS; | 27 | import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.PRODUCT_CATEGORY_NOT_EXISTS; |
| @@ -29,7 +38,12 @@ public class IotProductCategoryServiceImpl implements IotProductCategoryService | @@ -29,7 +38,12 @@ public class IotProductCategoryServiceImpl implements IotProductCategoryService | ||
| 29 | @Resource | 38 | @Resource |
| 30 | private IotProductCategoryMapper productCategoryMapper; | 39 | private IotProductCategoryMapper productCategoryMapper; |
| 31 | 40 | ||
| 32 | - @Override | 41 | + @Resource |
| 42 | + private IotProductService productService; | ||
| 43 | + | ||
| 44 | + @Resource | ||
| 45 | + private IotDeviceService deviceService; | ||
| 46 | + | ||
| 33 | public Long createProductCategory(IotProductCategorySaveReqVO createReqVO) { | 47 | public Long createProductCategory(IotProductCategorySaveReqVO createReqVO) { |
| 34 | // 插入 | 48 | // 插入 |
| 35 | IotProductCategoryDO productCategory = BeanUtils.toBean(createReqVO, IotProductCategoryDO.class); | 49 | IotProductCategoryDO productCategory = BeanUtils.toBean(createReqVO, IotProductCategoryDO.class); |
| @@ -84,4 +98,58 @@ public class IotProductCategoryServiceImpl implements IotProductCategoryService | @@ -84,4 +98,58 @@ public class IotProductCategoryServiceImpl implements IotProductCategoryService | ||
| 84 | return productCategoryMapper.selectListByStatus(status); | 98 | return productCategoryMapper.selectListByStatus(status); |
| 85 | } | 99 | } |
| 86 | 100 | ||
| 101 | + @Override | ||
| 102 | + public Long getProductCategoryCount(LocalDateTime createTime) { | ||
| 103 | + return productCategoryMapper.selectCountByCreateTime(createTime); | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + @Override | ||
| 107 | + public List<IotStatisticsRespVO.DataItem> getDeviceCountsOfProductCategory() { | ||
| 108 | + // 1. 获取所有数据 | ||
| 109 | + List<IotProductCategoryDO> categoryList = productCategoryMapper.selectList(); | ||
| 110 | + List<IotProductDO> productList = productService.getProductList(); | ||
| 111 | + List<IotDeviceDO> deviceList = deviceService.getDeviceList(); | ||
| 112 | + | ||
| 113 | + // 2. 统计每个分类下的设备数量 | ||
| 114 | + Map<String, Integer> categoryDeviceCountMap = new HashMap<>(); | ||
| 115 | + | ||
| 116 | + // 2.1 初始化所有分类的计数为0 | ||
| 117 | + for (IotProductCategoryDO category : categoryList) { | ||
| 118 | + categoryDeviceCountMap.put(category.getName(), 0); | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + // 2.2 构建产品ID到分类的映射 | ||
| 122 | + Map<Long, IotProductCategoryDO> productCategoryMap = new HashMap<>(); | ||
| 123 | + for (IotProductDO product : productList) { | ||
| 124 | + Long categoryId = product.getCategoryId(); | ||
| 125 | + IotProductCategoryDO category = categoryList.stream() | ||
| 126 | + .filter(c -> c.getId().equals(categoryId)) | ||
| 127 | + .findFirst() | ||
| 128 | + .orElse(null); | ||
| 129 | + if (category != null) { | ||
| 130 | + productCategoryMap.put(product.getId(), category); | ||
| 131 | + } | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + // 2.3 统计每个分类下的设备数量 | ||
| 135 | + for (IotDeviceDO device : deviceList) { | ||
| 136 | + Long productId = device.getProductId(); | ||
| 137 | + IotProductCategoryDO category = productCategoryMap.get(productId); | ||
| 138 | + if (category != null) { | ||
| 139 | + String categoryName = category.getName(); | ||
| 140 | + categoryDeviceCountMap.merge(categoryName, 1, Integer::sum); | ||
| 141 | + } | ||
| 142 | + } | ||
| 143 | + | ||
| 144 | + // 3. 转换为 DataItem 列表 | ||
| 145 | + return categoryDeviceCountMap.entrySet().stream() | ||
| 146 | + .map(entry -> { | ||
| 147 | + IotStatisticsRespVO.DataItem dataItem = new IotStatisticsRespVO.DataItem(); | ||
| 148 | + dataItem.setName(entry.getKey()); | ||
| 149 | + dataItem.setValue(entry.getValue()); | ||
| 150 | + return dataItem; | ||
| 151 | + }) | ||
| 152 | + .collect(Collectors.toList()); | ||
| 153 | + } | ||
| 154 | + | ||
| 87 | } | 155 | } |
| 88 | \ No newline at end of file | 156 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductService.java
| @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.product.vo.product.IotProduc | @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.product.vo.product.IotProduc | ||
| 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 7 | import jakarta.validation.Valid; | 7 | import jakarta.validation.Valid; |
| 8 | 8 | ||
| 9 | +import java.time.LocalDateTime; | ||
| 9 | import java.util.List; | 10 | import java.util.List; |
| 10 | 11 | ||
| 11 | /** | 12 | /** |
| @@ -92,4 +93,20 @@ public interface IotProductService { | @@ -92,4 +93,20 @@ public interface IotProductService { | ||
| 92 | */ | 93 | */ |
| 93 | List<IotProductDO> getProductList(); | 94 | List<IotProductDO> getProductList(); |
| 94 | 95 | ||
| 96 | + /** | ||
| 97 | + * 获得产品数量 | ||
| 98 | + * | ||
| 99 | + * @param createTime 创建时间,如果为空,则统计所有产品数量 | ||
| 100 | + * @return 产品数量 | ||
| 101 | + */ | ||
| 102 | + Long getProductCount(LocalDateTime createTime); | ||
| 103 | + | ||
| 104 | + /** | ||
| 105 | + * 获得产品列表,基于分类编号 | ||
| 106 | + * | ||
| 107 | + * @param categoryId 分类编号 | ||
| 108 | + * @return 产品列表 | ||
| 109 | + */ | ||
| 110 | + List<IotProductDO> getProductListByCategoryId(Long categoryId); | ||
| 111 | + | ||
| 95 | } | 112 | } |
| 96 | \ No newline at end of file | 113 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductServiceImpl.java
| @@ -15,6 +15,7 @@ import org.springframework.context.annotation.Lazy; | @@ -15,6 +15,7 @@ import org.springframework.context.annotation.Lazy; | ||
| 15 | import org.springframework.stereotype.Service; | 15 | import org.springframework.stereotype.Service; |
| 16 | import org.springframework.validation.annotation.Validated; | 16 | import org.springframework.validation.annotation.Validated; |
| 17 | 17 | ||
| 18 | +import java.time.LocalDateTime; | ||
| 18 | import java.util.List; | 19 | import java.util.List; |
| 19 | import java.util.Objects; | 20 | import java.util.Objects; |
| 20 | 21 | ||
| @@ -137,4 +138,14 @@ public class IotProductServiceImpl implements IotProductService { | @@ -137,4 +138,14 @@ public class IotProductServiceImpl implements IotProductService { | ||
| 137 | return productMapper.selectList(); | 138 | return productMapper.selectList(); |
| 138 | } | 139 | } |
| 139 | 140 | ||
| 141 | + @Override | ||
| 142 | + public Long getProductCount(LocalDateTime createTime) { | ||
| 143 | + return productMapper.selectCountByCreateTime(createTime); | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + @Override | ||
| 147 | + public List<IotProductDO> getProductListByCategoryId(Long categoryId) { | ||
| 148 | + return productMapper.selectListByCategoryId(categoryId); | ||
| 149 | + } | ||
| 150 | + | ||
| 140 | } | 151 | } |
| 141 | \ No newline at end of file | 152 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java
| @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelS | @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelS | ||
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 8 | import jakarta.validation.Valid; | 8 | import jakarta.validation.Valid; |
| 9 | 9 | ||
| 10 | +import java.time.LocalDateTime; | ||
| 10 | import java.util.List; | 11 | import java.util.List; |
| 11 | 12 | ||
| 12 | /** | 13 | /** |
| @@ -80,4 +81,12 @@ public interface IotThingModelService { | @@ -80,4 +81,12 @@ public interface IotThingModelService { | ||
| 80 | */ | 81 | */ |
| 81 | List<IotThingModelDO> getThingModelList(IotThingModelListReqVO reqVO); | 82 | List<IotThingModelDO> getThingModelList(IotThingModelListReqVO reqVO); |
| 82 | 83 | ||
| 84 | + /** | ||
| 85 | + * 获得物模型数量 | ||
| 86 | + * | ||
| 87 | + * @param createTime 创建时间,如果为空,则统计所有物模型数量 | ||
| 88 | + * @return 物模型数量 | ||
| 89 | + */ | ||
| 90 | + Long getThingModelCount(LocalDateTime createTime); | ||
| 91 | + | ||
| 83 | } | 92 | } |
| 84 | \ No newline at end of file | 93 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java
| @@ -29,6 +29,7 @@ import org.springframework.stereotype.Service; | @@ -29,6 +29,7 @@ import org.springframework.stereotype.Service; | ||
| 29 | import org.springframework.transaction.annotation.Transactional; | 29 | import org.springframework.transaction.annotation.Transactional; |
| 30 | import org.springframework.validation.annotation.Validated; | 30 | import org.springframework.validation.annotation.Validated; |
| 31 | 31 | ||
| 32 | +import java.time.LocalDateTime; | ||
| 32 | import java.util.*; | 33 | import java.util.*; |
| 33 | 34 | ||
| 34 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 35 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| @@ -363,4 +364,9 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -363,4 +364,9 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 363 | return SpringUtil.getBean(getClass()); | 364 | return SpringUtil.getBean(getClass()); |
| 364 | } | 365 | } |
| 365 | 366 | ||
| 367 | + @Override | ||
| 368 | + public Long getThingModelCount(LocalDateTime createTime) { | ||
| 369 | + return thingModelMapper.selectCountByCreateTime(createTime); | ||
| 370 | + } | ||
| 371 | + | ||
| 366 | } | 372 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceLogMapper.xml
| @@ -55,4 +55,68 @@ | @@ -55,4 +55,68 @@ | ||
| 55 | ORDER BY ts DESC | 55 | ORDER BY ts DESC |
| 56 | </select> | 56 | </select> |
| 57 | 57 | ||
| 58 | + <select id="selectCountByCreateTime" resultType="Long"> | ||
| 59 | + SELECT COUNT(*) | ||
| 60 | + FROM device_log | ||
| 61 | + <where> | ||
| 62 | + <if test="createTime != null"> | ||
| 63 | + AND ts >= #{createTime} | ||
| 64 | + </if> | ||
| 65 | + </where> | ||
| 66 | + </select> | ||
| 67 | + | ||
| 68 | + <select id="selectDeviceLogUpCountByHour" resultType="cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsRespVO$TimeData"> | ||
| 69 | + SELECT | ||
| 70 | + TIMETRUNCATE(ts, 1h) as time, | ||
| 71 | + COUNT(*) as data | ||
| 72 | + FROM | ||
| 73 | + <choose> | ||
| 74 | + <when test="deviceKey != null and deviceKey != ''"> | ||
| 75 | + device_log_${deviceKey} | ||
| 76 | + </when> | ||
| 77 | + <otherwise> | ||
| 78 | + device_log | ||
| 79 | + </otherwise> | ||
| 80 | + </choose> | ||
| 81 | + <where> | ||
| 82 | + <if test="startTime != null"> | ||
| 83 | + AND ts >= #{startTime} | ||
| 84 | + </if> | ||
| 85 | + <if test="endTime != null"> | ||
| 86 | + AND ts <= #{endTime} | ||
| 87 | + </if> | ||
| 88 | + AND ( | ||
| 89 | + identifier IN ('online', 'offline', 'pull', 'progress', 'report', 'register', 'register_sub') | ||
| 90 | + ) | ||
| 91 | + </where> | ||
| 92 | + GROUP BY TIMETRUNCATE(ts, 1h) | ||
| 93 | + ORDER BY time ASC | ||
| 94 | + </select> | ||
| 95 | + | ||
| 96 | + <select id="selectDeviceLogDownCountByHour" resultType="cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsRespVO$TimeData"> | ||
| 97 | + SELECT | ||
| 98 | + TIMETRUNCATE(ts, 1h) as time, | ||
| 99 | + COUNT(*) as data | ||
| 100 | + FROM | ||
| 101 | + <choose> | ||
| 102 | + <when test="deviceKey != null and deviceKey != ''"> | ||
| 103 | + device_log_${deviceKey} | ||
| 104 | + </when> | ||
| 105 | + <otherwise> | ||
| 106 | + device_log | ||
| 107 | + </otherwise> | ||
| 108 | + </choose> | ||
| 109 | + <where> | ||
| 110 | + <if test="startTime != null"> | ||
| 111 | + AND ts >= #{startTime} | ||
| 112 | + </if> | ||
| 113 | + <if test="endTime != null"> | ||
| 114 | + AND ts <= #{endTime} | ||
| 115 | + </if> | ||
| 116 | + AND identifier IN ('set', 'get', 'upgrade', 'unregister_sub', 'topology_add') | ||
| 117 | + </where> | ||
| 118 | + GROUP BY TIMETRUNCATE(ts, 1h) | ||
| 119 | + ORDER BY time ASC | ||
| 120 | + </select> | ||
| 121 | + | ||
| 58 | </mapper> | 122 | </mapper> |
| 59 | \ No newline at end of file | 123 | \ No newline at end of file |
yudao-server/src/main/resources/application-local.yaml
| @@ -78,10 +78,10 @@ spring: | @@ -78,10 +78,10 @@ spring: | ||
| 78 | # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 | 78 | # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 |
| 79 | data: | 79 | data: |
| 80 | redis: | 80 | redis: |
| 81 | - host: 127.0.0.1 # 地址 | 81 | + host: chaojiniu.top # 地址 |
| 82 | port: 6379 # 端口 | 82 | port: 6379 # 端口 |
| 83 | - database: 1 # 数据库索引 | ||
| 84 | - # password: 123456 # 密码,建议生产环境开启 | 83 | + database: 15 # 数据库索引 |
| 84 | + password: fsknKD7UvQYZsyf2hXXn # 密码,建议生产环境开启 | ||
| 85 | 85 | ||
| 86 | --- #################### 定时任务相关配置 #################### | 86 | --- #################### 定时任务相关配置 #################### |
| 87 | 87 |