From 8712f199a169c6368616e1895ee240027d83554f Mon Sep 17 00:00:00 2001 From: dengqichen Date: Tue, 11 Nov 2025 10:56:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=93=E5=8D=B0=E4=BA=86JENKINS=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/IEnvironmentRepository.java | 2 +- .../service/impl/DeployServiceImpl.java | 78 ++++++++++++------- .../TeamEnvironmentConfigServiceImpl.java | 62 +++++++++++++++ 3 files changed, 114 insertions(+), 28 deletions(-) diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/repository/IEnvironmentRepository.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/repository/IEnvironmentRepository.java index 19d3a699..841f81ee 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/repository/IEnvironmentRepository.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/repository/IEnvironmentRepository.java @@ -27,4 +27,4 @@ public interface IEnvironmentRepository extends IBaseRepository allTeamApps = teamApplicationRepository.findByTeamIdIn(teamIds); - if (allTeamApps.isEmpty()) { - log.debug("团队 {} 未配置任何应用", teamIds); - return Collections.emptyList(); - } - + // 8. 提取所有需要的ID集合 Set allEnvIds = new HashSet<>(); Set appIds = new HashSet<>(); @@ -201,7 +197,20 @@ public class DeployServiceImpl implements IDeployService { Map> teamAppsMap = allTeamApps.stream() .collect(groupingBy(TeamApplication::getTeamId)); - // 10. 批量查询环境信息 + // 10. 批量查询团队环境配置(获取团队配置的环境) + List teamEnvConfigs = teamEnvironmentConfigRepository.findByTeamIdIn(teamIds); + Map teamEnvConfigMap = teamEnvConfigs.stream() + .collect(toMap(c -> c.getTeamId() + "_" + c.getEnvironmentId(), c -> c)); + + // 从团队环境配置中提取环境ID + Set teamConfiguredEnvIds = teamEnvConfigs.stream() + .map(TeamEnvironmentConfig::getEnvironmentId) + .collect(Collectors.toSet()); + + // 合并应用配置中的环境ID和团队配置的环境ID + allEnvIds.addAll(teamConfiguredEnvIds); + + // 批量查询环境信息 Map envMap = environmentRepository.findAllById(allEnvIds).stream() .collect(toMap(Environment::getId, e -> e)); @@ -220,12 +229,7 @@ public class DeployServiceImpl implements IDeployService { ? workflowDefinitionRepository.findAllById(workflowIds).stream().collect(toMap(WorkflowDefinition::getId, w -> w)) : Collections.emptyMap(); - // 14. 批量查询团队环境配置 - List teamEnvConfigs = teamEnvironmentConfigRepository.findByTeamIdIn(teamIds); - Map teamEnvConfigMap = teamEnvConfigs.stream() - .collect(toMap(c -> c.getTeamId() + "_" + c.getEnvironmentId(), c -> c)); - - // 15. 批量查询审批人信息 + // 14. 批量查询审批人信息 Set approverUserIds = teamEnvConfigs.stream() .filter(c -> c.getApproverUserIds() != null) .flatMap(c -> c.getApproverUserIds().stream()) @@ -234,12 +238,12 @@ public class DeployServiceImpl implements IDeployService { ? userRepository.findAllById(approverUserIds).stream().collect(toMap(User::getId, u -> u)) : Collections.emptyMap(); - // 16. 批量查询动态数据(部署统计、最近记录) + // 15. 批量查询动态数据(部署统计、最近记录) Map statisticsMap = queryDeployStatistics(teamApplicationIds); Map latestRecordMap = queryLatestRecords(teamApplicationIds); Map> recentRecordsMap = queryRecentRecords(teamApplicationIds); - // 17. 为每个团队组装完整数据 + // 16. 为每个团队组装完整数据 List result = new ArrayList<>(); for (Long teamId : teamIds) { UserTeamDeployableDTO teamDTO = buildUserTeamDeployableDTO( @@ -323,12 +327,13 @@ public class DeployServiceImpl implements IDeployService { // 构建环境列表 List teamApps = teamAppsMap.get(teamId); + List environments = new ArrayList<>(); + if (teamApps != null && !teamApps.isEmpty()) { - // 按环境分组 + // 有应用配置:按环境分组 Map> appsByEnv = teamApps.stream() .collect(groupingBy(TeamApplication::getEnvironmentId)); - List environments = new ArrayList<>(); for (Map.Entry> entry : appsByEnv.entrySet()) { Long envId = entry.getKey(); Environment env = envMap.get(envId); @@ -345,14 +350,24 @@ public class DeployServiceImpl implements IDeployService { ); environments.add(envDTO); } - - // 按sort排序 - environments.sort(Comparator.comparingInt(e -> e.getSort() != null ? e.getSort() : Integer.MAX_VALUE)); - dto.setEnvironments(environments); } else { - dto.setEnvironments(Collections.emptyList()); + // 没有应用配置:显示所有可用环境,但应用列表为空 + for (Environment env : envMap.values()) { + UserDeployableTeamEnvironmentDTO envDTO = buildUserDeployableTeamEnvironmentDTO( + currentUserId, team.getOwnerId(), + teamId, env, Collections.emptyList(), // 空的应用列表 + appMap, systemMap, workflowMap, + teamEnvConfigMap, approverMap, + statisticsMap, latestRecordMap, recentRecordsMap + ); + environments.add(envDTO); + } } + // 按sort排序 + environments.sort(Comparator.comparingInt(e -> e.getSort() != null ? e.getSort() : Integer.MAX_VALUE)); + dto.setEnvironments(environments); + return dto; } @@ -386,13 +401,15 @@ public class DeployServiceImpl implements IDeployService { String configKey = teamId + "_" + env.getId(); TeamEnvironmentConfig config = teamEnvConfigMap.get(configKey); if (config != null) { - dto.setRequiresApproval(config.getApprovalRequired() != null ? config.getApprovalRequired() : false); + boolean requiresApproval = config.getApprovalRequired() != null ? config.getApprovalRequired() : false; + boolean notificationEnabled = config.getNotificationEnabled() != null ? config.getNotificationEnabled() : true; + + dto.setRequiresApproval(requiresApproval); dto.setRequireCodeReview(config.getRequireCodeReview() != null ? config.getRequireCodeReview() : false); - dto.setNotificationEnabled(config.getNotificationEnabled() != null ? config.getNotificationEnabled() : true); - dto.setNotificationChannelId(config.getNotificationChannelId()); - - // 设置审批人列表 - if (config.getApproverUserIds() != null && !config.getApproverUserIds().isEmpty()) { + dto.setNotificationEnabled(notificationEnabled); + + // 兜底逻辑:只有需要审批时才返回审批人列表 + if (requiresApproval && config.getApproverUserIds() != null && !config.getApproverUserIds().isEmpty()) { List approvers = config.getApproverUserIds().stream() .map(userId -> { User user = approverMap.get(userId); @@ -411,6 +428,13 @@ public class DeployServiceImpl implements IDeployService { } else { dto.setApprovers(Collections.emptyList()); } + + // 兜底逻辑:只有启用通知时才返回通知渠道ID + if (notificationEnabled) { + dto.setNotificationChannelId(config.getNotificationChannelId()); + } else { + dto.setNotificationChannelId(null); + } } else { dto.setRequiresApproval(false); dto.setRequireCodeReview(false); diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/TeamEnvironmentConfigServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/TeamEnvironmentConfigServiceImpl.java index ec2b7c11..edc5155e 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/TeamEnvironmentConfigServiceImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/TeamEnvironmentConfigServiceImpl.java @@ -86,6 +86,68 @@ public class TeamEnvironmentConfigServiceImpl return list; } + /** + * 重写创建方法,添加数据一致性兜底逻辑 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public TeamEnvironmentConfigDTO create(TeamEnvironmentConfigDTO dto) { + // 执行兜底逻辑:确保数据一致性 + applyDataConsistencyRules(dto); + return super.create(dto); + } + + /** + * 重写更新方法,添加数据一致性兜底逻辑 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public TeamEnvironmentConfigDTO update(Long id, TeamEnvironmentConfigDTO dto) { + // 执行兜底逻辑:确保数据一致性 + applyDataConsistencyRules(dto); + return super.update(id, dto); + } + + /** + * 数据一致性兜底逻辑 + *

规则: + *

    + *
  • 1. 如果不需要审批(approvalRequired = false),清空审批人列表
  • + *
  • 2. 如果不需要通知(notificationEnabled = false),清空通知渠道
  • + *
  • 3. 如果不需要代码审查(requireCodeReview = false),清空代码审查相关配置
  • + *
+ */ + private void applyDataConsistencyRules(TeamEnvironmentConfigDTO dto) { + if (dto == null) { + return; + } + + // 规则1:不需要审批时,清空审批人 + if (dto.getApprovalRequired() != null && !dto.getApprovalRequired()) { + if (dto.getApproverUserIds() != null && !dto.getApproverUserIds().isEmpty()) { + log.info("兜底逻辑触发:团队 {} 环境 {} 不需要审批,清空审批人列表 {}", + dto.getTeamId(), dto.getEnvironmentId(), dto.getApproverUserIds()); + dto.setApproverUserIds(null); + } + } + + // 规则2:不需要通知时,清空通知渠道 + if (dto.getNotificationEnabled() != null && !dto.getNotificationEnabled()) { + if (dto.getNotificationChannelId() != null) { + log.info("兜底逻辑触发:团队 {} 环境 {} 不需要通知,清空通知渠道 {}", + dto.getTeamId(), dto.getEnvironmentId(), dto.getNotificationChannelId()); + dto.setNotificationChannelId(null); + } + } + + // 规则3:不需要代码审查时,清空相关配置(如果将来有相关字段) + if (dto.getRequireCodeReview() != null && !dto.getRequireCodeReview()) { + // 目前没有代码审查相关的其他配置字段 + // 如果将来有(如 codeReviewerUserIds),在这里清空 + log.debug("团队 {} 环境 {} 不需要代码审查", dto.getTeamId(), dto.getEnvironmentId()); + } + } + /** * 批量填充扩展字段:environmentName、notificationChannelName、applicationCount *