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 6234500c..20d68bbd 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
@@ -102,15 +102,17 @@ public class TeamEnvironmentConfigServiceImpl
@Override
@Transactional(rollbackFor = Exception.class)
public TeamEnvironmentConfigDTO create(TeamEnvironmentConfigDTO dto) {
- // 执行兜底逻辑:确保数据一致性
- applyDataConsistencyRules(dto);
+ // 0) 前置处理:数据归一化和业务规则
+ prepareForCreate(dto);
- // 创建主配置
+ // 1) 创建主配置(会自动调用 validateUniqueConstraints)
TeamEnvironmentConfigDTO result = super.create(dto);
- // 保存或更新通知配置
+ // 2) 保存通知配置(基于 teamId + environmentId)
saveOrUpdateNotificationConfig(dto);
+ // 3) 附带扩展信息(环境名、通知配置含渠道名、应用数量)
+ attachSnapshot(result);
return result;
}
@@ -120,18 +122,37 @@ public class TeamEnvironmentConfigServiceImpl
@Override
@Transactional(rollbackFor = Exception.class)
public TeamEnvironmentConfigDTO update(Long id, TeamEnvironmentConfigDTO dto) {
- // 执行兜底逻辑:确保数据一致性
- applyDataConsistencyRules(dto);
+ // 0) 前置处理:数据归一化、业务规则和维度验证
+ prepareForUpdate(id, dto);
- // 更新主配置
+ // 1) 更新主配置(会自动调用 validateUniqueConstraints)
TeamEnvironmentConfigDTO result = super.update(id, dto);
- // 保存或更新通知配置
+ // 2) 保存通知配置
saveOrUpdateNotificationConfig(dto);
+ // 3) 附带扩展信息(环境名、通知配置含渠道名、应用数量)
+ attachSnapshot(result);
return result;
}
+ /**
+ * 校验唯一性约束
+ *
+ * @param dto 团队环境配置DTO
+ */
+ @Override
+ protected void validateUniqueConstraints(TeamEnvironmentConfigDTO dto) {
+ if (dto == null || dto.getTeamId() == null || dto.getEnvironmentId() == null) {
+ return;
+ }
+
+ // 检查 teamId + environmentId 组合唯一性
+ if (teamEnvironmentConfigRepository.existsByTeamIdAndEnvironmentId(dto.getTeamId(), dto.getEnvironmentId())) {
+ throw new BusinessException(ResponseCode.CONFLICT, new Object[]{"团队/环境配置已存在"});
+ }
+ }
+
/**
* 数据一致性兜底逻辑
*
规则:
@@ -294,7 +315,7 @@ public class TeamEnvironmentConfigServiceImpl
}
/**
- * 重写删除方法,删除前校验该团队环境下是否有绑定的应用
+ * 重写删除方法,删除前校验该团队环境下是否有绑定的应用,并级联删除通知配置
*
* @param id 团队环境配置ID
*/
@@ -317,10 +338,114 @@ public class TeamEnvironmentConfigServiceImpl
throw new BusinessException(ResponseCode.TEAM_ENVIRONMENT_HAS_APPLICATIONS, new Object[] {appCount});
}
- // 3. 执行删除(逻辑删除)
+ //3. 删除关联的通知配置
+ Optional notificationConfig =
+ teamEnvironmentNotificationConfigRepository.findByTeamIdAndEnvironmentId(
+ config.getTeamId(),
+ config.getEnvironmentId()
+ );
+
+ if (notificationConfig.isPresent()) {
+ teamEnvironmentNotificationConfigRepository.deleteById(notificationConfig.get().getId());
+ log.info("删除关联的通知配置: teamId={}, environmentId={}",
+ config.getTeamId(), config.getEnvironmentId());
+ }
+
+ // 4. 执行删除(逻辑删除)
super.delete(id);
log.info("成功删除团队环境配置: id={}, teamId={}, environmentId={}",
id, config.getTeamId(), config.getEnvironmentId());
}
+
+/**
+ * 创建前预处理
+ * 包含数据归一化和业务规则应用
+ */
+ private void prepareForCreate(TeamEnvironmentConfigDTO dto) {
+ if (dto == null) {
+ return;
+ }
+
+ // 1) 应用业务规则
+ applyDataConsistencyRules(dto);
+
+ // 2) 数据归一化
+ normalizeDataFields(dto);
+ }
+
+ /**
+ * 更新前预处理
+ * 包含数据归一化、业务规则应用和维度验证
+ */
+ private void prepareForUpdate(Long id, TeamEnvironmentConfigDTO dto) {
+ if (dto == null) {
+ return;
+ }
+
+ // 1) 验证维度不可变更
+ validateDimensionChangeOnUpdate(id, dto);
+
+ // 2) 应用业务规则
+ applyDataConsistencyRules(dto);
+
+ // 3) 数据归一化
+ normalizeDataFields(dto);
+ }
+
+ /**
+ * 数据字段归一化
+ * 处理空值、格式标准化等
+ */
+ private void normalizeDataFields(TeamEnvironmentConfigDTO dto) {
+ if (dto == null) {
+ return;
+ }
+
+ // 空集合归一化
+ if (dto.getApproverUserIds() != null && dto.getApproverUserIds().isEmpty()) {
+ dto.setApproverUserIds(null);
+ }
+
+ // 归一化通知配置的 team/environment(以主 DTO 为准)
+ if (dto.getNotificationConfig() != null) {
+ TeamEnvironmentNotificationConfigDTO nc = dto.getNotificationConfig();
+ nc.setTeamId(dto.getTeamId());
+ nc.setEnvironmentId(dto.getEnvironmentId());
+ }
+ }
+
+ /**
+ * 验证更新时维度不可变更
+ */
+ private void validateDimensionChangeOnUpdate(Long id, TeamEnvironmentConfigDTO dto) {
+ TeamEnvironmentConfig origin = teamEnvironmentConfigRepository.findById(id)
+ .orElseThrow(() -> new BusinessException(ResponseCode.TEAM_CONFIG_NOT_FOUND, new Object[] {id}));
+
+ // 禁止修改 teamId 和 environmentId
+ if (dto.getTeamId() != null && !Objects.equals(dto.getTeamId(), origin.getTeamId())) {
+ throw new BusinessException(ResponseCode.CONFLICT, new Object[]{"不允许变更 teamId"});
+ }
+ if (dto.getEnvironmentId() != null && !Objects.equals(dto.getEnvironmentId(), origin.getEnvironmentId())) {
+ throw new BusinessException(ResponseCode.CONFLICT, new Object[]{"不允许变更 environmentId"});
+ }
+
+ // 将主维度补齐,确保后续处理使用
+ dto.setTeamId(origin.getTeamId());
+ dto.setEnvironmentId(origin.getEnvironmentId());
+ }
+
+
+ /**
+ * 在返回结果上附带扩展数据快照(环境名、通知配置含渠道名、应用数量)
+ */
+ private void attachSnapshot(TeamEnvironmentConfigDTO result) {
+ if (result == null) {
+ return;
+ }
+ // 复用已有批量填充逻辑(单元素列表)
+ List list = new ArrayList<>();
+ list.add(result);
+ fillExtendedFields(list);
+ }
}