吉安感知网项目-后端
linwei
2026-04-09 a37a8f03f3e5b4d54412b656ea32c6e623a98061
drone-service/drone-fw/src/main/java/org/sxkj/fw/cockpit/service/impl/CockpitServiceImpl.java
@@ -174,55 +174,71 @@
      return iFwDefenseSceneManageService.selectFwDefenseSceneManageList(filterTime);
   }
   /**
    * 统计场景管理与区域数量
    * <p>
    * 该方法统计指定时间下的场景管理数量和关联的区域总数。
    * 统计逻辑:
    * 1. 查询符合条件的场景管理列表
    * 2. 去重统计场景管理数量
    * 3. 获取场景管理关联的防控场景ID集合
    * 4. 查询防控场景并统计每个场景关联的区域划分数量
    * 5. 累加所有场景的区域数量得到总数
    * </p>
    *
    * @param filterTime 过滤时间,用于筛选有效的场景管理数据
    * @return 场景管理统计结果,包含场景管理数量和区域总数
    */
   @Override
   public SceneManageStatisticsVO statisticsSceneManageAndArea(Date filterTime) {
      List<FwDefenseSceneManageVO> sceneManageList = iFwDefenseSceneManageService.selectFwDefenseSceneManageCockpitList(buildFwBaseInfo(), filterTime);
      log.info("场景管理列表数据:{}", sceneManageList);
      SceneManageStatisticsVO statisticsVO = new SceneManageStatisticsVO();
      if (sceneManageList == null || sceneManageList.isEmpty()) {
         statisticsVO.setSceneManageCount(0);
         statisticsVO.setAreaCount(0);
         return statisticsVO;
      }
      Map<Long, Long> sceneManageSceneMap = new HashMap<>();
      for (FwDefenseSceneManageVO sceneManage : sceneManageList) {
         if (sceneManage == null || sceneManage.getId() == null) {
            continue;
         }
         sceneManageSceneMap.putIfAbsent(sceneManage.getId(), sceneManage.getDefenseSceneId());
      }
      statisticsVO.setSceneManageCount(sceneManageSceneMap.size());
      // 场景管理数量:按 id 去重(JOIN 可能产生重复行)
      long sceneManageCount = sceneManageList.stream()
         .filter(vo -> vo != null && vo.getId() != null)
         .map(FwDefenseSceneManageVO::getId)
         .distinct()
         .count();
      statisticsVO.setSceneManageCount((int) sceneManageCount);
      Set<Long> defenseSceneIds = new HashSet<>();
      for (Long defenseSceneId : sceneManageSceneMap.values()) {
         if (defenseSceneId != null) {
            defenseSceneIds.add(defenseSceneId);
      // 区域数量:按防控场景ID去重后,统计每个防控场景关联的区域数量
      // 同一个防控场景可能被多个场景管理引用,只计一次
      Map<Long, String> defenseSceneAreaMap = new HashMap<>();
      for (FwDefenseSceneManageVO vo : sceneManageList) {
         if (vo != null && vo.getDefenseSceneId() != null) {
            defenseSceneAreaMap.putIfAbsent(vo.getDefenseSceneId(), vo.getDefenseSceneName());
         }
      }
      if (defenseSceneIds.isEmpty()) {
      if (defenseSceneAreaMap.isEmpty()) {
         statisticsVO.setAreaCount(0);
         return statisticsVO;
      }
      List<FwDefenseSceneEntity> defenseScenes = iFwDefenseSceneService.listByIds(defenseSceneIds);
      Map<Long, Integer> sceneAreaCountMap = new HashMap<>();
      if (defenseScenes != null && !defenseScenes.isEmpty()) {
      // 批量查询防控场景,统计区域数量(同一防控场景只计一次)
      List<FwDefenseSceneEntity> defenseScenes = iFwDefenseSceneService.listByIds(defenseSceneAreaMap.keySet());
      Set<Long> countedAreaIds = new HashSet<>();
      int totalAreaCount = 0;
      if (defenseScenes != null) {
         for (FwDefenseSceneEntity scene : defenseScenes) {
            if (scene == null || scene.getId() == null) {
               continue;
            }
            sceneAreaCountMap.put(scene.getId(), countAreaDivide(scene.getAreaDivideIds()));
            List<Long> areaIds = Func.toLongList(scene.getAreaDivideIds());
            for (Long areaId : areaIds) {
               // 全局去重:同一区域ID被多个防控场景引用只计一次
               if (countedAreaIds.add(areaId)) {
                  totalAreaCount++;
         }
      }
      int totalAreaCount = 0;
      for (Long defenseSceneId : sceneManageSceneMap.values()) {
         if (defenseSceneId == null) {
            continue;
         }
         Integer areaCount = sceneAreaCountMap.get(defenseSceneId);
         if (areaCount != null) {
            totalAreaCount += areaCount;
         }
      }
      statisticsVO.setAreaCount(totalAreaCount);
@@ -269,16 +285,4 @@
      return fwBaseInfo;
   }
   /**
    * 统计逗号分隔区域ID的数量
    *
    * @param areaDivideIds 区域ID字符串
    * @return 区域数量
    */
   private int countAreaDivide(String areaDivideIds) {
      if (StringUtil.isBlank(areaDivideIds)) {
         return 0;
      }
      return Func.toLongList(areaDivideIds).size();
   }
}