From 6d3b5201e0146f59f0453ca2a52c58ae581e83ad Mon Sep 17 00:00:00 2001 From: gaoyutao Date: Mon, 15 Dec 2025 19:50:44 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AD=98=E5=82=A8=E5=AD=90?= =?UTF-8?q?=E7=BD=91=E5=8D=A1=E4=BF=A1=E6=81=AF=E3=80=81=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=AD=90=E7=BD=91=E5=8D=A1=E6=B5=81=E9=87=8F=E9=80=92=E5=A2=9E?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20=E5=AD=90=E7=BD=91=E5=8D=A1=E6=B5=81?= =?UTF-8?q?=E9=87=8F=E5=9B=BE=E5=90=88=E5=B9=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/api/RemoteRocketMqService.java | 10 +- .../system/api/domain/NetworkInfo.java | 9 + .../api/domain/RmNetworkInterfaceRemote.java | 3 + .../RemoteRocketMqFallbackFactory.java | 5 + .../core/utils/EchartsMoreDataUtils.java | 409 ++++++++++++++++++ .../common/core/utils/NetworkNameUtil.java | 20 + .../system/domain/RmResourceRegistration.java | 8 + .../mapper/RmResourceRegistrationMapper.java | 10 + .../impl/AllInterfaceNameServiceImpl.java | 30 +- .../RmResourceRegistrationServiceImpl.java | 34 +- .../system/RmResourceRegistrationMapper.xml | 4 + .../RmNetworkInterfaceChildController.java | 52 +++ .../domain/RmNetworkInterfaceChild.java | 74 ++++ .../rocketmq/handler/MessageHandler.java | 70 ++- .../mapper/RmNetworkInterfaceChildMapper.java | 61 +++ .../IRmNetworkInterfaceChildService.java | 61 +++ .../InitialBandwidthTrafficServiceImpl.java | 85 +++- .../RmNetworkInterfaceChildServiceImpl.java | 96 ++++ .../impl/RmNetworkInterfaceServiceImpl.java | 31 ++ .../RmNetworkInterfaceChildMapper.xml | 149 +++++++ 20 files changed, 1192 insertions(+), 29 deletions(-) create mode 100644 tongran-common/tongran-common-core/src/main/java/com/tongran/common/core/utils/EchartsMoreDataUtils.java create mode 100644 tongran-common/tongran-common-core/src/main/java/com/tongran/common/core/utils/NetworkNameUtil.java create mode 100644 tongran-rocketmq/src/main/java/com/tongran/rocketmq/controller/RmNetworkInterfaceChildController.java create mode 100644 tongran-rocketmq/src/main/java/com/tongran/rocketmq/domain/RmNetworkInterfaceChild.java create mode 100644 tongran-rocketmq/src/main/java/com/tongran/rocketmq/mapper/RmNetworkInterfaceChildMapper.java create mode 100644 tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/IRmNetworkInterfaceChildService.java create mode 100644 tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/impl/RmNetworkInterfaceChildServiceImpl.java create mode 100644 tongran-rocketmq/src/main/resources/mapper/rocketmq/RmNetworkInterfaceChildMapper.xml diff --git a/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/RemoteRocketMqService.java b/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/RemoteRocketMqService.java index 4351abf..45085a0 100644 --- a/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/RemoteRocketMqService.java +++ b/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/RemoteRocketMqService.java @@ -56,7 +56,7 @@ public interface RemoteRocketMqService { public R> getNetworkInterfaceList(@RequestBody RmNetworkInterfaceRemote rmNetworkInterfaceRemote, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); /** - * 获取网卡接口列表 + * 绑定业务网卡 * @param rmNetworkInterfaceRemote * @param source * @return @@ -98,4 +98,12 @@ public interface RemoteRocketMqService { public R issueDefaultPolicyByClientId(@RequestParam("clientId") String clientId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); @PostMapping("policy/addDeployScript") R addDeployScript(@RequestBody RmDeployScriptRemote addData, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + /** + * 获取子网卡接口列表 + * @param rmNetworkInterfaceRemote + * @param source + * @return + */ + @PostMapping("/networkInterfaceChild/innerGetChildList") + public R> innerGetChildList(@RequestBody RmNetworkInterfaceRemote rmNetworkInterfaceRemote, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); } diff --git a/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/domain/NetworkInfo.java b/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/domain/NetworkInfo.java index 2a0b161..d47427c 100644 --- a/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/domain/NetworkInfo.java +++ b/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/domain/NetworkInfo.java @@ -3,6 +3,8 @@ package com.tongran.system.api.domain; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; +import java.util.List; + @Data public class NetworkInfo { // 运营商 @@ -34,4 +36,11 @@ public class NetworkInfo { private String publicIp; @JsonProperty("type") private String type; + // 如果是子接口,存储父接口名称 + @JsonProperty("parentInterface") + private String parentInterface; + + // 如果是父接口,存储子接口列表 + @JsonProperty("subInterfaces") + private List subInterfaces; } diff --git a/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/domain/RmNetworkInterfaceRemote.java b/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/domain/RmNetworkInterfaceRemote.java index 445b806..1afed71 100644 --- a/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/domain/RmNetworkInterfaceRemote.java +++ b/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/domain/RmNetworkInterfaceRemote.java @@ -56,4 +56,7 @@ public class RmNetworkInterfaceRemote extends BaseEntity { private Integer newFlag; /** 服务器clientId集合 */ private String clientIds; + + // 如果是子接口,存储父接口名称 + private String parentInterface; } diff --git a/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/factory/RemoteRocketMqFallbackFactory.java b/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/factory/RemoteRocketMqFallbackFactory.java index c3fecd7..5c173b5 100644 --- a/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/factory/RemoteRocketMqFallbackFactory.java +++ b/tongran-api/tongran-api-system/src/main/java/com/tongran/system/api/factory/RemoteRocketMqFallbackFactory.java @@ -83,6 +83,11 @@ public class RemoteRocketMqFallbackFactory implements FallbackFactory addDeployScript(RmDeployScriptRemote addData, String source) { return R.fail(throwable.getMessage()); } + + @Override + public R> innerGetChildList(RmNetworkInterfaceRemote rmNetworkInterfaceRemote, String source) { + return R.fail(throwable.getMessage()); + } }; } } diff --git a/tongran-common/tongran-common-core/src/main/java/com/tongran/common/core/utils/EchartsMoreDataUtils.java b/tongran-common/tongran-common-core/src/main/java/com/tongran/common/core/utils/EchartsMoreDataUtils.java new file mode 100644 index 0000000..c64385e --- /dev/null +++ b/tongran-common/tongran-common-core/src/main/java/com/tongran/common/core/utils/EchartsMoreDataUtils.java @@ -0,0 +1,409 @@ +package com.tongran.common.core.utils; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class EchartsMoreDataUtils { + + + /** + * 构建多网卡ECharts图表数据(带汇总流量) + * 每个网卡会生成两个独立的Y轴属性:{interfaceName}netInTraffic 和 {interfaceName}netOutTraffic + * 同时生成汇总流量:totalNetInTraffic 和 totalNetOutTraffic + */ + public static Map buildMultiInterfaceEchartsDataWithTotal( + Map> interfaceDataMap, + Function timeExtractor, + Function inSpeedExtractor, + Function outSpeedExtractor, + String startTime, + String endTime, + BigDecimal divisor) { + + try { + // 解析时间字符串 + Date startDate = parseStringToDate(startTime); + Date endDate = parseStringToDate(endTime); + + if (startDate == null || endDate == null) { + throw new IllegalArgumentException("开始时间或结束时间格式错误"); + } + + if (startDate.after(endDate)) { + throw new IllegalArgumentException("开始时间不能晚于结束时间"); + } + + // 收集所有网卡的时间点 + Set allTimePoints = new TreeSet<>(); + Map> interfaceTimeMap = new LinkedHashMap<>(); + + // 为每个网卡处理数据 + for (Map.Entry> entry : interfaceDataMap.entrySet()) { + String interfaceName = entry.getKey(); + List interfaceList = entry.getValue(); + + if (interfaceList == null || interfaceList.isEmpty()) { + continue; + } + + // 按时间排序 + List sortedList = interfaceList.stream() + .sorted(Comparator.comparing(timeExtractor)) + .collect(Collectors.toList()); + + // 自动检测时间间隔 + long timeInterval = detectTimeInterval(sortedList, timeExtractor); + + // 创建时间到数据的映射 + Map timeMap = sortedList.stream() + .collect(Collectors.toMap( + item -> normalizeTime(timeExtractor.apply(item), timeInterval), + Function.identity(), + (a, b) -> a + )); + + interfaceTimeMap.put(interfaceName, timeMap); + + // 添加时间点到总集合 + for (T item : sortedList) { + allTimePoints.add(timeExtractor.apply(item)); + } + } + + // 生成完整的时间序列 + List fullTimeSeries = generateFullTimeSeriesForMultiInterface( + allTimePoints, startDate, endDate); + + // 准备X轴和Y轴数据 + List xAxisData = new ArrayList<>(); + Map yData = new LinkedHashMap<>(); + + // 初始化每个网卡的Y轴数据结构 + interfaceDataMap.keySet().forEach(interfaceName -> { + yData.put(interfaceName + "netInTraffic", new ArrayList()); + yData.put(interfaceName + "netOutTraffic", new ArrayList()); + }); + + // 初始化汇总流量数据结构 + List totalNetInTraffic = new ArrayList<>(); + List totalNetOutTraffic = new ArrayList<>(); + yData.put("totalNetInTraffic", totalNetInTraffic); + yData.put("totalNetOutTraffic", totalNetOutTraffic); + + // 遍历所有时间点 + for (Date time : fullTimeSeries) { + // X轴数据 + xAxisData.add(parseDateToStr(time)); + + // 标准化当前时间 + long normalizedTime = normalizeTime(time, 300000L); // 5分钟间隔 + + // 当前时间点的总流量 + BigDecimal timeTotalInSpeed = BigDecimal.ZERO; + BigDecimal timeTotalOutSpeed = BigDecimal.ZERO; + + // 处理每个网卡的数据 + for (Map.Entry> entry : interfaceTimeMap.entrySet()) { + String interfaceName = entry.getKey(); + Map timeMap = entry.getValue(); + + T item = timeMap.get(normalizedTime); + + // 获取入方向数据列表 + @SuppressWarnings("unchecked") + List inSpeedList = (List) yData.get(interfaceName + "netInTraffic"); + // 获取出方向数据列表 + @SuppressWarnings("unchecked") + List outSpeedList = (List) yData.get(interfaceName + "netOutTraffic"); + + if (item != null) { + // 有真实数据 + BigDecimal inSpeed = inSpeedExtractor.apply(item); + BigDecimal outSpeed = outSpeedExtractor.apply(item); + + // 单位转换 + BigDecimal convertedInSpeed = inSpeed != null ? + inSpeed.divide(divisor, 2, RoundingMode.HALF_UP) : null; + BigDecimal convertedOutSpeed = outSpeed != null ? + outSpeed.divide(divisor, 2, RoundingMode.HALF_UP) : null; + + inSpeedList.add(convertedInSpeed); + outSpeedList.add(convertedOutSpeed); + + // 累加到总流量 + if (convertedInSpeed != null) { + timeTotalInSpeed = timeTotalInSpeed.add(convertedInSpeed); + } + if (convertedOutSpeed != null) { + timeTotalOutSpeed = timeTotalOutSpeed.add(convertedOutSpeed); + } + } else { + // 无数据的时间点,补null + inSpeedList.add(null); + outSpeedList.add(null); + } + } + + // 添加当前时间点的总流量 + totalNetInTraffic.add(timeTotalInSpeed.compareTo(BigDecimal.ZERO) == 0 ? null : timeTotalInSpeed); + totalNetOutTraffic.add(timeTotalOutSpeed.compareTo(BigDecimal.ZERO) == 0 ? null : timeTotalOutSpeed); + } + + Map result = new HashMap<>(); + result.put("xData", xAxisData); + result.put("yData", yData); + return result; + + } catch (Exception e) { + // 记录日志 + System.err.println("构建多网卡图表数据失败: " + e.getMessage()); + return createEmptyMultiInterfaceResultWithTotal(interfaceDataMap.keySet(), startTime, endTime); + } + } + + /** + * 为多网卡生成完整的时间序列 + */ + private static List generateFullTimeSeriesForMultiInterface( + Set allInterfaceTimePoints, + Date startDate, + Date endDate) { + + // 获取实际数据的时间范围 + Date actualStartTime = allInterfaceTimePoints.isEmpty() ? startDate : + Collections.min(allInterfaceTimePoints); + Date actualEndTime = allInterfaceTimePoints.isEmpty() ? endDate : + Collections.max(allInterfaceTimePoints); + + // 计算稀疏间隔 + long totalTimeRange = endDate.getTime() - startDate.getTime(); + long sparseInterval = totalTimeRange > 12L * 30 * 24 * 60 * 60 * 1000 ? + 30L * 24 * 60 * 60 * 1000 : 2L * 24 * 60 * 60 * 1000; + + // 使用默认的5分钟作为数据期间间隔 + long dataInterval = 300000L; + + // 生成三段时间序列 + List fullTimeSeries = new ArrayList<>(); + + // 1. 开始时间到数据开始时间(稀疏间隔) + if (startDate.before(actualStartTime)) { + List beforeSeries = generateTimeSeries(startDate, actualStartTime, sparseInterval); + fullTimeSeries.addAll(beforeSeries); + } + + // 2. 数据开始时间到数据结束时间(正常间隔) + List dataSeries = generateTimeSeries(actualStartTime, actualEndTime, dataInterval); + fullTimeSeries.addAll(dataSeries); + + // 3. 数据结束时间到结束时间(稀疏间隔) + if (actualEndTime.before(endDate)) { + // 调整actualEndTime的下一个点开始,避免重复 + Calendar cal = Calendar.getInstance(); + cal.setTime(actualEndTime); + cal.setTimeInMillis(cal.getTimeInMillis() + dataInterval); + Date nextAfterActualEnd = cal.getTime(); + + if (nextAfterActualEnd.before(endDate) || nextAfterActualEnd.equals(endDate)) { + List afterSeries = generateTimeSeries(nextAfterActualEnd, endDate, sparseInterval); + fullTimeSeries.addAll(afterSeries); + } + } + + return fullTimeSeries; + } + + /** + * 创建多网卡空结果(带汇总流量) + */ + private static Map createEmptyMultiInterfaceResultWithTotal( + Set interfaceNames, String startTime, String endTime) { + + Map result = new HashMap<>(); + + try { + // 解析时间范围 + Date startDate = parseStringToDate(startTime); + Date endDate = parseStringToDate(endTime); + + if (startDate != null && endDate != null && !startDate.after(endDate)) { + // 动态计算时间间隔 + long timeRange = endDate.getTime() - startDate.getTime(); + long interval; + + if (timeRange > 12L * 30 * 24 * 60 * 60 * 1000) { // 超过12个月 + interval = 30L * 24 * 60 * 60 * 1000; // 每月1个点 + } else { + interval = 2L * 24 * 60 * 60 * 1000; // 2天1个点 + } + + List fullTimeSeries = generateTimeSeries(startDate, endDate, interval); + + // 构建x轴数据 + List xAxisData = new ArrayList<>(); + for (Date date : fullTimeSeries) { + xAxisData.add(parseDateToStr(date)); + } + result.put("xData", xAxisData); + + // 构建y轴数据(空数据集) + Map yData = new LinkedHashMap<>(); + int dataSize = xAxisData.size(); + + // 为每个网卡创建空数据系列 + for (String interfaceName : interfaceNames) { + List inSpeedSeries = new ArrayList<>(); + List outSpeedSeries = new ArrayList<>(); + + for (int i = 0; i < dataSize; i++) { + if (i == 0) { + // 第一个点补0 + inSpeedSeries.add(0); + outSpeedSeries.add(0); + } else { + // 其他点补null + inSpeedSeries.add(null); + outSpeedSeries.add(null); + } + } + + yData.put(interfaceName + "netInTraffic", inSpeedSeries); + yData.put(interfaceName + "netOutTraffic", outSpeedSeries); + } + + // 创建汇总流量的空数据系列 + List totalInSpeedSeries = new ArrayList<>(); + List totalOutSpeedSeries = new ArrayList<>(); + for (int i = 0; i < dataSize; i++) { + if (i == 0) { + totalInSpeedSeries.add(0); + totalOutSpeedSeries.add(0); + } else { + totalInSpeedSeries.add(null); + totalOutSpeedSeries.add(null); + } + } + yData.put("totalNetInTraffic", totalInSpeedSeries); + yData.put("totalNetOutTraffic", totalOutSpeedSeries); + + result.put("yData", yData); + + } else { + // 时间解析失败时返回空数据 + result.put("xData", new ArrayList<>()); + Map yData = new LinkedHashMap<>(); + for (String interfaceName : interfaceNames) { + yData.put(interfaceName + "netInTraffic", new ArrayList<>()); + yData.put(interfaceName + "netOutTraffic", new ArrayList<>()); + } + yData.put("totalNetInTraffic", new ArrayList<>()); + yData.put("totalNetOutTraffic", new ArrayList<>()); + result.put("yData", yData); + } + + } catch (Exception e) { + // 异常时返回空数据 + result.put("xData", new ArrayList<>()); + Map yData = new LinkedHashMap<>(); + for (String interfaceName : interfaceNames) { + yData.put(interfaceName + "netInTraffic", new ArrayList<>()); + yData.put(interfaceName + "netOutTraffic", new ArrayList<>()); + } + yData.put("totalNetInTraffic", new ArrayList<>()); + yData.put("totalNetOutTraffic", new ArrayList<>()); + result.put("yData", yData); + } + + return result; + } + + + /** + * 字符串转日期 + */ + private static Date parseStringToDate(String dateStr) { + if (dateStr == null || dateStr.trim().isEmpty()) { + return null; + } + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + sdf.setLenient(false); // 严格模式 + return sdf.parse(dateStr); + } catch (ParseException e) { + System.err.println("日期解析失败: " + dateStr); + return null; + } + } + + /** + * 日期转字符串 + */ + private static String parseDateToStr(Date date) { + if (date == null) { + return ""; + } + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return sdf.format(date); + } + + /** + * 生成完整的时间序列 + */ + private static List generateTimeSeries(Date start, Date end, long interval) { + List timeSeries = new ArrayList<>(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(start); + + // 确保开始时间对齐到时间间隔 + long startMillis = normalizeTime(start, interval); + calendar.setTimeInMillis(startMillis); + + while (!calendar.getTime().after(end)) { + timeSeries.add(calendar.getTime()); + calendar.setTimeInMillis(calendar.getTimeInMillis() + interval); + } + return timeSeries; + } + + /** + * 自动检测时间间隔 + */ + private static long detectTimeInterval(List list, Function timeExtractor) { + if (list.size() < 2) { + return 300000; // 默认5分钟 + } + + // 计算时间间隔的众数 + Map intervalCount = new HashMap<>(); + for (int i = 1; i < list.size(); i++) { + long interval = timeExtractor.apply(list.get(i)).getTime() - + timeExtractor.apply(list.get(i - 1)).getTime(); + if (interval > 0) { + intervalCount.merge(interval, 1, Integer::sum); + } + } + + // 如果没有有效间隔,使用默认值 + if (intervalCount.isEmpty()) { + return 300000L; + } + + return intervalCount.entrySet().stream() + .max(Map.Entry.comparingByValue()) + .map(Map.Entry::getKey) + .orElse(300000L); + } + + /** + * 时间标准化(对齐到时间间隔) + */ + private static long normalizeTime(Date time, long interval) { + long timeMillis = time.getTime(); + return (timeMillis / interval) * interval; + } +} \ No newline at end of file diff --git a/tongran-common/tongran-common-core/src/main/java/com/tongran/common/core/utils/NetworkNameUtil.java b/tongran-common/tongran-common-core/src/main/java/com/tongran/common/core/utils/NetworkNameUtil.java new file mode 100644 index 0000000..35549cb --- /dev/null +++ b/tongran-common/tongran-common-core/src/main/java/com/tongran/common/core/utils/NetworkNameUtil.java @@ -0,0 +1,20 @@ +package com.tongran.common.core.utils; + +public class NetworkNameUtil { + + /** + * 判断网卡是否为子网卡 + * @param interfaceName + * @return + */ + public static boolean isSubInterface(String interfaceName) { + // 非空检查 + if (interfaceName == null || interfaceName.isEmpty()) { + return false; + } + + // 匹配模式:冒号后跟数字 或 点后跟数字 + String pattern = ".*[:.]\\d+$"; + return interfaceName.matches(pattern); + } +} diff --git a/tongran-modules/tongran-system/src/main/java/com/tongran/system/domain/RmResourceRegistration.java b/tongran-modules/tongran-system/src/main/java/com/tongran/system/domain/RmResourceRegistration.java index 65e5d09..e8d0580 100644 --- a/tongran-modules/tongran-system/src/main/java/com/tongran/system/domain/RmResourceRegistration.java +++ b/tongran-modules/tongran-system/src/main/java/com/tongran/system/domain/RmResourceRegistration.java @@ -122,6 +122,8 @@ public class RmResourceRegistration extends BaseEntity @Excel(name = "IP1-网关") private String ip1Gateway; // IP1-网关 + /** ip1是否存在子网卡 */ + private boolean ip1IsVirth; // IP2 相关字段 @Excel(name = "IP2-运营商") @@ -153,6 +155,8 @@ public class RmResourceRegistration extends BaseEntity @Excel(name = "IP2-网关") private String ip2Gateway; + /** ip2是否存在子网卡 */ + private boolean ip2IsVirth; // IP3 相关字段 @Excel(name = "IP3-运营商") @@ -184,6 +188,8 @@ public class RmResourceRegistration extends BaseEntity @Excel(name = "IP3-网关") private String ip3Gateway; + /** ip3是否存在子网卡 */ + private boolean ip3IsVirth; // 管理网相关字段 @Excel(name = "管理网-运营商") @@ -215,6 +221,8 @@ public class RmResourceRegistration extends BaseEntity @Excel(name = "管理网-网关") private String mgmtGateway; // 管理网-网关地址 + /** 管理网-是否存在子网卡 */ + private boolean mgmIsVirth; /** 多条件查询 */ private String queryParam; diff --git a/tongran-modules/tongran-system/src/main/java/com/tongran/system/mapper/RmResourceRegistrationMapper.java b/tongran-modules/tongran-system/src/main/java/com/tongran/system/mapper/RmResourceRegistrationMapper.java index 650473a..0aac6e0 100644 --- a/tongran-modules/tongran-system/src/main/java/com/tongran/system/mapper/RmResourceRegistrationMapper.java +++ b/tongran-modules/tongran-system/src/main/java/com/tongran/system/mapper/RmResourceRegistrationMapper.java @@ -1,6 +1,7 @@ package com.tongran.system.mapper; import com.tongran.system.domain.RmResourceRegistration; +import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Map; @@ -112,4 +113,13 @@ public interface RmResourceRegistrationMapper int updateRemark(RmResourceRegistration rmResourceRegistration); int addReportedBandwidth(RmResourceRegistration rmResourceRegistration); + + /** + * 判断该网卡是否存在子网卡 + * @param clientId + * @param interfaceName + * @return + */ + int countChildNetwork(@Param("clientId") String clientId, + @Param("interfaceName") String interfaceName); } diff --git a/tongran-modules/tongran-system/src/main/java/com/tongran/system/service/impl/AllInterfaceNameServiceImpl.java b/tongran-modules/tongran-system/src/main/java/com/tongran/system/service/impl/AllInterfaceNameServiceImpl.java index 1d92182..9abfb32 100644 --- a/tongran-modules/tongran-system/src/main/java/com/tongran/system/service/impl/AllInterfaceNameServiceImpl.java +++ b/tongran-modules/tongran-system/src/main/java/com/tongran/system/service/impl/AllInterfaceNameServiceImpl.java @@ -3,6 +3,7 @@ package com.tongran.system.service.impl; import com.tongran.common.core.constant.SecurityConstants; import com.tongran.common.core.domain.R; import com.tongran.common.core.utils.DateUtils; +import com.tongran.common.core.utils.NetworkNameUtil; import com.tongran.system.api.RemoteRocketMqService; import com.tongran.system.api.domain.RmNetworkInterfaceRemote; import com.tongran.system.domain.AllInterfaceName; @@ -13,6 +14,7 @@ import com.tongran.system.service.IRmEpsTopologyManagementService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -43,7 +45,6 @@ public class AllInterfaceNameServiceImpl implements IAllInterfaceNameService { return allInterfaceNameMapper.selectAllInterfaceNameById(id); } - /** * 查询所有接口名称列表 * @@ -54,16 +55,35 @@ public class AllInterfaceNameServiceImpl implements IAllInterfaceNameService public List selectAllInterfaceNameList(AllInterfaceName allInterfaceName) { List allInterfaceNameList = allInterfaceNameMapper.selectAllInterfaceNameList(allInterfaceName); - if (allInterfaceNameList == null || allInterfaceNameList.isEmpty()) { return allInterfaceNameList; } + // 用于存储非子网卡的接口 + List nonSubInterfaces = new ArrayList<>(); + for (AllInterfaceName interfaceName : allInterfaceNameList) { + String originalName = interfaceName.getInterfaceName(); + String name = originalName; + if (originalName != null && originalName.contains("(")) { + int index = originalName.indexOf("("); + name = originalName.substring(0, index); + } + + // 如果不是子网卡,则加入列表 + if (originalName == null || !NetworkNameUtil.isSubInterface(name)) { + nonSubInterfaces.add(interfaceName); + } + } + if (nonSubInterfaces.isEmpty()) { + return nonSubInterfaces; + } // 使用自定义排序 - return allInterfaceNameList.stream() + return nonSubInterfaces.stream() .sorted((a, b) -> { - boolean aMatched = isInterfaceMatched(a); - boolean bMatched = isInterfaceMatched(b); + // 根据实际业务逻辑判断是否匹配 + // 这里用接口名不为null且包含特定字符作为示例 + boolean aMatched = a.getInterfaceName() != null && a.getInterfaceName().contains("eth"); + boolean bMatched = b.getInterfaceName() != null && b.getInterfaceName().contains("eth"); // 匹配的排在前面(返回-1),不匹配的排在后面(返回1) if (aMatched && !bMatched) { diff --git a/tongran-modules/tongran-system/src/main/java/com/tongran/system/service/impl/RmResourceRegistrationServiceImpl.java b/tongran-modules/tongran-system/src/main/java/com/tongran/system/service/impl/RmResourceRegistrationServiceImpl.java index e979a6e..639398c 100644 --- a/tongran-modules/tongran-system/src/main/java/com/tongran/system/service/impl/RmResourceRegistrationServiceImpl.java +++ b/tongran-modules/tongran-system/src/main/java/com/tongran/system/service/impl/RmResourceRegistrationServiceImpl.java @@ -469,6 +469,12 @@ public class RmResourceRegistrationServiceImpl implements IRmResourceRegistratio for (RmNetworkInterfaceRemote network : networkList) { if ("1".equals(network.getBindIp()) || "3".equals(network.getBindIp())) { + // 查询是否存在子网卡 + int count = rmResourceRegistrationMapper.countChildNetwork(clientId, network.getInterfaceName()); + boolean isVirth = false; + if(count > 0){ + isVirth = true; + } // 业务IP处理 if (businessIpCount > 3) { continue; // 最多只处理3个业务IP @@ -487,6 +493,7 @@ public class RmResourceRegistrationServiceImpl implements IRmResourceRegistratio registration.setIp1Ipv4Address(network.getIpv4Address()); registration.setIp1Ipv6Address(network.getIpv6Address()); registration.setIp1Gateway(network.getGateway()); + registration.setIp1IsVirth(isVirth); break; case 2: registration.setIp2Isp(network.getIsp()); @@ -499,6 +506,7 @@ public class RmResourceRegistrationServiceImpl implements IRmResourceRegistratio registration.setIp2Ipv4Address(network.getIpv4Address()); registration.setIp2Ipv6Address(network.getIpv6Address()); registration.setIp2Gateway(network.getGateway()); + registration.setIp2IsVirth(isVirth); break; case 3: registration.setIp3Isp(network.getIsp()); @@ -511,12 +519,19 @@ public class RmResourceRegistrationServiceImpl implements IRmResourceRegistratio registration.setIp3Ipv4Address(network.getIpv4Address()); registration.setIp3Ipv6Address(network.getIpv6Address()); registration.setIp3Gateway(network.getGateway()); + registration.setIp3IsVirth(isVirth); break; } businessIpCount++; } if ("2".equals(network.getBindIp()) || "3".equals(network.getBindIp())) { + // 查询是否存在子网卡 + int count = rmResourceRegistrationMapper.countChildNetwork(clientId, network.getInterfaceName()); + boolean isVirth = false; + if(count > 0){ + isVirth = true; + } // 管理网IP处理 registration.setMgmtIsp(network.getIsp()); registration.setMgmtProvince(network.getProvince()); @@ -528,6 +543,7 @@ public class RmResourceRegistrationServiceImpl implements IRmResourceRegistratio registration.setMgmtIpv4Address(network.getIpv4Address()); registration.setMgmtIpv6Address(network.getIpv6Address()); registration.setMgmtGateway(network.getGateway()); + registration.setMgmIsVirth(isVirth); } } } @@ -1012,7 +1028,16 @@ public class RmResourceRegistrationServiceImpl implements IRmResourceRegistratio // 如果有符合条件的网络接口 if (!filteredNetworks.isEmpty()) { updateData.setRegistrationStatus("1"); - + List childList = new ArrayList<>(); + filteredNetworks.forEach(netMsg -> { + RmNetworkInterfaceRemote query = new RmNetworkInterfaceRemote(); + query.setClientId(clientId); + query.setParentInterface(netMsg.getInterfaceName()); + R> children = remoteRocketMqService.innerGetChildList(query, SecurityConstants.INNER); + if(children != null && children.getData()!=null && !children.getData().isEmpty()){ + childList.addAll(children.getData()); + } + }); // 拼接所有符合条件的网络接口名称,用分号隔开 StringBuilder netNameBuilder = new StringBuilder(); for (int i = 0; i < filteredNetworks.size(); i++) { @@ -1021,6 +1046,13 @@ public class RmResourceRegistrationServiceImpl implements IRmResourceRegistratio } netNameBuilder.append(filteredNetworks.get(i).getInterfaceName()); } + // 添加子接口名称 + for (int i = 0; i < childList.size(); i++) { + if (netNameBuilder.length() > 0 || i > 0) { + netNameBuilder.append(";"); + } + netNameBuilder.append(childList.get(i).getInterfaceName()); + } String netName = netNameBuilder.toString(); // 发送注册响应 diff --git a/tongran-modules/tongran-system/src/main/resources/mapper/system/RmResourceRegistrationMapper.xml b/tongran-modules/tongran-system/src/main/resources/mapper/system/RmResourceRegistrationMapper.xml index e80d864..ebd7927 100644 --- a/tongran-modules/tongran-system/src/main/resources/mapper/system/RmResourceRegistrationMapper.xml +++ b/tongran-modules/tongran-system/src/main/resources/mapper/system/RmResourceRegistrationMapper.xml @@ -275,4 +275,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update rm_resource_registration set reported_bandwidth = #{reportedBandwidth} where id =#{id} + \ No newline at end of file diff --git a/tongran-rocketmq/src/main/java/com/tongran/rocketmq/controller/RmNetworkInterfaceChildController.java b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/controller/RmNetworkInterfaceChildController.java new file mode 100644 index 0000000..05ffb90 --- /dev/null +++ b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/controller/RmNetworkInterfaceChildController.java @@ -0,0 +1,52 @@ +package com.tongran.rocketmq.controller; + +import com.tongran.common.core.domain.R; +import com.tongran.common.core.web.controller.BaseController; +import com.tongran.common.core.web.domain.AjaxResult; +import com.tongran.common.security.annotation.InnerAuth; +import com.tongran.common.security.annotation.RequiresPermissions; +import com.tongran.rocketmq.domain.RmNetworkInterfaceChild; +import com.tongran.rocketmq.service.IRmNetworkInterfaceChildService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 客户端网络接口子接口信息Controller + * + * @author gyt + * @date 2025-12-15 + */ +@RestController +@RequestMapping("/networkInterfaceChild") +@RequiresPermissions("system:registration") +public class RmNetworkInterfaceChildController extends BaseController +{ + @Autowired + private IRmNetworkInterfaceChildService rmNetworkInterfaceChildService; + + /** + * 查询客户端网络接口子接口信息列表 + */ + @PostMapping("/list") + public AjaxResult list(@RequestBody RmNetworkInterfaceChild rmNetworkInterfaceChild) + { + List list = rmNetworkInterfaceChildService.selectRmNetworkInterfaceChildList(rmNetworkInterfaceChild); + return success(list); + } + /** + * 查询客户端网络接口子接口信息列表 + */ + @PostMapping("/innerGetChildList") + @InnerAuth + public R innerGetChildList(@RequestBody RmNetworkInterfaceChild rmNetworkInterfaceChild) + { + List list = rmNetworkInterfaceChildService.selectRmNetworkInterfaceChildList(rmNetworkInterfaceChild); + return R.ok(list); + } + +} diff --git a/tongran-rocketmq/src/main/java/com/tongran/rocketmq/domain/RmNetworkInterfaceChild.java b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/domain/RmNetworkInterfaceChild.java new file mode 100644 index 0000000..f97f228 --- /dev/null +++ b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/domain/RmNetworkInterfaceChild.java @@ -0,0 +1,74 @@ +package com.tongran.rocketmq.domain; + +import com.tongran.common.core.annotation.Excel; +import com.tongran.common.core.web.domain.BaseEntity; +import lombok.Data; + +/** + * 客户端网络接口子接口信息对象 rm_network_interface_child + * + * @author gyt + * @date 2025-12-15 + */ +@Data +public class RmNetworkInterfaceChild extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 客户端ID */ + @Excel(name = "客户端ID") + private String clientId; + /** 父接口名称 */ + private String parentInterface; + + /** 运营商 */ + @Excel(name = "运营商") + private String isp; + + /** 省 */ + @Excel(name = "省") + private String province; + + /** 市 */ + @Excel(name = "市") + private String city; + + /** 公网IP */ + @Excel(name = "公网IP") + private String publicIp; + + /** 接口名称 */ + @Excel(name = "接口名称") + private String interfaceName; + + /** MAC地址 */ + @Excel(name = "MAC地址") + private String macAddress; + + /** 接口类型 */ + @Excel(name = "接口类型") + private String interfaceType; + + /** IPv4地址 */ + @Excel(name = "IPv4地址") + private String ipv4Address; + + /** IPv6地址 */ + @Excel(name = "IPv6地址") + private String ipv6Address; + + /** 网关 */ + @Excel(name = "网关") + private String gateway; + + /** 绑定公网ip类型(0未绑定,1业务ip,2管理ip,3管理和业务ip) */ + @Excel(name = "绑定公网ip类型(0未绑定,1业务ip,2管理ip,3管理和业务ip)") + private String bindIp; + + /** 是否为新的(0否 1是) */ + @Excel(name = "是否为新的(0否 1是)") + private Integer newFlag; +} diff --git a/tongran-rocketmq/src/main/java/com/tongran/rocketmq/handler/MessageHandler.java b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/handler/MessageHandler.java index 686c8f4..11d30fe 100644 --- a/tongran-rocketmq/src/main/java/com/tongran/rocketmq/handler/MessageHandler.java +++ b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/handler/MessageHandler.java @@ -89,6 +89,8 @@ public class MessageHandler { @Autowired private IRmNetworkInterfaceService rmNetworkInterfaceService; @Autowired + private IRmNetworkInterfaceChildService rmNetworkInterfaceChildService; + @Autowired private IRmMonitorPolicyService rmMonitorPolicyService; @Autowired private IRmDeploymentPolicyService rmDeploymentPolicyService; @@ -260,10 +262,10 @@ public class MessageHandler { temp.setClientId(clientId); List tempList = initialBandwidthTrafficTempService.selectInitialBandwidthTrafficTempList(temp); if(!tempList.isEmpty()){ - // 1. 构建快速查找的Map + // 1. 构建快速查找的Map,使用MAC地址+网卡名称作为唯一键 Map tempMap = tempList.stream() .collect(Collectors.toMap( - InitialBandwidthTrafficTemp::getMac, + tempItem -> generateKey(tempItem.getMac(), tempItem.getName()), Function.identity(), (existing, replacement) -> existing )); @@ -290,7 +292,9 @@ public class MessageHandler { iface.setIpv6InSpeed(null); iface.setIpv6OutSpeed(null); - InitialBandwidthTrafficTemp tempInfo = tempMap.get(iface.getMac()); + // 使用MAC地址+网卡名称作为查找键 + String key = generateKey(iface.getMac(), iface.getName()); + InitialBandwidthTrafficTemp tempInfo = tempMap.get(key); if (tempInfo != null) { // 计算总流入速率 if (iface.getTotalInSpeed() != null && tempInfo.getTotalInSpeed() != null) { @@ -387,6 +391,15 @@ public class MessageHandler { throw new RuntimeException("NET流量data数据为空"); } } + private String generateKey(String mac, String name) { + if (mac == null) { + mac = ""; + } + if (name == null) { + name = ""; + } + return mac + "|" + name; + } /** * docker数据入库 * @param message @@ -1031,6 +1044,7 @@ public class MessageHandler { boolean isSingleInterface = networkInfoList.size() == 1; for (NetworkInfo networkInfo : networkInfoList) { + List childList = networkInfo.getSubInterfaces(); // 查询该网卡信息是否存在 RmNetworkInterface queryParam = new RmNetworkInterface(); queryParam.setClientId(clientId); @@ -1048,14 +1062,31 @@ public class MessageHandler { insertData.setBindIp("3"); } rmNetworkInterfaceService.insertRmNetworkInterface(insertData); + if(childList != null && !childList.isEmpty()){ + for (NetworkInfo info : childList) { + RmNetworkInterfaceChild insertChild = new RmNetworkInterfaceChild(); + setNetworkInterfaceChildData(insertChild, info, clientId, networkInfo.getName()); + // 设置bindIp + if (isSingleInterface) { + insertChild.setBindIp("3"); + } + rmNetworkInterfaceChildService.insertRmNetworkInterfaceChild(insertChild); + } + } } else { // 更新网卡信息 RmNetworkInterface oldInterfaceMsg = exits.get(0); - + cleanChildOldRecords(clientId, networkInfo.getMac()); // 判断是否需要创建新记录 boolean needCreateNew = !StringUtils.equals(networkInfo.getName(), oldInterfaceMsg.getInterfaceName()) || !StringUtils.equals(networkInfo.getGateway(), oldInterfaceMsg.getGateway()); - + if(childList != null && !childList.isEmpty()){ + for (NetworkInfo info : childList) { + RmNetworkInterfaceChild insertChild = new RmNetworkInterfaceChild(); + setNetworkInterfaceChildData(insertChild, info, clientId, networkInfo.getName()); + rmNetworkInterfaceChildService.insertRmNetworkInterfaceChild(insertChild); + } + } if(needCreateNew) { // 清理旧的历史数据 cleanOldRecords(clientId, networkInfo.getMac()); @@ -1095,6 +1126,20 @@ public class MessageHandler { networkInterface.setPublicIp(networkInfo.getPublicIp()); networkInterface.setInterfaceType(networkInfo.getType()); } + private void setNetworkInterfaceChildData(RmNetworkInterfaceChild networkInterface, NetworkInfo networkInfo, String clientId, String parentName) { + networkInterface.setClientId(clientId); + networkInterface.setParentInterface(parentName); + networkInterface.setIsp(networkInfo.getCarrier()); + networkInterface.setCity(networkInfo.getCity()); + networkInterface.setGateway(networkInfo.getGateway()); + networkInterface.setInterfaceName(networkInfo.getName()); + networkInterface.setIpv4Address(networkInfo.getIpv4()); + networkInterface.setIpv6Address(networkInfo.getIpv6()); + networkInterface.setMacAddress(networkInfo.getMac()); + networkInterface.setProvince(networkInfo.getProvince()); + networkInterface.setPublicIp(networkInfo.getPublicIp()); + networkInterface.setInterfaceType(networkInfo.getType()); + } /** * 清理旧记录 @@ -1111,7 +1156,20 @@ public class MessageHandler { }); } } - + /** + * 清理旧记录 + */ + private void cleanChildOldRecords(String clientId, String macAddress) { + RmNetworkInterfaceChild childQuery = new RmNetworkInterfaceChild(); + childQuery.setClientId(clientId); + childQuery.setMacAddress(macAddress); + List oldChildExits = rmNetworkInterfaceChildService.selectRmNetworkInterfaceChildList(childQuery); + if(!oldChildExits.isEmpty()) { + oldChildExits.forEach(oldMsg -> { + rmNetworkInterfaceChildService.deleteRmNetworkInterfaceChildById(oldMsg.getId()); + }); + } + } /** * 更新网卡信息 */ diff --git a/tongran-rocketmq/src/main/java/com/tongran/rocketmq/mapper/RmNetworkInterfaceChildMapper.java b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/mapper/RmNetworkInterfaceChildMapper.java new file mode 100644 index 0000000..b33c2fd --- /dev/null +++ b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/mapper/RmNetworkInterfaceChildMapper.java @@ -0,0 +1,61 @@ +package com.tongran.rocketmq.mapper; + +import java.util.List; +import com.tongran.rocketmq.domain.RmNetworkInterfaceChild; + +/** + * 客户端网络接口子接口信息Mapper接口 + * + * @author gyt + * @date 2025-12-15 + */ +public interface RmNetworkInterfaceChildMapper +{ + /** + * 查询客户端网络接口子接口信息 + * + * @param id 客户端网络接口子接口信息主键 + * @return 客户端网络接口子接口信息 + */ + public RmNetworkInterfaceChild selectRmNetworkInterfaceChildById(Long id); + + /** + * 查询客户端网络接口子接口信息列表 + * + * @param rmNetworkInterfaceChild 客户端网络接口子接口信息 + * @return 客户端网络接口子接口信息集合 + */ + public List selectRmNetworkInterfaceChildList(RmNetworkInterfaceChild rmNetworkInterfaceChild); + + /** + * 新增客户端网络接口子接口信息 + * + * @param rmNetworkInterfaceChild 客户端网络接口子接口信息 + * @return 结果 + */ + public int insertRmNetworkInterfaceChild(RmNetworkInterfaceChild rmNetworkInterfaceChild); + + /** + * 修改客户端网络接口子接口信息 + * + * @param rmNetworkInterfaceChild 客户端网络接口子接口信息 + * @return 结果 + */ + public int updateRmNetworkInterfaceChild(RmNetworkInterfaceChild rmNetworkInterfaceChild); + + /** + * 删除客户端网络接口子接口信息 + * + * @param id 客户端网络接口子接口信息主键 + * @return 结果 + */ + public int deleteRmNetworkInterfaceChildById(Long id); + + /** + * 批量删除客户端网络接口子接口信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteRmNetworkInterfaceChildByIds(Long[] ids); +} diff --git a/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/IRmNetworkInterfaceChildService.java b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/IRmNetworkInterfaceChildService.java new file mode 100644 index 0000000..8ee66b0 --- /dev/null +++ b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/IRmNetworkInterfaceChildService.java @@ -0,0 +1,61 @@ +package com.tongran.rocketmq.service; + +import java.util.List; +import com.tongran.rocketmq.domain.RmNetworkInterfaceChild; + +/** + * 客户端网络接口子接口信息Service接口 + * + * @author gyt + * @date 2025-12-15 + */ +public interface IRmNetworkInterfaceChildService +{ + /** + * 查询客户端网络接口子接口信息 + * + * @param id 客户端网络接口子接口信息主键 + * @return 客户端网络接口子接口信息 + */ + public RmNetworkInterfaceChild selectRmNetworkInterfaceChildById(Long id); + + /** + * 查询客户端网络接口子接口信息列表 + * + * @param rmNetworkInterfaceChild 客户端网络接口子接口信息 + * @return 客户端网络接口子接口信息集合 + */ + public List selectRmNetworkInterfaceChildList(RmNetworkInterfaceChild rmNetworkInterfaceChild); + + /** + * 新增客户端网络接口子接口信息 + * + * @param rmNetworkInterfaceChild 客户端网络接口子接口信息 + * @return 结果 + */ + public int insertRmNetworkInterfaceChild(RmNetworkInterfaceChild rmNetworkInterfaceChild); + + /** + * 修改客户端网络接口子接口信息 + * + * @param rmNetworkInterfaceChild 客户端网络接口子接口信息 + * @return 结果 + */ + public int updateRmNetworkInterfaceChild(RmNetworkInterfaceChild rmNetworkInterfaceChild); + + /** + * 批量删除客户端网络接口子接口信息 + * + * @param ids 需要删除的客户端网络接口子接口信息主键集合 + * @return 结果 + */ + public int deleteRmNetworkInterfaceChildByIds(Long[] ids); + + /** + * 删除客户端网络接口子接口信息信息 + * + * @param id 客户端网络接口子接口信息主键 + * @return 结果 + */ + public int deleteRmNetworkInterfaceChildById(Long id); +} diff --git a/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/impl/InitialBandwidthTrafficServiceImpl.java b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/impl/InitialBandwidthTrafficServiceImpl.java index 29388fe..31903a0 100644 --- a/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/impl/InitialBandwidthTrafficServiceImpl.java +++ b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/impl/InitialBandwidthTrafficServiceImpl.java @@ -2,9 +2,12 @@ package com.tongran.rocketmq.service.impl; import com.tongran.common.core.utils.DateUtils; import com.tongran.common.core.utils.EchartsDataUtils; +import com.tongran.common.core.utils.EchartsMoreDataUtils; import com.tongran.common.core.utils.SpeedUtils; import com.tongran.rocketmq.domain.InitialBandwidthTraffic; +import com.tongran.rocketmq.domain.RmNetworkInterfaceChild; import com.tongran.rocketmq.mapper.InitialBandwidthTrafficMapper; +import com.tongran.rocketmq.mapper.RmNetworkInterfaceChildMapper; import com.tongran.rocketmq.service.IInitialBandwidthTrafficService; import com.tongran.rocketmq.utils.TableRouterUtil; import lombok.extern.slf4j.Slf4j; @@ -34,6 +37,8 @@ public class InitialBandwidthTrafficServiceImpl implements IInitialBandwidthTraf { @Autowired private InitialBandwidthTrafficMapper initialBandwidthTrafficMapper; + @Autowired + private RmNetworkInterfaceChildMapper rmNetworkInterfaceChildMapper; /** * 查询初始带宽流量 @@ -217,6 +222,11 @@ public class InitialBandwidthTrafficServiceImpl implements IInitialBandwidthTraf .collect(Collectors.toList()); return list; } + private boolean isEthernetInterface(String name) { + return name.startsWith("eth") || // Linux 传统 + name.startsWith("en") || // systemd 命名 (enp3s0) + name.startsWith("em"); // 有些主板网卡 + } /** * 查询eth0流量信息并封装为多折线ECharts图表数据 * @param initialBandwidthTraffic @@ -224,34 +234,77 @@ public class InitialBandwidthTrafficServiceImpl implements IInitialBandwidthTraf */ @Override public Map netInterfaceTrafficEcharts(InitialBandwidthTraffic initialBandwidthTraffic) { - // 流量信息 - List list = getListByTableName(initialBandwidthTraffic); + // 主网卡流量信息 + List mainList = getListByTableName(initialBandwidthTraffic); + String originalName = initialBandwidthTraffic.getName(); + String name = originalName; + + if (originalName != null && originalName.contains("(")) { + int index = originalName.indexOf("("); + name = originalName.substring(0, index); + } + + // 存储所有网卡的数据 + Map> interfaceDataMap = new LinkedHashMap<>(); + // 展示关系 + Map showRealation = new HashMap<>(); + interfaceDataMap.put(name, mainList); + showRealation.put(name+"netInTraffic", name+"入站流量"); + showRealation.put(name+"netOutTraffic", name+"出站流量"); + + // 如果是Ethernet类型,查询子网卡 + if(isEthernetInterface(name)){ + RmNetworkInterfaceChild query = new RmNetworkInterfaceChild(); + query.setClientId(initialBandwidthTraffic.getClientId()); + query.setParentInterface(name); + List children = rmNetworkInterfaceChildMapper.selectRmNetworkInterfaceChildList(query); + if(children != null && !children.isEmpty()){ + for (RmNetworkInterfaceChild child : children) { + InitialBandwidthTraffic childTraffic = new InitialBandwidthTraffic(); + BeanUtils.copyProperties(initialBandwidthTraffic, childTraffic); + childTraffic.setName(child.getInterfaceName()); + List childTrafficList = getListByTableName(childTraffic); + + if(childTrafficList != null && !childTrafficList.isEmpty()){ + interfaceDataMap.put(child.getInterfaceName(), childTrafficList); + showRealation.put(child.getInterfaceName()+"netInTraffic", child.getInterfaceName()+"入站流量"); + showRealation.put(child.getInterfaceName()+"netOutTraffic", child.getInterfaceName()+"出站流量"); + } + } + } + } + try { - String unit = SpeedUtils.calculateUnitWithStringTraffic(list, "inSpeed", "outSpeed"); + // 计算单位 + String unit = SpeedUtils.calculateUnitWithStringTraffic(mainList, "inSpeed", "outSpeed"); if(initialBandwidthTraffic.getUnit() != null){ unit = initialBandwidthTraffic.getUnit(); } BigDecimal divisor = SpeedUtils.getDivisor(unit); - Map> extractors = new LinkedHashMap<>(); - extractors.put("netInSpeedData", info -> - info != null && info.getInSpeed() != null ? - new BigDecimal(info.getInSpeed()).divide(divisor, 2, RoundingMode.HALF_UP) : - null); - extractors.put("netOutSpeedData", info -> - info != null && info.getOutSpeed() != null ? - new BigDecimal(info.getOutSpeed()).divide(divisor, 2, RoundingMode.HALF_UP) : - null); - Map resultMap = EchartsDataUtils.buildEchartsDataAutoPadding( - list, InitialBandwidthTraffic::getCreateTime, extractors, - initialBandwidthTraffic.getStartTime(), initialBandwidthTraffic.getEndTime() + // 使用工具类构建多网卡图表数据 + Map resultMap = EchartsMoreDataUtils.buildMultiInterfaceEchartsDataWithTotal( + interfaceDataMap, + InitialBandwidthTraffic::getCreateTime, + info -> info.getInSpeed() != null ? new BigDecimal(info.getInSpeed()) : null, + info -> info.getOutSpeed() != null ? new BigDecimal(info.getOutSpeed()) : null, + initialBandwidthTraffic.getStartTime(), + initialBandwidthTraffic.getEndTime(), + divisor ); + resultMap.put("unit", unit); + if(!showRealation.isEmpty()){ + showRealation.put("totalNetInTraffic", name+"总入站流量"); + showRealation.put("totalNetOutTraffic", name+"总出站流量"); + } + resultMap.put("showRealation", showRealation); return resultMap; + } catch (Exception e){ e.printStackTrace(); + return new HashMap<>(); } - return new HashMap<>(); } // 安全转换方法(处理可能的NumberFormatException) private Double safeConvertToKB(String byteValue) { diff --git a/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/impl/RmNetworkInterfaceChildServiceImpl.java b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/impl/RmNetworkInterfaceChildServiceImpl.java new file mode 100644 index 0000000..d49b070 --- /dev/null +++ b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/impl/RmNetworkInterfaceChildServiceImpl.java @@ -0,0 +1,96 @@ +package com.tongran.rocketmq.service.impl; + +import java.util.List; +import com.tongran.common.core.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.tongran.rocketmq.mapper.RmNetworkInterfaceChildMapper; +import com.tongran.rocketmq.domain.RmNetworkInterfaceChild; +import com.tongran.rocketmq.service.IRmNetworkInterfaceChildService; + +/** + * 客户端网络接口子接口信息Service业务层处理 + * + * @author gyt + * @date 2025-12-15 + */ +@Service +public class RmNetworkInterfaceChildServiceImpl implements IRmNetworkInterfaceChildService +{ + @Autowired + private RmNetworkInterfaceChildMapper rmNetworkInterfaceChildMapper; + + /** + * 查询客户端网络接口子接口信息 + * + * @param id 客户端网络接口子接口信息主键 + * @return 客户端网络接口子接口信息 + */ + @Override + public RmNetworkInterfaceChild selectRmNetworkInterfaceChildById(Long id) + { + return rmNetworkInterfaceChildMapper.selectRmNetworkInterfaceChildById(id); + } + + /** + * 查询客户端网络接口子接口信息列表 + * + * @param rmNetworkInterfaceChild 客户端网络接口子接口信息 + * @return 客户端网络接口子接口信息 + */ + @Override + public List selectRmNetworkInterfaceChildList(RmNetworkInterfaceChild rmNetworkInterfaceChild) + { + return rmNetworkInterfaceChildMapper.selectRmNetworkInterfaceChildList(rmNetworkInterfaceChild); + } + + /** + * 新增客户端网络接口子接口信息 + * + * @param rmNetworkInterfaceChild 客户端网络接口子接口信息 + * @return 结果 + */ + @Override + public int insertRmNetworkInterfaceChild(RmNetworkInterfaceChild rmNetworkInterfaceChild) + { + rmNetworkInterfaceChild.setCreateTime(DateUtils.getNowDate()); + return rmNetworkInterfaceChildMapper.insertRmNetworkInterfaceChild(rmNetworkInterfaceChild); + } + + /** + * 修改客户端网络接口子接口信息 + * + * @param rmNetworkInterfaceChild 客户端网络接口子接口信息 + * @return 结果 + */ + @Override + public int updateRmNetworkInterfaceChild(RmNetworkInterfaceChild rmNetworkInterfaceChild) + { + rmNetworkInterfaceChild.setUpdateTime(DateUtils.getNowDate()); + return rmNetworkInterfaceChildMapper.updateRmNetworkInterfaceChild(rmNetworkInterfaceChild); + } + + /** + * 批量删除客户端网络接口子接口信息 + * + * @param ids 需要删除的客户端网络接口子接口信息主键 + * @return 结果 + */ + @Override + public int deleteRmNetworkInterfaceChildByIds(Long[] ids) + { + return rmNetworkInterfaceChildMapper.deleteRmNetworkInterfaceChildByIds(ids); + } + + /** + * 删除客户端网络接口子接口信息信息 + * + * @param id 客户端网络接口子接口信息主键 + * @return 结果 + */ + @Override + public int deleteRmNetworkInterfaceChildById(Long id) + { + return rmNetworkInterfaceChildMapper.deleteRmNetworkInterfaceChildById(id); + } +} diff --git a/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/impl/RmNetworkInterfaceServiceImpl.java b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/impl/RmNetworkInterfaceServiceImpl.java index c3945b8..0fa602f 100644 --- a/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/impl/RmNetworkInterfaceServiceImpl.java +++ b/tongran-rocketmq/src/main/java/com/tongran/rocketmq/service/impl/RmNetworkInterfaceServiceImpl.java @@ -5,7 +5,9 @@ import com.tongran.common.core.enums.MsgEnum; import com.tongran.common.core.utils.DateUtils; import com.tongran.rocketmq.domain.DeviceMessage; import com.tongran.rocketmq.domain.RmNetworkInterface; +import com.tongran.rocketmq.domain.RmNetworkInterfaceChild; import com.tongran.rocketmq.domain.vo.PolicyTypeVo; +import com.tongran.rocketmq.mapper.RmNetworkInterfaceChildMapper; import com.tongran.rocketmq.mapper.RmNetworkInterfaceMapper; import com.tongran.rocketmq.model.ProducerMode; import com.tongran.rocketmq.producer.MessageProducer; @@ -15,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.Instant; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,6 +35,8 @@ public class RmNetworkInterfaceServiceImpl implements IRmNetworkInterfaceService @Autowired private RmNetworkInterfaceMapper rmNetworkInterfaceMapper; @Autowired + private RmNetworkInterfaceChildMapper rmNetworkInterfaceChildMapper; + @Autowired private ProducerMode producerMode; /** @@ -185,15 +190,41 @@ public class RmNetworkInterfaceServiceImpl implements IRmNetworkInterfaceService RmNetworkInterface rmNetworkInterface = new RmNetworkInterface(); rmNetworkInterface.setClientIds(clientId); List networkInterfaces = rmNetworkInterfaceMapper.selectRmNetworkInterfaceList(rmNetworkInterface); + List childList = new ArrayList<>(); + networkInterfaces.forEach(netMsg -> { + RmNetworkInterfaceChild query = new RmNetworkInterfaceChild(); + query.setClientId(clientId); + query.setParentInterface(netMsg.getInterfaceName()); + List children = rmNetworkInterfaceChildMapper.selectRmNetworkInterfaceChildList(query); + childList.addAll(children); + }); + // 拼接所有符合条件的网络接口名称,用分号隔开 StringBuilder netNameBuilder = new StringBuilder(); + + // 添加父接口名称 for (int i = 0; i < networkInterfaces.size(); i++) { if (i > 0) { netNameBuilder.append(";"); } netNameBuilder.append(networkInterfaces.get(i).getInterfaceName()); } + + // 添加子接口名称 + for (int i = 0; i < childList.size(); i++) { + if (netNameBuilder.length() > 0 || i > 0) { + netNameBuilder.append(";"); + } + netNameBuilder.append(childList.get(i).getInterfaceName()); + } + String netName = netNameBuilder.toString(); + + // 如果没有找到任何接口,可以设置为空或特定值 + if (netName.isEmpty()) { + netName = ""; // 或者设置为 "none" 等其他标识 + } + MessageProducer messageProducer = new MessageProducer(); PolicyTypeVo policyTypeVo = new PolicyTypeVo(); policyTypeVo.setNetName(netName); diff --git a/tongran-rocketmq/src/main/resources/mapper/rocketmq/RmNetworkInterfaceChildMapper.xml b/tongran-rocketmq/src/main/resources/mapper/rocketmq/RmNetworkInterfaceChildMapper.xml new file mode 100644 index 0000000..a40a679 --- /dev/null +++ b/tongran-rocketmq/src/main/resources/mapper/rocketmq/RmNetworkInterfaceChildMapper.xml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, client_id, parent_interface, isp, province, city, public_ip, interface_name, mac_address, interface_type, ipv4_address, ipv6_address, gateway, create_time, update_time, create_by, update_by, bind_ip, new_flag from rm_network_interface_child + + + + + + + + insert into rm_network_interface_child + + client_id, + parent_interface, + isp, + province, + city, + public_ip, + interface_name, + mac_address, + interface_type, + ipv4_address, + ipv6_address, + gateway, + create_time, + update_time, + create_by, + update_by, + bind_ip, + new_flag, + + + #{clientId}, + #{parentInterface}, + #{isp}, + #{province}, + #{city}, + #{publicIp}, + #{interfaceName}, + #{macAddress}, + #{interfaceType}, + #{ipv4Address}, + #{ipv6Address}, + #{gateway}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{bindIp}, + #{newFlag}, + + + + + update rm_network_interface_child + + client_id = #{clientId}, + parent_interface = #{parentInterface}, + isp = #{isp}, + province = #{province}, + city = #{city}, + public_ip = #{publicIp}, + interface_name = #{interfaceName}, + mac_address = #{macAddress}, + interface_type = #{interfaceType}, + ipv4_address = #{ipv4Address}, + ipv6_address = #{ipv6Address}, + gateway = #{gateway}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + bind_ip = #{bindIp}, + new_flag = #{newFlag}, + + + + + and id = #{id} + + + and mac_address = #{macAddress} and client_id = #{clientId} + + + and 1=0 + + + + + + + delete from rm_network_interface_child where id = #{id} + + + + delete from rm_network_interface_child where id in + + #{id} + + + \ No newline at end of file