feat(测试计划): 批量移动

This commit is contained in:
WangXu10 2024-05-09 16:22:01 +08:00 committed by Craftsman
parent 44819f72a4
commit 89f184b5a6
13 changed files with 404 additions and 155 deletions

View File

@ -95,4 +95,10 @@ log.test_plan.functional_case=Functional case
log.test_plan.api_case=Api case
log.test_plan.api_scenario=Api scenario
test_plan.type.not_blank=Test plan type cannot be empty
test_plan.group.not_plan=There are no archived plans in the current testing plan group
test_plan.group.not_plan=There are no archived plans in the current testing plan group
log.copy.test_plan_group=Copy test plan group
log.copy.test_plan=Copy test plan
log.update.test_plan_group=Update test plan group
log.update.test_plan=Update test plan
log.move.test_plan_group=Move test plan group
log.move.test_plan=Move test plan

View File

@ -95,4 +95,10 @@ log.test_plan.functional_case=功能用例
log.test_plan.api_case=接口用例
log.test_plan.api_scenario=接口场景
test_plan.type.not_blank=测试计划类型不能为空
test_plan.group.not_plan=当前测试计划组没有可归档计划
test_plan.group.not_plan=当前测试计划组没有可归档计划
log.copy.test_plan_group=复制测试计划组
log.copy.test_plan=复制测试计划
log.update.test_plan_group=更新测试计划组
log.update.test_plan=更新测试计划
log.move.test_plan_group=移动测试计划组
log.move.test_plan=移动测试计划

View File

@ -95,4 +95,10 @@ log.test_plan.functional_case=功能用例
log.test_plan.api_case=接口用例
log.test_plan.api_scenario=接口場景
test_plan.type.not_blank=測試計劃類型不能為空
test_plan.group.not_plan=當前測試計劃組沒有可歸檔計劃
test_plan.group.not_plan=當前測試計劃組沒有可歸檔計劃
log.copy.test_plan_group=複製測試計劃組
log.copy.test_plan=複製測試計劃
log.update.test_plan_group=更新測試計劃組
log.update.test_plan=更新測試計劃
log.move.test_plan_group=移動測試計劃組
log.move.test_plan=移動測試計劃

View File

@ -142,4 +142,13 @@ public class TestPlanController {
public void batchCopy(@Validated @RequestBody TestPlanBatchRequest request) {
testPlanService.batchCopy(request, SessionUtils.getUserId(), "/test-plan/batch/copy", HttpMethodConstants.POST.name());
}
@PostMapping("/batch/move")
@Operation(summary = "测试计划-批量移动测试计划")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE)
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
public void batchMove(@Validated @RequestBody TestPlanBatchRequest request) {
testPlanService.batchMove(request, SessionUtils.getUserId(), "/test-plan/batch/move", HttpMethodConstants.POST.name());
}
}

View File

@ -8,7 +8,7 @@ import lombok.Data;
* @author wx
*/
@Data
public class TestPlanBatchRequest extends TestPlanBatchProcessRequest{
public class TestPlanBatchRequest extends TestPlanBatchProcessRequest {
@Schema(description = "模块ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan.module_id.not_blank}")

View File

@ -30,4 +30,6 @@ public interface ExtTestPlanMapper {
String selectProjectIdByTestPlanId(String testPlanId);
void batchUpdateStatus(@Param("status") String status, @Param("userId") String userId, @Param("updateTime") Long updateTime, @Param("ids") List<String> ids);
void batchMove(@Param("ids") List<String> ids, @Param("moduleId") String moduleId, @Param("userId") String userId, @Param("updateTime") long updateTime);
}

View File

@ -369,4 +369,13 @@
</foreach>
</update>
<update id="batchMove">
UPDATE test_plan
SET module_id = #{moduleId}, update_user = #{userId}, update_time = #{updateTime}
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
</mapper>

View File

@ -0,0 +1,93 @@
package io.metersphere.plan.service;
import io.metersphere.plan.domain.TestPlan;
import io.metersphere.plan.domain.TestPlanExample;
import io.metersphere.plan.dto.request.TestPlanBatchProcessRequest;
import io.metersphere.plan.mapper.ExtTestPlanMapper;
import io.metersphere.plan.mapper.TestPlanMapper;
import io.metersphere.sdk.constants.ModuleConstants;
import io.metersphere.sdk.constants.TestPlanConstants;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.TestPlanModuleExample;
import io.metersphere.system.mapper.TestPlanModuleMapper;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional(rollbackFor = Exception.class)
public class TestPlanBaseUtilsService {
@Resource
private TestPlanMapper testPlanMapper;
@Resource
private TestPlanModuleMapper testPlanModuleMapper;
@Resource
private ExtTestPlanMapper extTestPlanMapper;
/**
* 校验模块下重名
*
* @param testPlan
*/
public void validateTestPlan(TestPlan testPlan) {
if (StringUtils.equals(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_PLAN) && !StringUtils.equals(testPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
TestPlan group = testPlanMapper.selectByPrimaryKey(testPlan.getGroupId());
testPlan.setModuleId(group.getModuleId());
}
TestPlanExample example = new TestPlanExample();
if (StringUtils.isBlank(testPlan.getId())) {
//新建 校验
example.createCriteria().andNameEqualTo(testPlan.getName()).andProjectIdEqualTo(testPlan.getProjectId()).andModuleIdEqualTo(testPlan.getModuleId());
if (testPlanMapper.countByExample(example) > 0) {
throw new MSException(Translator.get("test_plan.name.exist") + ":" + testPlan.getName());
}
} else {
//更新 校验
example.createCriteria().andNameEqualTo(testPlan.getName()).andProjectIdEqualTo(testPlan.getProjectId()).andIdNotEqualTo(testPlan.getId()).andModuleIdEqualTo(testPlan.getModuleId());
if (testPlanMapper.countByExample(example) > 0) {
throw new MSException(Translator.get("test_plan.name.exist") + ":" + testPlan.getName());
}
}
}
/**
* 校验模块
*
* @param moduleId
*/
public void checkModule(String moduleId) {
if (!StringUtils.equals(moduleId, ModuleConstants.DEFAULT_NODE_ID)) {
TestPlanModuleExample example = new TestPlanModuleExample();
example.createCriteria().andIdEqualTo(moduleId);
if (testPlanModuleMapper.countByExample(example) == 0) {
throw new MSException(Translator.get("module.not.exist"));
}
}
}
/**
* 获取选择的计划id集合
*
* @param request
* @return
*/
public List<String> getSelectIds(TestPlanBatchProcessRequest request) {
if (request.isSelectAll()) {
List<String> ids = extTestPlanMapper.selectIdByConditions(request);
if (org.apache.commons.collections.CollectionUtils.isNotEmpty(request.getExcludeIds())) {
ids.removeAll(request.getExcludeIds());
}
return ids;
} else {
return request.getSelectIds();
}
}
}

View File

@ -0,0 +1,125 @@
package io.metersphere.plan.service;
import io.metersphere.plan.domain.*;
import io.metersphere.plan.dto.request.TestPlanBatchProcessRequest;
import io.metersphere.plan.dto.request.TestPlanBatchRequest;
import io.metersphere.plan.mapper.TestPlanAllocationMapper;
import io.metersphere.plan.mapper.TestPlanConfigMapper;
import io.metersphere.plan.mapper.TestPlanMapper;
import io.metersphere.sdk.constants.ApplicationNumScope;
import io.metersphere.sdk.constants.TestPlanConstants;
import io.metersphere.system.uid.IDGenerator;
import io.metersphere.system.uid.NumGenerator;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
@Transactional(rollbackFor = Exception.class)
public class TestPlanBatchCopyService {
@Resource
private TestPlanConfigMapper testPlanConfigMapper;
@Resource
private TestPlanAllocationMapper testPlanAllocationMapper;
@Resource
private TestPlanMapper testPlanMapper;
public void batchCopy(Map<String, List<TestPlan>> plans, TestPlanBatchRequest request, String userId) {
batchCopyGroup(plans, request, userId);
batchCopyPlan(plans, request, userId);
}
/**
* 批量复制组
*
* @param plans
*/
private void batchCopyGroup(Map<String, List<TestPlan>> plans, TestPlanBatchProcessRequest request, String userId) {
//TODO 批量复制计划组
}
/**
* 批量复制计划
*
* @param plans
*/
private void batchCopyPlan(Map<String, List<TestPlan>> plans, TestPlanBatchRequest request, String userId) {
if (plans.containsKey(TestPlanConstants.TEST_PLAN_TYPE_PLAN)) {
List<TestPlan> testPlans = plans.get(TestPlanConstants.TEST_PLAN_TYPE_PLAN);
List<String> ids = testPlans.stream().map(TestPlan::getId).collect(Collectors.toList());
//额外信息
TestPlanConfigExample configExample = new TestPlanConfigExample();
configExample.createCriteria().andTestPlanIdIn(ids);
List<TestPlanConfig> testPlanConfigs = testPlanConfigMapper.selectByExample(configExample);
//测试规划配置信息
TestPlanAllocationExample allocationExample = new TestPlanAllocationExample();
allocationExample.createCriteria().andTestPlanIdIn(ids);
List<TestPlanAllocation> testPlanAllocations = testPlanAllocationMapper.selectByExampleWithBLOBs(allocationExample);
batchInsertPlan(testPlans, testPlanConfigs, testPlanAllocations, request, userId);
}
}
private void batchInsertPlan(List<TestPlan> testPlans, List<TestPlanConfig> testPlanConfigs, List<TestPlanAllocation> testPlanAllocations, TestPlanBatchRequest request, String userId) {
Map<String, List<TestPlanConfig>> configs = testPlanConfigs.stream().collect(Collectors.groupingBy(TestPlanConfig::getTestPlanId));
Map<String, List<TestPlanAllocation>> allocationsList = testPlanAllocations.stream().collect(Collectors.groupingBy(TestPlanAllocation::getTestPlanId));
List<TestPlanConfig> newConfigs = new ArrayList<>();
List<TestPlanAllocation> newAllocations = new ArrayList<>();
testPlans.forEach(testPlan -> {
List<TestPlanConfig> config = configs.get(testPlan.getId());
List<TestPlanAllocation> allocations = allocationsList.get(testPlan.getId());
Long num = testPlan.getNum();
testPlan.setId(IDGenerator.nextStr());
testPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_PREPARED);
testPlan.setNum(NumGenerator.nextNum(testPlan.getProjectId(), ApplicationNumScope.TEST_PLAN));
testPlan.setName(getCopyName(testPlan.getName(), num, testPlan.getNum()));
testPlan.setModuleId(request.getModuleId());
testPlan.setCreateTime(System.currentTimeMillis());
testPlan.setUpdateTime(System.currentTimeMillis());
testPlan.setCreateUser(userId);
testPlan.setUpdateUser(userId);
if (CollectionUtils.isNotEmpty(config)) {
TestPlanConfig testPlanConfig = config.get(0);
testPlanConfig.setTestPlanId(testPlan.getId());
newConfigs.add(testPlanConfig);
}
if (CollectionUtils.isNotEmpty(allocations)) {
TestPlanAllocation testPlanAllocation = allocations.get(0);
testPlanAllocation.setTestPlanId(testPlan.getId());
testPlanAllocation.setId(IDGenerator.nextStr());
newAllocations.add(testPlanAllocation);
}
});
testPlanMapper.batchInsert(testPlans);
if (CollectionUtils.isNotEmpty(newConfigs)) {
testPlanConfigMapper.batchInsert(newConfigs);
}
if (CollectionUtils.isNotEmpty(newAllocations)) {
testPlanAllocationMapper.batchInsert(newAllocations);
}
}
private String getCopyName(String name, long oldNum, long newNum) {
if (!StringUtils.startsWith(name, "copy_")) {
name = "copy_" + name;
}
if (name.length() > 250) {
name = name.substring(0, 200) + "...";
}
if (StringUtils.endsWith(name, "_" + oldNum)) {
name = StringUtils.substringBeforeLast(name, "_" + oldNum);
}
name = name + "_" + newNum;
return name;
}
}

View File

@ -0,0 +1,56 @@
package io.metersphere.plan.service;
import io.metersphere.plan.domain.TestPlan;
import io.metersphere.plan.dto.request.TestPlanBatchProcessRequest;
import io.metersphere.plan.dto.request.TestPlanBatchRequest;
import io.metersphere.plan.mapper.ExtTestPlanMapper;
import io.metersphere.sdk.constants.TestPlanConstants;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
@Transactional(rollbackFor = Exception.class)
public class TestPlanBatchMoveService extends TestPlanBaseUtilsService {
@Resource
private ExtTestPlanMapper extTestPlanMapper;
public void batchMove(Map<String, List<TestPlan>> plans, TestPlanBatchRequest request, String userId) {
batchMoveGroup(plans, request, userId);
batchMovePlan(plans, request, userId);
}
/**
* 批量移动组
*
* @param plans
*/
private void batchMoveGroup(Map<String, List<TestPlan>> plans, TestPlanBatchProcessRequest request, String userId) {
//TODO 批量移动计划组
}
/**
* 批量移动计划
*
* @param plans
*/
private void batchMovePlan(Map<String, List<TestPlan>> plans, TestPlanBatchRequest request, String userId) {
if (plans.containsKey(TestPlanConstants.TEST_PLAN_TYPE_PLAN)) {
List<TestPlan> testPlans = plans.get(TestPlanConstants.TEST_PLAN_TYPE_PLAN);
testPlans.forEach(testPlan -> {
testPlan.setModuleId(request.getModuleId());
validateTestPlan(testPlan);
});
List<String> ids = testPlans.stream().map(TestPlan::getId).collect(Collectors.toList());
extTestPlanMapper.batchMove(ids, request.getModuleId(), userId, System.currentTimeMillis());
}
}
}

View File

@ -45,7 +45,7 @@ public class TestPlanLogService {
.method(requestMethod)
.path(requestUrl)
.sourceId(module.getId())
.content(generateTestPlanSimpleContent(module))
.content(generateTestPlanSimpleContent(module,"test_plan.test_plan_group","test_plan.test_plan"))
.originalValue(JSON.toJSONBytes(module))
.createUser(operator)
.build().getLogDTO();
@ -62,7 +62,7 @@ public class TestPlanLogService {
.method(requestMethod)
.path(requestUrl)
.sourceId(newTestPlan.getId())
.content(newTestPlan.getName())
.content(generateTestPlanSimpleContent(newTestPlan,"log.update.test_plan_group","log.update.test_plan"))
.originalValue(JSON.toJSONBytes(oldTestPlan))
.modifiedValue(JSON.toJSONBytes(newTestPlan))
.createUser(operator)
@ -80,7 +80,7 @@ public class TestPlanLogService {
.method(requestMethod)
.path(requestUrl)
.sourceId(deleteTestPlan.getId())
.content(this.generateTestPlanDeleteContent(deleteTestPlan))
.content(generateTestPlanSimpleContent(deleteTestPlan,"log.delete.test_plan_group","log.delete.test_plan"))
.originalValue(JSON.toJSONBytes(deleteTestPlan))
.createUser(operator)
.build().getLogDTO();
@ -99,7 +99,7 @@ public class TestPlanLogService {
.method(requestMethod)
.path(requestUrl)
.sourceId(testPlan.getId())
.content(this.generateTestPlanDeleteContent(testPlan))
.content(generateTestPlanSimpleContent(testPlan, "log.delete.test_plan_group", "log.delete.test_plan"))
.originalValue(JSON.toJSONBytes(testPlan))
.createUser(operator)
.build().getLogDTO();
@ -108,22 +108,12 @@ public class TestPlanLogService {
operationLogService.batchAdd(list);
}
private String generateTestPlanSimpleContent(TestPlan testPlan) {
private String generateTestPlanSimpleContent(TestPlan testPlan,String groupKey,String planKey) {
StringBuilder content = new StringBuilder();
if (StringUtils.equals(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
content.append(Translator.get("test_plan.test_plan_group")).append(StringUtils.SPACE).append(testPlan.getName()).append(StringUtils.SPACE);
content.append(Translator.get(groupKey)).append(StringUtils.SPACE).append(testPlan.getName()).append(StringUtils.SPACE);
} else {
content.append(Translator.get("test_plan.test_plan")).append(StringUtils.SPACE).append(testPlan.getName()).append(StringUtils.SPACE);
}
return content.toString();
}
private String generateTestPlanDeleteContent(TestPlan deleteTestPlan) {
StringBuilder content = new StringBuilder();
if (StringUtils.equals(deleteTestPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
content.append(Translator.get("log.delete.test_plan_group")).append(":").append(deleteTestPlan.getName()).append(StringUtils.SPACE);
} else {
content.append(Translator.get("log.delete.test_plan")).append(":").append(deleteTestPlan.getName()).append(StringUtils.SPACE);
content.append(Translator.get(planKey)).append(StringUtils.SPACE).append(testPlan.getName()).append(StringUtils.SPACE);
}
return content.toString();
}
@ -157,6 +147,8 @@ public class TestPlanLogService {
* @return
*/
public LogDTO copyLog(TestPlanCopyRequest request) {
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getTestPlanId());
testPlan.setName(request.getName());
LogDTO dto = new LogDTO(
request.getProjectId(),
null,
@ -164,12 +156,52 @@ public class TestPlanLogService {
null,
OperationLogType.COPY.name(),
logModule,
request.getName());
generateTestPlanSimpleContent(testPlan, "log.copy.test_plan_group", "log.copy.test_plan"));
dto.setPath("/test-plan/copy");
dto.setMethod(HttpMethodConstants.POST.name());
dto.setOriginalValue(JSON.toJSONBytes(request));
return dto;
}
public void saveBatchCopyLog(List<TestPlan> testPlanList, String operator, String requestUrl, String requestMethod) {
Project project = projectMapper.selectByPrimaryKey(testPlanList.get(0).getProjectId());
List<LogDTO> list = new ArrayList<>();
for (TestPlan testPlan : testPlanList) {
LogDTO dto = LogDTOBuilder.builder()
.projectId(testPlan.getProjectId())
.organizationId(project.getOrganizationId())
.type(OperationLogType.COPY.name())
.module(logModule)
.method(requestMethod)
.path(requestUrl)
.sourceId(testPlan.getId())
.content(generateTestPlanSimpleContent(testPlan, "log.copy.test_plan_group", "log.copy.test_plan"))
.originalValue(JSON.toJSONBytes(testPlan))
.createUser(operator)
.build().getLogDTO();
list.add(dto);
}
operationLogService.batchAdd(list);
}
public void saveBatchMoveLog(List<TestPlan> testPlanList, String operator, String requestUrl, String requestMethod) {
Project project = projectMapper.selectByPrimaryKey(testPlanList.get(0).getProjectId());
List<LogDTO> list = new ArrayList<>();
for (TestPlan testPlan : testPlanList) {
LogDTO dto = LogDTOBuilder.builder()
.projectId(testPlan.getProjectId())
.organizationId(project.getOrganizationId())
.type(OperationLogType.UPDATE.name())
.module(logModule)
.method(requestMethod)
.path(requestUrl)
.sourceId(testPlan.getId())
.content(generateTestPlanSimpleContent(testPlan, "log.move.test_plan_group", "log.move.test_plan"))
.originalValue(JSON.toJSONBytes(testPlan))
.createUser(operator)
.build().getLogDTO();
list.add(dto);
}
operationLogService.batchAdd(list);
}
}

View File

@ -12,7 +12,6 @@ import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.TestPlanModuleExample;
import io.metersphere.system.mapper.TestPlanModuleMapper;
import io.metersphere.system.uid.IDGenerator;
import io.metersphere.system.uid.NumGenerator;
@ -29,7 +28,7 @@ import java.util.stream.Collectors;
@Service
@Transactional(rollbackFor = Exception.class)
public class TestPlanService {
public class TestPlanService extends TestPlanBaseUtilsService {
@Resource
private TestPlanMapper testPlanMapper;
@Resource
@ -46,16 +45,10 @@ public class TestPlanService {
private TestPlanFunctionalCaseService testPlanFunctionCaseService;
@Resource
private TestPlanAllocationMapper testPlanAllocationMapper;
public void checkModule(String moduleId) {
if (!StringUtils.equals(moduleId, ModuleConstants.DEFAULT_NODE_ID)) {
TestPlanModuleExample example = new TestPlanModuleExample();
example.createCriteria().andIdEqualTo(moduleId);
if (testPlanModuleMapper.countByExample(example) == 0) {
throw new MSException(Translator.get("module.not.exist"));
}
}
}
@Resource
private TestPlanBatchCopyService testPlanBatchCopyService;
@Resource
private TestPlanBatchMoveService testPlanBatchMoveService;
/**
@ -83,11 +76,11 @@ public class TestPlanService {
*/
private TestPlan savePlanDTO(TestPlanCreateRequest createOrCopyRequest, String operator, String id) {
//检查模块的合法性
this.checkModule(createOrCopyRequest.getModuleId());
checkModule(createOrCopyRequest.getModuleId());
TestPlan createTestPlan = new TestPlan();
BeanUtils.copyBean(createTestPlan, createOrCopyRequest);
this.validateTestPlan(createTestPlan);
validateTestPlan(createTestPlan);
createTestPlan.setId(IDGenerator.nextStr());
long operateTime = System.currentTimeMillis();
@ -142,27 +135,6 @@ public class TestPlanService {
}
}
private void validateTestPlan(TestPlan testPlan) {
if (StringUtils.equals(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_PLAN) && !StringUtils.equals(testPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
TestPlan group = testPlanMapper.selectByPrimaryKey(testPlan.getGroupId());
testPlan.setModuleId(group.getModuleId());
}
TestPlanExample example = new TestPlanExample();
if (StringUtils.isBlank(testPlan.getId())) {
//新建 校验
example.createCriteria().andNameEqualTo(testPlan.getName()).andProjectIdEqualTo(testPlan.getProjectId()).andModuleIdEqualTo(testPlan.getModuleId());
if (testPlanMapper.countByExample(example) > 0) {
throw new MSException(Translator.get("test_plan.name.exist") + ":" + testPlan.getName());
}
} else {
//更新 校验
example.createCriteria().andNameEqualTo(testPlan.getName()).andProjectIdEqualTo(testPlan.getProjectId()).andIdNotEqualTo(testPlan.getId()).andModuleIdEqualTo(testPlan.getModuleId());
if (testPlanMapper.countByExample(example) > 0) {
throw new MSException(Translator.get("test_plan.name.exist") + ":" + testPlan.getName());
}
}
}
/**
* 删除测试计划
@ -243,18 +215,6 @@ public class TestPlanService {
}
private List<String> getSelectIds(TestPlanBatchProcessRequest request) {
if (request.isSelectAll()) {
List<String> ids = extTestPlanMapper.selectIdByConditions(request);
if (org.apache.commons.collections.CollectionUtils.isNotEmpty(request.getExcludeIds())) {
ids.removeAll(request.getExcludeIds());
}
return ids;
} else {
return request.getSelectIds();
}
}
private void cascadeDeleteTestPlanIds(List<String> testPlanIds) {
//删除当前计划对应的资源
Map<String, TestPlanResourceService> subTypes = CommonBeanFactory.getBeansOfType(TestPlanResourceService.class);
@ -297,13 +257,13 @@ public class TestPlanService {
updateTestPlan.setId(request.getId());
if (StringUtils.isNotBlank(request.getModuleId())) {
//检查模块的合法性
this.checkModule(request.getModuleId());
checkModule(request.getModuleId());
updateTestPlan.setModuleId(request.getModuleId());
}
if (StringUtils.isNotBlank(request.getName())) {
updateTestPlan.setName(request.getName());
updateTestPlan.setProjectId(testPlan.getProjectId());
this.validateTestPlan(updateTestPlan);
validateTestPlan(updateTestPlan);
}
if (CollectionUtils.isNotEmpty(request.getTags())) {
updateTestPlan.setTags(new ArrayList<>(request.getTags()));
@ -508,95 +468,25 @@ public class TestPlanService {
List<TestPlan> copyTestPlanList = testPlanMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(copyTestPlanList)) {
Map<String, List<TestPlan>> plans = copyTestPlanList.stream().collect(Collectors.groupingBy(TestPlan::getType));
batchCopyGroup(plans, request, userId);
batchCopyPlan(plans, request, userId);
// TODO 日志
testPlanBatchCopyService.batchCopy(plans, request, userId);
//日志
testPlanLogService.saveBatchCopyLog(copyTestPlanList, userId, url, method);
}
}
}
/**
* 批量复制计划
*
* @param plans
*/
private void batchCopyPlan(Map<String, List<TestPlan>> plans, TestPlanBatchRequest request, String userId) {
if (plans.containsKey(TestPlanConstants.TEST_PLAN_TYPE_PLAN)) {
List<TestPlan> testPlans = plans.get(TestPlanConstants.TEST_PLAN_TYPE_PLAN);
List<String> ids = testPlans.stream().map(TestPlan::getId).collect(Collectors.toList());
//额外信息
TestPlanConfigExample configExample = new TestPlanConfigExample();
configExample.createCriteria().andTestPlanIdIn(ids);
List<TestPlanConfig> testPlanConfigs = testPlanConfigMapper.selectByExample(configExample);
//测试规划配置信息
TestPlanAllocationExample allocationExample = new TestPlanAllocationExample();
allocationExample.createCriteria().andTestPlanIdIn(ids);
List<TestPlanAllocation> testPlanAllocations = testPlanAllocationMapper.selectByExampleWithBLOBs(allocationExample);
batchInsertPlan(testPlans, testPlanConfigs, testPlanAllocations, request, userId);
}
}
private void batchInsertPlan(List<TestPlan> testPlans, List<TestPlanConfig> testPlanConfigs, List<TestPlanAllocation> testPlanAllocations, TestPlanBatchRequest request, String userId) {
Map<String, List<TestPlanConfig>> configs = testPlanConfigs.stream().collect(Collectors.groupingBy(TestPlanConfig::getTestPlanId));
Map<String, List<TestPlanAllocation>> allocationsList = testPlanAllocations.stream().collect(Collectors.groupingBy(TestPlanAllocation::getTestPlanId));
List<TestPlanConfig> newConfigs = new ArrayList<>();
List<TestPlanAllocation> newAllocations = new ArrayList<>();
testPlans.forEach(testPlan -> {
List<TestPlanConfig> config = configs.get(testPlan.getId());
List<TestPlanAllocation> allocations = allocationsList.get(testPlan.getId());
Long num = testPlan.getNum();
testPlan.setId(IDGenerator.nextStr());
testPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_PREPARED);
testPlan.setNum(NumGenerator.nextNum(testPlan.getProjectId(), ApplicationNumScope.TEST_PLAN));
testPlan.setName(getCopyName(testPlan.getName(), num, testPlan.getNum()));
testPlan.setModuleId(request.getModuleId());
testPlan.setCreateTime(System.currentTimeMillis());
testPlan.setUpdateTime(System.currentTimeMillis());
testPlan.setCreateUser(userId);
testPlan.setUpdateUser(userId);
if (CollectionUtils.isNotEmpty(config)) {
TestPlanConfig testPlanConfig = config.get(0);
testPlanConfig.setTestPlanId(testPlan.getId());
newConfigs.add(testPlanConfig);
public void batchMove(TestPlanBatchRequest request, String userId, String url, String method) {
List<String> moveIds = getSelectIds(request);
if (CollectionUtils.isNotEmpty(moveIds)) {
TestPlanExample example = new TestPlanExample();
example.createCriteria().andIdIn(moveIds);
List<TestPlan> moveTestPlanList = testPlanMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(moveTestPlanList)) {
Map<String, List<TestPlan>> plans = moveTestPlanList.stream().collect(Collectors.groupingBy(TestPlan::getType));
testPlanBatchMoveService.batchMove(plans, request, userId);
//日志
testPlanLogService.saveBatchMoveLog(moveTestPlanList, userId, url, method);
}
if (CollectionUtils.isNotEmpty(allocations)) {
TestPlanAllocation testPlanAllocation = allocations.get(0);
testPlanAllocation.setTestPlanId(testPlan.getId());
testPlanAllocation.setId(IDGenerator.nextStr());
newAllocations.add(testPlanAllocation);
}
});
testPlanMapper.batchInsert(testPlans);
if (CollectionUtils.isNotEmpty(newConfigs)) {
testPlanConfigMapper.batchInsert(newConfigs);
}
if (CollectionUtils.isNotEmpty(newAllocations)) {
testPlanAllocationMapper.batchInsert(newAllocations);
}
}
private String getCopyName(String name, long oldNum, long newNum) {
if (!StringUtils.startsWith(name, "copy_")) {
name = "copy_" + name;
}
if (name.length() > 250) {
name = name.substring(0, 200) + "...";
}
if (StringUtils.endsWith(name, "_" + oldNum)) {
name = StringUtils.substringBeforeLast(name, "_" + oldNum);
}
name = name + "_" + newNum;
return name;
}
/**
* 批量复制组
*
* @param plans
*/
private void batchCopyGroup(Map<String, List<TestPlan>> plans, TestPlanBatchProcessRequest request, String userId) {
//TODO 批量复制计划组
}
}

View File

@ -123,6 +123,7 @@ public class TestPlanTests extends BaseTest {
private static final String URL_TEST_PLAN_COPY = "/test-plan/copy";
private static final String URL_TEST_PLAN_DETAIL = "/test-plan/%s";
private static final String URL_TEST_PLAN_BATCH_COPY = "/test-plan/batch/copy";
private static final String URL_TEST_PLAN_BATCH_MOVE = "/test-plan/batch/move";
private static String groupTestPlanId7 = null;
private static String groupTestPlanId15 = null;
@ -2191,4 +2192,18 @@ public class TestPlanTests extends BaseTest {
this.requestPostWithOkAndReturn(URL_TEST_PLAN_BATCH_COPY, request);
}
@Test
@Order(304)
public void testBatchMove() throws Exception {
TestPlanBatchRequest request = new TestPlanBatchRequest();
request.setProjectId("123");
request.setType("ALL");
request.setSelectAll(true);
request.setModuleId("3");
this.requestPostWithOkAndReturn(URL_TEST_PLAN_BATCH_MOVE, request);
}
}