fix(测试计划): 执行通知问题

--bug=1044741 --user=宋昌昌 【Jenkins插件】MS消息管理中配置了Jenkins执行成功/执行失败,给接收人是创建人发送通知失败 https://www.tapd.cn/55049933/s/1558376
This commit is contained in:
song-cc-rock 2024-08-07 18:45:28 +08:00 committed by Craftsman
parent fc46239b5b
commit 209c5a9e44
5 changed files with 1292 additions and 1232 deletions

View File

@ -23,6 +23,7 @@ import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
@Service @Service
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -43,6 +44,7 @@ public class BugLogService {
* @param files 文件 * @param files 文件
* @return 日志 * @return 日志
*/ */
@SuppressWarnings("unused")
public LogDTO addLog(BugEditRequest request, List<MultipartFile> files) { public LogDTO addLog(BugEditRequest request, List<MultipartFile> files) {
LogDTO dto = new LogDTO(request.getProjectId(), null, null, null, OperationLogType.ADD.name(), OperationLogModule.BUG_MANAGEMENT_INDEX, getPlatformTitle(request)); LogDTO dto = new LogDTO(request.getProjectId(), null, null, null, OperationLogType.ADD.name(), OperationLogModule.BUG_MANAGEMENT_INDEX, getPlatformTitle(request));
dto.setHistory(true); dto.setHistory(true);
@ -59,6 +61,7 @@ public class BugLogService {
* @param files 文件 * @param files 文件
* @return 日志 * @return 日志
*/ */
@SuppressWarnings("unused")
public LogDTO updateLog(BugEditRequest request, List<MultipartFile> files) { public LogDTO updateLog(BugEditRequest request, List<MultipartFile> files) {
BugDTO history = getOriginalValue(request.getId()); BugDTO history = getOriginalValue(request.getId());
LogDTO dto = new LogDTO(request.getProjectId(), null, request.getId(), null, OperationLogType.UPDATE.name(), OperationLogModule.BUG_MANAGEMENT_INDEX, getPlatformTitle(request)); LogDTO dto = new LogDTO(request.getProjectId(), null, request.getId(), null, OperationLogType.UPDATE.name(), OperationLogModule.BUG_MANAGEMENT_INDEX, getPlatformTitle(request));
@ -76,6 +79,7 @@ public class BugLogService {
* @param id 缺陷ID * @param id 缺陷ID
* @return 日志 * @return 日志
*/ */
@SuppressWarnings("unused")
public LogDTO deleteLog(String id) { public LogDTO deleteLog(String id) {
Bug bug = bugMapper.selectByPrimaryKey(id); Bug bug = bugMapper.selectByPrimaryKey(id);
if (bug != null) { if (bug != null) {
@ -95,6 +99,7 @@ public class BugLogService {
* @param id 缺陷ID * @param id 缺陷ID
* @return 日志 * @return 日志
*/ */
@SuppressWarnings("unused")
public LogDTO recoverLog(String id) { public LogDTO recoverLog(String id) {
Bug bug = bugMapper.selectByPrimaryKey(id); Bug bug = bugMapper.selectByPrimaryKey(id);
if (bug != null) { if (bug != null) {
@ -146,11 +151,8 @@ public class BugLogService {
bugs.forEach(bug -> { bugs.forEach(bug -> {
BugDTO originalBug = new BugDTO(); BugDTO originalBug = new BugDTO();
BeanUtils.copyBean(originalBug, bug); BeanUtils.copyBean(originalBug, bug);
BugContent bugContent = bugContents.stream().filter(content -> StringUtils.equals(content.getBugId(), bug.getId())).findFirst().orElse(null); bugContents.stream().filter(content -> StringUtils.equals(content.getBugId(), bug.getId())).findFirst().ifPresent(bugContent -> originalBug.setDescription(bugContent.getDescription()));
if (bugContent != null) { bugOriginalList.add(originalBug);
originalBug.setDescription(bugContent.getDescription());
}
bugOriginalList.add(originalBug);
}); });
// 缺陷自定义字段 // 缺陷自定义字段
return bugService.handleCustomField(bugOriginalList, bugOriginalList.getFirst().getProjectId()); return bugService.handleCustomField(bugOriginalList, bugOriginalList.getFirst().getProjectId());
@ -162,7 +164,8 @@ public class BugLogService {
* @return 缺陷标题 * @return 缺陷标题
*/ */
private String getPlatformTitle(BugEditRequest request) { private String getPlatformTitle(BugEditRequest request) {
BugCustomFieldDTO platformTitle = request.getCustomFields().stream().filter(field -> StringUtils.equalsAny(field.getId(), "summary")).findFirst().get(); Optional<BugCustomFieldDTO> find = request.getCustomFields().stream().filter(field -> StringUtils.equalsAny(field.getId(), "summary", "title")).findFirst();
return StringUtils.isNotBlank(request.getTitle()) ? request.getTitle() : platformTitle.getValue(); BugCustomFieldDTO titleField = find.orElseGet(BugCustomFieldDTO::new);
return StringUtils.isNotBlank(request.getTitle()) ? request.getTitle() : titleField.getValue();
} }
} }

View File

@ -40,6 +40,7 @@ public class BugNoticeService {
* @param request 请求参数 * @param request 请求参数
* @return 缺陷通知 * @return 缺陷通知
*/ */
@SuppressWarnings("unused")
public BugNoticeDTO getNoticeByRequest(BugEditRequest request) { public BugNoticeDTO getNoticeByRequest(BugEditRequest request) {
// 获取状态选项, 处理人选项 // 获取状态选项, 处理人选项
Map<String, String> statusMap = getStatusMap(request.getProjectId()); Map<String, String> statusMap = getStatusMap(request.getProjectId());
@ -88,22 +89,7 @@ public class BugNoticeService {
if (bugDTO == null) { if (bugDTO == null) {
return null; return null;
} }
// 构建通知对象 return buildNotice(bugDTO);
BugNoticeDTO notice = new BugNoticeDTO();
BeanUtils.copyBean(notice, bugDTO);
// 自定义字段解析{name: value}
if (CollectionUtils.isNotEmpty(bugDTO.getCustomFields())) {
List<OptionDTO> fields = new ArrayList<>();
bugDTO.getCustomFields().forEach(field -> {
// 其他自定义字段
OptionDTO fieldDTO = new OptionDTO();
fieldDTO.setId(field.getName());
fieldDTO.setName(field.getValue());
fields.add(fieldDTO);
});
notice.setFields(fields);
}
return notice;
} }
/** /**
@ -116,22 +102,7 @@ public class BugNoticeService {
return null; return null;
} }
List<BugNoticeDTO> notices = new ArrayList<>(); List<BugNoticeDTO> notices = new ArrayList<>();
bugs.forEach(bug -> { bugs.forEach(bug -> notices.add(buildNotice(bug)));
BugNoticeDTO notice = new BugNoticeDTO();
BeanUtils.copyBean(notice, bug);
if (CollectionUtils.isNotEmpty(bug.getCustomFields())) {
List<OptionDTO> fields = new ArrayList<>();
bug.getCustomFields().forEach(field -> {
// 其他自定义字段
OptionDTO fieldDTO = new OptionDTO();
fieldDTO.setId(field.getName());
fieldDTO.setName(field.getValue());
fields.add(fieldDTO);
});
notice.setFields(fields);
}
notices.add(notice);
});
return notices; return notices;
} }
@ -140,6 +111,7 @@ public class BugNoticeService {
* @param request 批量请求参数 * @param request 批量请求参数
* @return 缺陷通知集合 * @return 缺陷通知集合
*/ */
@SuppressWarnings("unused")
public List<BugNoticeDTO> getBatchNoticeByRequest(BugBatchRequest request) { public List<BugNoticeDTO> getBatchNoticeByRequest(BugBatchRequest request) {
List<String> batchIds = bugService.getBatchIdsByRequest(request); List<String> batchIds = bugService.getBatchIdsByRequest(request);
return getNoticeByIds(batchIds); return getNoticeByIds(batchIds);
@ -164,4 +136,28 @@ public class BugNoticeService {
List<SelectOption> handlerOption = bugCommonService.getHeaderHandlerOption(projectId); List<SelectOption> handlerOption = bugCommonService.getHeaderHandlerOption(projectId);
return handlerOption.stream().collect(Collectors.toMap(SelectOption::getValue, SelectOption::getText)); return handlerOption.stream().collect(Collectors.toMap(SelectOption::getValue, SelectOption::getText));
} }
/**
* 构建通知对象
* @param bugDTO 缺陷DTO
* @return 通知对象
*/
private BugNoticeDTO buildNotice(BugDTO bugDTO) {
// 构建通知对象
BugNoticeDTO notice = new BugNoticeDTO();
BeanUtils.copyBean(notice, bugDTO);
// 自定义字段解析{name: value}
if (CollectionUtils.isNotEmpty(bugDTO.getCustomFields())) {
List<OptionDTO> fields = new ArrayList<>();
bugDTO.getCustomFields().forEach(field -> {
// 其他自定义字段
OptionDTO fieldDTO = new OptionDTO();
fieldDTO.setId(field.getName());
fieldDTO.setName(field.getValue());
fields.add(fieldDTO);
});
notice.setFields(fields);
}
return notice;
}
} }

View File

@ -1,13 +1,17 @@
package io.metersphere.system.dto.sdk; package io.metersphere.system.dto.sdk;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.List; import java.util.List;
@Data @Data
@Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor
public class TestPlanMessageDTO { public class TestPlanMessageDTO {
@Schema(description = "message.domain.test_plan_num") @Schema(description = "message.domain.test_plan_num")
private String num; private String num;

View File

@ -4,27 +4,36 @@ import io.metersphere.functional.domain.FunctionalCase;
import io.metersphere.functional.mapper.FunctionalCaseMapper; import io.metersphere.functional.mapper.FunctionalCaseMapper;
import io.metersphere.plan.domain.*; import io.metersphere.plan.domain.*;
import io.metersphere.plan.dto.TestPlanDTO; import io.metersphere.plan.dto.TestPlanDTO;
import io.metersphere.plan.dto.TestPlanShareInfo;
import io.metersphere.plan.dto.request.TestPlanCreateRequest; import io.metersphere.plan.dto.request.TestPlanCreateRequest;
import io.metersphere.plan.dto.request.TestPlanReportShareRequest;
import io.metersphere.plan.dto.request.TestPlanUpdateRequest; import io.metersphere.plan.dto.request.TestPlanUpdateRequest;
import io.metersphere.plan.mapper.TestPlanConfigMapper; import io.metersphere.plan.mapper.TestPlanConfigMapper;
import io.metersphere.plan.mapper.TestPlanFollowerMapper; import io.metersphere.plan.mapper.TestPlanFollowerMapper;
import io.metersphere.plan.mapper.TestPlanMapper; import io.metersphere.plan.mapper.TestPlanMapper;
import io.metersphere.project.domain.Project;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.sdk.constants.ResultStatus; import io.metersphere.sdk.constants.ResultStatus;
import io.metersphere.sdk.constants.TaskTriggerMode; import io.metersphere.sdk.constants.TaskTriggerMode;
import io.metersphere.sdk.constants.TestPlanConstants; import io.metersphere.sdk.constants.TestPlanConstants;
import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
import io.metersphere.system.domain.User; import io.metersphere.system.domain.User;
import io.metersphere.system.dto.sdk.BaseSystemConfigDTO;
import io.metersphere.system.dto.sdk.TestPlanMessageDTO;
import io.metersphere.system.mapper.UserMapper; import io.metersphere.system.mapper.UserMapper;
import io.metersphere.system.notice.NoticeModel; import io.metersphere.system.notice.NoticeModel;
import io.metersphere.system.notice.constants.NoticeConstants; import io.metersphere.system.notice.constants.NoticeConstants;
import io.metersphere.system.notice.utils.MessageTemplateUtils; import io.metersphere.system.notice.utils.MessageTemplateUtils;
import io.metersphere.system.service.CommonNoticeSendService; import io.metersphere.system.service.CommonNoticeSendService;
import io.metersphere.system.service.NoticeSendService; import io.metersphere.system.service.NoticeSendService;
import io.metersphere.system.service.SystemParameterService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.beanutils.BeanMap; import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -37,170 +46,216 @@ import java.util.stream.Collectors;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public class TestPlanSendNoticeService { public class TestPlanSendNoticeService {
@Resource @Resource
private FunctionalCaseMapper functionalCaseMapper; private FunctionalCaseMapper functionalCaseMapper;
@Resource @Resource
private UserMapper userMapper; private UserMapper userMapper;
@Resource @Resource
private TestPlanMapper testPlanMapper; private TestPlanMapper testPlanMapper;
@Resource @Resource
private NoticeSendService noticeSendService; private NoticeSendService noticeSendService;
@Resource @Resource
private CommonNoticeSendService commonNoticeSendService; private CommonNoticeSendService commonNoticeSendService;
@Resource @Resource
private TestPlanConfigMapper testPlanConfigMapper; private TestPlanConfigMapper testPlanConfigMapper;
@Resource @Resource
private TestPlanFollowerMapper testPlanFollowerMapper; private TestPlanFollowerMapper testPlanFollowerMapper;
@Autowired
private ProjectMapper projectMapper;
@Resource
private TestPlanReportShareService testPlanReportShareService;
public void sendNoticeCase(List<String> relatedUsers, String userId, String caseId, String task, String event, String testPlanId) { public void sendNoticeCase(List<String> relatedUsers, String userId, String caseId, String task, String event, String testPlanId) {
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(caseId); FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(caseId);
User user = userMapper.selectByPrimaryKey(userId); User user = userMapper.selectByPrimaryKey(userId);
setLanguage(user.getLanguage()); setLanguage(user.getLanguage());
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanId); TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanId);
Map<String, String> defaultTemplateMap = MessageTemplateUtils.getDefaultTemplateMap(); Map<String, String> defaultTemplateMap = MessageTemplateUtils.getDefaultTemplateMap();
String template = defaultTemplateMap.get(task + "_" + event); String template = defaultTemplateMap.get(task + "_" + event);
Map<String, String> defaultSubjectMap = MessageTemplateUtils.getDefaultTemplateSubjectMap(); Map<String, String> defaultSubjectMap = MessageTemplateUtils.getDefaultTemplateSubjectMap();
String subject = defaultSubjectMap.get(task + "_" + event); String subject = defaultSubjectMap.get(task + "_" + event);
Map paramMap; Map paramMap;
BeanMap beanMap = new BeanMap(functionalCase); BeanMap beanMap = new BeanMap(functionalCase);
paramMap = new HashMap<>(beanMap); paramMap = new HashMap<>(beanMap);
paramMap.put("testPlanName", testPlan.getName()); paramMap.put("testPlanName", testPlan.getName());
paramMap.put(NoticeConstants.RelatedUser.OPERATOR, user.getName()); paramMap.put(NoticeConstants.RelatedUser.OPERATOR, user.getName());
NoticeModel noticeModel = NoticeModel.builder() NoticeModel noticeModel = NoticeModel.builder()
.operator(user.getId()) .operator(user.getId())
.context(template) .context(template)
.subject(subject) .subject(subject)
.paramMap(paramMap) .paramMap(paramMap)
.event(event) .event(event)
.status((String) paramMap.get("status")) .status((String) paramMap.get("status"))
.excludeSelf(true) .excludeSelf(true)
.relatedUsers(relatedUsers) .relatedUsers(relatedUsers)
.build(); .build();
noticeSendService.send(task, noticeModel); noticeSendService.send(task, noticeModel);
} }
private static void setLanguage(String language) { private static void setLanguage(String language) {
Locale locale = Locale.SIMPLIFIED_CHINESE; Locale locale = Locale.SIMPLIFIED_CHINESE;
if (StringUtils.containsIgnoreCase("US", language)) { if (StringUtils.containsIgnoreCase("US", language)) {
locale = Locale.US; locale = Locale.US;
} else if (StringUtils.containsIgnoreCase("TW", language)) { } else if (StringUtils.containsIgnoreCase("TW", language)) {
locale = Locale.TAIWAN; locale = Locale.TAIWAN;
} }
LocaleContextHolder.setLocale(locale); LocaleContextHolder.setLocale(locale);
} }
public void batchSendNotice(String projectId, List<String> ids, User user, String event) { public void batchSendNotice(String projectId, List<String> ids, User user, String event) {
int amount = 100;//每次读取的条数 int amount = 100;// 每次读取的条数
long roundTimes = Double.valueOf(Math.ceil((double) ids.size() / amount)).longValue();//循环的次数 long roundTimes = Double.valueOf(Math.ceil((double) ids.size() / amount)).longValue();// 循环的次数
for (int i = 0; i < (int) roundTimes; i++) { for (int i = 0; i < (int) roundTimes; i++) {
int fromIndex = (i * amount); int fromIndex = (i * amount);
int toIndex = ((i + 1) * amount); int toIndex = ((i + 1) * amount);
if (i == roundTimes - 1 || toIndex > ids.size()) {//最后一次遍历 if (i == roundTimes - 1 || toIndex > ids.size()) {// 最后一次遍历
toIndex = ids.size(); toIndex = ids.size();
} }
List<String> subList = ids.subList(fromIndex, toIndex); List<String> subList = ids.subList(fromIndex, toIndex);
List<TestPlanDTO> testPlanDTOS = handleBatchNotice(projectId, subList); List<TestPlanDTO> testPlanDTOS = handleBatchNotice(projectId, subList);
List<Map> resources = new ArrayList<>(); List<Map> resources = new ArrayList<>();
resources.addAll(JSON.parseArray(JSON.toJSONString(testPlanDTOS), Map.class)); resources.addAll(JSON.parseArray(JSON.toJSONString(testPlanDTOS), Map.class));
commonNoticeSendService.sendNotice(NoticeConstants.TaskType.TEST_PLAN_TASK, event, resources, user, projectId); commonNoticeSendService.sendNotice(NoticeConstants.TaskType.TEST_PLAN_TASK, event, resources, user, projectId);
} }
} }
private List<TestPlanDTO> handleBatchNotice(String projectId, List<String> ids) { private List<TestPlanDTO> handleBatchNotice(String projectId, List<String> ids) {
List<TestPlanDTO> dtoList = new ArrayList<>(); List<TestPlanDTO> dtoList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(ids)) { if (CollectionUtils.isNotEmpty(ids)) {
Map<String, TestPlan> testPlanMap = getTestPlanInfo(projectId, ids); Map<String, TestPlan> testPlanMap = getTestPlanInfo(projectId, ids);
ids.forEach(id -> { ids.forEach(id -> {
if (testPlanMap.containsKey(id)) { if (testPlanMap.containsKey(id)) {
TestPlan testPlan = testPlanMap.get(id); TestPlan testPlan = testPlanMap.get(id);
TestPlanDTO testPlanDTO = new TestPlanDTO(); TestPlanDTO testPlanDTO = new TestPlanDTO();
BeanUtils.copyBean(testPlanDTO, testPlan); BeanUtils.copyBean(testPlanDTO, testPlan);
dtoList.add(testPlanDTO); dtoList.add(testPlanDTO);
} }
}); });
} }
return dtoList; return dtoList;
} }
private Map<String, TestPlan> getTestPlanInfo(String projectId, List<String> ids) { private Map<String, TestPlan> getTestPlanInfo(String projectId, List<String> ids) {
TestPlanExample example = new TestPlanExample(); TestPlanExample example = new TestPlanExample();
example.createCriteria().andProjectIdEqualTo(projectId).andIdIn(ids); example.createCriteria().andProjectIdEqualTo(projectId).andIdIn(ids);
List<TestPlan> testPlans = testPlanMapper.selectByExample(example); List<TestPlan> testPlans = testPlanMapper.selectByExample(example);
return testPlans.stream().collect(Collectors.toMap(TestPlan::getId, testPlan -> testPlan)); return testPlans.stream().collect(Collectors.toMap(TestPlan::getId, testPlan -> testPlan));
} }
@SuppressWarnings("unused")
public TestPlanDTO sendAddNotice(TestPlanCreateRequest request) {
TestPlanDTO dto = new TestPlanDTO();
BeanUtils.copyBean(dto, request);
dto.setStatus(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED);
return dto;
}
public TestPlanDTO sendAddNotice(TestPlanCreateRequest request) { @SuppressWarnings("unused")
TestPlanDTO dto = new TestPlanDTO(); public TestPlanDTO sendUpdateNotice(TestPlanUpdateRequest request) {
BeanUtils.copyBean(dto, request); TestPlanDTO dto = new TestPlanDTO();
dto.setStatus(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED); BeanUtils.copyBean(dto, request);
return dto; TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getId());
} dto.setStatus(testPlan.getStatus());
dto.setType(testPlan.getType());
dto.setActualEndTime(testPlan.getActualEndTime());
dto.setActualStartTime(testPlan.getActualStartTime());
dto.setCreateTime(testPlan.getCreateTime());
dto.setCreateUser(testPlan.getCreateUser());
dto.setUpdateTime(testPlan.getUpdateTime());
dto.setUpdateUser(testPlan.getUpdateUser());
dto.setNum(testPlan.getNum());
return dto;
}
public TestPlanDTO sendUpdateNotice(TestPlanUpdateRequest request) { @SuppressWarnings("unused")
TestPlanDTO dto = new TestPlanDTO(); public TestPlanDTO sendDeleteNotice(String id) {
BeanUtils.copyBean(dto, request); TestPlan testPlan = testPlanMapper.selectByPrimaryKey(id);
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getId()); TestPlanConfig testPlanConfig = testPlanConfigMapper.selectByPrimaryKey(id);
dto.setStatus(testPlan.getStatus()); TestPlanFollowerExample example = new TestPlanFollowerExample();
dto.setType(testPlan.getType()); example.createCriteria().andTestPlanIdEqualTo(id);
dto.setActualEndTime(testPlan.getActualEndTime()); List<TestPlanFollower> testPlanFollowers = testPlanFollowerMapper.selectByExample(example);
dto.setActualStartTime(testPlan.getActualStartTime()); List<String> followUsers = testPlanFollowers.stream().map(TestPlanFollower::getUserId).toList();
dto.setCreateTime(testPlan.getCreateTime()); TestPlanDTO dto = new TestPlanDTO();
dto.setCreateUser(testPlan.getCreateUser()); if (testPlan != null) {
dto.setUpdateTime(testPlan.getUpdateTime()); BeanUtils.copyBean(dto, testPlan);
dto.setUpdateUser(testPlan.getUpdateUser()); BeanUtils.copyBean(dto, testPlanConfig);
dto.setNum(testPlan.getNum()); dto.setFollowUsers(followUsers);
return dto; return dto;
} }
return null;
}
public TestPlanDTO sendDeleteNotice(String id) { /**
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(id); * 报告汇总-计划执行结束通知
TestPlanConfig testPlanConfig = testPlanConfigMapper.selectByPrimaryKey(id); *
TestPlanFollowerExample example = new TestPlanFollowerExample(); * @param currentUser 当前用户
example.createCriteria().andTestPlanIdEqualTo(id); * @param planId 计划ID
List<TestPlanFollower> testPlanFollowers = testPlanFollowerMapper.selectByExample(example); * @param report 报告
List<String> followUsers = testPlanFollowers.stream().map(TestPlanFollower::getUserId).toList(); */
TestPlanDTO dto = new TestPlanDTO(); @Async
if (testPlan != null) { public void sendExecuteNotice(String currentUser, String planId, TestPlanReport report) {
BeanUtils.copyBean(dto, testPlan); TestPlan testPlan = testPlanMapper.selectByPrimaryKey(planId);
BeanUtils.copyBean(dto, testPlanConfig); if (testPlan != null) {
dto.setFollowUsers(followUsers); User user = userMapper.selectByPrimaryKey(currentUser);
return dto; setLanguage(user.getLanguage());
} Map<String, String> defaultTemplateMap = MessageTemplateUtils.getDefaultTemplateMap();
return null; String template = defaultTemplateMap.get(StringUtils.equals(report.getResultStatus(), ResultStatus.SUCCESS.name()) ?
} NoticeConstants.TemplateText.TEST_PLAN_TASK_EXECUTE_SUCCESSFUL : NoticeConstants.TemplateText.TEST_PLAN_TASK_EXECUTE_FAILED);
Map<String, String> defaultSubjectMap = MessageTemplateUtils.getDefaultTemplateSubjectMap();
String subject = defaultSubjectMap.get(StringUtils.equals(report.getResultStatus(), ResultStatus.SUCCESS.name()) ?
NoticeConstants.TemplateText.TEST_PLAN_TASK_EXECUTE_SUCCESSFUL : NoticeConstants.TemplateText.TEST_PLAN_TASK_EXECUTE_FAILED);
TestPlanMessageDTO messageDTO = buildMessageNotice(planId, report, currentUser);
BeanMap beanMap = new BeanMap(messageDTO);
Map paramMap = new HashMap<>(beanMap);
paramMap.put(NoticeConstants.RelatedUser.OPERATOR, user.getName());
paramMap.put("name", testPlan.getName());
paramMap.put("projectId", report.getProjectId());
paramMap.put("id", planId);
paramMap.put("Language", user.getLanguage());
paramMap.put("createUser", testPlan.getCreateUser());
NoticeModel noticeModel = NoticeModel.builder().operator(currentUser).excludeSelf(false)
.context(template).subject(subject).paramMap(paramMap).event(StringUtils.equals(report.getResultStatus(), ResultStatus.SUCCESS.name()) ?
NoticeConstants.Event.EXECUTE_SUCCESSFUL : NoticeConstants.Event.EXECUTE_FAILED).build();
noticeSendService.send(StringUtils.equals(TaskTriggerMode.API.name(), report.getTriggerMode()) ?
NoticeConstants.TaskType.JENKINS_TASK : NoticeConstants.TaskType.TEST_PLAN_TASK, noticeModel);
}
}
/** /**
* 报告汇总-计划执行结束通知 * 构建计划消息通知对象
* @param currentUser 当前用户 *
* @param planId 计划ID * @param planId 计划ID
* @param projectId 项目ID * @param report 报告
* @param executeResult 执行结果 * @param currentUser 当前用户
*/ * @return 计划消息通知对象
@Async */
public void sendExecuteNotice(String currentUser, String planId, String projectId, String executeResult, String triggerMode) { private TestPlanMessageDTO buildMessageNotice(String planId, TestPlanReport report, String currentUser) {
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(planId); TestPlan testPlan = testPlanMapper.selectByPrimaryKey(planId);
if (testPlan != null) { // 报告URL
User user = userMapper.selectByPrimaryKey(currentUser); Project project = projectMapper.selectByPrimaryKey(testPlan.getProjectId());
setLanguage(user.getLanguage()); SystemParameterService systemParameterService = CommonBeanFactory.getBean(SystemParameterService.class);
Map<String, String> defaultTemplateMap = MessageTemplateUtils.getDefaultTemplateMap(); assert systemParameterService != null;
String template = defaultTemplateMap.get(StringUtils.equals(executeResult, ResultStatus.SUCCESS.name()) ? BaseSystemConfigDTO baseSystemConfigDTO = systemParameterService.getBaseInfo();
NoticeConstants.TemplateText.TEST_PLAN_TASK_EXECUTE_SUCCESSFUL : NoticeConstants.TemplateText.TEST_PLAN_TASK_EXECUTE_FAILED); String reportUrl = baseSystemConfigDTO.getUrl() + "/#/test-plan/testPlanReportDetail?id=%s&type=%s&orgId=%s&pId=%s";
Map<String, String> defaultSubjectMap = MessageTemplateUtils.getDefaultTemplateSubjectMap(); reportUrl = String.format(reportUrl, report.getId(), report.getIntegrated() ? TestPlanConstants.TEST_PLAN_TYPE_GROUP : TestPlanConstants.TEST_PLAN_TYPE_PLAN,
String subject = defaultSubjectMap.get(StringUtils.equals(executeResult, ResultStatus.SUCCESS.name()) ? project.getOrganizationId(), project.getId());
NoticeConstants.TemplateText.TEST_PLAN_TASK_EXECUTE_SUCCESSFUL : NoticeConstants.TemplateText.TEST_PLAN_TASK_EXECUTE_FAILED); // 报告分享URL
Map<String, Object> paramMap = new HashMap<>(4); TestPlanReportShareRequest shareRequest = new TestPlanReportShareRequest();
paramMap.put(NoticeConstants.RelatedUser.OPERATOR, user.getName()); shareRequest.setReportId(report.getId());
paramMap.put("name", testPlan.getName()); shareRequest.setProjectId(project.getId());
paramMap.put("projectId", projectId); shareRequest.setShareType("TEST_PLAN_SHARE_REPORT");
paramMap.put("id", planId); TestPlanShareInfo shareInfo = testPlanReportShareService.gen(shareRequest, currentUser);
paramMap.put("Language", user.getLanguage()); String reportShareUrl = baseSystemConfigDTO.getUrl() + "/#/share/shareReportTestPlan?type=" +
NoticeModel noticeModel = NoticeModel.builder().operator(currentUser).excludeSelf(false) (report.getIntegrated() ? TestPlanConstants.TEST_PLAN_TYPE_GROUP : TestPlanConstants.TEST_PLAN_TYPE_PLAN) + "shareId=" + shareInfo.getId();
.context(template).subject(subject).paramMap(paramMap).event(StringUtils.equals(executeResult, ResultStatus.SUCCESS.name()) ? return TestPlanMessageDTO.builder()
NoticeConstants.Event.EXECUTE_SUCCESSFUL : NoticeConstants.Event.EXECUTE_FAILED).build(); .num(testPlan.getNum().toString()).name(testPlan.getName()).status(testPlan.getStatus()).type(testPlan.getType()).tags(testPlan.getTags())
noticeSendService.send(StringUtils.equals(TaskTriggerMode.API.name(), triggerMode) ? .createUser(testPlan.getCreateUser()).createTime(testPlan.getCreateTime()).updateUser(testPlan.getUpdateUser()).updateTime(testPlan.getUpdateTime())
NoticeConstants.TaskType.JENKINS_TASK : NoticeConstants.TaskType.TEST_PLAN_TASK, noticeModel); .plannedStartTime(testPlan.getPlannedStartTime()).plannedEndTime(testPlan.getPlannedEndTime())
} .actualStartTime(testPlan.getActualStartTime()).actualEndTime(testPlan.getActualEndTime())
} .description(testPlan.getDescription()).reportName(report.getName()).reportUrl(reportUrl).reportShareUrl(reportShareUrl)
.startTime(report.getStartTime()).endTime(report.getEndTime()).execStatus(report.getExecStatus()).resultStatus(report.getResultStatus())
.passRate(report.getPassRate()).passThreshold(report.getPassThreshold()).executeRate(report.getExecuteRate())
.build();
}
} }