ソースを参照

feat(device): 新增设备今日掉线次数统计功能

新增 DeviceDTO.offlineCount 字段用于展示设备今日掉线次数。
DevOnOffInfoService 新增 devOfflineCount 和 batchDevOfflineCount 接口,分别用于单设备和批量设备的今日掉线次数查询。
WebGatewayImpl 中调用新接口批量获取并回填设备掉线次数。
hxd 4 週間 前
コミット
994115fdf8

+ 7 - 0
portal-service-common/src/main/java/com/hfln/portal/common/dto/data/device/DeviceDTO.java

@@ -182,6 +182,13 @@ public class DeviceDTO extends BaseVO {
     @Schema(description = "设备上下线时间")
     private LocalDateTime onoffTime;
 
+
+    /**
+     * 今日掉线次数
+     */
+    @Schema(description = "今日掉线次数")
+    private Integer offlineCount;
+
     /**
      * 人物存在标志:0-无人,1-有人
      */

+ 27 - 11
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/WebGatewayImpl.java

@@ -106,6 +106,9 @@ public class WebGatewayImpl implements WebGateway {
     @Autowired
     private TblParameterService tblParameterService;
 
+    @Autowired
+    private DevOnOffInfoService devOnOffInfoService;
+
     @Override
     public void upsertParameter(ParameterUpsertParam param) {
 
@@ -242,25 +245,38 @@ public class WebGatewayImpl implements WebGateway {
                 .filter(Objects::nonNull)
                 .collect(Collectors.toSet());
 
-        //校验tenantId是否为空
-        if (CollectionUtils.isEmpty(tenantIds)) {
-            return CopyUtils.copyPage(devInfoPage, deviceDTOList);
+        // 批量查租户信息
+        Map<Long, String> tenantIdNameMap = Collections.emptyMap();
+        if (!CollectionUtils.isEmpty(tenantIds)) {
+            List<TblTenant> tenantList = tblTenantService.listByIds(tenantIds);
+            tenantIdNameMap = tenantList.stream()
+                    .collect(Collectors.toMap(TblTenant::getTenantId, TblTenant::getTenantName));
         }
 
-        // 批量查询租户信息
-        List<TblTenant> tenantList = tblTenantService.listByIds(tenantIds);
-        Map<Long, String> tenantIdNameMap = tenantList.stream()
-                .collect(Collectors.toMap(TblTenant::getTenantId, TblTenant::getTenantName));
+        // 收集所有设备的devId
+        Set<Long> devIds = deviceDTOList.stream()
+                .map(DeviceDTO::getDevId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+        // 批量查今日掉线次数
+        Map<Long, Integer> offlineCountMap = Collections.emptyMap();
+        if (!CollectionUtils.isEmpty(devIds)) {
+            offlineCountMap = devOnOffInfoService.batchDevOfflineCount(devIds);
+        }
+
+        // 一次性回填 tenantName & offlineCount
+        Map<Long, String> finalTenantIdNameMap = tenantIdNameMap;
+        Map<Long, Integer> finalOfflineCountMap = offlineCountMap;
 
-        //设置tenantName到DTO
         deviceDTOList.forEach(dto -> {
             if (dto.getTenantId() != null) {
-                dto.setTenantName(tenantIdNameMap.get(dto.getTenantId()));
+                dto.setTenantName(finalTenantIdNameMap.get(dto.getTenantId()));
             }
-
-
+            dto.setOfflineCount(finalOfflineCountMap.getOrDefault(dto.getDevId(), 0));
         });
 
+
         return CopyUtils.copyPage(devInfoPage, deviceDTOList);
     }
 

+ 16 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/DevOnOffInfoService.java

@@ -5,7 +5,23 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.hfln.portal.common.request.web.OnoffRecordParams;
 import com.hfln.portal.infrastructure.po.DevOnOffInfo;
 
+import java.util.Map;
+import java.util.Set;
+
 public interface DevOnOffInfoService extends IService<DevOnOffInfo> {
 
     Page<DevOnOffInfo> queryOnoffRecord(OnoffRecordParams params);
+
+
+    /**
+     * 单设备今日掉线次数
+     */
+    Long devOfflineCount(Long devId);
+
+    /**
+     * 批量设备今日掉线次数
+     * @param devIds 设备ID集合
+     * @return Map<devId, 今日掉线次数>
+     */
+    Map<Long, Integer> batchDevOfflineCount(Set<Long> devIds);
 }

+ 48 - 1
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/DevOnOffInfoServiceImpl.java

@@ -1,6 +1,8 @@
 package com.hfln.portal.infrastructure.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.hfln.portal.common.request.web.OnoffRecordParams;
@@ -10,7 +12,10 @@ import com.hfln.portal.infrastructure.service.DevOnOffInfoService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
-import java.util.Objects;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
 
 
 @Service
@@ -34,4 +39,46 @@ public class DevOnOffInfoServiceImpl extends ServiceImpl<DevOnOffInfoMapper, Dev
         queryWrapper.orderByDesc(DevOnOffInfo::getCreateTime);
         return this.baseMapper.selectPage(page, queryWrapper);
     }
+
+    @Override
+    public Long devOfflineCount(Long devId) {
+        //定义时间范围
+        LocalDateTime start = LocalDate.now().atStartOfDay();
+        LocalDateTime end = start.plusDays(1);
+
+        // 构建查询条件
+        LambdaQueryWrapper<DevOnOffInfo> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(DevOnOffInfo::getDevId, devId);
+        queryWrapper.eq(DevOnOffInfo::getType, "off");
+        queryWrapper.between(DevOnOffInfo::getCreateTime, start, end);
+
+        return this.baseMapper.selectCount(queryWrapper);
+    }
+
+    @Override
+    public Map<Long, Integer> batchDevOfflineCount(Set<Long> devIds) {
+        if (CollectionUtils.isEmpty(devIds)) {
+            return Collections.emptyMap();
+        }
+
+        LocalDateTime start = LocalDate.now().atStartOfDay();
+        LocalDateTime end = start.plusDays(1);
+
+        // 批量统计 SQL
+        List<Map<String, Object>> countList = this.baseMapper.selectMaps(
+                new QueryWrapper<DevOnOffInfo>()
+                        .select("dev_id, COUNT(*) AS cnt")
+                        .in("dev_id", devIds)
+                        .eq("type", "off")
+                        .between("create_time", start, end)
+                        .groupBy("dev_id")
+        );
+
+        // 转成 Map<devId, count>
+        return countList.stream()
+                .collect(Collectors.toMap(
+                        m -> (Long) m.get("dev_id"),
+                        m -> ((Long) m.get("cnt")).intValue()
+                ));
+    }
 }