From 64baa08aa706d8c33a24e43cb3481cc60d07aa52 Mon Sep 17 00:00:00 2001
From: gaoxq <376340421@qq.com>
Date: Mon, 10 Nov 2025 15:03:59 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=AE=9A=E6=97=B6=E4=BB=BB?=
=?UTF-8?q?=E5=8A=A1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...{bizController.java => erpController.java} | 4 +-
src/main/java/com/mini/capi/api/startApp.java | 9 ++
.../controller/BizMonitorHostController.java | 18 +++
.../mini/capi/biz/domain/BizMonitorHost.java | 128 ++++++++++++++++++
.../capi/biz/mapper/BizMonitorHostMapper.java | 16 +++
.../biz/service/BizMonitorHostService.java | 16 +++
.../impl/BizMonitorHostServiceImpl.java | 20 +++
.../capi/config/MonitorExecutorConfig.java | 31 +++++
.../com/mini/capi/config/WebMvcConfig.java | 14 ++
.../java/com/mini/capi/job/jobController.java | 60 ++++++++
src/main/java/com/mini/capi/mybatis/demo.java | 2 +-
.../com/mini/capi/utils/NetworkUtils.java | 125 +++++++++++++++++
.../resources/mapper/BizMonitorHostMapper.xml | 31 +++++
13 files changed, 471 insertions(+), 3 deletions(-)
rename src/main/java/com/mini/capi/api/biz/{bizController.java => erpController.java} (98%)
create mode 100644 src/main/java/com/mini/capi/biz/controller/BizMonitorHostController.java
create mode 100644 src/main/java/com/mini/capi/biz/domain/BizMonitorHost.java
create mode 100644 src/main/java/com/mini/capi/biz/mapper/BizMonitorHostMapper.java
create mode 100644 src/main/java/com/mini/capi/biz/service/BizMonitorHostService.java
create mode 100644 src/main/java/com/mini/capi/biz/service/impl/BizMonitorHostServiceImpl.java
create mode 100644 src/main/java/com/mini/capi/config/MonitorExecutorConfig.java
create mode 100644 src/main/java/com/mini/capi/config/WebMvcConfig.java
create mode 100644 src/main/java/com/mini/capi/job/jobController.java
create mode 100644 src/main/java/com/mini/capi/utils/NetworkUtils.java
create mode 100644 src/main/resources/mapper/BizMonitorHostMapper.xml
diff --git a/src/main/java/com/mini/capi/api/biz/bizController.java b/src/main/java/com/mini/capi/api/biz/erpController.java
similarity index 98%
rename from src/main/java/com/mini/capi/api/biz/bizController.java
rename to src/main/java/com/mini/capi/api/biz/erpController.java
index a646a9a..795fe4a 100644
--- a/src/main/java/com/mini/capi/api/biz/bizController.java
+++ b/src/main/java/com/mini/capi/api/biz/erpController.java
@@ -15,8 +15,8 @@ import java.math.BigDecimal;
import java.time.LocalDateTime;
@RestController
-@RequestMapping("/bizApi")
-public class bizController {
+@RequestMapping("/erpApi")
+public class erpController {
@Resource
diff --git a/src/main/java/com/mini/capi/api/startApp.java b/src/main/java/com/mini/capi/api/startApp.java
index f390571..705ab0a 100644
--- a/src/main/java/com/mini/capi/api/startApp.java
+++ b/src/main/java/com/mini/capi/api/startApp.java
@@ -1,4 +1,13 @@
package com.mini.capi.api;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+
+@Controller
public class startApp {
+
+ @GetMapping("/")
+ public String redirectToSwagger() {
+ return "redirect:/swagger-ui/index.html";
+ }
}
diff --git a/src/main/java/com/mini/capi/biz/controller/BizMonitorHostController.java b/src/main/java/com/mini/capi/biz/controller/BizMonitorHostController.java
new file mode 100644
index 0000000..f8d3152
--- /dev/null
+++ b/src/main/java/com/mini/capi/biz/controller/BizMonitorHostController.java
@@ -0,0 +1,18 @@
+package com.mini.capi.biz.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ *
+ * 主机信息表 前端控制器
+ *
+ *
+ * @author gaoxq
+ * @since 2025-11-10
+ */
+@RestController
+@RequestMapping("/biz/bizMonitorHost")
+public class BizMonitorHostController {
+
+}
diff --git a/src/main/java/com/mini/capi/biz/domain/BizMonitorHost.java b/src/main/java/com/mini/capi/biz/domain/BizMonitorHost.java
new file mode 100644
index 0000000..9d790e1
--- /dev/null
+++ b/src/main/java/com/mini/capi/biz/domain/BizMonitorHost.java
@@ -0,0 +1,128 @@
+package com.mini.capi.biz.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * 主机信息表
+ *
+ *
+ * @author gaoxq
+ * @since 2025-11-10
+ */
+@Getter
+@Setter
+@TableName("biz_monitor_host")
+public class BizMonitorHost implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 记录创建时间
+ */
+ @TableField("create_time")
+ private LocalDateTime createTime;
+
+ /**
+ * 主机唯一标识(自增主键)
+ */
+ @TableId(value = "host_id", type = IdType.AUTO)
+ private String hostId;
+
+ /**
+ * 主机名称
+ */
+ @TableField("hostname")
+ private String hostname;
+
+ /**
+ * IP地址
+ */
+ @TableField("ip_address")
+ private String ipAddress;
+
+ /**
+ * 主机类型
+ */
+ @TableField("host_type")
+ private String hostType;
+
+ /**
+ * 操作系统
+ */
+ @TableField("host_os")
+ private String hostOs;
+
+ /**
+ * 主机状态(1-在线、0-离线、9-维护中)
+ */
+ @TableField("ustatus")
+ private String ustatus;
+
+ /**
+ * 最后一次检测到在线的时间
+ */
+ @TableField("last_online_time")
+ private LocalDateTime lastOnlineTime;
+
+ /**
+ * 物理位置
+ */
+ @TableField("location_name")
+ private String locationName;
+
+ /**
+ * 管理人员
+ */
+ @TableField("admin_user")
+ private String adminUser;
+
+ /**
+ * 联系方式
+ */
+ @TableField("other_contact")
+ private String otherContact;
+
+ /**
+ * 备注信息
+ */
+ @TableField("remark")
+ private String remark;
+
+ /**
+ * 记录最后更新时间
+ */
+ @TableField("update_time")
+ private LocalDateTime updateTime;
+
+ /**
+ * 租户id
+ */
+ @TableField("f_tenant_id")
+ private String fTenantId;
+
+ /**
+ * 流程id
+ */
+ @TableField("f_flow_id")
+ private String fFlowId;
+
+ /**
+ * 流程任务主键
+ */
+ @TableField("f_flow_task_id")
+ private String fFlowTaskId;
+
+ /**
+ * 流程任务状态
+ */
+ @TableField("f_flow_state")
+ private Integer fFlowState;
+}
diff --git a/src/main/java/com/mini/capi/biz/mapper/BizMonitorHostMapper.java b/src/main/java/com/mini/capi/biz/mapper/BizMonitorHostMapper.java
new file mode 100644
index 0000000..6d7491f
--- /dev/null
+++ b/src/main/java/com/mini/capi/biz/mapper/BizMonitorHostMapper.java
@@ -0,0 +1,16 @@
+package com.mini.capi.biz.mapper;
+
+import com.mini.capi.biz.domain.BizMonitorHost;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ *
+ * 主机信息表 Mapper 接口
+ *
+ *
+ * @author gaoxq
+ * @since 2025-11-10
+ */
+public interface BizMonitorHostMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/mini/capi/biz/service/BizMonitorHostService.java b/src/main/java/com/mini/capi/biz/service/BizMonitorHostService.java
new file mode 100644
index 0000000..bea3776
--- /dev/null
+++ b/src/main/java/com/mini/capi/biz/service/BizMonitorHostService.java
@@ -0,0 +1,16 @@
+package com.mini.capi.biz.service;
+
+import com.mini.capi.biz.domain.BizMonitorHost;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 主机信息表 服务类
+ *
+ *
+ * @author gaoxq
+ * @since 2025-11-10
+ */
+public interface BizMonitorHostService extends IService {
+
+}
diff --git a/src/main/java/com/mini/capi/biz/service/impl/BizMonitorHostServiceImpl.java b/src/main/java/com/mini/capi/biz/service/impl/BizMonitorHostServiceImpl.java
new file mode 100644
index 0000000..b9f0071
--- /dev/null
+++ b/src/main/java/com/mini/capi/biz/service/impl/BizMonitorHostServiceImpl.java
@@ -0,0 +1,20 @@
+package com.mini.capi.biz.service.impl;
+
+import com.mini.capi.biz.domain.BizMonitorHost;
+import com.mini.capi.biz.mapper.BizMonitorHostMapper;
+import com.mini.capi.biz.service.BizMonitorHostService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 主机信息表 服务实现类
+ *
+ *
+ * @author gaoxq
+ * @since 2025-11-10
+ */
+@Service
+public class BizMonitorHostServiceImpl extends ServiceImpl implements BizMonitorHostService {
+
+}
diff --git a/src/main/java/com/mini/capi/config/MonitorExecutorConfig.java b/src/main/java/com/mini/capi/config/MonitorExecutorConfig.java
new file mode 100644
index 0000000..ca25bf9
--- /dev/null
+++ b/src/main/java/com/mini/capi/config/MonitorExecutorConfig.java
@@ -0,0 +1,31 @@
+package com.mini.capi.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+@Configuration
+@EnableAsync // 启用异步任务支持
+public class MonitorExecutorConfig {
+
+ /**
+ * 配置主机监控专用线程池
+ */
+ @Bean(name = "hostMonitorExecutor")
+ public ThreadPoolTaskExecutor hostMonitorExecutor() {
+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+ int corePoolSize = Runtime.getRuntime().availableProcessors();
+ executor.setCorePoolSize(corePoolSize);
+ executor.setMaxPoolSize(corePoolSize * 2);
+ executor.setQueueCapacity(200);
+ executor.setKeepAliveSeconds(60);
+ executor.setThreadNamePrefix("Host-Monitor-");
+ executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+ executor.initialize();
+ return executor;
+ }
+}
diff --git a/src/main/java/com/mini/capi/config/WebMvcConfig.java b/src/main/java/com/mini/capi/config/WebMvcConfig.java
new file mode 100644
index 0000000..656aebd
--- /dev/null
+++ b/src/main/java/com/mini/capi/config/WebMvcConfig.java
@@ -0,0 +1,14 @@
+package com.mini.capi.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer{
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ // 访问根路径 "/" 时,自动重定向到 Swagger UI
+ registry.addRedirectViewController("/", "/swagger-ui/index.html");
+ }
+}
diff --git a/src/main/java/com/mini/capi/job/jobController.java b/src/main/java/com/mini/capi/job/jobController.java
new file mode 100644
index 0000000..f0fb801
--- /dev/null
+++ b/src/main/java/com/mini/capi/job/jobController.java
@@ -0,0 +1,60 @@
+package com.mini.capi.job;
+
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.mini.capi.biz.domain.BizMonitorHost;
+import com.mini.capi.biz.service.BizMonitorHostService;
+import com.mini.capi.utils.NetworkUtils;
+import jakarta.annotation.Resource;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Controller;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+@Controller
+public class jobController {
+
+
+ @Resource
+ private BizMonitorHostService bizMonitorHostService;
+
+ // 注入配置好的线程池
+ @Resource(name = "hostMonitorExecutor")
+ private ThreadPoolTaskExecutor hostMonitorExecutor;
+
+ /**
+ *
+ */
+ @Scheduled(cron = "0 0/10 * * * ?")
+ public void getJobMonitHostStatus() {
+ List monitorHosts = bizMonitorHostService.list();
+ List> futures = new ArrayList<>(monitorHosts.size());
+ for (BizMonitorHost monitorHost : monitorHosts) {
+ CompletableFuture future = CompletableFuture.runAsync(() -> {
+ try {
+ UpdateWrapper updateWrapper = new UpdateWrapper<>();
+ updateWrapper.eq("host_id", monitorHost.getHostId());
+ boolean isReachable = NetworkUtils.isNetworkReachable(monitorHost.getIpAddress());
+ monitorHost.setUstatus(isReachable ? "1" : "0");
+ if (isReachable) {
+ monitorHost.setLastOnlineTime(LocalDateTime.now());
+ }
+ bizMonitorHostService.update(monitorHost, updateWrapper);
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ }, hostMonitorExecutor); // 指定使用配置的线程池
+ futures.add(future);
+ }
+ try {
+ CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
+ .get(60, TimeUnit.SECONDS); // 超时时间可根据业务调整
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/com/mini/capi/mybatis/demo.java b/src/main/java/com/mini/capi/mybatis/demo.java
index a27b6f4..78235a7 100644
--- a/src/main/java/com/mini/capi/mybatis/demo.java
+++ b/src/main/java/com/mini/capi/mybatis/demo.java
@@ -29,7 +29,7 @@ public class demo {
.pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir") + "/src/main/resources/mapper"));
})
.strategyConfig(builder -> {
- builder.addInclude("biz_cities,biz_company,biz_mail_account,biz_project_info,biz_project_requirements,biz_province,biz_resume_employee,erp_transfer,biz_website_storage,erp_period_summary,biz_municipalities,erp_account,erp_transaction_flow,erp_expense,erp_category,erp_income,biz_project_report,biz_mail_sent")
+ builder.addInclude("biz_monitor_host")
.addTablePrefix("biz_,erp_")
.entityBuilder()
.enableLombok()
diff --git a/src/main/java/com/mini/capi/utils/NetworkUtils.java b/src/main/java/com/mini/capi/utils/NetworkUtils.java
new file mode 100644
index 0000000..3f399ff
--- /dev/null
+++ b/src/main/java/com/mini/capi/utils/NetworkUtils.java
@@ -0,0 +1,125 @@
+package com.mini.capi.utils;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+/**
+ * 网络连通性检测工具类(支持IPv4和域名)
+ */
+public class NetworkUtils {
+
+ // IPv4地址校验正则(支持带前后空白)
+ private static final Pattern IPV4_PATTERN = Pattern.compile(
+ "^\\s*((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\s*$"
+ );
+
+ // Ping命令配置常量
+ private static final int PING_COUNT = 2;
+ private static final int WINDOWS_TIMEOUT_MS = 3000;
+ private static final int LINUX_TIMEOUT_SEC = 3;
+ private static final int PROCESS_WAIT_TIMEOUT_SEC = 6;
+
+ // 私有构造器:禁止实例化
+ private NetworkUtils() {
+ throw new AssertionError("工具类不允许实例化");
+ }
+
+ /**
+ * 检测本地网络到目标IP或域名的连通性
+ */
+ public static boolean isNetworkReachable(String target) {
+ if (target == null || target.trim().isEmpty()) {
+ return false;
+ }
+ target = target.trim();
+
+ List ipList = new ArrayList<>();
+ // 区分IP和域名,解析目标为IP列表
+ if (isValidIpv4(target)) {
+ ipList.add(target); // 是IP,直接加入
+ } else {
+ // 是域名,尝试解析为IP
+ try {
+ InetAddress[] addresses = InetAddress.getAllByName(target);
+ for (InetAddress addr : addresses) {
+ ipList.add(addr.getHostAddress());
+ }
+ if (ipList.isEmpty()) {
+ return false; // 域名解析无结果
+ }
+ } catch (UnknownHostException e) {
+ return false; // 域名无法解析(如不存在、网络故障)
+ }
+ }
+
+ // 对每个IP执行ping检测,有一个成功则返回true
+ for (String ip : ipList) {
+ if (executePingCommand(buildPingCommand(ip))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 校验是否为合法的IPv4地址(支持带前后空白)
+ */
+ private static boolean isValidIpv4(String ip) {
+ return IPV4_PATTERN.matcher(ip).matches();
+ }
+
+ /**
+ * 构建跨系统的ping命令
+ */
+ private static List buildPingCommand(String ip) {
+ List command = new ArrayList<>(5);
+ command.add("ping");
+
+ String osName = System.getProperty("os.name", "").toLowerCase();
+ if (osName.contains("windows")) {
+ command.add("-n");
+ command.add(String.valueOf(PING_COUNT));
+ command.add("-w");
+ command.add(String.valueOf(WINDOWS_TIMEOUT_MS));
+ } else {
+ command.add("-c");
+ command.add(String.valueOf(PING_COUNT));
+ command.add("-W");
+ command.add(String.valueOf(LINUX_TIMEOUT_SEC));
+ }
+
+ command.add(ip);
+ return command;
+ }
+
+ /**
+ * 执行ping命令并返回执行结果
+ */
+ private static boolean executePingCommand(List command) {
+ Process process = null;
+ try {
+ ProcessBuilder processBuilder = new ProcessBuilder(command);
+ processBuilder.redirectErrorStream(true);
+ process = processBuilder.start();
+
+ boolean isFinished = process.waitFor(PROCESS_WAIT_TIMEOUT_SEC, TimeUnit.SECONDS);
+ if (!isFinished) {
+ process.destroyForcibly();
+ return false;
+ }
+ return process.exitValue() == 0;
+
+ } catch (IOException | InterruptedException e) {
+ return false;
+ } finally {
+ if (process != null) {
+ process.destroyForcibly();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/mapper/BizMonitorHostMapper.xml b/src/main/resources/mapper/BizMonitorHostMapper.xml
new file mode 100644
index 0000000..fc7362a
--- /dev/null
+++ b/src/main/resources/mapper/BizMonitorHostMapper.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ create_time, host_id, hostname, ip_address, host_type, host_os, ustatus, last_online_time, location_name, admin_user, other_contact, remark, update_time, f_tenant_id, f_flow_id, f_flow_task_id, f_flow_state
+
+
+