|
|
@ -36,11 +36,15 @@ import javax.servlet.http.HttpServletResponse; |
|
|
|
import java.io.IOException; |
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.math.RoundingMode; |
|
|
|
import java.text.DecimalFormat; |
|
|
|
import java.time.LocalDate; |
|
|
|
import java.time.LocalDateTime; |
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
import java.time.temporal.ChronoUnit; |
|
|
|
import java.util.*; |
|
|
|
import java.util.concurrent.atomic.AtomicLong; |
|
|
|
import java.util.regex.Matcher; |
|
|
|
import java.util.regex.Pattern; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
@Api(tags = "设备在线监测") |
|
|
@ -214,23 +218,61 @@ public class DcDeviceOnlineController extends BaseController { |
|
|
|
//分类在用数
|
|
|
|
Map<String, Long> useCounts = useDeviceList.stream() |
|
|
|
.collect(Collectors.groupingBy(DcDevice::getRealType, Collectors.counting())); |
|
|
|
|
|
|
|
Map<String, List<OnlineSum>> typeSumGroup = onlineSums.stream().collect(Collectors.groupingBy(OnlineSum::getDeviceType)); |
|
|
|
//在线数量//离线数量
|
|
|
|
Map<String, Map<String, Long>> deviceCounts = useDeviceList.stream() |
|
|
|
.filter(device -> device.getDeviceState() != null) |
|
|
|
.collect(Collectors.groupingBy( |
|
|
|
DcDevice::getRealType, |
|
|
|
Collectors.groupingBy( |
|
|
|
device -> device.getDeviceState().equals("1") ? "online" : "offline", |
|
|
|
Collectors.counting() |
|
|
|
) |
|
|
|
)); |
|
|
|
// 计算总的在线和离线设备数量
|
|
|
|
// 使用原子变量来累加总的在线和离线设备数量
|
|
|
|
AtomicLong totalOnline = new AtomicLong(0L); |
|
|
|
AtomicLong totalOffline = new AtomicLong(0L); |
|
|
|
|
|
|
|
|
|
|
|
DeviceType.toMap().forEach((k, v) -> { |
|
|
|
Map<String, Object> itemMap = new HashMap<>(); |
|
|
|
itemMap.put(SUM, totalCounts.getOrDefault(k, 0L).toString());//总数
|
|
|
|
itemMap.put(SUM_USE_STATE, useCounts.getOrDefault(k, 0L).toString());//在用数
|
|
|
|
List<OnlineSum> onlineSumsOfType = typeSumGroup.getOrDefault(k, new ArrayList<>()); |
|
|
|
itemMap.put(LOST_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsOfType.stream().mapToDouble(OnlineSum::getLossRate).average().orElse(0.0)) + "%"); |
|
|
|
itemMap.put(SUCESS_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsOfType.stream().mapToDouble(OnlineSum::getOnlineRate).average().orElse(0.0)) + "%"); |
|
|
|
itemMap.put(FAIL_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsOfType.stream().mapToDouble(OnlineSum::getOfflineRate).average().orElse(0.0)) + "%"); |
|
|
|
//List<OnlineSum> onlineSumsOfType = typeSumGroup.getOrDefault(k, new ArrayList<>());
|
|
|
|
// itemMap.put(LOST_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsOfType.stream().mapToDouble(OnlineSum::getLossRate).average().orElse(0.0)) + "%");
|
|
|
|
// itemMap.put(SUCESS_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsOfType.stream().mapToDouble(OnlineSum::getOnlineRate).average().orElse(0.0)) + "%");
|
|
|
|
// itemMap.put(FAIL_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsOfType.stream().mapToDouble(OnlineSum::getOfflineRate).average().orElse(0.0)) + "%");
|
|
|
|
long onlineCount = deviceCounts.getOrDefault(k, Collections.emptyMap()).getOrDefault("online", 0L); |
|
|
|
long offlineCount = deviceCounts.getOrDefault(k, Collections.emptyMap()).getOrDefault("offline", 0L); |
|
|
|
long totalCount = onlineCount + offlineCount; |
|
|
|
// 计算在线率和离线率
|
|
|
|
double onlineRate = totalCount > 0 ? (double) onlineCount / totalCount : 0.0; |
|
|
|
double offlineRate = totalCount > 0 ? (double) offlineCount / totalCount : 0.0; |
|
|
|
itemMap.put(SUCESS_RATE, formatPercentage(onlineRate*100));//在线率
|
|
|
|
itemMap.put(FAIL_RATE, formatPercentage(offlineRate*100));//离线率
|
|
|
|
// 累加总的在线和离线设备数量
|
|
|
|
/* totalOnline.addAndGet(onlineCount); |
|
|
|
totalOffline.addAndGet(offlineCount);*/ |
|
|
|
returnMap.put(v, itemMap); |
|
|
|
}); |
|
|
|
Map<String, Object> allMap = new HashMap<>(); |
|
|
|
allMap.put(SUM, dcDeviceList.size() + "");//总数
|
|
|
|
allMap.put(SUM_USE_STATE, useDeviceList.size() + "");//在用数
|
|
|
|
allMap.put(LOST_RATE, MathUtil.doubleTwoDecimalStr(onlineSums.stream().mapToDouble(OnlineSum::getLossRate).average().orElse(0.0)) + "%"); |
|
|
|
allMap.put(SUCESS_RATE, MathUtil.doubleTwoDecimalStr(onlineSums.stream().mapToDouble(OnlineSum::getOnlineRate).average().orElse(0.0)) + "%"); |
|
|
|
allMap.put(FAIL_RATE, MathUtil.doubleTwoDecimalStr(onlineSums.stream().mapToDouble(OnlineSum::getOfflineRate).average().orElse(0.0)) + "%"); |
|
|
|
// allMap.put(LOST_RATE, MathUtil.doubleTwoDecimalStr(onlineSums.stream().mapToDouble(OnlineSum::getLossRate).average().orElse(0.0)) + "%");
|
|
|
|
// allMap.put(SUCESS_RATE, MathUtil.doubleTwoDecimalStr(onlineSums.stream().mapToDouble(OnlineSum::getOnlineRate).average().orElse(0.0)) + "%");
|
|
|
|
// allMap.put(FAIL_RATE, MathUtil.doubleTwoDecimalStr(onlineSums.stream().mapToDouble(OnlineSum::getOfflineRate).average().orElse(0.0)) + "%");
|
|
|
|
|
|
|
|
// 将总的在线和离线设备数量添加到返回结果中
|
|
|
|
Map<String, Long> totalOnlineMap = Collections.unmodifiableMap(new HashMap<String, Long>() {{ |
|
|
|
put(SUCESS_RATE, totalOnline.get()); |
|
|
|
}}); |
|
|
|
Map<String, Long> totalOfflineMap = Collections.unmodifiableMap(new HashMap<String, Long>() {{ |
|
|
|
put(FAIL_RATE, totalOffline.get()); |
|
|
|
}}); |
|
|
|
allMap.put(SUCESS_RATE, formatPercentage((totalOnlineMap.get(SUCESS_RATE)/useDeviceList.size())*100) ); |
|
|
|
allMap.put(FAIL_RATE,formatPercentage((totalOfflineMap.get(FAIL_RATE)/useDeviceList.size())*100)); |
|
|
|
returnMap.put(All_TYPE, allMap); |
|
|
|
Map<String, Object> sortMap = new TreeMap<>(); |
|
|
|
String orderRule = redisCache.getCacheObject(ORDERRULE); |
|
|
@ -242,7 +284,10 @@ public class DcDeviceOnlineController extends BaseController { |
|
|
|
returnMap.put(SORT_RULE, sortMap); |
|
|
|
return AjaxResult.success(returnMap); |
|
|
|
} |
|
|
|
|
|
|
|
private static String formatPercentage(double value) { |
|
|
|
DecimalFormat decimalFormat = new DecimalFormat("#.##"); |
|
|
|
return decimalFormat.format(value) + "%"; |
|
|
|
} |
|
|
|
//按路段统计设备在线率
|
|
|
|
@ApiOperation("设备状态列表按路段") |
|
|
|
@GetMapping("/section") |
|
|
@ -253,27 +298,109 @@ public class DcDeviceOnlineController extends BaseController { |
|
|
|
String SUM_USE_STATE = "sumUseState";//在用数
|
|
|
|
String SUM = "sum";//总数
|
|
|
|
Map<String, Object> returnMap = new HashMap<>(); |
|
|
|
List<Map<String, Object>> deviceOfRoad = dcDeviceService.selectDeviceOfRoad(); |
|
|
|
List<DcDevice> dcDeviceList = dcDeviceService.list(); |
|
|
|
List<DcRoadSection> dcRoadSections = dcRoadSectionService.selectDcRoadSectionList(new DcRoadSection()); |
|
|
|
List<OnlineSum> onlineSums = onlineSumService.queryByDateOfRoad(LocalDate.now()); |
|
|
|
Map<String, Long> totalRoadCounts = deviceOfRoad.stream() |
|
|
|
.collect(Collectors.groupingBy(m -> m.get("roadId").toString(), Collectors.counting())); |
|
|
|
Map<String, Long> useRoadCounts = deviceOfRoad.stream().filter(dr -> dr.get("useStata") != null && dr.get("useStata").toString().equals("1")) |
|
|
|
.collect(Collectors.groupingBy(m -> m.get("roadId").toString(), Collectors.counting())); |
|
|
|
Map<Long, List<OnlineSum>> onLineSumMap = onlineSums.stream().filter(onlineSum -> onlineSum.getRoadId() != null).collect(Collectors.groupingBy(OnlineSum::getRoadId)); |
|
|
|
/* // 去重设备列表
|
|
|
|
dcDeviceList = dcDeviceList.stream() |
|
|
|
.distinct() |
|
|
|
.collect(Collectors.toList());*/ |
|
|
|
// 按路段分组统计在线和离线设备数量
|
|
|
|
Map<String, Map<String, Long>> deviceCounts = new HashMap<>(); |
|
|
|
Map<String, Long> totalRoadCounts = new HashMap<>(); |
|
|
|
Map<String, Long> useRoadCounts = new HashMap<>(); |
|
|
|
for (DcRoadSection dcRoadSection : dcRoadSections) { |
|
|
|
String roadId = dcRoadSection.getId().toString(); |
|
|
|
double startStakeMark = parseStakeMark(dcRoadSection.getStartStakeMark()); |
|
|
|
double endStakeMark = parseStakeMark(dcRoadSection.getEndStakeMark()); |
|
|
|
List<DcDevice> devicesInRoad = dcDeviceList.stream() |
|
|
|
.filter(device -> isValidStakeMark(device.getStakeMark())) |
|
|
|
.filter(device -> parseStakeMark(device.getStakeMark()) >= startStakeMark && parseStakeMark(device.getStakeMark()) <= endStakeMark) |
|
|
|
.collect(Collectors.toList()); |
|
|
|
long totalDevices = devicesInRoad.size(); |
|
|
|
long useDevices = devicesInRoad.stream() |
|
|
|
.filter(device -> device.getUseState() == 1) |
|
|
|
.count(); |
|
|
|
long onlineDevices = devicesInRoad.stream() |
|
|
|
.filter(device -> device.getUseState() == 1 && device.getDeviceState().equals("1")) |
|
|
|
.count(); |
|
|
|
long offlineDevices = devicesInRoad.stream() |
|
|
|
.filter(device -> device.getUseState() == 1 && !device.getDeviceState().equals("1")) |
|
|
|
.count(); |
|
|
|
Map<String, Long> counts = new HashMap<>(); |
|
|
|
counts.put("online", onlineDevices); |
|
|
|
counts.put("offline", offlineDevices); |
|
|
|
deviceCounts.put(roadId, counts); |
|
|
|
totalRoadCounts.put(roadId, totalDevices); |
|
|
|
useRoadCounts.put(roadId, useDevices); |
|
|
|
// 打印调试信息
|
|
|
|
/* System.out.println("Road Section: " + dcRoadSection.getSectionName()); |
|
|
|
System.out.println("Start Stake Mark: " + startStakeMark); |
|
|
|
System.out.println("End Stake Mark: " + endStakeMark); |
|
|
|
System.out.println("Total Devices: " + totalDevices); |
|
|
|
System.out.println("Use Devices: " + useDevices); |
|
|
|
System.out.println("Online Devices: " + onlineDevices); |
|
|
|
System.out.println("Offline Devices: " + offlineDevices); |
|
|
|
System.out.println("--------------------------------------------------"); |
|
|
|
|
|
|
|
if ("殷家林枢纽-大学城立交".equals(dcRoadSection.getSectionName())) { |
|
|
|
System.out.println("Detailed devices in '殷家林枢纽-大学城立交':"); |
|
|
|
devicesInRoad.forEach(device -> System.out.println("Device ID: " + device.getId() + ", Stake Mark: " + device.getStakeMark())); |
|
|
|
}*/ |
|
|
|
} |
|
|
|
for (DcRoadSection dcRoadSection : dcRoadSections) { |
|
|
|
Map<String, Object> itemMap = new HashMap<>(); |
|
|
|
itemMap.put(SUM, totalRoadCounts.getOrDefault(dcRoadSection.getId().toString(), 0L).toString());//总数
|
|
|
|
itemMap.put(SUM_USE_STATE, useRoadCounts.getOrDefault(dcRoadSection.getId().toString(), 0L).toString());//在用数
|
|
|
|
List<OnlineSum> onlineSumsByRoad = onLineSumMap.getOrDefault(dcRoadSection.getId(), new ArrayList<>()); |
|
|
|
itemMap.put(LOST_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsByRoad.stream().mapToDouble(OnlineSum::getLossRate).average().orElse(0.0)) + "%"); |
|
|
|
itemMap.put(SUCESS_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsByRoad.stream().mapToDouble(OnlineSum::getOnlineRate).average().orElse(0.0)) + "%"); |
|
|
|
itemMap.put(FAIL_RATE, MathUtil.doubleTwoDecimalStr(onlineSumsByRoad.stream().mapToDouble(OnlineSum::getOfflineRate).average().orElse(0.0)) + "%"); |
|
|
|
String roadId = dcRoadSection.getId().toString(); |
|
|
|
|
|
|
|
// 总设备数量
|
|
|
|
long totalDevices = totalRoadCounts.getOrDefault(roadId, 0L); |
|
|
|
itemMap.put(SUM, totalDevices); |
|
|
|
|
|
|
|
// 在用设备数量
|
|
|
|
long useDevices = useRoadCounts.getOrDefault(roadId, 0L); |
|
|
|
itemMap.put(SUM_USE_STATE, useDevices); |
|
|
|
|
|
|
|
// 在线设备数量
|
|
|
|
long onlineDevices = deviceCounts.getOrDefault(roadId, Collections.emptyMap()).getOrDefault("online", 0L); |
|
|
|
|
|
|
|
// 离线设备数量
|
|
|
|
long offlineDevices = deviceCounts.getOrDefault(roadId, Collections.emptyMap()).getOrDefault("offline", 0L); |
|
|
|
|
|
|
|
// 计算在线率
|
|
|
|
double successRate = useDevices > 0 ? (double) onlineDevices / useDevices * 100 : 0.0; |
|
|
|
itemMap.put(SUCESS_RATE, formatPercentage(successRate)); |
|
|
|
|
|
|
|
// 计算离线率
|
|
|
|
double failRate = useDevices > 0 ? (double) offlineDevices / useDevices * 100 : 0.0; |
|
|
|
itemMap.put("failRate", formatPercentage(failRate)); |
|
|
|
|
|
|
|
// 丢包率暂时设置为空
|
|
|
|
itemMap.put(LOST_RATE, ""); |
|
|
|
|
|
|
|
returnMap.put(dcRoadSection.getSectionName(), itemMap); |
|
|
|
} |
|
|
|
|
|
|
|
return AjaxResult.success(returnMap); |
|
|
|
} |
|
|
|
|
|
|
|
// 解析桩号为距离
|
|
|
|
private static double parseStakeMark(String stakeMarkStr) { |
|
|
|
Pattern pattern = Pattern.compile("(?i)K(\\d+)(?:\\+(\\d+))?"); |
|
|
|
Matcher matcher = pattern.matcher(stakeMarkStr); |
|
|
|
if (matcher.matches()) { |
|
|
|
int km = Integer.parseInt(matcher.group(1)); |
|
|
|
int m = matcher.group(2) != null ? Integer.parseInt(matcher.group(2)) : 0; |
|
|
|
return km * 1000 + m; |
|
|
|
} |
|
|
|
throw new IllegalArgumentException("无效的桩标格式:" + stakeMarkStr); |
|
|
|
} |
|
|
|
// 判断桩标是否有效
|
|
|
|
private static boolean isValidStakeMark(String stakeMarkStr) { |
|
|
|
try { |
|
|
|
parseStakeMark(stakeMarkStr); |
|
|
|
return true; |
|
|
|
} catch (IllegalArgumentException e) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
@ApiOperation("查询设备网络日志") |
|
|
|
@GetMapping("/networkLogTable") |
|
|
|
public TableDataInfo networkLogTable( |
|
|
@ -334,7 +461,7 @@ public class DcDeviceOnlineController extends BaseController { |
|
|
|
DRIVING_GUIDANCE("12", "智能行车诱导系统"), |
|
|
|
DEVICE_BOX("13", "智能设备箱"), |
|
|
|
//光纤在线监测14
|
|
|
|
SOLAR_PANEL("15", "太阳能板"), |
|
|
|
SOLAR_PANEL("15", "离网光伏供电"), |
|
|
|
REMOTE_COMPUTER("16", "远端机"); |
|
|
|
private final String value; |
|
|
|
private final String description; |
|
|
@ -390,4 +517,4 @@ public class DcDeviceOnlineController extends BaseController { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |