From 1dbb411e08e369b326492ede139b4a2b33685837 Mon Sep 17 00:00:00 2001 From: dengqichen Date: Thu, 30 Oct 2025 15:59:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9C=8D=E5=8A=A1=E5=99=A8?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E8=AE=A4=E8=AF=81=E6=96=B9=E5=BC=8F=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B5=8B=E8=AF=95=E8=BF=9E=E6=8E=A5=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/JenkinsServiceIntegrationImpl.java | 3 +- .../service/impl/ServerServiceImpl.java | 37 ++++++++++++++++++- .../backend/framework/enums/ResponseCode.java | 9 ++++- .../src/main/resources/messages.properties | 7 ++++ 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/JenkinsServiceIntegrationImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/JenkinsServiceIntegrationImpl.java index d5ad8608..14e8acdc 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/JenkinsServiceIntegrationImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/JenkinsServiceIntegrationImpl.java @@ -664,8 +664,7 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration */ public List listBuilds(ExternalSystem externalSystem, String jobName) { // Jenkins API 默认只返回最近的若干个构建,通过 {from,to} 可以指定范围 - // 这里获取最近200个构建记录 - String treeQuery = "builds[number,url,result,timestamp,duration,building,actions[_class,parameters[_class,name,value]]]{0,200}"; + String treeQuery = "builds[number,url,result,timestamp,duration,building,actions[_class,parameters[_class,name,value]]]"; List builds = callJenkinsApi( externalSystem, "/job/" + jobName + "/api/json", diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/ServerServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/ServerServiceImpl.java index 76000f04..fb5a706a 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/ServerServiceImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/ServerServiceImpl.java @@ -16,6 +16,7 @@ import lombok.extern.slf4j.Slf4j; import net.schmizz.sshj.SSHClient; import net.schmizz.sshj.transport.verification.PromiscuousVerifier; import net.schmizz.sshj.userauth.keyprovider.KeyProvider; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -40,6 +41,22 @@ public class ServerServiceImpl this.serverRepository = serverRepository; } + /** + * 校验服务器唯一约束 + * 检查IP是否已存在 + */ + @Override + protected void validateUniqueConstraints(ServerDTO dto) { + // 检查IP是否已存在(排除已删除的记录) + if (dto.getHostIp() != null) { + boolean exists = serverRepository.existsByHostIpAndDeletedFalse(dto.getHostIp()); + if (exists) { + log.warn("服务器IP已存在: {}", dto.getHostIp()); + throw new BusinessException(ResponseCode.SERVER_IP_EXISTS, new Object[]{dto.getHostIp()}); + } + } + } + @Override @Transactional public ServerDTO initializeServerInfo(Long serverId, ServerInitializeDTO dto) { @@ -65,6 +82,7 @@ public class ServerServiceImpl } @Override + @Transactional public boolean testConnection(Long serverId) { // 1. 查询服务器信息 Server server = serverRepository.findById(serverId) @@ -130,18 +148,35 @@ public class ServerServiceImpl if (cmd.getExitStatus() == 0) { log.info("SSH连接测试成功: {}", server.getHostIp()); + + // 7. 更新服务器状态和最后连接时间 + server.setStatus(ServerStatusEnum.ONLINE); + server.setLastConnectTime(LocalDateTime.now()); + serverRepository.save(server); + log.info("已更新服务器状态为ONLINE: serverId={}", serverId); + return true; } else { log.warn("SSH连接测试失败,命令执行异常: {}", server.getHostIp()); + + // 8. 更新服务器状态为离线 + server.setStatus(ServerStatusEnum.OFFLINE); + serverRepository.save(server); + return false; } } } catch (IOException e) { log.error("SSH连接测试失败: {} - {}", server.getHostIp(), e.getMessage()); + + // 9. 连接失败,更新服务器状态为离线 + server.setStatus(ServerStatusEnum.OFFLINE); + serverRepository.save(server); + throw new BusinessException(ResponseCode.ERROR, new Object[]{"SSH连接失败: " + e.getMessage()}); } finally { - // 7. 关闭连接 + // 10. 关闭连接 try { if (ssh.isConnected()) { ssh.disconnect(); diff --git a/backend/src/main/java/com/qqchen/deploy/backend/framework/enums/ResponseCode.java b/backend/src/main/java/com/qqchen/deploy/backend/framework/enums/ResponseCode.java index 4ee0da9f..dbddc79d 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/framework/enums/ResponseCode.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/framework/enums/ResponseCode.java @@ -197,7 +197,14 @@ public enum ResponseCode { TEAM_MEMBER_NOT_FOUND(2924, "team.member.not.found"), TEAM_MEMBER_ALREADY_EXISTS(2925, "team.member.already.exists"), TEAM_APPLICATION_NOT_FOUND(2926, "team.application.not.found"), - TEAM_APPLICATION_ALREADY_EXISTS(2927, "team.application.already.exists"); + TEAM_APPLICATION_ALREADY_EXISTS(2927, "team.application.already.exists"), + + // 服务器管理相关错误码 (2950-2969) + SERVER_NOT_FOUND(2950, "server.not.found"), + SERVER_IP_EXISTS(2951, "server.ip.exists"), + SERVER_CATEGORY_NOT_FOUND(2952, "server.category.not.found"), + SERVER_CATEGORY_CODE_EXISTS(2953, "server.category.code.exists"), + SERVER_CATEGORY_HAS_SERVERS(2954, "server.category.has.servers"); private final int code; private final String messageKey; // 国际化消息key diff --git a/backend/src/main/resources/messages.properties b/backend/src/main/resources/messages.properties index ee073323..9da2f5c2 100644 --- a/backend/src/main/resources/messages.properties +++ b/backend/src/main/resources/messages.properties @@ -188,6 +188,13 @@ team.member.already.exists=该用户已是团队成员 team.application.not.found=团队应用关联不存在或已删除 team.application.already.exists=该应用已关联到此团队 +# 服务器管理相关 (2950-2969) +server.not.found=服务器不存在或已删除 +server.ip.exists=服务器IP {0} 已存在 +server.category.not.found=服务器分类不存在或已删除 +server.category.code.exists=服务器分类编码{0}已存在 +server.category.has.servers=该分类下存在服务器,无法删除 + # 定时任务相关 (2800-2899) # 任务基础错误 (2800-2819) schedule.job.not.found=定时任务不存在或已删除