From 006c9c841ea5d7c5f9a8fe8e6875b3e78fc56223 Mon Sep 17 00:00:00 2001 From: wangran <3189505710@qq.com> Date: Tue, 13 Jan 2026 20:22:33 +0800 Subject: [PATCH] =?UTF-8?q?2026.1.13=E6=8F=90=E4=BA=A4=E6=9C=80=E7=BB=88?= =?UTF-8?q?=E7=89=88(2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AppTrafficController.java | 352 ------------- .../service/impl/AppTrafficServiceImpl.java | 468 ------------------ 2 files changed, 820 deletions(-) diff --git a/src/main/java/com/bigdata/controller/AppTrafficController.java b/src/main/java/com/bigdata/controller/AppTrafficController.java index ce6fd3a..f71a9cc 100644 --- a/src/main/java/com/bigdata/controller/AppTrafficController.java +++ b/src/main/java/com/bigdata/controller/AppTrafficController.java @@ -381,358 +381,6 @@ public class AppTrafficController { ", Records: " + dto.getRecordCount()); } System.out.println("================================================"); - - return result; - } - - /** - * 统计各手机网络质量使用情况,支持按运营商、网络制式、流量范围和日期范围筛选 - * @param request 查询请求参数,所有字段均为可选 - * @return 手机网络质量使用情况统计列表,按总流量降序排列 - */ - @PostMapping("/appTraffic/phoneQuality") - public List getPhoneQualityUsage( - @RequestBody(required = false) com.bigdata.dto.PhoneQualityUsageRequest request) { - // 如果请求体为空,创建默认请求对象 - if (request == null) { - request = new com.bigdata.dto.PhoneQualityUsageRequest(); - } - - String operator = null; - String networkType = null; - Double minUploadTraffic = null; - Double maxUploadTraffic = null; - Double minDownloadTraffic = null; - Double maxDownloadTraffic = null; - String startDate = null; - String endDate = null; - - // 处理运营商参数:ALL 或不传表示查询所有 - if (request.getOperator() != null && !request.getOperator().trim().isEmpty()) { - String op = request.getOperator().trim().toUpperCase(); - if (!"ALL".equals(op)) { - operator = op; - } - } - - // 处理网络制式 - if (request.getNetworkType() != null && !request.getNetworkType().trim().isEmpty()) { - networkType = request.getNetworkType().trim(); - } - - // 处理流量范围 - if (request.getMinUploadTraffic() != null) { - minUploadTraffic = request.getMinUploadTraffic(); - } - if (request.getMaxUploadTraffic() != null) { - maxUploadTraffic = request.getMaxUploadTraffic(); - } - if (request.getMinDownloadTraffic() != null) { - minDownloadTraffic = request.getMinDownloadTraffic(); - } - if (request.getMaxDownloadTraffic() != null) { - maxDownloadTraffic = request.getMaxDownloadTraffic(); - } - - // 处理日期范围:将 yyyy-MM-dd 格式转换为 yyyyMMdd - if (request.getStartDate() != null && !request.getStartDate().trim().isEmpty()) { - startDate = request.getStartDate().trim().replace("-", ""); - } - if (request.getEndDate() != null && !request.getEndDate().trim().isEmpty()) { - endDate = request.getEndDate().trim().replace("-", ""); - } - - // 查询手机网络质量使用情况统计 - List result = - appTrafficService.getPhoneQualityUsage( - operator, networkType, - minUploadTraffic, maxUploadTraffic, - minDownloadTraffic, maxDownloadTraffic, - startDate, endDate); - - // 打印到控制台 - System.out.println("====== app_traffic phone quality statistics ======"); - System.out.println("Operator: " + (operator != null ? operator : "ALL")); - System.out.println("Network Type: " + (networkType != null ? networkType : "ALL")); - System.out.println("Upload Traffic Range: " + - (minUploadTraffic != null ? minUploadTraffic : "MIN") + " ~ " + - (maxUploadTraffic != null ? maxUploadTraffic : "MAX")); - System.out.println("Download Traffic Range: " + - (minDownloadTraffic != null ? minDownloadTraffic : "MIN") + " ~ " + - (maxDownloadTraffic != null ? maxDownloadTraffic : "MAX")); - System.out.println("Start Date: " + (startDate != null ? startDate : "ALL")); - System.out.println("End Date: " + (endDate != null ? endDate : "ALL")); - System.out.println("Total phones: " + result.size()); - for (com.bigdata.dto.PhoneQualityUsageDTO dto : result) { - System.out.println("Phone: " + dto.getPhoneModel() + - ", OS: " + dto.getOs() + - ", OS Version: " + dto.getOsVersion() + - ", Operator: " + dto.getOperator() + - ", Total Traffic: " + dto.getTotalTraffic() + - ", Records: " + dto.getRecordCount()); - } - System.out.println("================================================"); - - return result; - } - - /** - * 统计各手机流量占比,支持按运营商、网络制式、流量范围和日期范围筛选 - * @param request 查询请求参数,所有字段均为可选 - * @return 手机流量占比统计列表,按总流量降序排列 - */ - @PostMapping("/appTraffic/phoneTrafficRatio") - public List getPhoneTrafficRatio( - @RequestBody(required = false) AppTrafficQueryRequest request) { - // 如果请求体为空,创建默认请求对象 - if (request == null) { - request = new AppTrafficQueryRequest(); - } - - String operator = null; - String networkType = null; - Double minUploadTraffic = null; - Double maxUploadTraffic = null; - Double minDownloadTraffic = null; - Double maxDownloadTraffic = null; - String startDate = null; - String endDate = null; - - // 处理运营商参数:ALL 或不传表示查询所有 - if (request.getOperator() != null && !request.getOperator().trim().isEmpty()) { - String op = request.getOperator().trim().toUpperCase(); - if (!"ALL".equals(op)) { - operator = op; - } - } - - // 处理网络制式 - if (request.getNetworkType() != null && !request.getNetworkType().trim().isEmpty()) { - networkType = request.getNetworkType().trim(); - } - - // 处理流量范围 - if (request.getMinUploadTraffic() != null) { - minUploadTraffic = request.getMinUploadTraffic(); - } - if (request.getMaxUploadTraffic() != null) { - maxUploadTraffic = request.getMaxUploadTraffic(); - } - if (request.getMinDownloadTraffic() != null) { - minDownloadTraffic = request.getMinDownloadTraffic(); - } - if (request.getMaxDownloadTraffic() != null) { - maxDownloadTraffic = request.getMaxDownloadTraffic(); - } - - // 处理日期范围:将 yyyy-MM-dd 格式转换为 yyyyMMdd - if (request.getStartDate() != null && !request.getStartDate().trim().isEmpty()) { - startDate = request.getStartDate().trim().replace("-", ""); - } - if (request.getEndDate() != null && !request.getEndDate().trim().isEmpty()) { - endDate = request.getEndDate().trim().replace("-", ""); - } - - // 查询手机流量占比统计 - List result = - appTrafficService.getPhoneTrafficRatio( - operator, networkType, - minUploadTraffic, maxUploadTraffic, - minDownloadTraffic, maxDownloadTraffic, - startDate, endDate); - - // 打印到控制台 - System.out.println("====== app_traffic phone traffic ratio statistics ======"); - System.out.println("Operator: " + (operator != null ? operator : "ALL")); - System.out.println("Network Type: " + (networkType != null ? networkType : "ALL")); - System.out.println("Upload Traffic Range: " + - (minUploadTraffic != null ? minUploadTraffic : "MIN") + " ~ " + - (maxUploadTraffic != null ? maxUploadTraffic : "MAX")); - System.out.println("Download Traffic Range: " + - (minDownloadTraffic != null ? minDownloadTraffic : "MIN") + " ~ " + - (maxDownloadTraffic != null ? maxDownloadTraffic : "MAX")); - System.out.println("Start Date: " + (startDate != null ? startDate : "ALL")); - System.out.println("End Date: " + (endDate != null ? endDate : "ALL")); - System.out.println("Total phones: " + result.size()); - for (com.bigdata.dto.PhoneTrafficRatioDTO dto : result) { - System.out.println("Phone: " + dto.getPhoneModel() + - ", OS: " + dto.getOs() + - ", OS Version: " + dto.getOsVersion() + - ", Operator: " + dto.getOperator() + - ", Total Traffic: " + dto.getTotalTraffic() + - ", Ratio: " + dto.getTrafficRatio() + "%" + - ", Records: " + dto.getRecordCount()); - } - System.out.println("================================================"); - - return result; - } - - /** - * 统计各操作系统流量占比,支持按运营商、网络制式、流量范围和日期范围筛选 - * @param request 查询请求参数,所有字段均为可选 - * @return 操作系统流量占比统计列表,按总流量降序排列 - */ - @PostMapping("/appTraffic/osTrafficRatio") - public List getOsTrafficRatio( - @RequestBody(required = false) AppTrafficQueryRequest request) { - // 如果请求体为空,创建默认请求对象 - if (request == null) { - request = new AppTrafficQueryRequest(); - } - - String operator = null; - String networkType = null; - Double minUploadTraffic = null; - Double maxUploadTraffic = null; - Double minDownloadTraffic = null; - Double maxDownloadTraffic = null; - String startDate = null; - String endDate = null; - - // 处理运营商参数:ALL 或不传表示查询所有 - if (request.getOperator() != null && !request.getOperator().trim().isEmpty()) { - String op = request.getOperator().trim().toUpperCase(); - if (!"ALL".equals(op)) { - operator = op; - } - } - - // 处理网络制式 - if (request.getNetworkType() != null && !request.getNetworkType().trim().isEmpty()) { - networkType = request.getNetworkType().trim(); - } - - // 处理流量范围 - if (request.getMinUploadTraffic() != null) { - minUploadTraffic = request.getMinUploadTraffic(); - } - if (request.getMaxUploadTraffic() != null) { - maxUploadTraffic = request.getMaxUploadTraffic(); - } - if (request.getMinDownloadTraffic() != null) { - minDownloadTraffic = request.getMinDownloadTraffic(); - } - if (request.getMaxDownloadTraffic() != null) { - maxDownloadTraffic = request.getMaxDownloadTraffic(); - } - - // 处理日期范围:将 yyyy-MM-dd 格式转换为 yyyyMMdd - if (request.getStartDate() != null && !request.getStartDate().trim().isEmpty()) { - startDate = request.getStartDate().trim().replace("-", ""); - } - if (request.getEndDate() != null && !request.getEndDate().trim().isEmpty()) { - endDate = request.getEndDate().trim().replace("-", ""); - } - - // 查询操作系统流量占比统计 - List result = - appTrafficService.getOsTrafficRatio( - operator, networkType, - minUploadTraffic, maxUploadTraffic, - minDownloadTraffic, maxDownloadTraffic, - startDate, endDate); - - // 打印到控制台 - System.out.println("====== app_traffic os traffic ratio statistics ======"); - System.out.println("Operator: " + (operator != null ? operator : "ALL")); - System.out.println("Network Type: " + (networkType != null ? networkType : "ALL")); - System.out.println("Upload Traffic Range: " + - (minUploadTraffic != null ? minUploadTraffic : "MIN") + " ~ " + - (maxUploadTraffic != null ? maxUploadTraffic : "MAX")); - System.out.println("Download Traffic Range: " + - (minDownloadTraffic != null ? minDownloadTraffic : "MIN") + " ~ " + - (maxDownloadTraffic != null ? maxDownloadTraffic : "MAX")); - System.out.println("Start Date: " + (startDate != null ? startDate : "ALL")); - System.out.println("End Date: " + (endDate != null ? endDate : "ALL")); - System.out.println("Total OS: " + result.size()); - for (com.bigdata.dto.OsTrafficRatioDTO dto : result) { - System.out.println("OS: " + dto.getOsName() + - ", OS: " + dto.getOs() + - ", OS Version: " + dto.getOsVersion() + - ", Operator: " + dto.getOperator() + - ", Total Traffic: " + dto.getTotalTraffic() + - ", Ratio: " + dto.getTrafficRatio() + "%" + - ", Records: " + dto.getRecordCount()); - } - System.out.println("================================================"); - - return result; - } - - /** - * 统计可视区域内每个区域的流量top1 热门手机 - * 将可视区域划分为300个矩形(20x15),返回每个区域的top1 热门手机 - * @param request 查询请求参数,包含运营商、网络制式、流量范围、日期范围、可视区域范围等 - * @return 各区域的top1 热门手机统计列表 - */ - @PostMapping("/appTraffic/phoneRegionTop") - public List getPhoneRegionTop( - @RequestBody(required = false) com.bigdata.dto.PhoneTrafficRegionTopRequest request) { - // 如果请求体为空,创建默认请求对象 - if (request == null) { - request = new com.bigdata.dto.PhoneTrafficRegionTopRequest(); - } - - // 查询区域top1 热门手机 - List result = appTrafficService.getPhoneRegionTop(request); - - // 打印到控制台 - System.out.println("====== app_traffic phone region top1 statistics ======"); - System.out.println("Operator: " + (request.getOperator() != null ? request.getOperator() : "ALL")); - System.out.println("Network Type: " + (request.getNetworkType() != null ? request.getNetworkType() : "ALL")); - System.out.println("Start Date: " + (request.getStartDate() != null ? request.getStartDate() : "ALL")); - System.out.println("End Date: " + (request.getEndDate() != null ? request.getEndDate() : "ALL")); - System.out.println("Grid: " + request.getGridRows() + "x" + request.getGridCols() + " = " + - (request.getGridRows() * request.getGridCols()) + " regions"); - System.out.println("Total regions with data: " + result.size()); - for (com.bigdata.dto.PhoneTrafficRegionTopDTO dto : result) { - System.out.println("Region [" + dto.getRowIndex() + "," + dto.getColIndex() + - "] (" + dto.getCenterLat() + "," + dto.getCenterLon() + - ") Top1: " + dto.getPhoneModel() + - " (OS: " + dto.getOs() + ", Version: " + dto.getOsVersion() + ")" + - ", Traffic: " + dto.getTotalTraffic() + - ", Records: " + dto.getRecordCount()); - } - System.out.println("================================================"); - - return result; - } - - /** - * 统计可视区域内每个区域的流量top1 手机OS - * 将可视区域划分为300个矩形(20x15),返回每个区域的top1 手机OS - * @param request 查询请求参数,包含运营商、网络制式、流量范围、日期范围、可视区域范围等 - * @return 各区域的top1 手机OS统计列表 - */ - @PostMapping("/appTraffic/osRegionTop") - public List getOsRegionTop( - @RequestBody(required = false) com.bigdata.dto.OsTrafficRegionTopRequest request) { - // 如果请求体为空,创建默认请求对象 - if (request == null) { - request = new com.bigdata.dto.OsTrafficRegionTopRequest(); - } - - // 查询区域top1 手机OS - List result = appTrafficService.getOsRegionTop(request); - - // 打印到控制台 - System.out.println("====== app_traffic OS region top1 statistics ======"); - System.out.println("Operator: " + (request.getOperator() != null ? request.getOperator() : "ALL")); - System.out.println("Network Type: " + (request.getNetworkType() != null ? request.getNetworkType() : "ALL")); - System.out.println("Start Date: " + (request.getStartDate() != null ? request.getStartDate() : "ALL")); - System.out.println("End Date: " + (request.getEndDate() != null ? request.getEndDate() : "ALL")); - System.out.println("Grid: " + request.getGridRows() + "x" + request.getGridCols() + " = " + - (request.getGridRows() * request.getGridCols()) + " regions"); - System.out.println("Total regions with data: " + result.size()); - for (com.bigdata.dto.OsTrafficRegionTopDTO dto : result) { - System.out.println("Region [" + dto.getRowIndex() + "," + dto.getColIndex() + - "] (" + dto.getCenterLat() + "," + dto.getCenterLon() + - ") Top1: " + dto.getOsName() + - ", Traffic: " + dto.getTotalTraffic() + - ", Records: " + dto.getRecordCount()); - } - System.out.println("================================================"); return result; } diff --git a/src/main/java/com/bigdata/service/impl/AppTrafficServiceImpl.java b/src/main/java/com/bigdata/service/impl/AppTrafficServiceImpl.java index 33f9326..374da0d 100644 --- a/src/main/java/com/bigdata/service/impl/AppTrafficServiceImpl.java +++ b/src/main/java/com/bigdata/service/impl/AppTrafficServiceImpl.java @@ -147,95 +147,6 @@ public class AppTrafficServiceImpl implements AppTrafficService { startDate, endDate); } - @Override - public List getPhoneTrafficRatio( - String operator, - String networkType, - Double minUploadTraffic, - Double maxUploadTraffic, - Double minDownloadTraffic, - Double maxDownloadTraffic, - String startDate, - String endDate) { - List result = appTrafficMapper.selectPhoneTrafficRatio( - operator, networkType, - minUploadTraffic, maxUploadTraffic, - minDownloadTraffic, maxDownloadTraffic, - startDate, endDate); - - // 计算总流量,用于计算占比 - double totalTrafficSum = result.stream() - .mapToDouble(dto -> dto.getTotalTraffic() != null ? dto.getTotalTraffic() : 0.0) - .sum(); - - // 计算每个手机的流量占比 - if (totalTrafficSum > 0) { - for (com.bigdata.dto.PhoneTrafficRatioDTO dto : result) { - if (dto.getTotalTraffic() != null && dto.getTotalTraffic() > 0) { - double ratio = (dto.getTotalTraffic() / totalTrafficSum) * 100.0; - dto.setTrafficRatio(Math.round(ratio * 100.0) / 100.0); // 保留2位小数 - } else { - dto.setTrafficRatio(0.0); - } - } - } - - return result; - } - - @Override - public List getOsTrafficRatio( - String operator, - String networkType, - Double minUploadTraffic, - Double maxUploadTraffic, - Double minDownloadTraffic, - Double maxDownloadTraffic, - String startDate, - String endDate) { - List result = appTrafficMapper.selectOsTrafficRatio( - operator, networkType, - minUploadTraffic, maxUploadTraffic, - minDownloadTraffic, maxDownloadTraffic, - startDate, endDate); - - // 计算总流量,用于计算占比 - double totalTrafficSum = result.stream() - .mapToDouble(dto -> dto.getTotalTraffic() != null ? dto.getTotalTraffic() : 0.0) - .sum(); - - // 计算每个操作系统的流量占比 - if (totalTrafficSum > 0) { - for (com.bigdata.dto.OsTrafficRatioDTO dto : result) { - if (dto.getTotalTraffic() != null && dto.getTotalTraffic() > 0) { - double ratio = (dto.getTotalTraffic() / totalTrafficSum) * 100.0; - dto.setTrafficRatio(Math.round(ratio * 100.0) / 100.0); // 保留2位小数 - } else { - dto.setTrafficRatio(0.0); - } - } - } - - return result; - } - - @Override - public List getPhoneQualityUsage( - String operator, - String networkType, - Double minUploadTraffic, - Double maxUploadTraffic, - Double minDownloadTraffic, - Double maxDownloadTraffic, - String startDate, - String endDate) { - return appTrafficMapper.selectPhoneQualityUsage( - operator, networkType, - minUploadTraffic, maxUploadTraffic, - minDownloadTraffic, maxDownloadTraffic, - startDate, endDate); - } - @Override public List getPhoneTrafficRatio( String operator, @@ -872,385 +783,6 @@ public class AppTrafficServiceImpl implements AppTrafficService { } } } - - return result; - } - - @Override - public List getPhoneRegionTop(com.bigdata.dto.PhoneTrafficRegionTopRequest request) { - // 1. 准备查询参数 - String operator = null; - if (request.getOperator() != null && !request.getOperator().trim().isEmpty() && !"ALL".equals(request.getOperator().trim().toUpperCase())) { - operator = request.getOperator().trim().toUpperCase(); - } - - String networkType = request.getNetworkType(); - Double minUploadTraffic = request.getMinUploadTraffic(); - Double maxUploadTraffic = request.getMaxUploadTraffic(); - Double minDownloadTraffic = request.getMinDownloadTraffic(); - Double maxDownloadTraffic = request.getMaxDownloadTraffic(); - String startDate = request.getStartDate() != null ? request.getStartDate().replace("-", "") : null; - String endDate = request.getEndDate() != null ? request.getEndDate().replace("-", "") : null; - - // 2. 查询数据 - List dataList = appTrafficMapper.selectByCondition( - operator, networkType, null, - minUploadTraffic, maxUploadTraffic, - minDownloadTraffic, maxDownloadTraffic, - startDate, endDate); - - if (dataList == null || dataList.isEmpty()) { - return new ArrayList<>(); - } - - // 3. 确定可视区域范围 - Double minLon = request.getMinLon(); - Double maxLon = request.getMaxLon(); - Double minLat = request.getMinLat(); - Double maxLat = request.getMaxLat(); - - if (minLon == null || maxLon == null || minLat == null || maxLat == null) { - // 如果没有指定范围,从数据中计算 - List validLons = new ArrayList<>(); - List validLats = new ArrayList<>(); - - for (AppTraffic traffic : dataList) { - try { - if (traffic.getUserLon() != null && !traffic.getUserLon().trim().isEmpty()) { - validLons.add(Double.parseDouble(traffic.getUserLon())); - } - if (traffic.getUserLat() != null && !traffic.getUserLat().trim().isEmpty()) { - validLats.add(Double.parseDouble(traffic.getUserLat())); - } - } catch (NumberFormatException e) { - // 忽略无效的经纬度数据 - } - } - - // 如果没有有效的经纬度数据,返回空列表 - if (validLons.isEmpty() || validLats.isEmpty()) { - return new ArrayList<>(); - } - - minLon = validLons.stream().mapToDouble(Double::doubleValue).min().orElse(116.0); - maxLon = validLons.stream().mapToDouble(Double::doubleValue).max().orElse(117.0); - minLat = validLats.stream().mapToDouble(Double::doubleValue).min().orElse(39.0); - maxLat = validLats.stream().mapToDouble(Double::doubleValue).max().orElse(40.0); - - // 如果范围太小,扩展一点 - if (maxLon - minLon < 0.001) { - double centerLon = (minLon + maxLon) / 2.0; - minLon = centerLon - 0.01; - maxLon = centerLon + 0.01; - } - if (maxLat - minLat < 0.001) { - double centerLat = (minLat + maxLat) / 2.0; - minLat = centerLat - 0.01; - maxLat = centerLat + 0.01; - } - } - - // 4. 网格参数 - int gridRows = request.getGridRows() != null ? request.getGridRows() : 20; - int gridCols = request.getGridCols() != null ? request.getGridCols() : 15; - - // 确保范围有效 - if (maxLon <= minLon || maxLat <= minLat) { - return new ArrayList<>(); - } - - double lonStep = (maxLon - minLon) / gridCols; - double latStep = (maxLat - minLat) / gridRows; - - // 确保步长不为0 - if (lonStep <= 0 || latStep <= 0) { - return new ArrayList<>(); - } - - // 5. 按区域分组统计(按手机型号分组) - Map> regionPhoneTrafficMap = new HashMap<>(); - Map regionRecordCountMap = new HashMap<>(); - Map phoneOsMap = new HashMap<>(); // 存储手机型号对应的OS - Map phoneOsVersionMap = new HashMap<>(); // 存储手机型号对应的OS_ANDVERSION - - for (AppTraffic traffic : dataList) { - if (traffic.getUserLon() == null || traffic.getUserLon().trim().isEmpty() || - traffic.getUserLat() == null || traffic.getUserLat().trim().isEmpty()) { - continue; - } - - try { - double lon = Double.parseDouble(traffic.getUserLon()); - double lat = Double.parseDouble(traffic.getUserLat()); - - // 检查是否在可视区域内 - if (lon < minLon || lon > maxLon || lat < minLat || lat > maxLat) { - continue; - } - - // 计算所属区域 - int colIndex = Math.min((int) ((lon - minLon) / lonStep), gridCols - 1); - int rowIndex = Math.min((int) ((lat - minLat) / latStep), gridRows - 1); - - String regionKey = rowIndex + "_" + colIndex; - - // 构建手机型号key(OS + OS_ANDVERSION) - // 注意:实体类中osVersion字段对应数据库的OS_ANDVERSION列 - String os = traffic.getOs() != null ? traffic.getOs() : ""; - String osAndVersion = traffic.getOsVersion() != null ? traffic.getOsVersion() : ""; - String phoneKey = (os.toLowerCase() + osAndVersion).trim(); - - if (phoneKey.isEmpty()) { - continue; // 跳过没有OS信息的记录 - } - - // 计算总流量 - double totalTraffic = (traffic.getUploadTraffic() != null ? traffic.getUploadTraffic() : 0.0) + - (traffic.getDownloadTraffic() != null ? traffic.getDownloadTraffic() : 0.0); - - // 累计流量 - regionPhoneTrafficMap.computeIfAbsent(regionKey, k -> new HashMap<>()) - .merge(phoneKey, totalTraffic, Double::sum); - - regionRecordCountMap.merge(regionKey, 1L, Long::sum); - - // 保存手机型号对应的OS和OS_ANDVERSION - phoneOsMap.put(phoneKey, os); - phoneOsVersionMap.put(phoneKey, osAndVersion); - } catch (NumberFormatException e) { - // 忽略无效的经纬度数据 - continue; - } - } - - // 6. 找出每个区域的top1 热门手机 - List result = new ArrayList<>(); - - for (int row = 0; row < gridRows; row++) { - for (int col = 0; col < gridCols; col++) { - String regionKey = row + "_" + col; - Map phoneTrafficMap = regionPhoneTrafficMap.get(regionKey); - - if (phoneTrafficMap == null || phoneTrafficMap.isEmpty()) { - continue; // 该区域没有数据,跳过 - } - - // 找出流量最大的手机 - Map.Entry topPhone = phoneTrafficMap.entrySet().stream() - .max(Map.Entry.comparingByValue()) - .orElse(null); - - if (topPhone != null) { - String phoneKey = topPhone.getKey(); - String os = phoneOsMap.getOrDefault(phoneKey, ""); - String osVersion = phoneOsVersionMap.getOrDefault(phoneKey, ""); - String phoneModel = (os.toLowerCase() + osVersion).trim(); - - // 计算区域中心点 - double centerLon = minLon + (col + 0.5) * lonStep; - double centerLat = minLat + (row + 0.5) * latStep; - - com.bigdata.dto.PhoneTrafficRegionTopDTO dto = new com.bigdata.dto.PhoneTrafficRegionTopDTO(); - dto.setRowIndex(row); - dto.setColIndex(col); - dto.setCenterLon(centerLon); - dto.setCenterLat(centerLat); - dto.setPhoneModel(phoneModel); - dto.setOs(os); - dto.setOsVersion(osVersion); - dto.setTotalTraffic(topPhone.getValue()); - dto.setRecordCount(regionRecordCountMap.getOrDefault(regionKey, 0L)); - - result.add(dto); - } - } - } - - return result; - } - - @Override - public List getOsRegionTop(com.bigdata.dto.OsTrafficRegionTopRequest request) { - // 1. 准备查询参数 - String operator = null; - if (request.getOperator() != null && !request.getOperator().trim().isEmpty() && !"ALL".equals(request.getOperator().trim().toUpperCase())) { - operator = request.getOperator().trim().toUpperCase(); - } - - String networkType = request.getNetworkType(); - Double minUploadTraffic = request.getMinUploadTraffic(); - Double maxUploadTraffic = request.getMaxUploadTraffic(); - Double minDownloadTraffic = request.getMinDownloadTraffic(); - Double maxDownloadTraffic = request.getMaxDownloadTraffic(); - String startDate = request.getStartDate() != null ? request.getStartDate().replace("-", "") : null; - String endDate = request.getEndDate() != null ? request.getEndDate().replace("-", "") : null; - - // 2. 查询数据 - List dataList = appTrafficMapper.selectByCondition( - operator, networkType, null, - minUploadTraffic, maxUploadTraffic, - minDownloadTraffic, maxDownloadTraffic, - startDate, endDate); - - if (dataList == null || dataList.isEmpty()) { - return new ArrayList<>(); - } - - // 3. 确定可视区域范围 - Double minLon = request.getMinLon(); - Double maxLon = request.getMaxLon(); - Double minLat = request.getMinLat(); - Double maxLat = request.getMaxLat(); - - if (minLon == null || maxLon == null || minLat == null || maxLat == null) { - // 如果没有指定范围,从数据中计算 - List validLons = new ArrayList<>(); - List validLats = new ArrayList<>(); - - for (AppTraffic traffic : dataList) { - try { - if (traffic.getUserLon() != null && !traffic.getUserLon().trim().isEmpty()) { - validLons.add(Double.parseDouble(traffic.getUserLon())); - } - if (traffic.getUserLat() != null && !traffic.getUserLat().trim().isEmpty()) { - validLats.add(Double.parseDouble(traffic.getUserLat())); - } - } catch (NumberFormatException e) { - // 忽略无效的经纬度数据 - } - } - - // 如果没有有效的经纬度数据,返回空列表 - if (validLons.isEmpty() || validLats.isEmpty()) { - return new ArrayList<>(); - } - - minLon = validLons.stream().mapToDouble(Double::doubleValue).min().orElse(116.0); - maxLon = validLons.stream().mapToDouble(Double::doubleValue).max().orElse(117.0); - minLat = validLats.stream().mapToDouble(Double::doubleValue).min().orElse(39.0); - maxLat = validLats.stream().mapToDouble(Double::doubleValue).max().orElse(40.0); - - // 如果范围太小,扩展一点 - if (maxLon - minLon < 0.001) { - double centerLon = (minLon + maxLon) / 2.0; - minLon = centerLon - 0.01; - maxLon = centerLon + 0.01; - } - if (maxLat - minLat < 0.001) { - double centerLat = (minLat + maxLat) / 2.0; - minLat = centerLat - 0.01; - maxLat = centerLat + 0.01; - } - } - - // 4. 网格参数 - int gridRows = request.getGridRows() != null ? request.getGridRows() : 20; - int gridCols = request.getGridCols() != null ? request.getGridCols() : 15; - - // 确保范围有效 - if (maxLon <= minLon || maxLat <= minLat) { - return new ArrayList<>(); - } - - double lonStep = (maxLon - minLon) / gridCols; - double latStep = (maxLat - minLat) / gridRows; - - // 确保步长不为0 - if (lonStep <= 0 || latStep <= 0) { - return new ArrayList<>(); - } - - // 5. 按区域分组统计(按OS分组) - Map> regionOsTrafficMap = new HashMap<>(); - Map regionRecordCountMap = new HashMap<>(); - Map osNameMap = new HashMap<>(); // 存储OS key对应的OS名称 - - for (AppTraffic traffic : dataList) { - if (traffic.getUserLon() == null || traffic.getUserLon().trim().isEmpty() || - traffic.getUserLat() == null || traffic.getUserLat().trim().isEmpty()) { - continue; - } - - try { - double lon = Double.parseDouble(traffic.getUserLon()); - double lat = Double.parseDouble(traffic.getUserLat()); - - // 检查是否在可视区域内 - if (lon < minLon || lon > maxLon || lat < minLat || lat > maxLat) { - continue; - } - - // 计算所属区域 - int colIndex = Math.min((int) ((lon - minLon) / lonStep), gridCols - 1); - int rowIndex = Math.min((int) ((lat - minLat) / latStep), gridRows - 1); - - String regionKey = rowIndex + "_" + colIndex; - - // 构建OS key(只按OS分组,不包含版本号) - String os = traffic.getOs() != null ? traffic.getOs() : ""; - String osKey = os.toLowerCase().trim(); - - if (osKey.isEmpty()) { - continue; // 跳过没有OS信息的记录 - } - - // 计算总流量 - double totalTraffic = (traffic.getUploadTraffic() != null ? traffic.getUploadTraffic() : 0.0) + - (traffic.getDownloadTraffic() != null ? traffic.getDownloadTraffic() : 0.0); - - // 累计流量 - regionOsTrafficMap.computeIfAbsent(regionKey, k -> new HashMap<>()) - .merge(osKey, totalTraffic, Double::sum); - - regionRecordCountMap.merge(regionKey, 1L, Long::sum); - - // 保存OS key对应的OS名称(保留原始大小写) - osNameMap.put(osKey, os); - } catch (NumberFormatException e) { - // 忽略无效的经纬度数据 - continue; - } - } - - // 6. 找出每个区域的top1 手机OS - List result = new ArrayList<>(); - - for (int row = 0; row < gridRows; row++) { - for (int col = 0; col < gridCols; col++) { - String regionKey = row + "_" + col; - Map osTrafficMap = regionOsTrafficMap.get(regionKey); - - if (osTrafficMap == null || osTrafficMap.isEmpty()) { - continue; // 该区域没有数据,跳过 - } - - // 找出流量最大的OS - Map.Entry topOs = osTrafficMap.entrySet().stream() - .max(Map.Entry.comparingByValue()) - .orElse(null); - - if (topOs != null) { - String osKey = topOs.getKey(); - String osName = osNameMap.getOrDefault(osKey, osKey); - - // 计算区域中心点 - double centerLon = minLon + (col + 0.5) * lonStep; - double centerLat = minLat + (row + 0.5) * latStep; - - com.bigdata.dto.OsTrafficRegionTopDTO dto = new com.bigdata.dto.OsTrafficRegionTopDTO(); - dto.setRowIndex(row); - dto.setColIndex(col); - dto.setCenterLon(centerLon); - dto.setCenterLat(centerLat); - dto.setOsName(osName); - dto.setOs(osName); - dto.setTotalTraffic(topOs.getValue()); - dto.setRecordCount(regionRecordCountMap.getOrDefault(regionKey, 0L)); - - result.add(dto); - } - } - } return result; }