From df7ed79fcbd5dcf0933141e76a4fa2bbbdf9e37f Mon Sep 17 00:00:00 2001 From: gaoyutao Date: Tue, 9 Sep 2025 17:45:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=A6=96=E9=A1=B5=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=EF=BC=8C=E5=BF=83=E8=B7=B3=E7=9B=91=E6=8E=A7=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E6=94=B9=E4=B8=BAredis=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/RemoteRevenueConfigService.java | 4 + .../api/domain/AllInterfaceNameRemote.java | 77 +++++++++ .../RemoteRevenueConfigFallbackFactory.java | 6 + .../AllInterfaceNameController.java | 13 ++ .../system/controller/ScreenController.java | 114 +++++++++++++ .../mapper/EpsServerRevenueConfigMapper.java | 12 ++ .../service/EpsInitialTrafficDataService.java | 6 + .../IEpsServerRevenueConfigService.java | 11 ++ .../IInitialSwitchInfoDetailsService.java | 6 + .../IRmResourceRegistrationService.java | 3 + .../EpsInitialTrafficDataServiceImpl.java | 34 ++++ .../EpsServerRevenueConfigServiceImpl.java | 17 ++ .../InitialSwitchInfoDetailsServiceImpl.java | 47 ++++- .../RmResourceRegistrationServiceImpl.java | 40 +++++ .../system/EpsServerRevenueConfigMapper.xml | 7 + .../system/RmResourceRegistrationMapper.xml | 2 +- .../rocketmq/consumer/RocketMsgListener.java | 161 ++++++++++++++---- 17 files changed, 519 insertions(+), 41 deletions(-) create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/AllInterfaceNameRemote.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/ScreenController.java diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteRevenueConfigService.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteRevenueConfigService.java index d337b4c..1c1dcaa 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteRevenueConfigService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteRevenueConfigService.java @@ -3,6 +3,7 @@ package com.ruoyi.system.api; import com.ruoyi.common.core.constant.SecurityConstants; import com.ruoyi.common.core.constant.ServiceNameConstants; import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.api.domain.AllInterfaceNameRemote; import com.ruoyi.system.api.domain.EpsInitialTrafficDataRemote; import com.ruoyi.system.api.domain.InitialSwitchInfoDetailsRemote; import com.ruoyi.system.api.domain.RmResourceRegistrationRemote; @@ -37,4 +38,7 @@ public interface RemoteRevenueConfigService @PostMapping("/registration/updateStatusByResource") public R updateStatusByResource(@RequestBody RmResourceRegistrationRemote queryParam, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + @PostMapping("/interfaceName/getMsgByClientId") + public R getMsgByClientId(@RequestBody AllInterfaceNameRemote queryParam, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); } diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/AllInterfaceNameRemote.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/AllInterfaceNameRemote.java new file mode 100644 index 0000000..b3c3561 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/AllInterfaceNameRemote.java @@ -0,0 +1,77 @@ +package com.ruoyi.system.api.domain; + +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import lombok.Data; + +import java.util.Set; + +/** + * 所有接口名称对象 all_interface_name + * + * @author gyt + * @date 2025-08-25 + */ +@Data +public class AllInterfaceNameRemote extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 客户端唯一标识 */ + @Excel(name = "客户端唯一标识") + private String clientId; + + /** 接口名称 */ + @Excel(name = "接口名称") + private String interfaceName; + + /** 设备序列号 */ + @Excel(name = "设备序列号") + private String deviceSn; + + /** 节点名称 */ + @Excel(name = "节点名称") + private String nodeName; + + /** 业务代码 */ + @Excel(name = "业务代码") + private String businessCode; + + /** 业务名称 */ + @Excel(name = "业务名称") + private String businessName; + + /** 资源类型 */ + @Excel(name = "资源类型") + private String resourceType; + + /** 交换机名称 */ + @Excel(name = "交换机名称") + private String switchName; + + /** 接口连接设备类型 */ + @Excel(name = "接口连接设备类型") + private String interfaceDeviceType; + + /** 服务器网口 */ + @Excel(name = "服务器网口") + private String serverPort; + + /** 交换机硬件SN */ + @Excel(name = "交换机硬件SN") + private String switchSn; + + /** 接口名称集合 */ + private Set interfaceNames; + /** 交换机ip */ + @Excel(name = "交换机ip") + private String switchIp; + + /** 服务器ip */ + @Excel(name = "服务器ip") + private String serverIp; + +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteRevenueConfigFallbackFactory.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteRevenueConfigFallbackFactory.java index 643e12c..36e45cc 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteRevenueConfigFallbackFactory.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteRevenueConfigFallbackFactory.java @@ -2,6 +2,7 @@ package com.ruoyi.system.api.factory; import com.ruoyi.common.core.domain.R; import com.ruoyi.system.api.RemoteRevenueConfigService; +import com.ruoyi.system.api.domain.AllInterfaceNameRemote; import com.ruoyi.system.api.domain.EpsInitialTrafficDataRemote; import com.ruoyi.system.api.domain.InitialSwitchInfoDetailsRemote; import com.ruoyi.system.api.domain.RmResourceRegistrationRemote; @@ -40,6 +41,11 @@ public class RemoteRevenueConfigFallbackFactory implements FallbackFactory updateStatusByResource(RmResourceRegistrationRemote queryParam, String source) { return R.fail("资源状态修改失败:" + throwable.getMessage()); } + + @Override + public R getMsgByClientId(AllInterfaceNameRemote queryParam, String source) { + return R.fail("获取服务器信息失败:" + throwable.getMessage()); + } }; } } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/AllInterfaceNameController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/AllInterfaceNameController.java index f4feda5..2eb006b 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/AllInterfaceNameController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/AllInterfaceNameController.java @@ -1,6 +1,8 @@ package com.ruoyi.system.controller; +import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.security.annotation.InnerAuth; import com.ruoyi.common.security.annotation.RequiresPermissions; import com.ruoyi.system.domain.AllInterfaceName; import com.ruoyi.system.service.IAllInterfaceNameService; @@ -35,5 +37,16 @@ public class AllInterfaceNameController extends BaseController List list = allInterfaceNameService.selectAllInterfaceNameList(allInterfaceName); return list; } + /** + * 查询所有接口名称列表 + */ + @InnerAuth + @PostMapping("/getMsgByClientId") + public R getMsgByClientId(@RequestBody AllInterfaceName allInterfaceName) + { + List list = allInterfaceNameService.selectAllInterfaceNameList(allInterfaceName); + AllInterfaceName allInterfaceName1 = list.isEmpty()?new AllInterfaceName():list.get(0); + return R.ok(allInterfaceName1); + } } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/ScreenController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/ScreenController.java new file mode 100644 index 0000000..61e5eed --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/ScreenController.java @@ -0,0 +1,114 @@ +package com.ruoyi.system.controller; + +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.system.domain.RmResourceRegistration; +import com.ruoyi.system.service.EpsInitialTrafficDataService; +import com.ruoyi.system.service.IEpsServerRevenueConfigService; +import com.ruoyi.system.service.IInitialSwitchInfoDetailsService; +import com.ruoyi.system.service.IRmResourceRegistrationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * 首页Controller + * + * @author gyt + * @date 2025-08-25 + */ +@RestController +@RequestMapping("/screen") +public class ScreenController extends BaseController +{ + @Autowired + private IEpsServerRevenueConfigService epsServerRevenueConfigService; + @Autowired + private IRmResourceRegistrationService rmResourceRegistrationService; + @Autowired + private EpsInitialTrafficDataService epsInitialTrafficDataService; + @Autowired + private IInitialSwitchInfoDetailsService initialSwitchInfoDetailsService; + + /** + * 统计当前在线服务器的流量相关的业务数 + * @return + */ + @RequiresPermissions("system:config:list") + @GetMapping("/countBusinessByTraffic") + public AjaxResult countBusinessByTraffic() + { + return success(epsServerRevenueConfigService.countBusinessByTraffic()); + } + + /** + * 服务器在线率 + * @return + */ + @RequiresPermissions("system:config:list") + @GetMapping("/getServerOnlineRate") + public AjaxResult getServerOnlineRate() + { + return rmResourceRegistrationService.getServerOnlineRate(); + } + /** + * 交换机在线数量 + * @return + */ + @RequiresPermissions("system:config:list") + @GetMapping("/countSwitchNum") + public AjaxResult countSwitchNum() + { + RmResourceRegistration rmResourceRegistration = new RmResourceRegistration(); + rmResourceRegistration.setResourceType("2"); + // 查询资源列表(处理可能的null结果) + List resourceList = Optional.ofNullable(rmResourceRegistrationService.selectRmResourceRegistrationList(rmResourceRegistration)) + .orElse(Collections.emptyList()); + int onlineCount = (int) resourceList.stream() + .filter(resource -> "1".equals(resource.getOnlineStatus())) + .count(); + return AjaxResult.success() + .put("total", resourceList.size()) + .put("onlineCount", onlineCount); + } + + /** + * 当日业务的在线设备数量统计TOP5 + * @return + */ + @RequiresPermissions("system:config:list") + @GetMapping("/countDeviceNumTop5") + public AjaxResult countDeviceNumTop5() + { + List maps = epsServerRevenueConfigService.countDeviceNumTop5(); + return success(maps); + } + + /** + * 当前在线服务器发送带宽总流量 + * @return + */ + @RequiresPermissions("system:config:list") + @GetMapping("/sumTrafficByServer") + public AjaxResult sumTrafficByServer() + { + return success(epsInitialTrafficDataService.sumTrafficByServer()); + } + /** + * 当前在线交换机接收带宽总流量 + * @return + */ + @RequiresPermissions("system:config:list") + @GetMapping("/sumTrafficBySwitch") + public AjaxResult sumTrafficBySwitch() + { + return success(initialSwitchInfoDetailsService.sumTrafficBySwitch()); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/EpsServerRevenueConfigMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/EpsServerRevenueConfigMapper.java index a4f4815..56a8d23 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/EpsServerRevenueConfigMapper.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/EpsServerRevenueConfigMapper.java @@ -79,4 +79,16 @@ public interface EpsServerRevenueConfigMapper public Map getNodeMsgByIp(@Param("ipAddress") String ipAddress); int updateEpsServerRevenueConfigByServerSn(EpsServerRevenueConfig epsServerRevenueConfig); + + /** + * 当前在线服务器的流量相关的业务数 + * @return + */ + Integer countBusinessByTraffic(); + + /** + * 当日业务的在线设备数量统计TOP5 + * @return + */ + List countDeviceNumTop5(); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/EpsInitialTrafficDataService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/EpsInitialTrafficDataService.java index 4e4042d..eb49455 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/EpsInitialTrafficDataService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/EpsInitialTrafficDataService.java @@ -3,6 +3,7 @@ package com.ruoyi.system.service; import com.ruoyi.system.domain.EpsInitialTrafficData; import com.ruoyi.system.domain.EpsNodeBandwidth; +import java.math.BigDecimal; import java.util.List; /** @@ -55,4 +56,9 @@ public interface EpsInitialTrafficDataService { */ void recalculateServer95Bandwidth(EpsNodeBandwidth epsNodeBandwidth, String dailyStartTime, String dailyEndTime); + /** + * 当前在线服务器发送带宽总流量 + * @return + */ + BigDecimal sumTrafficByServer(); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IEpsServerRevenueConfigService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IEpsServerRevenueConfigService.java index df76a57..65fe5ef 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IEpsServerRevenueConfigService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IEpsServerRevenueConfigService.java @@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.R; import com.ruoyi.system.domain.EpsServerRevenueConfig; import java.util.List; +import java.util.Map; /** * 服务器收益方式配置Service接口 @@ -66,4 +67,14 @@ public interface IEpsServerRevenueConfigService * @param epsServerRevenueConfig */ R autoSaveServiceTrafficData(EpsServerRevenueConfig epsServerRevenueConfig); + /** + * 当前在线服务器的流量相关的业务数 + * @return + */ + Integer countBusinessByTraffic(); + /** + * 当日业务的在线设备数量统计TOP5 + * @return + */ + List countDeviceNumTop5(); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IInitialSwitchInfoDetailsService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IInitialSwitchInfoDetailsService.java index 7156578..3ef2572 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IInitialSwitchInfoDetailsService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IInitialSwitchInfoDetailsService.java @@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.R; import com.ruoyi.system.domain.EpsNodeBandwidth; import com.ruoyi.system.domain.InitialSwitchInfoDetails; +import java.math.BigDecimal; import java.util.List; /** @@ -88,4 +89,9 @@ public interface IInitialSwitchInfoDetailsService * @return */ List getRelevantSwitch(EpsNodeBandwidth epsNodeBandwidth, String dailyStartTime, String dailyEndTime); + /** + * 当前在线交换机接收带宽总流量 + * @return + */ + BigDecimal sumTrafficBySwitch(); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IRmResourceRegistrationService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IRmResourceRegistrationService.java index a5b8e35..786067b 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IRmResourceRegistrationService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IRmResourceRegistrationService.java @@ -1,6 +1,7 @@ package com.ruoyi.system.service; import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.system.domain.RmResourceRegistration; import java.util.List; @@ -85,4 +86,6 @@ public interface IRmResourceRegistrationService * @return */ R updateStatusByResource(RmResourceRegistration rmResourceRegistration); + + AjaxResult getServerOnlineRate(); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EpsInitialTrafficDataServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EpsInitialTrafficDataServiceImpl.java index 04e492f..e2f2297 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EpsInitialTrafficDataServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EpsInitialTrafficDataServiceImpl.java @@ -17,7 +17,9 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -257,6 +259,38 @@ public class EpsInitialTrafficDataServiceImpl implements EpsInitialTrafficDataSe } } + /** + * 当前在线服务器发送带宽总流量 + * @return + */ + @Override + public BigDecimal sumTrafficByServer() { + // 获取当前时间 + LocalDateTime now = LocalDateTime.now(); + // 结束时间 + LocalDateTime endTime = now.minusSeconds(1); + // 开始时间 + LocalDateTime startTime = now.minusMinutes(5); + // 定义日期时间格式 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // 格式化为字符串 + String dailyStartTime = startTime.format(formatter); + String dailyEndTime = endTime.format(formatter); + BigDecimal total = BigDecimal.ZERO; + EpsInitialTrafficData epsInitialTrafficData = new EpsInitialTrafficData(); + epsInitialTrafficData.setStartTime(dailyStartTime); + epsInitialTrafficData.setEndTime(dailyEndTime); + List dataList = query(epsInitialTrafficData); + if(!dataList.isEmpty()){ + for (EpsInitialTrafficData initialTrafficData : dataList) { + // 服务器发送带宽流量 + BigDecimal outSpeed = CalculateUtil.parseSpeedToMbps(initialTrafficData.getOutSpeed()); + total = total.add(outSpeed); + } + } + return total.setScale(0, RoundingMode.HALF_UP); + } + /** * 处理单个设备的带宽计算 */ diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EpsServerRevenueConfigServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EpsServerRevenueConfigServiceImpl.java index e4d79c2..bea852c 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EpsServerRevenueConfigServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EpsServerRevenueConfigServiceImpl.java @@ -213,6 +213,23 @@ public class EpsServerRevenueConfigServiceImpl implements IEpsServerRevenueConfi return R.fail("数据保存失败:" + e.getMessage()); } } + /** + * 当前在线服务器的流量相关的业务数 + * @return + */ + @Override + public Integer countBusinessByTraffic() { + return epsServerRevenueConfigMapper.countBusinessByTraffic(); + } + /** + * 当日业务的在线设备数量统计TOP5 + * @return + */ + @Override + public List countDeviceNumTop5() { + return epsServerRevenueConfigMapper.countDeviceNumTop5(); + } + private static String getNullableString(Map map, String key) { Object value = map.get(key); return value != null ? value.toString() : null; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/InitialSwitchInfoDetailsServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/InitialSwitchInfoDetailsServiceImpl.java index 9b7ba7a..822cdf8 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/InitialSwitchInfoDetailsServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/InitialSwitchInfoDetailsServiceImpl.java @@ -16,6 +16,8 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -342,8 +344,9 @@ public class InitialSwitchInfoDetailsServiceImpl implements IInitialSwitchInfoDe List speedsInMbps = dataList.stream() .map(data -> { // 根据 interfaceDeviceType 选择 inSpeed 或 outSpeed - String speed = ("1".equals(data.getInterfaceDeviceType())) ? - data.getInSpeed() + "" : data.getOutSpeed() + ""; + String speed = "1".equals(data.getInterfaceDeviceType()) + ? (data.getInSpeed() != null ? data.getInSpeed().toString() : BigDecimal.ZERO.toString()) + : (data.getOutSpeed() != null ? data.getOutSpeed().toString() : BigDecimal.ZERO.toString()); // 如果 speed 是纯数字,补充单位 "B/S"(Bytes/s) if (speed.matches("^\\d+(\\.\\d+)?$")) { speed += " B/S"; @@ -388,6 +391,40 @@ public class InitialSwitchInfoDetailsServiceImpl implements IInitialSwitchInfoDe return dataList; } + @Override + public BigDecimal sumTrafficBySwitch() { + // 获取当前时间 + LocalDateTime now = LocalDateTime.now(); + // 结束时间 + LocalDateTime endTime = now.minusSeconds(1); + // 开始时间 + LocalDateTime startTime = now.minusMinutes(5); + // 定义日期时间格式 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + // 格式化为字符串 + String dailyStartTime = startTime.format(formatter); + String dailyEndTime = endTime.format(formatter); + BigDecimal total = BigDecimal.ZERO; + InitialSwitchInfoDetails switchInfoDetails = new InitialSwitchInfoDetails(); + switchInfoDetails.setStartTime(dailyStartTime); + switchInfoDetails.setEndTime(dailyEndTime); + List dataList = initialSwitchInfoDetailsMapper + .selectInitialSwitchInfoDetailsList(switchInfoDetails); + if(!dataList.isEmpty()){ + for (InitialSwitchInfoDetails initialSwitchInfoDetails : dataList) { + // 交换机接收带宽流量 + String speed = initialSwitchInfoDetails.getInSpeed() != null ? initialSwitchInfoDetails.getInSpeed().toString() : BigDecimal.ZERO.toString(); + // 如果 speed 是纯数字,补充单位 "B/S"(Bytes/s) + if (speed.matches("^\\d+(\\.\\d+)?$")) { + speed += " B/S"; + } + BigDecimal inSpeed = CalculateUtil.parseSpeedToMbps(speed); + total = total.add(inSpeed); + } + } + return total.setScale(0, RoundingMode.HALF_UP); + } + /** * 处理单个交换机的带宽计算 @@ -565,8 +602,10 @@ public class InitialSwitchInfoDetailsServiceImpl implements IInitialSwitchInfoDe // 1. 提取并转换带宽值 List speedsInMbps = dataList.stream() .map(data -> { - String speed = ("1".equals(data.getInterfaceDeviceType())) ? - data.getInSpeed() + "" : data.getOutSpeed() + ""; + // 根据 interfaceDeviceType 选择 inSpeed 或 outSpeed + String speed = "1".equals(data.getInterfaceDeviceType()) + ? (data.getInSpeed() != null ? data.getInSpeed().toString() : BigDecimal.ZERO.toString()) + : (data.getOutSpeed() != null ? data.getOutSpeed().toString() : BigDecimal.ZERO.toString()); if (speed.matches("^\\d+(\\.\\d+)?$")) { speed += " B/S"; } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/RmResourceRegistrationServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/RmResourceRegistrationServiceImpl.java index 5b77ccf..96e0740 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/RmResourceRegistrationServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/RmResourceRegistrationServiceImpl.java @@ -2,6 +2,7 @@ package com.ruoyi.system.service.impl; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.system.domain.EpsNodeBandwidth; import com.ruoyi.system.domain.EpsServerRevenueConfig; @@ -15,6 +16,8 @@ import com.ruoyi.system.service.IRmResourceRegistrationService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.List; import java.util.Map; @@ -241,4 +244,41 @@ public class RmResourceRegistrationServiceImpl implements IRmResourceRegistratio return R.ok("状态修改成功"); } + /** + * 服务器在线率 + * @return + */ + @Override + public AjaxResult getServerOnlineRate() { + // 查询所有符合条件的资源 + RmResourceRegistration queryParam = new RmResourceRegistration(); + queryParam.setResourceType("1"); + List resourceList = rmResourceRegistrationMapper.selectRmResourceRegistrationList(queryParam); + + // 计算在线数量和总数 + int totalCount = resourceList.size(); + if (totalCount == 0) { + return AjaxResult.error("没有找到符合条件的资源"); + } + + int onlineCount = (int) resourceList.stream() + .filter(resource -> "1".equals(resource.getOnlineStatus())) + .count(); + int offlineCount = (int) resourceList.stream() + .filter(resource -> "0".equals(resource.getOnlineStatus())) + .count(); + + // 计算在线率 + BigDecimal onlineRate = BigDecimal.valueOf(onlineCount) + .divide(BigDecimal.valueOf(totalCount), 0, RoundingMode.HALF_UP).multiply(new BigDecimal(100)); + + // 返回结果 + return AjaxResult.success() + .put("onlineCount", onlineCount) + .put("offlineCount", offlineCount) + .put("total", totalCount) + .put("onlineRate", onlineRate); + } + + } diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/EpsServerRevenueConfigMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/EpsServerRevenueConfigMapper.xml index 78a2a9a..a639d60 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/EpsServerRevenueConfigMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/EpsServerRevenueConfigMapper.xml @@ -152,4 +152,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where hardware_sn = #{hardwareSn} + + + \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/RmResourceRegistrationMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/RmResourceRegistrationMapper.xml index 0c79242..0d78ba3 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/RmResourceRegistrationMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/RmResourceRegistrationMapper.xml @@ -267,6 +267,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" updater_id = #{updaterId}, updater_name = #{updaterName}, - where id = #{id} + where ip_address = #{ipAddress} \ No newline at end of file diff --git a/ruoyi-rocketmq/src/main/java/com/ruoyi/rocketmq/consumer/RocketMsgListener.java b/ruoyi-rocketmq/src/main/java/com/ruoyi/rocketmq/consumer/RocketMsgListener.java index 1d12370..ce5d295 100644 --- a/ruoyi-rocketmq/src/main/java/com/ruoyi/rocketmq/consumer/RocketMsgListener.java +++ b/ruoyi-rocketmq/src/main/java/com/ruoyi/rocketmq/consumer/RocketMsgListener.java @@ -2,21 +2,26 @@ package com.ruoyi.rocketmq.consumer; import com.alibaba.fastjson.JSON; import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.rocketmq.domain.*; import com.ruoyi.rocketmq.enums.MessageCodeEnum; import com.ruoyi.rocketmq.producer.ConsumeException; import com.ruoyi.rocketmq.service.*; import com.ruoyi.rocketmq.utils.JsonDataParser; import com.ruoyi.system.api.RemoteRevenueConfigService; +import com.ruoyi.system.api.domain.AllInterfaceNameRemote; import com.ruoyi.system.api.domain.EpsInitialTrafficDataRemote; import com.ruoyi.system.api.domain.InitialSwitchInfoDetailsRemote; +import com.ruoyi.system.api.domain.RmResourceRegistrationRemote; import lombok.extern.slf4j.Slf4j; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; import org.apache.rocketmq.common.message.MessageExt; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -27,7 +32,7 @@ import java.math.RoundingMode; import java.util.Date; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -38,11 +43,15 @@ import java.util.stream.Collectors; @Component public class RocketMsgListener implements MessageListenerConcurrently { - // 在类中添加以下成员变量来记录心跳状态 - private final Map heartbeatStatusMap = new ConcurrentHashMap<>(); // 客户端ID -> 连续丢失心跳次数 - private final Map lastHeartbeatTimeMap = new ConcurrentHashMap<>(); // 客户端ID -> 最后心跳时间 + private static final String HEARTBEAT_STATUS_PREFIX = "heartbeat:status:"; + private static final String HEARTBEAT_TIME_PREFIX = "heartbeat:time:"; + private static final String HEARTBEAT_ALERT_PREFIX = "heartbeat:alert:"; + String HEARTBEAT_RECOVERY_COUNT_PREFIX = "heartbeat:recovery:count:"; + private static final long HEARTBEAT_TIMEOUT = 180000; // 3分钟超时 + @Autowired + private RedisTemplate redisTemplate; private final IInitialBandwidthTrafficService initialBandwidthTrafficService; private final RemoteRevenueConfigService remoteRevenueConfigService; @Autowired @@ -396,26 +405,43 @@ public class RocketMsgListener implements MessageListenerConcurrently { * @param message */ private void handleHeartbeatMessage(DeviceMessage message) { - try { - List heartbeats = JsonDataParser.parseJsonData(message.getData(), InitialHeartbeatListen.class); - if(!heartbeats.isEmpty()){ - InitialHeartbeatListen heartbeat = heartbeats.get(0); - String clientId = message.getClientId(); - log.info("处理心跳消息,客户端ID: {}, 时间: {}", clientId, heartbeat.getTimestamp()); + List heartbeats = JsonDataParser.parseJsonData(message.getData(), InitialHeartbeatListen.class); + if(!heartbeats.isEmpty()){ + InitialHeartbeatListen heartbeat = heartbeats.get(0); + String clientId = message.getClientId(); + log.info("处理心跳消息,客户端ID: {}, 时间: {}", clientId, heartbeat.getTimestamp()); + // 使用Redis存储状态 + String statusKey = HEARTBEAT_STATUS_PREFIX + clientId; + String timeKey = HEARTBEAT_TIME_PREFIX + clientId; + String recoveryCountKey = HEARTBEAT_RECOVERY_COUNT_PREFIX + clientId; // 恢复次数计数器 + try { + // 重置丢失计数为0,设置最后心跳时间 + redisTemplate.opsForValue().set(statusKey, "0"); + redisTemplate.opsForValue().set(timeKey, String.valueOf(System.currentTimeMillis())); - // 更新心跳状态 - heartbeatStatusMap.put(clientId, 0); // 重置为0表示收到心跳 - lastHeartbeatTimeMap.put(clientId, System.currentTimeMillis()); + // 检查是否之前有告警状态 + if (Boolean.TRUE.equals(redisTemplate.hasKey(HEARTBEAT_ALERT_PREFIX + clientId))) { + // 获取当前恢复次数 + String recoveryCountStr = redisTemplate.opsForValue().get(recoveryCountKey); + int recoveryCount = (recoveryCountStr == null) ? 1 : Integer.parseInt(recoveryCountStr) + 1; - // 检查是否之前有丢失心跳的情况 - if (heartbeatStatusMap.getOrDefault(clientId, 0) > 0) { - // 之前有丢失心跳,现在恢复了,记录恢复日志 - log.warn("客户端ID: {} 心跳恢复", clientId); - insertHeartbeatLog(clientId, "2", "心跳恢复,服务器在线"); // 1表示恢复 + if (recoveryCount == 2) { + // 达到2次恢复,执行状态修改 + log.warn("客户端ID: {} 心跳恢复达到2次,修改设备状态为在线", clientId); + insertHeartbeatLog(clientId, "2", "心跳恢复,设备在线状态改为在线"); + redisTemplate.delete(HEARTBEAT_ALERT_PREFIX + clientId); + redisTemplate.delete(recoveryCountKey); // 清除恢复计数器 + // 修改资源状态 + getResourceMsg(clientId, "1"); + } else { + // 未达到2次,只记录恢复次数 + log.info("客户端ID: {} 心跳恢复第{}次", clientId, recoveryCount); + redisTemplate.opsForValue().set(recoveryCountKey, String.valueOf(recoveryCount)); + } } + } catch (Exception e) { + log.error("处理心跳消息异常, clientId: {}", clientId, e); } - } catch (Exception e) { - log.error("处理心跳消息异常", e); } } @@ -423,31 +449,94 @@ public class RocketMsgListener implements MessageListenerConcurrently { @Scheduled(fixedRate = 60000) // 每分钟检查一次 public void checkHeartbeatStatus() { long currentTime = System.currentTimeMillis(); - long heartbeatTimeout = 180000; // 3分钟无心跳认为丢失 + // 获取所有客户端时间键 + Set timeKeys = redisTemplate.keys(HEARTBEAT_TIME_PREFIX + "*"); + if (timeKeys == null) return; - for (Map.Entry entry : lastHeartbeatTimeMap.entrySet()) { - String clientId = entry.getKey(); - long lastHeartbeatTime = entry.getValue(); + for (String timeKey : timeKeys) { + String clientId = timeKey.substring(HEARTBEAT_TIME_PREFIX.length()); + String statusKey = HEARTBEAT_STATUS_PREFIX + clientId; - if (currentTime - lastHeartbeatTime > heartbeatTimeout) { - // 心跳超时 - int lostCount = heartbeatStatusMap.getOrDefault(clientId, 0) + 1; - heartbeatStatusMap.put(clientId, lostCount); + try { + String lastTimeStr = redisTemplate.opsForValue().get(timeKey); + if (lastTimeStr == null) continue; - log.warn("客户端ID: {} 心跳丢失,连续次数: {}", clientId, lostCount); + long lastHeartbeatTime = Long.parseLong(lastTimeStr); - if (lostCount == 3) { - // 两次获取不到心跳 - insertHeartbeatLog(clientId, "3", "连续三次心跳丢失,服务器离线"); - // 把资源注册表资源信息改为离线 -// RmResourceRegistrationRemote rmResourceRegistrationRemote = new RmResourceRegistrationRemote(); -// rmResourceRegistrationRemote.setOnlineStatus("0"); -// remoteRevenueConfigService.updateStatusByResource(rmResourceRegistrationRemote, SecurityConstants.INNER); + if (currentTime - lastHeartbeatTime > HEARTBEAT_TIMEOUT) { + // 心跳超时处理 + String lostCountStr = redisTemplate.opsForValue().get(statusKey); + int lostCount = (lostCountStr == null ? 0 : Integer.parseInt(lostCountStr)) + 1; + redisTemplate.opsForValue().set(statusKey, String.valueOf(lostCount)); + + log.warn("客户端ID: {} 心跳丢失,连续次数: {}", clientId, lostCount); + + if (lostCount == 3) { + insertHeartbeatLog(clientId, "3", "连续三次心跳丢失"); + redisTemplate.opsForValue().set(HEARTBEAT_ALERT_PREFIX + clientId, "1"); + // 修改资源状态 + getResourceMsg(clientId, "0"); + } } + } catch (Exception e) { + log.error("检查心跳状态异常, clientId: {}", clientId, e); } } } + /** + * 修改资源在线状态 + * @param clientId + * @param status + */ + private void getResourceMsg(String clientId, String status){ + String ipAddress = null; + AllInterfaceNameRemote interfaceNameRemote = new AllInterfaceNameRemote(); + interfaceNameRemote.setClientId(clientId); + + // 1. 先获取交换机IP + interfaceNameRemote.setResourceType("2"); + R switchResult = remoteRevenueConfigService.getMsgByClientId( + interfaceNameRemote, SecurityConstants.INNER); + + if (switchResult != null && switchResult.getData() != null && + StringUtils.isNotEmpty(switchResult.getData().getSwitchIp())) { + // 更新交换机状态 + ipAddress = switchResult.getData().getSwitchIp(); + updateResourceStatus(ipAddress, status); + + // 2. 再获取服务器IP + interfaceNameRemote.setResourceType("1"); + R serverResult = remoteRevenueConfigService.getMsgByClientId( + interfaceNameRemote, SecurityConstants.INNER); + + if (serverResult != null && serverResult.getData() != null && + StringUtils.isNotEmpty(serverResult.getData().getServerIp())) { + // 更新服务器状态 + updateResourceStatus(serverResult.getData().getServerIp(), status); + } + } else { + // 3. 如果没有交换机IP,只获取服务器IP + interfaceNameRemote.setResourceType("1"); + R serverResult = remoteRevenueConfigService.getMsgByClientId( + interfaceNameRemote, SecurityConstants.INNER); + + if (serverResult != null && serverResult.getData() != null && + StringUtils.isNotEmpty(serverResult.getData().getServerIp())) { + // 更新服务器状态 + updateResourceStatus(serverResult.getData().getServerIp(), status); + } else { + log.warn("未找到客户端ID: {} 对应的IP地址", clientId); + } + } + } + // 更新资源状态的公共方法 + private void updateResourceStatus(String ipAddress, String status) { + RmResourceRegistrationRemote rmResourceRegistrationRemote = new RmResourceRegistrationRemote(); + rmResourceRegistrationRemote.setOnlineStatus(status); + rmResourceRegistrationRemote.setIpAddress(ipAddress); + remoteRevenueConfigService.updateStatusByResource(rmResourceRegistrationRemote, SecurityConstants.INNER); + } // 插入心跳日志到数据库 private void insertHeartbeatLog(String machineId, String status, String remark) { try {