Browse Source

太阳能板改为 离网光伏供电;设备在线率统计修改

develop
王兴琳 1 month ago
parent
commit
bccaf1c838
  1. 25
      zc-business/src/main/java/com/zc/business/controller/AESEncryptionController.java
  2. 175
      zc-business/src/main/java/com/zc/business/controller/DcDeviceOnlineController.java
  3. 2
      zc-business/src/main/java/com/zc/business/domain/DcDevice.java
  4. 2
      zc-business/src/main/java/com/zc/business/enums/UniversalEnum.java

25
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);

175
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<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 {
}
}
}
}

2
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 = "所属网段")

2
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, "远端机"),

Loading…
Cancel
Save