增加构建通知
This commit is contained in:
parent
694e6690ca
commit
8e6dbec07e
@ -1,9 +1,17 @@
|
||||
package com.qqchen.deploy.backend.deploy.converter;
|
||||
|
||||
import com.qqchen.deploy.backend.deploy.dto.TeamEnvironmentNotificationConfigDTO;
|
||||
import com.qqchen.deploy.backend.deploy.dto.UserTeamEnvironmentNotificationConfigDTO;
|
||||
import com.qqchen.deploy.backend.deploy.entity.TeamEnvironmentNotificationConfig;
|
||||
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
||||
import com.qqchen.deploy.backend.notification.entity.NotificationChannel;
|
||||
import com.qqchen.deploy.backend.notification.entity.NotificationTemplate;
|
||||
import org.mapstruct.Context;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 团队环境通知配置Converter
|
||||
@ -14,4 +22,41 @@ import org.mapstruct.Mapper;
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface TeamEnvironmentNotificationConfigConverter
|
||||
extends BaseConverter<TeamEnvironmentNotificationConfig, TeamEnvironmentNotificationConfigDTO> {
|
||||
|
||||
/**
|
||||
* 转换为用户环境通知配置DTO(包含扩展字段)
|
||||
*/
|
||||
@Mapping(target = "notificationChannelName",
|
||||
expression = "java(getChannelName(config.getNotificationChannelId(), channelMap))")
|
||||
@Mapping(target = "deployNotificationTemplateName",
|
||||
expression = "java(getTemplateName(config.getDeployNotificationTemplateId(), templateMap))")
|
||||
@Mapping(target = "buildNotificationTemplateName",
|
||||
expression = "java(getTemplateName(config.getBuildNotificationTemplateId(), templateMap))")
|
||||
@Mapping(target = "buildFailureNotificationTemplateName",
|
||||
expression = "java(getTemplateName(config.getBuildFailureNotificationTemplateId(), templateMap))")
|
||||
UserTeamEnvironmentNotificationConfigDTO toUserDTO(
|
||||
TeamEnvironmentNotificationConfig config,
|
||||
@Context Map<Long, NotificationChannel> channelMap,
|
||||
@Context Map<Long, NotificationTemplate> templateMap
|
||||
);
|
||||
|
||||
/**
|
||||
* 获取渠道名称
|
||||
*/
|
||||
default String getChannelName(Long channelId, Map<Long, NotificationChannel> channelMap) {
|
||||
return Optional.ofNullable(channelId)
|
||||
.map(channelMap::get)
|
||||
.map(NotificationChannel::getName)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模板名称
|
||||
*/
|
||||
default String getTemplateName(Long templateId, Map<Long, NotificationTemplate> templateMap) {
|
||||
return Optional.ofNullable(templateId)
|
||||
.map(templateMap::get)
|
||||
.map(NotificationTemplate::getName)
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,12 +106,27 @@ public class DeployExecuteRequest {
|
||||
@Data
|
||||
@Schema(description = "通知配置")
|
||||
public static class NotificationConfig {
|
||||
@Schema(description = "是否需要通知", required = true)
|
||||
@NotNull(message = "是否需要通知不能为空")
|
||||
private Boolean required;
|
||||
|
||||
|
||||
@Schema(description = "通知渠道ID")
|
||||
private Long channelId;
|
||||
private Long notificationChannelId;
|
||||
|
||||
@Schema(description = "是否启用部署通知")
|
||||
private Boolean deployNotificationEnabled;
|
||||
|
||||
@Schema(description = "部署通知模板ID")
|
||||
private Long deployNotificationTemplateId;
|
||||
|
||||
@Schema(description = "是否启用构建通知")
|
||||
private Boolean buildNotificationEnabled;
|
||||
|
||||
@Schema(description = "构建通知模板ID")
|
||||
private Long buildNotificationTemplateId;
|
||||
|
||||
@Schema(description = "构建失败时是否发送日志文件到企业微信")
|
||||
private Boolean buildFailureFileEnabled;
|
||||
|
||||
@Schema(description = "构建失败通知模板ID")
|
||||
private Long buildFailureNotificationTemplateId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,10 @@ import com.qqchen.deploy.backend.deploy.dto.*;
|
||||
import com.qqchen.deploy.backend.deploy.entity.*;
|
||||
import com.qqchen.deploy.backend.deploy.repository.*;
|
||||
import com.qqchen.deploy.backend.notification.entity.NotificationChannel;
|
||||
import com.qqchen.deploy.backend.notification.entity.NotificationTemplate;
|
||||
import com.qqchen.deploy.backend.notification.repository.INotificationChannelRepository;
|
||||
import com.qqchen.deploy.backend.notification.repository.INotificationTemplateRepository;
|
||||
import com.qqchen.deploy.backend.deploy.converter.TeamEnvironmentNotificationConfigConverter;
|
||||
import com.qqchen.deploy.backend.deploy.service.IDeployService;
|
||||
import com.qqchen.deploy.backend.framework.security.SecurityUtils;
|
||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||
@ -46,6 +49,7 @@ import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.stream.Collectors.*;
|
||||
|
||||
@ -113,6 +117,12 @@ public class DeployServiceImpl implements IDeployService {
|
||||
@Resource
|
||||
private INotificationChannelRepository notificationChannelRepository;
|
||||
|
||||
@Resource
|
||||
private INotificationTemplateRepository notificationTemplateRepository;
|
||||
|
||||
@Resource
|
||||
private TeamEnvironmentNotificationConfigConverter notificationConfigConverter;
|
||||
|
||||
|
||||
@Override
|
||||
public List<UserTeamDeployableDTO> getDeployableEnvironments() {
|
||||
@ -262,7 +272,24 @@ public class DeployServiceImpl implements IDeployService {
|
||||
);
|
||||
}
|
||||
|
||||
// 16. 批量查询审批人信息
|
||||
// 16. 批量查询通知模板信息
|
||||
Set<Long> templateIds = notificationConfigMap.values().stream()
|
||||
.flatMap(config -> Stream.of(
|
||||
config.getDeployNotificationTemplateId(),
|
||||
config.getBuildNotificationTemplateId(),
|
||||
config.getBuildFailureNotificationTemplateId()
|
||||
))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Map<Long, NotificationTemplate> templateMap = new HashMap<>();
|
||||
if (!templateIds.isEmpty()) {
|
||||
notificationTemplateRepository.findAllById(templateIds).forEach(template ->
|
||||
templateMap.put(template.getId(), template)
|
||||
);
|
||||
}
|
||||
|
||||
// 17. 批量查询审批人信息
|
||||
Set<Long> approverUserIds = teamEnvConfigs.stream()
|
||||
.filter(c -> c.getApproverUserIds() != null)
|
||||
.flatMap(c -> c.getApproverUserIds().stream())
|
||||
@ -283,7 +310,7 @@ public class DeployServiceImpl implements IDeployService {
|
||||
currentUserId, teamId, teamMap, ownerMap, membersByTeam, memberUserMap,
|
||||
teamAppsMap, envMap, appMap, systemMap, workflowMap,
|
||||
teamEnvConfigMap, approverMap,
|
||||
notificationConfigMap, channelMap,
|
||||
notificationConfigMap, channelMap, templateMap,
|
||||
statisticsMap, latestRecordMap, recentRecordsMap
|
||||
);
|
||||
if (teamDTO != null) {
|
||||
@ -314,6 +341,7 @@ public class DeployServiceImpl implements IDeployService {
|
||||
Map<Long, User> approverMap,
|
||||
Map<String, TeamEnvironmentNotificationConfig> notificationConfigMap,
|
||||
Map<Long, NotificationChannel> channelMap,
|
||||
Map<Long, NotificationTemplate> templateMap,
|
||||
Map<Long, DeployStatisticsDTO> statisticsMap,
|
||||
Map<Long, DeployRecord> latestRecordMap,
|
||||
Map<Long, List<DeployRecordSummaryDTO>> recentRecordsMap
|
||||
@ -380,7 +408,7 @@ public class DeployServiceImpl implements IDeployService {
|
||||
teamId, env, envApps,
|
||||
appMap, systemMap, workflowMap,
|
||||
teamEnvConfigMap, approverMap,
|
||||
notificationConfigMap, channelMap,
|
||||
notificationConfigMap, channelMap, templateMap,
|
||||
statisticsMap, latestRecordMap, recentRecordsMap
|
||||
);
|
||||
environments.add(envDTO);
|
||||
@ -409,6 +437,7 @@ public class DeployServiceImpl implements IDeployService {
|
||||
Map<Long, User> approverMap,
|
||||
Map<String, TeamEnvironmentNotificationConfig> notificationConfigMap,
|
||||
Map<Long, NotificationChannel> channelMap,
|
||||
Map<Long, NotificationTemplate> templateMap,
|
||||
Map<Long, DeployStatisticsDTO> statisticsMap,
|
||||
Map<Long, DeployRecord> latestRecordMap,
|
||||
Map<Long, List<DeployRecordSummaryDTO>> recentRecordsMap
|
||||
@ -451,24 +480,10 @@ public class DeployServiceImpl implements IDeployService {
|
||||
dto.setApprovers(Collections.emptyList());
|
||||
}
|
||||
|
||||
// 构建通知配置
|
||||
UserTeamEnvironmentNotificationConfigDTO notificationConfigDTO = null;
|
||||
// 构建通知配置 - 使用MapStruct转换器
|
||||
TeamEnvironmentNotificationConfig notificationConfig = notificationConfigMap.get(configKey);
|
||||
if (notificationConfig != null) {
|
||||
notificationConfigDTO = new UserTeamEnvironmentNotificationConfigDTO();
|
||||
notificationConfigDTO.setNotificationChannelId(notificationConfig.getNotificationChannelId());
|
||||
notificationConfigDTO.setDeployNotificationEnabled(notificationConfig.getDeployNotificationEnabled());
|
||||
notificationConfigDTO.setBuildNotificationEnabled(notificationConfig.getBuildNotificationEnabled());
|
||||
notificationConfigDTO.setBuildFailureFileEnabled(notificationConfig.getBuildFailureFileEnabled());
|
||||
|
||||
// 设置通知渠道名称
|
||||
if (notificationConfig.getNotificationChannelId() != null) {
|
||||
NotificationChannel channel = channelMap.get(notificationConfig.getNotificationChannelId());
|
||||
if (channel != null) {
|
||||
notificationConfigDTO.setNotificationChannelName(channel.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
UserTeamEnvironmentNotificationConfigDTO notificationConfigDTO =
|
||||
notificationConfigConverter.toUserDTO(notificationConfig, channelMap, templateMap);
|
||||
dto.setNotificationConfig(notificationConfigDTO);
|
||||
} else {
|
||||
dto.setRequiresApproval(false);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.qqchen.deploy.backend.notification.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@ -16,14 +17,16 @@ import java.util.Map;
|
||||
@Schema(description = "发送通知请求")
|
||||
public class SendNotificationRequest {
|
||||
|
||||
@Schema(description = "渠道ID", required = true, example = "1")
|
||||
@NotNull(message = "渠道ID不能为空")
|
||||
private Long channelId;
|
||||
|
||||
@Schema(description = "通知模板ID", required = true, example = "1")
|
||||
@NotNull(message = "通知模板ID不能为空")
|
||||
private Long notificationTemplateId;
|
||||
|
||||
@Schema(description = "模板参数", example = "{\"projectName\":\"测试项目\",\"buildNumber\":\"123\"}")
|
||||
private Map<String, Object> params;
|
||||
@Schema(description = "模板渲染参数(仅用于模板变量替换)",
|
||||
example = "{\"projectName\":\"测试项目\",\"buildNumber\":\"123\"}")
|
||||
private Map<String, Object> templateParams;
|
||||
|
||||
@Schema(description = "具体的发送请求配置", required = true)
|
||||
@NotNull(message = "发送请求配置不能为空")
|
||||
@Valid
|
||||
private BaseSendNotificationRequest sendRequest;
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ public class NotificationServiceImpl implements INotificationService {
|
||||
.orElseThrow(() -> new BusinessException(ResponseCode.NOTIFICATION_TEMPLATE_NOT_FOUND));
|
||||
|
||||
// 2. 获取通知渠道
|
||||
NotificationChannel channel = notificationChannelRepository.findById(request.getChannelId())
|
||||
NotificationChannel channel = notificationChannelRepository.findById(request.getSendRequest().getChannelId())
|
||||
.orElseThrow(() -> new BusinessException(ResponseCode.DATA_NOT_FOUND));
|
||||
|
||||
// 3. 验证模板和渠道类型是否匹配
|
||||
@ -62,7 +62,12 @@ public class NotificationServiceImpl implements INotificationService {
|
||||
throw new BusinessException(ResponseCode.INVALID_PARAM);
|
||||
}
|
||||
|
||||
// 4. 验证模板和渠道是否启用
|
||||
// 4. 验证SendRequest渠道类型和模板渠道类型是否匹配
|
||||
if (!request.getSendRequest().getChannelType().equals(template.getChannelType())) {
|
||||
throw new BusinessException(ResponseCode.INVALID_PARAM);
|
||||
}
|
||||
|
||||
// 5. 验证模板和渠道是否启用
|
||||
if (!template.getEnabled()) {
|
||||
throw new BusinessException(ResponseCode.NOTIFICATION_TEMPLATE_DISABLED);
|
||||
}
|
||||
@ -70,103 +75,12 @@ public class NotificationServiceImpl implements INotificationService {
|
||||
throw new BusinessException(ResponseCode.DATA_NOT_FOUND);
|
||||
}
|
||||
|
||||
// 5. 渲染模板内容
|
||||
String content = notificationTemplateService.renderTemplate(template.getContentTemplate(), request.getParams());
|
||||
// 6. 渲染模板内容
|
||||
String content = notificationTemplateService.renderTemplate(template.getContentTemplate(), request.getTemplateParams());
|
||||
|
||||
// 6. 根据渠道类型发送通知
|
||||
switch (template.getChannelType()) {
|
||||
case WEWORK -> sendWeworkNotification(request.getChannelId(), content, template, request.getParams());
|
||||
case EMAIL -> sendEmailNotification(request.getChannelId(), content, template, request.getParams());
|
||||
default -> throw new BusinessException(ResponseCode.INVALID_PARAM);
|
||||
}
|
||||
// 7. 设置渲染后的内容并发送
|
||||
request.getSendRequest().setContent(content);
|
||||
notificationSendService.send(request.getSendRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送企业微信通知
|
||||
*/
|
||||
private void sendWeworkNotification(Long channelId, String content, NotificationTemplate template, Map<String, Object> params) {
|
||||
WeworkSendNotificationRequest request = new WeworkSendNotificationRequest();
|
||||
request.setChannelId(channelId);
|
||||
request.setContent(content);
|
||||
|
||||
// 从模板配置获取消息类型
|
||||
WeworkMessageTypeEnum messageType = WeworkMessageTypeEnum.TEXT; // 默认值
|
||||
try {
|
||||
BaseTemplateConfig baseTemplateConfig = JsonUtils.fromMap(template.getTemplateConfig(), BaseTemplateConfig.class);
|
||||
if (baseTemplateConfig instanceof WeworkTemplateConfig weworkTemplateConfig) {
|
||||
messageType = weworkTemplateConfig.getMessageType();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("获取模板配置失败,使用默认消息类型: {}", e.getMessage());
|
||||
}
|
||||
|
||||
// params 仍可以覆盖模板配置
|
||||
if (params != null && params.containsKey("messageType")) {
|
||||
messageType = WeworkMessageTypeEnum.valueOf(params.get("messageType").toString());
|
||||
}
|
||||
request.setMessageType(messageType);
|
||||
|
||||
// 从参数中获取@人员信息
|
||||
if (params != null) {
|
||||
if (params.containsKey("mentionedMobileList")) {
|
||||
request.setMentionedMobileList((List<String>) params.get("mentionedMobileList"));
|
||||
}
|
||||
if (params.containsKey("mentionedUserList")) {
|
||||
request.setMentionedUserList((List<String>) params.get("mentionedUserList"));
|
||||
}
|
||||
}
|
||||
|
||||
notificationSendService.send(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮件通知
|
||||
*/
|
||||
private void sendEmailNotification(Long channelId, String content, NotificationTemplate template, Map<String, Object> params) {
|
||||
EmailSendNotificationRequest request = new EmailSendNotificationRequest();
|
||||
request.setChannelId(channelId);
|
||||
request.setContent(content);
|
||||
|
||||
// 邮件标题从参数中获取,或使用默认值
|
||||
String subject = "系统通知";
|
||||
if (params != null && params.containsKey("subject")) {
|
||||
subject = params.get("subject").toString();
|
||||
}
|
||||
request.setSubject(subject);
|
||||
|
||||
// 从模板配置获取内容类型
|
||||
Boolean isHtml = false; // 默认值
|
||||
try {
|
||||
BaseTemplateConfig baseTemplateConfig = JsonUtils.fromMap(template.getTemplateConfig(), BaseTemplateConfig.class);
|
||||
if (baseTemplateConfig instanceof EmailTemplateConfig emailTemplateConfig) {
|
||||
isHtml = emailTemplateConfig.getContentType() == EmailContentTypeEnum.HTML;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("获取模板配置失败,使用默认内容类型: {}", e.getMessage());
|
||||
}
|
||||
|
||||
// params 仍可以覆盖模板配置
|
||||
if (params != null && params.containsKey("isHtml")) {
|
||||
isHtml = (Boolean) params.get("isHtml");
|
||||
}
|
||||
request.setIsHtml(isHtml);
|
||||
|
||||
// 收件人信息(必须)
|
||||
if (params == null || !params.containsKey("toReceivers")) {
|
||||
throw new BusinessException(ResponseCode.INVALID_PARAM);
|
||||
}
|
||||
request.setToReceivers((List<String>) params.get("toReceivers"));
|
||||
|
||||
// 可选参数
|
||||
if (params != null) {
|
||||
if (params.containsKey("ccReceivers")) {
|
||||
request.setCcReceivers((List<String>) params.get("ccReceivers"));
|
||||
}
|
||||
if (params.containsKey("bccReceivers")) {
|
||||
request.setBccReceivers((List<String>) params.get("bccReceivers"));
|
||||
}
|
||||
}
|
||||
|
||||
notificationSendService.send(request);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user