增加构建通知

This commit is contained in:
dengqichen 2025-11-14 14:35:46 +08:00
parent 566425869d
commit 3a7492ac91
4 changed files with 99 additions and 102 deletions

View File

@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@ -65,8 +66,11 @@ public class DeployExecuteRequest {
@Valid @Valid
private NotificationConfig notification; private NotificationConfig notification;
@Schema(description = "执行时间", required = true)
private Date deployDate = new Date();
@Schema(description = "部署备注") @Schema(description = "部署备注")
private String remark; private String deployRemark;
/** /**
* Jenkins配置 * Jenkins配置

View File

@ -162,7 +162,7 @@ public class DeployServiceImpl implements IDeployService {
// 补充查询作为成员但不是负责人的团队 // 补充查询作为成员但不是负责人的团队
Set<Long> missingTeamIds = teamIds.stream() Set<Long> missingTeamIds = teamIds.stream()
.filter(id -> !teamMap.containsKey(id)) .filter(id -> !teamMap.containsKey(id))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
if (!missingTeamIds.isEmpty()) { if (!missingTeamIds.isEmpty()) {
teamRepository.findAllById(missingTeamIds).forEach(team -> teamMap.put(team.getId(), team)); teamRepository.findAllById(missingTeamIds).forEach(team -> teamMap.put(team.getId(), team));
} }
@ -218,7 +218,7 @@ public class DeployServiceImpl implements IDeployService {
// 10. 批量查询团队环境配置获取团队配置的环境 // 10. 批量查询团队环境配置获取团队配置的环境
List<TeamEnvironmentConfig> teamEnvConfigs = teamEnvironmentConfigRepository.findByTeamIdIn(teamIds); List<TeamEnvironmentConfig> teamEnvConfigs = teamEnvironmentConfigRepository.findByTeamIdIn(teamIds);
Map<String, TeamEnvironmentConfig> teamEnvConfigMap = teamEnvConfigs.stream() Map<String, TeamEnvironmentConfig> teamEnvConfigMap = teamEnvConfigs.stream()
.collect(toMap(c -> c.getTeamId() + "_" + c.getEnvironmentId(), c -> c)); .collect(toMap(c -> c.getTeamId() + "_" + c.getEnvironmentId(), c -> c));
// 从团队环境配置中提取环境ID // 从团队环境配置中提取环境ID
Set<Long> teamConfiguredEnvIds = teamEnvConfigs.stream() Set<Long> teamConfiguredEnvIds = teamEnvConfigs.stream()
@ -291,9 +291,9 @@ public class DeployServiceImpl implements IDeployService {
// 17. 批量查询审批人信息 // 17. 批量查询审批人信息
Set<Long> approverUserIds = teamEnvConfigs.stream() Set<Long> approverUserIds = teamEnvConfigs.stream()
.filter(c -> c.getApproverUserIds() != null) .filter(c -> c.getApproverUserIds() != null)
.flatMap(c -> c.getApproverUserIds().stream()) .flatMap(c -> c.getApproverUserIds().stream())
.collect(Collectors.toSet()); .collect(Collectors.toSet());
Map<Long, User> approverMap = !approverUserIds.isEmpty() Map<Long, User> approverMap = !approverUserIds.isEmpty()
? userRepository.findAllById(approverUserIds).stream().collect(toMap(User::getId, u -> u)) ? userRepository.findAllById(approverUserIds).stream().collect(toMap(User::getId, u -> u))
: Collections.emptyMap(); : Collections.emptyMap();
@ -615,33 +615,33 @@ public class DeployServiceImpl implements IDeployService {
*/ */
private Map<Long, DeployStatisticsDTO> queryDeployStatistics(List<Long> teamApplicationIds) { private Map<Long, DeployStatisticsDTO> queryDeployStatistics(List<Long> teamApplicationIds) {
Map<Long, DeployStatisticsDTO> statisticsMap = new HashMap<>(); Map<Long, DeployStatisticsDTO> statisticsMap = new HashMap<>();
List<Object[]> statisticsList = deployRecordRepository.findDeployStatisticsByTeamApplicationIds(teamApplicationIds); List<Object[]> statisticsList = deployRecordRepository.findDeployStatisticsByTeamApplicationIds(teamApplicationIds);
for (Object[] row : statisticsList) { for (Object[] row : statisticsList) {
Long teamApplicationId = (Long) row[0]; Long teamApplicationId = (Long) row[0];
Long totalCount = ((Number) row[1]).longValue(); Long totalCount = ((Number) row[1]).longValue();
Long successCount = ((Number) row[2]).longValue(); Long successCount = ((Number) row[2]).longValue();
Long failedCount = ((Number) row[3]).longValue(); Long failedCount = ((Number) row[3]).longValue();
Long runningCount = ((Number) row[4]).longValue(); Long runningCount = ((Number) row[4]).longValue();
LocalDateTime lastDeployTime = null; LocalDateTime lastDeployTime = null;
if (row[5] != null) { if (row[5] != null) {
if (row[5] instanceof Timestamp) { if (row[5] instanceof Timestamp) {
lastDeployTime = ((Timestamp) row[5]).toLocalDateTime(); lastDeployTime = ((Timestamp) row[5]).toLocalDateTime();
} else if (row[5] instanceof LocalDateTime) { } else if (row[5] instanceof LocalDateTime) {
lastDeployTime = (LocalDateTime) row[5]; lastDeployTime = (LocalDateTime) row[5];
}
} }
DeployStatisticsDTO stats = new DeployStatisticsDTO();
stats.setTotalCount(totalCount);
stats.setSuccessCount(successCount);
stats.setFailedCount(failedCount);
stats.setRunningCount(runningCount);
stats.setLastDeployTime(lastDeployTime);
statisticsMap.put(teamApplicationId, stats);
} }
DeployStatisticsDTO stats = new DeployStatisticsDTO();
stats.setTotalCount(totalCount);
stats.setSuccessCount(successCount);
stats.setFailedCount(failedCount);
stats.setRunningCount(runningCount);
stats.setLastDeployTime(lastDeployTime);
statisticsMap.put(teamApplicationId, stats);
}
return statisticsMap; return statisticsMap;
} }
@ -649,12 +649,12 @@ public class DeployServiceImpl implements IDeployService {
* 批量查询最新部署记录 * 批量查询最新部署记录
*/ */
private Map<Long, DeployRecord> queryLatestRecords(List<Long> teamApplicationIds) { private Map<Long, DeployRecord> queryLatestRecords(List<Long> teamApplicationIds) {
List<DeployRecord> latestRecords = deployRecordRepository.findLatestDeployRecordsByTeamApplicationIds(teamApplicationIds); List<DeployRecord> latestRecords = deployRecordRepository.findLatestDeployRecordsByTeamApplicationIds(teamApplicationIds);
Map<Long, DeployRecord> latestRecordMap = latestRecords.stream() Map<Long, DeployRecord> latestRecordMap = latestRecords.stream()
.collect(toMap(DeployRecord::getTeamApplicationId, r -> r)); .collect(toMap(DeployRecord::getTeamApplicationId, r -> r));
// 更新统计信息中的最新状态和部署人 // 更新统计信息中的最新状态和部署人
latestRecordMap.forEach((teamAppId, record) -> { latestRecordMap.forEach((teamAppId, record) -> {
// 这里可以添加额外的处理逻辑 // 这里可以添加额外的处理逻辑
}); });
@ -756,7 +756,7 @@ public class DeployServiceImpl implements IDeployService {
*/ */
private void createDeployRecord(DeployExecuteRequest request, WorkflowInstanceDTO workflowInstance, String businessKey) { private void createDeployRecord(DeployExecuteRequest request, WorkflowInstanceDTO workflowInstance, String businessKey) {
String currentUsername = SecurityUtils.getCurrentUsername(); String currentUsername = SecurityUtils.getCurrentUsername();
deployRecordService.createDeployRecord(workflowInstance.getId(), businessKey, request.getTeamApplicationId(), request.getTeamId(), request.getApplicationId(), request.getEnvironmentId(), currentUsername, request.getRemark()); deployRecordService.createDeployRecord(workflowInstance.getId(), businessKey, request.getTeamApplicationId(), request.getTeamId(), request.getApplicationId(), request.getEnvironmentId(), currentUsername, request.getDeployRemark());
log.info("部署记录已创建: businessKey={}, workflowInstanceId={}", businessKey, workflowInstance.getId()); log.info("部署记录已创建: businessKey={}, workflowInstanceId={}", businessKey, workflowInstance.getId());
} }
@ -874,7 +874,7 @@ public class DeployServiceImpl implements IDeployService {
// 4. 查询部署记录 // 4. 查询部署记录
DeployRecord deployRecord = deployRecordRepository.findByBusinessKeyAndDeletedFalse(businessKey) DeployRecord deployRecord = deployRecordRepository.findByBusinessKeyAndDeletedFalse(businessKey)
.orElseThrow(() -> new BusinessException(ResponseCode.DEPLOY_RECORD_NOT_FOUND, .orElseThrow(() -> new BusinessException(ResponseCode.DEPLOY_RECORD_NOT_FOUND,
new Object[]{businessKey})); new Object[] {businessKey}));
// 5. 构建 DTO // 5. 构建 DTO
DeployApprovalTaskDTO dto = new DeployApprovalTaskDTO(); DeployApprovalTaskDTO dto = new DeployApprovalTaskDTO();
@ -1053,7 +1053,7 @@ public class DeployServiceImpl implements IDeployService {
* <p> NodeContext inputs 字段中解析审批配置 * <p> NodeContext inputs 字段中解析审批配置
* *
* @param variables 流程变量 Map * @param variables 流程变量 Map
* @param nodeId 审批节点ID * @param nodeId 审批节点ID
* @return ApprovalInputMapping 对象解析失败返回 null * @return ApprovalInputMapping 对象解析失败返回 null
*/ */
private ApprovalInputMapping extractApprovalInputMapping(Map<String, Object> variables, String nodeId) { private ApprovalInputMapping extractApprovalInputMapping(Map<String, Object> variables, String nodeId) {

View File

@ -91,8 +91,7 @@ public class JenkinsBuildDelegate extends BaseNodeDelegate<JenkinsBuildInputMapp
JenkinsBuildResponse buildDetails = jenkinsServiceIntegration.getBuildDetails(externalSystem, jobName, buildInfo.getBuildNumber()); JenkinsBuildResponse buildDetails = jenkinsServiceIntegration.getBuildDetails(externalSystem, jobName, buildInfo.getBuildNumber());
// 打印调试信息 // 打印调试信息
log.info("Build details - changeSets: {}, artifacts: {}", log.info("Build details - changeSets: {}, artifacts: {}", buildDetails.getChangeSets(), buildDetails.getArtifacts());
buildDetails.getChangeSets(), buildDetails.getArtifacts());
// 6. 设置输出结果执行到这里说明构建成功 // 6. 设置输出结果执行到这里说明构建成功
// 直接修改预初始化的 output 对象 // 直接修改预初始化的 output 对象

View File

@ -48,45 +48,39 @@ public class NotificationNodeDelegate extends BaseNodeDelegate<NotificationInput
logWarn(String.format("Notification delegate parameter verification failed - channelId: %s, templateId: %s", input.getChannelId(), input.getNotificationTemplateId())); logWarn(String.format("Notification delegate parameter verification failed - channelId: %s, templateId: %s", input.getChannelId(), input.getNotificationTemplateId()));
return; return;
} }
try { // 2. 查询渠道和模板信息
// 2. 查询渠道和模板信息 NotificationChannel channel = notificationChannelRepository.findById(input.getChannelId()).orElseThrow(() -> new RuntimeException("通知渠道不存在: " + input.getChannelId()));
NotificationChannel channel = notificationChannelRepository.findById(input.getChannelId()).orElseThrow(() -> new RuntimeException("通知渠道不存在: " + input.getChannelId())); NotificationTemplate template = notificationTemplateRepository.findById(input.getNotificationTemplateId()).orElseThrow(() -> new RuntimeException("通知模板不存在: " + input.getNotificationTemplateId()));
NotificationTemplate template = notificationTemplateRepository.findById(input.getNotificationTemplateId()).orElseThrow(() -> new RuntimeException("通知模板不存在: " + input.getNotificationTemplateId()));
// 3. 构建SendNotificationRequest // 3. 构建SendNotificationRequest
SendNotificationRequest request = new SendNotificationRequest(); SendNotificationRequest request = new SendNotificationRequest();
request.setNotificationTemplateId(input.getNotificationTemplateId()); request.setNotificationTemplateId(input.getNotificationTemplateId());
request.setTemplateParams(execution.getVariables()); request.setTemplateParams(execution.getVariables());
// 4. 根据渠道类型创建sendRequest并从模板配置中获取参数 // 4. 根据渠道类型创建sendRequest并从模板配置中获取参数
switch (channel.getChannelType()) { switch (channel.getChannelType()) {
case WEWORK -> { case WEWORK -> {
WeworkSendNotificationRequest weworkRequest = new WeworkSendNotificationRequest(); WeworkSendNotificationRequest weworkRequest = new WeworkSendNotificationRequest();
weworkRequest.setChannelId(input.getChannelId()); weworkRequest.setChannelId(input.getChannelId());
// 从模板配置中获取消息类型 // 从模板配置中获取消息类型
weworkRequest.setMessageType(getWeworkMessageType(template)); weworkRequest.setMessageType(getWeworkMessageType(template));
request.setSendRequest(weworkRequest); request.setSendRequest(weworkRequest);
}
case EMAIL -> {
EmailSendNotificationRequest emailRequest = new EmailSendNotificationRequest();
emailRequest.setChannelId(input.getChannelId());
// 收件人从工作流变量获取
emailRequest.setToReceivers(getEmailReceivers(execution, configs));
// 其他配置HTML格式等由NotificationService根据模板配置自动设置
request.setSendRequest(emailRequest);
}
default -> throw new RuntimeException("不支持的渠道类型: " + channel.getChannelType());
} }
case EMAIL -> {
// 5. 发送通知NotificationService会处理模板渲染和详细配置 EmailSendNotificationRequest emailRequest = new EmailSendNotificationRequest();
notificationService.send(request); emailRequest.setChannelId(input.getChannelId());
// 收件人从工作流变量获取
log.info("工作流通知发送成功 - 渠道ID: {}, 模板ID: {}", emailRequest.setToReceivers(getEmailReceivers(execution, configs));
input.getChannelId(), input.getNotificationTemplateId()); // 其他配置HTML格式等由NotificationService根据模板配置自动设置
} catch (Exception e) { request.setSendRequest(emailRequest);
logError("工作流通知发送失败: " + e.getMessage()); }
throw new RuntimeException("通知发送失败", e); default -> throw new RuntimeException("不支持的渠道类型: " + channel.getChannelType());
} }
// 5. 发送通知NotificationService会处理模板渲染和详细配置
notificationService.send(request);
log.info("工作流通知发送成功 - 渠道ID: {}, 模板ID: {}", input.getChannelId(), input.getNotificationTemplateId());
} }
/** /**