From bccaf1c838ddc401dfd6386cd3724c1938d63a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=85=B4=E7=90=B3?= <1911390090@qq.com> Date: Thu, 24 Oct 2024 09:08:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=AA=E9=98=B3=E8=83=BD=E6=9D=BF=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=20=E7=A6=BB=E7=BD=91=E5=85=89=E4=BC=8F=E4=BE=9B?= =?UTF-8?q?=E7=94=B5=EF=BC=9B=E8=AE=BE=E5=A4=87=E5=9C=A8=E7=BA=BF=E7=8E=87?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AESEncryptionController.java | 25 ++- .../controller/DcDeviceOnlineController.java | 175 +++++++++++++++--- .../java/com/zc/business/domain/DcDevice.java | 2 +- .../com/zc/business/enums/UniversalEnum.java | 2 +- 4 files changed, 177 insertions(+), 27 deletions(-) diff --git a/zc-business/src/main/java/com/zc/business/controller/AESEncryptionController.java b/zc-business/src/main/java/com/zc/business/controller/AESEncryptionController.java index 52fff2e9..7185266f 100644 --- a/zc-business/src/main/java/com/zc/business/controller/AESEncryptionController.java +++ b/zc-business/src/main/java/com/zc/business/controller/AESEncryptionController.java @@ -1,5 +1,7 @@ package com.zc.business.controller; +import cn.hutool.json.JSONArray; +import com.google.gson.Gson; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.SecurityUtils; @@ -15,6 +17,7 @@ import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.Base64; /** @@ -31,7 +34,27 @@ public class AESEncryptionController extends BaseController { public AjaxResult AESEncryption() throws Exception{ String secretKey= configService.selectConfigByKey("AESKey");//密钥 String iv= configService.selectConfigByKey("AESIv");// 偏移量(初始化向量) - String plainText = SecurityUtils.getLoginUser().getUser().getRoles().get(UniversalEnum.ZERO.getNumber()).getRoleKey(); // 要加密的文本 + String chargeOperationAuthority= configService.selectConfigByKey("chargeOperationAuthority");// 收费运营权限 + // 创建Gson对象 + Gson gson = new Gson(); + String plainText=""; + // 将JSON字符串转换为Integer类型的数组 + String[] numberArray = gson.fromJson(chargeOperationAuthority, String[].class); +if (SecurityUtils.getUserId()==UniversalEnum.ONE.getNumber()){ + plainText="100"; +}else { + int size = SecurityUtils.getLoginUser().getUser().getRoles().size(); + for (int i = 0; i < size; i++) { + String roleKey = SecurityUtils.getLoginUser().getUser().getRoles().get(i).getRoleKey(); + // 检查数组中是否包含 + if (Arrays.stream(numberArray).anyMatch(num -> num.equals(roleKey))) { + plainText=roleKey; + break; + } + + } +} + // String plainText = SecurityUtils.getLoginUser().getUser().getRoles().get(UniversalEnum.ZERO.getNumber()).getRoleKey(); // 要加密的文本 // 转换密钥和IV为字节数组 byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8); byte[] ivBytes = iv.getBytes(StandardCharsets.UTF_8); diff --git a/zc-business/src/main/java/com/zc/business/controller/DcDeviceOnlineController.java b/zc-business/src/main/java/com/zc/business/controller/DcDeviceOnlineController.java index 38aadc4d..a24a52ca 100644 --- a/zc-business/src/main/java/com/zc/business/controller/DcDeviceOnlineController.java +++ b/zc-business/src/main/java/com/zc/business/controller/DcDeviceOnlineController.java @@ -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 useCounts = useDeviceList.stream() .collect(Collectors.groupingBy(DcDevice::getRealType, Collectors.counting())); + Map> typeSumGroup = onlineSums.stream().collect(Collectors.groupingBy(OnlineSum::getDeviceType)); + //在线数量//离线数量 + Map> 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 itemMap = new HashMap<>(); itemMap.put(SUM, totalCounts.getOrDefault(k, 0L).toString());//总数 itemMap.put(SUM_USE_STATE, useCounts.getOrDefault(k, 0L).toString());//在用数 - List 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 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 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 totalOnlineMap = Collections.unmodifiableMap(new HashMap() {{ + put(SUCESS_RATE, totalOnline.get()); + }}); + Map totalOfflineMap = Collections.unmodifiableMap(new HashMap() {{ + 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 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 returnMap = new HashMap<>(); - List> deviceOfRoad = dcDeviceService.selectDeviceOfRoad(); + List dcDeviceList = dcDeviceService.list(); List dcRoadSections = dcRoadSectionService.selectDcRoadSectionList(new DcRoadSection()); - List onlineSums = onlineSumService.queryByDateOfRoad(LocalDate.now()); - Map totalRoadCounts = deviceOfRoad.stream() - .collect(Collectors.groupingBy(m -> m.get("roadId").toString(), Collectors.counting())); - Map 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> onLineSumMap = onlineSums.stream().filter(onlineSum -> onlineSum.getRoadId() != null).collect(Collectors.groupingBy(OnlineSum::getRoadId)); +/* // 去重设备列表 + dcDeviceList = dcDeviceList.stream() + .distinct() + .collect(Collectors.toList());*/ + // 按路段分组统计在线和离线设备数量 + Map> deviceCounts = new HashMap<>(); + Map totalRoadCounts = new HashMap<>(); + Map useRoadCounts = new HashMap<>(); + for (DcRoadSection dcRoadSection : dcRoadSections) { + String roadId = dcRoadSection.getId().toString(); + double startStakeMark = parseStakeMark(dcRoadSection.getStartStakeMark()); + double endStakeMark = parseStakeMark(dcRoadSection.getEndStakeMark()); + List 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 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 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 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 { } } -} +} \ No newline at end of file diff --git a/zc-business/src/main/java/com/zc/business/domain/DcDevice.java b/zc-business/src/main/java/com/zc/business/domain/DcDevice.java index d8f0d82e..d171cf70 100644 --- a/zc-business/src/main/java/com/zc/business/domain/DcDevice.java +++ b/zc-business/src/main/java/com/zc/business/domain/DcDevice.java @@ -56,7 +56,7 @@ public class DcDevice { @Excel(name = "设备编号") private String deviceCode; @ApiModelProperty("设备类型") - @Excel(name = "设备类型", readConverterExp = "1=摄像机,2=可变信息标志,3=气象监测器,4=出口诱导灯,5=路段语音广播,6=护栏碰撞,7=毫米波雷达,8=合流区预警,9=智慧锥桶,10=激光疲劳唤醒,11=一类交通量调查站,12=行车诱导,13=智能设备箱,14=光线在线监测,15=太阳能板,16=远端机") + @Excel(name = "设备类型", readConverterExp = "1=摄像机,2=可变信息标志,3=气象监测器,4=出口诱导灯,5=路段语音广播,6=护栏碰撞,7=毫米波雷达,8=合流区预警,9=智慧锥桶,10=激光疲劳唤醒,11=一类交通量调查站,12=行车诱导,13=智能设备箱,14=光线在线监测,15=离网光伏供电,16=远端机") private String deviceType; @ApiModelProperty("所属网段") @Excel(name = "所属网段") diff --git a/zc-business/src/main/java/com/zc/business/enums/UniversalEnum.java b/zc-business/src/main/java/com/zc/business/enums/UniversalEnum.java index 93eb0450..032ba26f 100644 --- a/zc-business/src/main/java/com/zc/business/enums/UniversalEnum.java +++ b/zc-business/src/main/java/com/zc/business/enums/UniversalEnum.java @@ -423,7 +423,7 @@ public enum UniversalEnum { SMART_DEVICE_BOX(0, "智能设备箱"), //太阳能板15 - SOLAR_PANEL(0, "太阳能板"), + SOLAR_PANEL(0, "离网光伏供电"), //远端机16 REMOTE_COMPUTER(0, "远端机"),