Commit 2a65e3bd2e1f7d2ca27716ddd039940e31d6e09d

Authored by YunaiV
2 parents 36dd18d4 3aef51f8

Merge branch 'feature/iot' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into 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&lt;IotDeviceDO&gt; { @@ -69,4 +70,26 @@ public interface IotDeviceMapper extends BaseMapperX&lt;IotDeviceDO&gt; {
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&lt;IotProductCategory @@ -28,4 +30,15 @@ public interface IotProductCategoryMapper extends BaseMapperX&lt;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&lt;IotProductDO&gt; { @@ -28,4 +31,27 @@ public interface IotProductMapper extends BaseMapperX&lt;IotProductDO&gt; {
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&lt;IotThingModelDO&gt; { @@ -72,4 +73,15 @@ public interface IotThingModelMapper extends BaseMapperX&lt;IotThingModelDO&gt; {
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 &lt;= #{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 &lt;= #{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