2026.1.13提交最终版(2)
This commit is contained in:
@@ -381,358 +381,6 @@ public class AppTrafficController {
|
||||
", Records: " + dto.getRecordCount());
|
||||
}
|
||||
System.out.println("================================================");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计各手机网络质量使用情况,支持按运营商、网络制式、流量范围和日期范围筛选
|
||||
* @param request 查询请求参数,所有字段均为可选
|
||||
* @return 手机网络质量使用情况统计列表,按总流量降序排列
|
||||
*/
|
||||
@PostMapping("/appTraffic/phoneQuality")
|
||||
public List<com.bigdata.dto.PhoneQualityUsageDTO> 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<com.bigdata.dto.PhoneQualityUsageDTO> 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<com.bigdata.dto.PhoneTrafficRatioDTO> 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<com.bigdata.dto.PhoneTrafficRatioDTO> 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<com.bigdata.dto.OsTrafficRatioDTO> 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<com.bigdata.dto.OsTrafficRatioDTO> 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<com.bigdata.dto.PhoneTrafficRegionTopDTO> getPhoneRegionTop(
|
||||
@RequestBody(required = false) com.bigdata.dto.PhoneTrafficRegionTopRequest request) {
|
||||
// 如果请求体为空,创建默认请求对象
|
||||
if (request == null) {
|
||||
request = new com.bigdata.dto.PhoneTrafficRegionTopRequest();
|
||||
}
|
||||
|
||||
// 查询区域top1 热门手机
|
||||
List<com.bigdata.dto.PhoneTrafficRegionTopDTO> 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<com.bigdata.dto.OsTrafficRegionTopDTO> getOsRegionTop(
|
||||
@RequestBody(required = false) com.bigdata.dto.OsTrafficRegionTopRequest request) {
|
||||
// 如果请求体为空,创建默认请求对象
|
||||
if (request == null) {
|
||||
request = new com.bigdata.dto.OsTrafficRegionTopRequest();
|
||||
}
|
||||
|
||||
// 查询区域top1 手机OS
|
||||
List<com.bigdata.dto.OsTrafficRegionTopDTO> 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;
|
||||
}
|
||||
|
||||
@@ -147,95 +147,6 @@ public class AppTrafficServiceImpl implements AppTrafficService {
|
||||
startDate, endDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<com.bigdata.dto.PhoneTrafficRatioDTO> getPhoneTrafficRatio(
|
||||
String operator,
|
||||
String networkType,
|
||||
Double minUploadTraffic,
|
||||
Double maxUploadTraffic,
|
||||
Double minDownloadTraffic,
|
||||
Double maxDownloadTraffic,
|
||||
String startDate,
|
||||
String endDate) {
|
||||
List<com.bigdata.dto.PhoneTrafficRatioDTO> 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<com.bigdata.dto.OsTrafficRatioDTO> getOsTrafficRatio(
|
||||
String operator,
|
||||
String networkType,
|
||||
Double minUploadTraffic,
|
||||
Double maxUploadTraffic,
|
||||
Double minDownloadTraffic,
|
||||
Double maxDownloadTraffic,
|
||||
String startDate,
|
||||
String endDate) {
|
||||
List<com.bigdata.dto.OsTrafficRatioDTO> 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<com.bigdata.dto.PhoneQualityUsageDTO> 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<com.bigdata.dto.PhoneTrafficRatioDTO> getPhoneTrafficRatio(
|
||||
String operator,
|
||||
@@ -872,385 +783,6 @@ public class AppTrafficServiceImpl implements AppTrafficService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<com.bigdata.dto.PhoneTrafficRegionTopDTO> 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<AppTraffic> 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<Double> validLons = new ArrayList<>();
|
||||
List<Double> 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<String, Map<String, Double>> regionPhoneTrafficMap = new HashMap<>();
|
||||
Map<String, Long> regionRecordCountMap = new HashMap<>();
|
||||
Map<String, String> phoneOsMap = new HashMap<>(); // 存储手机型号对应的OS
|
||||
Map<String, String> 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<com.bigdata.dto.PhoneTrafficRegionTopDTO> result = new ArrayList<>();
|
||||
|
||||
for (int row = 0; row < gridRows; row++) {
|
||||
for (int col = 0; col < gridCols; col++) {
|
||||
String regionKey = row + "_" + col;
|
||||
Map<String, Double> phoneTrafficMap = regionPhoneTrafficMap.get(regionKey);
|
||||
|
||||
if (phoneTrafficMap == null || phoneTrafficMap.isEmpty()) {
|
||||
continue; // 该区域没有数据,跳过
|
||||
}
|
||||
|
||||
// 找出流量最大的手机
|
||||
Map.Entry<String, Double> 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<com.bigdata.dto.OsTrafficRegionTopDTO> 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<AppTraffic> 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<Double> validLons = new ArrayList<>();
|
||||
List<Double> 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<String, Map<String, Double>> regionOsTrafficMap = new HashMap<>();
|
||||
Map<String, Long> regionRecordCountMap = new HashMap<>();
|
||||
Map<String, String> 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<com.bigdata.dto.OsTrafficRegionTopDTO> result = new ArrayList<>();
|
||||
|
||||
for (int row = 0; row < gridRows; row++) {
|
||||
for (int col = 0; col < gridCols; col++) {
|
||||
String regionKey = row + "_" + col;
|
||||
Map<String, Double> osTrafficMap = regionOsTrafficMap.get(regionKey);
|
||||
|
||||
if (osTrafficMap == null || osTrafficMap.isEmpty()) {
|
||||
continue; // 该区域没有数据,跳过
|
||||
}
|
||||
|
||||
// 找出流量最大的OS
|
||||
Map.Entry<String, Double> 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user