feat(项目管理): 新增消息通知异步自定义资源池设置以及修改部分功能用例批量通知操作的问题
--bug=1039332 --user=郭雨琦 https://www.tapd.cn/55049933/bugtrace/bugs/view/1155049933001039332 --bug=1039160 --user=郭雨琦 https://www.tapd.cn/55049933/bugtrace/bugs/view/1155049933001039160
This commit is contained in:
parent
33351bfee8
commit
ded906fc5e
|
@ -366,6 +366,7 @@ message.domain.delete_user=Delete user
|
|||
message.domain.create_time=Create time
|
||||
message.domain.update_time=Update time
|
||||
message.domain.delete_time=Delete time
|
||||
message.domain.triggerMode=Trigger mode
|
||||
#接口定义和case
|
||||
message.domain.protocol=Interface Protocol
|
||||
message.domain.method=Http protocol type
|
||||
|
|
|
@ -365,6 +365,7 @@ message.domain.deleteUser=删除人
|
|||
message.domain.createTime=创建时间
|
||||
message.domain.updateTime=更新时间
|
||||
message.domain.deleteTime=删除时间
|
||||
message.domain.triggerMode=触发方式
|
||||
#接口定义和用例
|
||||
message.domain.protocol=接口协议
|
||||
message.domain.method=http协议类型
|
||||
|
|
|
@ -366,6 +366,7 @@ message.domain.deleteUser=刪除人
|
|||
message.domain.createTime=創建時間
|
||||
message.domain.updateTime=更新時間
|
||||
message.domain.deleteTime=刪除時間
|
||||
message.domain.triggerMode=觸發方式
|
||||
#接口定義和用例
|
||||
message.domain.protocol=介面協定
|
||||
message.domain.method=http協定類型
|
||||
|
|
|
@ -68,8 +68,7 @@ public class FunctionalCaseController {
|
|||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ)
|
||||
@CheckOwner(resourceId = "#projectId", resourceType = "project")
|
||||
public TemplateDTO getDefaultTemplateField(@PathVariable String projectId) {
|
||||
TemplateDTO defaultTemplateDTO = projectTemplateService.getDefaultTemplateDTO(projectId, TemplateScene.FUNCTIONAL.name());
|
||||
return defaultTemplateDTO;
|
||||
return projectTemplateService.getDefaultTemplateDTO(projectId, TemplateScene.FUNCTIONAL.name());
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,7 +98,7 @@ public class FunctionalCaseController {
|
|||
@Operation(summary = "用例管理-功能用例-更新用例")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE)
|
||||
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateFunctionalCaseLog(#request, #files)", msClass = FunctionalCaseLogService.class)
|
||||
@SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.UPDATE, target = "#targetClass.getMainFunctionalCaseDTO(#request.name, #request.caseEditType, #request.projectId, #request.customFields)", targetClass = FunctionalCaseNoticeService.class)
|
||||
@SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.UPDATE, target = "#targetClass.getMainFunctionalCaseDTO(#request, #request.customFields)", targetClass = FunctionalCaseNoticeService.class)
|
||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||
public FunctionalCase updateFunctionalCase(@Validated @RequestPart("request") FunctionalCaseEditRequest request, @RequestPart(value = "files", required = false) List<MultipartFile> files) {
|
||||
String userId = SessionUtils.getUserId();
|
||||
|
@ -159,7 +158,6 @@ public class FunctionalCaseController {
|
|||
@Operation(summary = "用例管理-功能用例-批量删除用例")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_DELETE)
|
||||
@Log(type = OperationLogType.DELETE, expression = "#msClass.batchDeleteFunctionalCaseLog(#request)", msClass = FunctionalCaseLogService.class)
|
||||
@SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.DELETE, target = "#targetClass.getBatchDeleteFunctionalCaseDTO(#request)", targetClass = FunctionalCaseNoticeService.class)
|
||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||
public void batchDeleteFunctionalCaseToGc(@Validated @RequestBody FunctionalCaseBatchRequest request) {
|
||||
String userId = SessionUtils.getUserId();
|
||||
|
@ -199,7 +197,6 @@ public class FunctionalCaseController {
|
|||
@Operation(summary = "用例管理-功能用例-批量编辑用例")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE)
|
||||
@Log(type = OperationLogType.UPDATE, expression = "#msClass.batchEditFunctionalCaseLog(#request)", msClass = FunctionalCaseLogService.class)
|
||||
@SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.UPDATE, target = "#targetClass.getBatchEditFunctionalCaseDTO(#request)", targetClass = FunctionalCaseNoticeService.class)
|
||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||
public void batchEditFunctionalCase(@Validated @RequestBody FunctionalCaseBatchEditRequest request) {
|
||||
String userId = SessionUtils.getUserId();
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
package io.metersphere.functional.service;
|
||||
|
||||
import io.metersphere.functional.domain.FunctionalCase;
|
||||
import io.metersphere.functional.domain.FunctionalCaseCustomField;
|
||||
import io.metersphere.functional.domain.FunctionalCaseCustomFieldExample;
|
||||
import io.metersphere.functional.domain.*;
|
||||
import io.metersphere.functional.dto.CaseCustomFieldDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseDTO;
|
||||
import io.metersphere.functional.mapper.CaseReviewFunctionalCaseMapper;
|
||||
import io.metersphere.functional.mapper.CaseReviewMapper;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
||||
import io.metersphere.functional.request.FunctionalCaseBatchEditRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseBatchRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseEditRequest;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.CustomField;
|
||||
import io.metersphere.system.domain.CustomFieldExample;
|
||||
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||
|
@ -41,25 +39,26 @@ public class FunctionalCaseNoticeService {
|
|||
@Resource
|
||||
private CustomFieldMapper customFieldMapper;
|
||||
|
||||
@Resource
|
||||
private FunctionalCaseService functionalCaseService;
|
||||
|
||||
@Resource
|
||||
private FunctionalCaseCustomFieldService functionalCaseCustomFieldService;
|
||||
@Resource
|
||||
private ExtOrganizationCustomFieldMapper extOrganizationCustomFieldMapper;
|
||||
@Resource
|
||||
private CaseReviewFunctionalCaseMapper caseReviewFunctionalCaseMapper;
|
||||
@Resource
|
||||
private CaseReviewMapper caseReviewMapper;
|
||||
|
||||
|
||||
public FunctionalCaseDTO getFunctionalCaseDTO(FunctionalCaseCommentRequest functionalCaseCommentRequest) {
|
||||
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(functionalCaseCommentRequest.getCaseId());
|
||||
FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
|
||||
functionalCaseDTO.setTriggerMode(Translator.get("log.test_plan.functional_case"));
|
||||
functionalCaseDTO.setTriggerMode(NoticeConstants.TriggerMode.MANUAL_EXECUTION);
|
||||
BeanUtils.copyBean(functionalCaseDTO, functionalCase);
|
||||
setNotifier(functionalCaseCommentRequest, functionalCaseDTO);
|
||||
List<OptionDTO> customFields = getCustomFields(functionalCaseCommentRequest.getCaseId());
|
||||
functionalCaseDTO.setFields(customFields);
|
||||
//TODO:设置测试计划名称
|
||||
//TODO:设置用例评审名称
|
||||
setReviewName(functionalCaseCommentRequest.getCaseId(), functionalCaseDTO);
|
||||
return functionalCaseDTO;
|
||||
}
|
||||
|
||||
|
@ -129,12 +128,17 @@ public class FunctionalCaseNoticeService {
|
|||
return optionDTOList;
|
||||
}
|
||||
|
||||
public FunctionalCaseDTO getMainFunctionalCaseDTO(String name, String caseEditType, String projectId, List<CaseCustomFieldDTO> customFields) {
|
||||
public FunctionalCaseDTO getMainFunctionalCaseDTO(FunctionalCaseEditRequest request, List<CaseCustomFieldDTO> customFields) {
|
||||
FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
|
||||
functionalCaseDTO.setName(name);
|
||||
functionalCaseDTO.setProjectId(projectId);
|
||||
functionalCaseDTO.setCaseEditType(caseEditType);
|
||||
functionalCaseDTO.setCreateUser(null);
|
||||
if (StringUtils.isNotBlank(request.getId())) {
|
||||
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(request.getId());
|
||||
BeanUtils.copyBean(functionalCaseDTO, functionalCase);
|
||||
setReviewName(request.getId(), functionalCaseDTO);
|
||||
} else {
|
||||
BeanUtils.copyBean(functionalCaseDTO, request);
|
||||
functionalCaseDTO.setCreateUser(null);
|
||||
}
|
||||
functionalCaseDTO.setTriggerMode(NoticeConstants.TriggerMode.MANUAL_EXECUTION);
|
||||
List<OptionDTO> fields = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(customFields)) {
|
||||
for (CaseCustomFieldDTO customFieldDTO : customFields) {
|
||||
|
@ -150,10 +154,24 @@ public class FunctionalCaseNoticeService {
|
|||
}
|
||||
functionalCaseDTO.setFields(fields);
|
||||
//TODO:设置测试计划名称
|
||||
//TODO:设置用例评审名称
|
||||
return functionalCaseDTO;
|
||||
}
|
||||
|
||||
private void setReviewName(String caseId, FunctionalCaseDTO functionalCaseDTO) {
|
||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andCaseIdEqualTo(caseId);
|
||||
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
||||
List<String> reviewIds = caseReviewFunctionalCases.stream().map(CaseReviewFunctionalCase::getReviewId).distinct().toList();
|
||||
if (CollectionUtils.isNotEmpty(reviewIds)) {
|
||||
CaseReviewExample caseReviewExample = new CaseReviewExample();
|
||||
caseReviewExample.createCriteria().andIdIn(reviewIds);
|
||||
List<CaseReview> caseReviews = caseReviewMapper.selectByExample(caseReviewExample);
|
||||
List<String> reviewName = caseReviews.stream().map(CaseReview::getName).toList();
|
||||
String string = reviewName.toString();
|
||||
functionalCaseDTO.setReviewName(string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public FunctionalCaseDTO getDeleteFunctionalCaseDTO(String id) {
|
||||
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(id);
|
||||
|
@ -165,46 +183,65 @@ public class FunctionalCaseNoticeService {
|
|||
|
||||
});
|
||||
//TODO:设置测试计划名称
|
||||
//TODO:设置用例评审名称
|
||||
setReviewName(id, functionalCaseDTO);
|
||||
return functionalCaseDTO;
|
||||
}
|
||||
|
||||
|
||||
public List<FunctionalCaseDTO> getBatchDeleteFunctionalCaseDTO(FunctionalCaseBatchRequest request) {
|
||||
List<String> ids = functionalCaseService.doSelectIds(request, request.getProjectId());
|
||||
return handleBatchNotice(request.getProjectId(), ids);
|
||||
public Map<String, FunctionalCase> copyBaseCaseInfo(String projectId, List<String> ids) {
|
||||
FunctionalCaseExample example = new FunctionalCaseExample();
|
||||
example.createCriteria().andProjectIdEqualTo(projectId).andDeletedEqualTo(false).andIdIn(ids);
|
||||
List<FunctionalCase> functionalCaseLists = functionalCaseMapper.selectByExample(example);
|
||||
return functionalCaseLists.stream().collect(Collectors.toMap(FunctionalCase::getId, functionalCase -> functionalCase));
|
||||
}
|
||||
|
||||
private List<FunctionalCaseDTO> handleBatchNotice(String projectId, List<String> ids) {
|
||||
public List<FunctionalCaseDTO> handleBatchNotice(String projectId, List<String> ids) {
|
||||
List<FunctionalCaseDTO> dtoList = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(ids)) {
|
||||
Map<String, FunctionalCase> functionalCaseMap = functionalCaseService.copyBaseInfo(projectId, ids);
|
||||
Map<String, FunctionalCase> functionalCaseMap = copyBaseCaseInfo(projectId, ids);
|
||||
Map<String, List<FunctionalCaseCustomField>> customFieldMap = functionalCaseCustomFieldService.getCustomFieldMapByCaseIds(ids);
|
||||
AtomicReference<List<OptionDTO>> optionDTOS = new AtomicReference<>(new ArrayList<>());
|
||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andCaseIdIn(ids);
|
||||
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
||||
List<String> reviewIds = caseReviewFunctionalCases.stream().map(CaseReviewFunctionalCase::getReviewId).distinct().toList();
|
||||
Map<String, String> reviewMap = new HashMap<>();
|
||||
if (CollectionUtils.isNotEmpty(reviewIds)) {
|
||||
CaseReviewExample caseReviewExample = new CaseReviewExample();
|
||||
caseReviewExample.createCriteria().andIdIn(reviewIds);
|
||||
List<CaseReview> caseReviews = caseReviewMapper.selectByExample(caseReviewExample);
|
||||
reviewMap = caseReviews.stream().collect(Collectors.toMap(CaseReview::getId, CaseReview::getName));
|
||||
}
|
||||
Map<String, List<CaseReviewFunctionalCase>> caseReviewMap = caseReviewFunctionalCases.stream().collect(Collectors.groupingBy(CaseReviewFunctionalCase::getCaseId));
|
||||
Map<String, String> finalReviewMap = reviewMap;
|
||||
ids.forEach(id -> {
|
||||
FunctionalCase functionalCase = functionalCaseMap.get(id);
|
||||
List<FunctionalCaseCustomField> customFields = customFieldMap.get(id);
|
||||
if (CollectionUtils.isNotEmpty(customFields)) {
|
||||
List<String> fields = customFields.stream().map(functionalCaseCustomField -> functionalCaseCustomField.getFieldId()).toList();
|
||||
optionDTOS.set(extOrganizationCustomFieldMapper.getCustomFieldOptions(fields));
|
||||
if (functionalCase != null) {
|
||||
List<FunctionalCaseCustomField> customFields = customFieldMap.get(id);
|
||||
if (CollectionUtils.isNotEmpty(customFields)) {
|
||||
List<String> fields = customFields.stream().map(FunctionalCaseCustomField::getFieldId).toList();
|
||||
optionDTOS.set(extOrganizationCustomFieldMapper.getCustomFieldOptions(fields));
|
||||
}
|
||||
FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
|
||||
functionalCaseDTO.setName(functionalCase.getName());
|
||||
functionalCaseDTO.setProjectId(functionalCase.getProjectId());
|
||||
functionalCaseDTO.setCaseEditType(functionalCase.getCaseEditType());
|
||||
functionalCaseDTO.setCreateUser(null);
|
||||
functionalCaseDTO.setFields(optionDTOS.get());
|
||||
List<CaseReviewFunctionalCase> caseReviewFunctionalCases1 = caseReviewMap.get(id);
|
||||
List<String>reviewName = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(caseReviewFunctionalCases1)) {
|
||||
for (CaseReviewFunctionalCase caseReviewFunctionalCase : caseReviewFunctionalCases1) {
|
||||
String s = finalReviewMap.get(caseReviewFunctionalCase.getReviewId());
|
||||
reviewName.add(s);
|
||||
}
|
||||
}
|
||||
List<String> list = reviewName.stream().distinct().toList();
|
||||
functionalCaseDTO.setReviewName(list.toString());
|
||||
dtoList.add(functionalCaseDTO);
|
||||
}
|
||||
FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
|
||||
functionalCaseDTO.setName(functionalCase.getName());
|
||||
functionalCaseDTO.setProjectId(functionalCase.getProjectId());
|
||||
functionalCaseDTO.setCaseEditType(functionalCase.getCaseEditType());
|
||||
functionalCaseDTO.setCreateUser(null);
|
||||
functionalCaseDTO.setFields(optionDTOS.get());
|
||||
dtoList.add(functionalCaseDTO);
|
||||
});
|
||||
//TODO:设置测试计划名称
|
||||
//TODO:设置用例评审名称
|
||||
}
|
||||
return dtoList;
|
||||
}
|
||||
|
||||
|
||||
public List<FunctionalCaseDTO> getBatchEditFunctionalCaseDTO(FunctionalCaseBatchEditRequest request) {
|
||||
List<String> ids = functionalCaseService.doSelectIds(request, request.getProjectId());
|
||||
return handleBatchNotice(request.getProjectId(), ids);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,6 +168,9 @@ public class FunctionalCaseService {
|
|||
private FunctionalCaseCommentMapper functionalCaseCommentMapper;
|
||||
@Resource
|
||||
private ProjectService projectService;
|
||||
@Resource
|
||||
private FunctionalCaseNoticeService functionalCaseNoticeService;
|
||||
|
||||
|
||||
private static final int MAX_TAG_SIZE = 10;
|
||||
|
||||
|
@ -608,10 +611,10 @@ public class FunctionalCaseService {
|
|||
* @param userId userId
|
||||
*/
|
||||
public void deleteFunctionalCase(FunctionalCaseDeleteRequest request, String userId) {
|
||||
handDeleteFunctionalCase(Collections.singletonList(request.getId()), request.getDeleteAll(), userId);
|
||||
handDeleteFunctionalCase(Collections.singletonList(request.getId()), request.getDeleteAll(), userId, request.getProjectId());
|
||||
}
|
||||
|
||||
private void handDeleteFunctionalCase(List<String> ids, Boolean deleteAll, String userId) {
|
||||
private void handDeleteFunctionalCase(List<String> ids, Boolean deleteAll, String userId, String projectId) {
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
if (deleteAll) {
|
||||
//全部删除 进入回收站
|
||||
|
@ -626,6 +629,8 @@ public class FunctionalCaseService {
|
|||
param.put(CaseEvent.Param.CASE_IDS, CollectionUtils.isNotEmpty(ids) ? ids : new ArrayList<>());
|
||||
doDelete(ids, userId);
|
||||
}
|
||||
User user = userMapper.selectByPrimaryKey(userId);
|
||||
batchSendNotice(projectId, ids, user, NoticeConstants.Event.DELETE);
|
||||
param.put(CaseEvent.Param.USER_ID, userId);
|
||||
param.put(CaseEvent.Param.EVENT_NAME, CaseEvent.Event.DELETE_FUNCTIONAL_CASE);
|
||||
provider.updateCaseReview(param);
|
||||
|
@ -718,7 +723,7 @@ public class FunctionalCaseService {
|
|||
public void batchDeleteFunctionalCaseToGc(FunctionalCaseBatchRequest request, String userId) {
|
||||
List<String> ids = doSelectIds(request, request.getProjectId());
|
||||
if (CollectionUtils.isNotEmpty(ids)) {
|
||||
handDeleteFunctionalCase(ids, request.getDeleteAll(), userId);
|
||||
handDeleteFunctionalCase(ids, request.getDeleteAll(), userId, request.getProjectId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -744,10 +749,31 @@ public class FunctionalCaseService {
|
|||
* @param userId userId
|
||||
*/
|
||||
public void batchMoveFunctionalCase(FunctionalCaseBatchMoveRequest request, String userId) {
|
||||
User user = userMapper.selectByPrimaryKey(userId);
|
||||
List<String> ids = doSelectIds(request, request.getProjectId());
|
||||
if (CollectionUtils.isNotEmpty(ids)) {
|
||||
List<String> refId = extFunctionalCaseMapper.getRefIds(ids, false);
|
||||
extFunctionalCaseMapper.batchMoveModule(request, refId, userId);
|
||||
batchSendNotice(request.getProjectId(), ids, user, NoticeConstants.Event.UPDATE);
|
||||
}
|
||||
}
|
||||
|
||||
private void batchSendNotice(String projectId, List<String> ids, User user, String event) {
|
||||
int amount = 100;//每次读取的条数
|
||||
long roundTimes = Double.valueOf(Math.ceil((double) ids.size() / amount)).longValue();//循环的次数
|
||||
for (int i = 0; i < (int)roundTimes; i++) {
|
||||
int fromIndex = (i*amount);
|
||||
int toIndex = ((i+1)*amount);
|
||||
if (i == roundTimes-1){//最后一次遍历
|
||||
toIndex = ids.size();
|
||||
} else if (toIndex > ids.size()){
|
||||
toIndex = ids.size();
|
||||
}
|
||||
List<String> subList = ids.subList(fromIndex, toIndex);
|
||||
List<FunctionalCaseDTO> functionalCaseDTOS = functionalCaseNoticeService.handleBatchNotice(projectId, subList);
|
||||
List<Map> resources = new ArrayList<>();
|
||||
resources.addAll(JSON.parseArray(JSON.toJSONString(functionalCaseDTOS), Map.class));
|
||||
commonNoticeSendService.sendNotice(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event, resources, user, projectId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -833,6 +859,10 @@ public class FunctionalCaseService {
|
|||
historyLogDTO.setFileAssociationList(fileAssociationList);
|
||||
saveAddDataLog(functionalCase, new FunctionalCaseHistoryLogDTO(), historyLogDTO, userId, organizationId, OperationLogType.ADD.name(), OperationLogModule.FUNCTIONAL_CASE);
|
||||
}
|
||||
User user = userMapper.selectByPrimaryKey(userId);
|
||||
batchSendNotice(request.getProjectId(), ids, user, NoticeConstants.Event.CREATE);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -875,6 +905,7 @@ public class FunctionalCaseService {
|
|||
public void batchEditFunctionalCase(FunctionalCaseBatchEditRequest request, String userId) {
|
||||
List<String> ids = doSelectIds(request, request.getProjectId());
|
||||
if (CollectionUtils.isNotEmpty(ids)) {
|
||||
User user = userMapper.selectByPrimaryKey(userId);
|
||||
//标签处理
|
||||
handleTags(request, userId, ids);
|
||||
//自定义字段处理
|
||||
|
@ -885,6 +916,7 @@ public class FunctionalCaseService {
|
|||
functionalCase.setUpdateTime(System.currentTimeMillis());
|
||||
functionalCase.setUpdateUser(userId);
|
||||
extFunctionalCaseMapper.batchUpdate(functionalCase, ids);
|
||||
batchSendNotice(request.getProjectId(), ids, user, NoticeConstants.Event.UPDATE);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1057,7 +1089,7 @@ public class FunctionalCaseService {
|
|||
/**
|
||||
* 组装通知数据
|
||||
*
|
||||
* @param noticeList
|
||||
* @param noticeList xiao
|
||||
* @param functionalCaseExcelData
|
||||
* @param request
|
||||
* @param userId
|
||||
|
|
|
@ -1,10 +1,40 @@
|
|||
package io.metersphere.system.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
@EnableAsync(proxyTargetClass = true)
|
||||
@Configuration
|
||||
public class AsyncConfig {
|
||||
/**
|
||||
* 核心线程数
|
||||
*/
|
||||
private static final int CORE_POOL_SIZE = 10;
|
||||
/**
|
||||
* 最大线程数
|
||||
*/
|
||||
private static final int MAX_POOL_SIZE = 10;
|
||||
|
||||
|
||||
/**
|
||||
* ThreadPoolTaskExecutor不会自动创建ThreadPoolExecutor,需要手动调initialize才会创建。
|
||||
* 如果@Bean就不需手动,会自动InitializingBean的afterPropertiesSet来调initialize
|
||||
*
|
||||
*/
|
||||
@Bean(name = "threadPoolTaskExecutor")
|
||||
public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
// 设置线程池最大线程数
|
||||
executor.setMaxPoolSize(MAX_POOL_SIZE);
|
||||
// 线程池活跃的线程数
|
||||
executor.setCorePoolSize(CORE_POOL_SIZE);
|
||||
executor.setThreadNamePrefix("notice-task-");
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
return executor;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.metersphere.system.dto.request.OrganizationRequest;
|
|||
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||
import io.metersphere.system.log.annotation.Log;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.security.CheckOwner;
|
||||
import io.metersphere.system.service.OrganizationService;
|
||||
import io.metersphere.system.utils.PageUtils;
|
||||
import io.metersphere.system.utils.Pager;
|
||||
|
@ -43,6 +44,7 @@ public class OrganizationController {
|
|||
@PostMapping("/member/list")
|
||||
@Operation(summary = "系统设置-组织-成员-获取组织成员列表")
|
||||
@RequiresPermissions(PermissionConstants.ORGANIZATION_MEMBER_READ)
|
||||
@CheckOwner(resourceId = "#organizationId", resourceType = "organization")
|
||||
public Pager<List<OrgUserExtend>> getMemberList(@Validated @RequestBody OrganizationRequest organizationRequest) {
|
||||
Page<Object> page = PageHelper.startPage(organizationRequest.getCurrent(), organizationRequest.getPageSize());
|
||||
return PageUtils.setPageInfo(page, organizationService.getMemberListByOrg(organizationRequest));
|
||||
|
|
|
@ -17,4 +17,7 @@ public class BugSyncNoticeDTO {
|
|||
|
||||
@Schema(description ="message.domain.bug_sync_total_count")
|
||||
private Integer total;
|
||||
|
||||
@Schema(description ="message.domain.triggerMode")
|
||||
private String triggerMode;
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@ public class FunctionalCaseMessageDTO {
|
|||
@Schema(description ="message.domain.name")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "message.domain.testPlanName")
|
||||
/* @Schema(description = "message.domain.testPlanName")
|
||||
private String testPlanName;
|
||||
|
||||
*/
|
||||
@Schema(description = "message.domain.reviewName")
|
||||
private String reviewName;
|
||||
|
||||
|
@ -23,8 +23,8 @@ public class FunctionalCaseMessageDTO {
|
|||
@Schema(description = "message.domain.caseModel")
|
||||
private String caseEditType;
|
||||
|
||||
@Schema(description = "message.domain.lastExecuteResult")
|
||||
private String lastExecuteResult;
|
||||
/* @Schema(description = "message.domain.lastExecuteResult")
|
||||
private String lastExecuteResult;*/
|
||||
|
||||
@Schema(description = "message.domain.createUser")
|
||||
private String createUser;
|
||||
|
@ -44,4 +44,7 @@ public class FunctionalCaseMessageDTO {
|
|||
@Schema(description = "message.domain.deleteTime")
|
||||
private Long deleteTime;
|
||||
|
||||
@Schema(description = "message.domain.deleteTime")
|
||||
private String triggerMode;
|
||||
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@
|
|||
<select id="getProjectMemberByUserId" resultType="io.metersphere.system.domain.User">
|
||||
select distinct u.* from user_role_relation urr join `user` u on urr.user_id = u.id
|
||||
where
|
||||
u.deleted = 0 and u.enable = 1
|
||||
u.deleted = 0
|
||||
<if test="projectId != null and projectId != ''">
|
||||
and urr.source_id = #{projectId}
|
||||
</if>
|
||||
|
|
|
@ -231,7 +231,7 @@ public class MessageTemplateUtils {
|
|||
if (CollectionUtils.isNotEmpty(customFields)) {
|
||||
Map <String,String>customFielddNameMap = new HashMap<>();
|
||||
for (CustomField customField : customFields) {
|
||||
customFielddNameMap.put(customField.getName(), StringUtils.isBlank(customField.getName()) ? "-" : customField.getName());
|
||||
customFielddNameMap.put(customField.getName(), StringUtils.isBlank(customField.getName()) ? "-" : "<"+customField.getName()+">");
|
||||
}
|
||||
map.putAll(customFielddNameMap);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public class NoticeSendService {
|
|||
/**
|
||||
* 在线操作发送通知
|
||||
*/
|
||||
@Async
|
||||
@Async("threadPoolTaskExecutor")
|
||||
public void send(String taskType, NoticeModel noticeModel) {
|
||||
setLanguage(noticeModel);
|
||||
try {
|
||||
|
@ -96,7 +96,7 @@ public class NoticeSendService {
|
|||
/**
|
||||
* jenkins 和定时任务触发的发送
|
||||
*/
|
||||
@Async
|
||||
@Async("threadPoolTaskExecutor")
|
||||
public void sendJenkins(String triggerMode, NoticeModel noticeModel) {
|
||||
// api和定时任务调用不排除自己
|
||||
noticeModel.setExcludeSelf(false);
|
||||
|
@ -127,7 +127,7 @@ public class NoticeSendService {
|
|||
/**
|
||||
* 后台触发的发送,没有session
|
||||
*/
|
||||
@Async
|
||||
@Async("threadPoolTaskExecutor")
|
||||
public void send(Project project, String taskType, NoticeModel noticeModel) {
|
||||
setLanguage(noticeModel);
|
||||
try {
|
||||
|
|
|
@ -47,7 +47,7 @@ public class NotificationService {
|
|||
record.setStatus(NotificationConstants.Status.READ.name());
|
||||
NotificationExample example = new NotificationExample();
|
||||
if (StringUtils.isNotBlank(resourceType)) {
|
||||
example.createCriteria().andResourceTypeEqualTo(resourceType);
|
||||
example.createCriteria().andResourceTypeEqualTo("%" + resourceType + "%");
|
||||
}
|
||||
example.createCriteria().andReceiverEqualTo(userId);
|
||||
return notificationMapper.updateByExampleSelective(record, example);
|
||||
|
|
|
@ -246,7 +246,7 @@ public class TestResourcePoolService {
|
|||
pool.getCreateUser(),
|
||||
OperationLogType.UPDATE.name(),
|
||||
OperationLogModule.SETTING_SYSTEM_RESOURCE_POOL,
|
||||
"更新资源池配置");
|
||||
pool.getName());
|
||||
|
||||
dto.setPath("/update");
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
|
|
|
@ -2,23 +2,33 @@ package io.metersphere.system.controller;
|
|||
|
||||
import io.metersphere.project.domain.Notification;
|
||||
import io.metersphere.project.domain.NotificationExample;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.mapper.NotificationMapper;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.controller.handler.ResultHolder;
|
||||
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||
import io.metersphere.system.dto.sdk.request.NotificationRequest;
|
||||
import io.metersphere.system.log.dto.NotificationDTO;
|
||||
import io.metersphere.system.notice.NoticeModel;
|
||||
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||
import io.metersphere.system.notice.constants.NotificationConstants;
|
||||
import io.metersphere.system.service.NoticeSendService;
|
||||
import io.metersphere.system.utils.Pager;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.beanutils.BeanMap;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@AutoConfigureMockMvc
|
||||
|
@ -32,6 +42,10 @@ public class NotificationControllerTests extends BaseTest {
|
|||
|
||||
@Resource
|
||||
protected NotificationMapper notificationMapper;
|
||||
@Resource
|
||||
protected NoticeSendService noticeSendService;
|
||||
@Resource
|
||||
protected ProjectMapper projectMapper;
|
||||
|
||||
void saveNotice() {
|
||||
Notification notification = new Notification();
|
||||
|
@ -113,4 +127,34 @@ public class NotificationControllerTests extends BaseTest {
|
|||
}
|
||||
|
||||
|
||||
|
||||
@Autowired
|
||||
ThreadPoolTaskExecutor threadPoolTaskExecutor; //会去匹配 @Bean("poolExecutor") 这个线程池
|
||||
@Test
|
||||
void contextLoads() throws InterruptedException {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Project project = projectMapper.selectByPrimaryKey("10000100001");
|
||||
BeanMap beanMap = new BeanMap(project);
|
||||
Map paramMap = new HashMap<>(beanMap);
|
||||
paramMap.put(NoticeConstants.RelatedUser.OPERATOR, "admin");
|
||||
paramMap.put("projectId", "10000100001");
|
||||
NoticeModel noticeModel = NoticeModel.builder()
|
||||
.operator("admin")
|
||||
.context("nihao")
|
||||
.paramMap(paramMap)
|
||||
.subject("hahah")
|
||||
.event("UPDATE")
|
||||
.excludeSelf(true)
|
||||
.build();
|
||||
//一定要休眠 不然主线程关闭了,子线程还没有启动
|
||||
noticeSendService.send("FUNCTIONAL_CASE_TASK",noticeModel);
|
||||
}
|
||||
|
||||
Thread.sleep(10000);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue