parent
e1c724bf81
commit
07d7f0c18a
|
@ -4,6 +4,7 @@ import io.metersphere.base.domain.TestCase;
|
||||||
import io.metersphere.base.domain.TestCaseTest;
|
import io.metersphere.base.domain.TestCaseTest;
|
||||||
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||||
import io.metersphere.dto.*;
|
import io.metersphere.dto.*;
|
||||||
|
|
||||||
import io.metersphere.request.BaseQueryRequest;
|
import io.metersphere.request.BaseQueryRequest;
|
||||||
import io.metersphere.request.testcase.DeleteTestCaseRequest;
|
import io.metersphere.request.testcase.DeleteTestCaseRequest;
|
||||||
import io.metersphere.request.testcase.QueryTestCaseRequest;
|
import io.metersphere.request.testcase.QueryTestCaseRequest;
|
||||||
|
@ -171,6 +172,4 @@ public interface ExtTestCaseMapper {
|
||||||
List<TestCaseTest> getTestCaseRelateList(@Param("testCaseId") String testCaseId);
|
List<TestCaseTest> getTestCaseRelateList(@Param("testCaseId") String testCaseId);
|
||||||
|
|
||||||
List<TestCase> getTestCaseForLastResultLog(@Param("ids") List<String> ids);
|
List<TestCase> getTestCaseForLastResultLog(@Param("ids") List<String> ids);
|
||||||
|
|
||||||
List<TestCase> selectByRefIdsAndVersionId(@Param("refIds") List<String> refIds, @Param("versionId") String versionId);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1536,12 +1536,4 @@
|
||||||
AND ui_scenario.STATUS != 'Trash'
|
AND ui_scenario.STATUS != 'Trash'
|
||||||
)
|
)
|
||||||
</select>
|
</select>
|
||||||
<select id="selectByRefIdsAndVersionId" resultType="io.metersphere.base.domain.TestCase">
|
|
||||||
select * from test_case
|
|
||||||
where ref_id in
|
|
||||||
<foreach collection="refIds" item="refId" separator="," open="(" close=")">
|
|
||||||
#{refId}
|
|
||||||
</foreach>
|
|
||||||
and version_id = #{versionId}
|
|
||||||
</select>
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
package io.metersphere.dto;
|
|
||||||
|
|
||||||
import io.metersphere.base.domain.ProjectVersion;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class TestCaseBatchEditDTO {
|
|
||||||
private List<TestCaseDTO> testCaseDTOList;
|
|
||||||
private ProjectVersion projectVersion;
|
|
||||||
|
|
||||||
public boolean isNotEmpty() {
|
|
||||||
return projectVersion != null && CollectionUtils.isNotEmpty(testCaseDTOList);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -51,7 +51,6 @@ import io.metersphere.service.remote.project.TrackCustomFieldTemplateService;
|
||||||
import io.metersphere.service.remote.project.TrackTestCaseTemplateService;
|
import io.metersphere.service.remote.project.TrackTestCaseTemplateService;
|
||||||
import io.metersphere.service.remote.ui.RelevanceUiCaseService;
|
import io.metersphere.service.remote.ui.RelevanceUiCaseService;
|
||||||
import io.metersphere.service.wapper.TrackProjectService;
|
import io.metersphere.service.wapper.TrackProjectService;
|
||||||
import io.metersphere.utils.BatchProcessingUtil;
|
|
||||||
import io.metersphere.utils.DiscoveryUtil;
|
import io.metersphere.utils.DiscoveryUtil;
|
||||||
import io.metersphere.xmind.XmindCaseParser;
|
import io.metersphere.xmind.XmindCaseParser;
|
||||||
import io.metersphere.xmind.pojo.TestCaseXmindData;
|
import io.metersphere.xmind.pojo.TestCaseXmindData;
|
||||||
|
@ -85,7 +84,6 @@ import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@ -2123,9 +2121,6 @@ public class TestCaseService {
|
||||||
batchEditField(request);
|
batchEditField(request);
|
||||||
} else if (StringUtils.equals("tags", request.getType())) {
|
} else if (StringUtils.equals("tags", request.getType())) {
|
||||||
batchEditTag(request);
|
batchEditTag(request);
|
||||||
} else if (StringUtils.equals("version", request.getType())) {
|
|
||||||
//批量修改版本
|
|
||||||
this.preEditVersion(request);
|
|
||||||
} else {
|
} else {
|
||||||
// 批量移动
|
// 批量移动
|
||||||
if (request.getCondition().isSelectAll()) {
|
if (request.getCondition().isSelectAll()) {
|
||||||
|
@ -2141,99 +2136,6 @@ public class TestCaseService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void preEditVersion(TestCaseBatchRequest request) {
|
|
||||||
List<TestCaseDTO> testCaseDTOS = new ArrayList<>();
|
|
||||||
ProjectVersion projectVersion = projectVersionMapper.selectByPrimaryKey(request.getVersionId());
|
|
||||||
if (projectVersion == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.getCondition().isSelectAll()) {
|
|
||||||
// 全选则重新设置MoveIds
|
|
||||||
testCaseDTOS = listTestCase(request.getCondition(), true);
|
|
||||||
} else if (CollectionUtils.isNotEmpty(request.getIds())) {
|
|
||||||
testCaseDTOS = extTestCaseMapper.list(new QueryTestCaseRequest() {{
|
|
||||||
this.setIds(request.getIds());
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 过滤掉当前版本的用例
|
|
||||||
testCaseDTOS = testCaseDTOS.stream().filter(e -> !StringUtils.equals(request.getVersionId(), e.getVersionId()))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
BatchProcessingUtil.testCaseBatchProcess(testCaseDTOS, projectVersion, this::batchEditVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 级联删除
|
|
||||||
private void cascadeDeleteTestCase(List<String> testCaseIds) {
|
|
||||||
//删除refTestCaseList
|
|
||||||
deleteTestPlanTestCaseBath(testCaseIds);
|
|
||||||
relationshipEdgeService.delete(testCaseIds); // 删除关系图
|
|
||||||
customFieldTestCaseService.deleteByResourceIds(testCaseIds); // 删除自定义字段
|
|
||||||
//删除执行信息
|
|
||||||
functionCaseExecutionInfoService.deleteBySourceIdList(testCaseIds);
|
|
||||||
testCaseIds.forEach(testCaseId -> { // todo 优化下效率
|
|
||||||
testCaseIssueService.delTestCaseIssues(testCaseId);
|
|
||||||
testCaseCommentService.deleteCaseComment(testCaseId);
|
|
||||||
TestCaseTestExample examples = new TestCaseTestExample();
|
|
||||||
examples.createCriteria().andTestCaseIdEqualTo(testCaseId);
|
|
||||||
testCaseTestMapper.deleteByExample(examples);
|
|
||||||
relateDelete(testCaseId);
|
|
||||||
deleteFollows(testCaseId);
|
|
||||||
});
|
|
||||||
|
|
||||||
TestCaseExample example = new TestCaseExample();
|
|
||||||
example.createCriteria().andIdIn(testCaseIds);
|
|
||||||
testCaseMapper.deleteByExample(example);
|
|
||||||
// 删除富文本框图片
|
|
||||||
mdFileService.deleteBySourceIds(testCaseIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量移动到指定版本:
|
|
||||||
* 1.指定版本不存在该用例时,直接移动(修改用例的version_id).
|
|
||||||
* 2.指定版本存在该用例时,先删除,再修改version.
|
|
||||||
* 2.1):删除时判断refId是否和Id相同。如果相同的话,把要修改用例的refId设置为它自己的ID.
|
|
||||||
* 2.2):判断latest是否为true。为true的话,要把新用例的latest设置为true.
|
|
||||||
*/
|
|
||||||
private void batchEditVersion(TestCaseBatchEditDTO batchEditDTO) {
|
|
||||||
if (batchEditDTO.isNotEmpty()) {
|
|
||||||
Map<String, TestCaseDTO> refTestCaseMap = batchEditDTO.getTestCaseDTOList().stream().collect(Collectors.toMap(TestCaseDTO::getRefId, Function.identity()));
|
|
||||||
List<TestCase> refTestCaseList = extTestCaseMapper.selectByRefIdsAndVersionId(new ArrayList<>(refTestCaseMap.keySet()), batchEditDTO.getProjectVersion().getId());
|
|
||||||
//进行步骤2检查
|
|
||||||
if (CollectionUtils.isNotEmpty(refTestCaseList)) {
|
|
||||||
for (TestCase refTestCase : refTestCaseList) {
|
|
||||||
TestCaseDTO oldDTO = refTestCaseMap.get(refTestCase.getRefId());
|
|
||||||
if (oldDTO != null) {
|
|
||||||
if (StringUtils.equals(refTestCase.getId(), refTestCase.getRefId())) {
|
|
||||||
oldDTO.setRefId(oldDTO.getId());
|
|
||||||
}
|
|
||||||
if (BooleanUtils.isTrue(refTestCase.getLatest())) {
|
|
||||||
oldDTO.setLatest(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.cascadeDeleteTestCase(refTestCaseList.stream().map(TestCase::getId).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
|
|
||||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
|
||||||
TestCaseMapper mapper = sqlSession.getMapper(TestCaseMapper.class);
|
|
||||||
for (TestCaseDTO testCaseDTO : refTestCaseMap.values()) {
|
|
||||||
TestCaseWithBLOBs updateCase = new TestCaseWithBLOBs();
|
|
||||||
updateCase.setId(testCaseDTO.getId());
|
|
||||||
updateCase.setVersionId(batchEditDTO.getProjectVersion().getId());
|
|
||||||
updateCase.setLatest(testCaseDTO.getLatest());
|
|
||||||
updateCase.setRefId(testCaseDTO.getRefId());
|
|
||||||
mapper.updateByPrimaryKeySelective(updateCase);
|
|
||||||
}
|
|
||||||
sqlSession.flushStatements();
|
|
||||||
if (sqlSession != null && sqlSessionFactory != null) {
|
|
||||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void batchEditTag(TestCaseBatchRequest request) {
|
private void batchEditTag(TestCaseBatchRequest request) {
|
||||||
ServiceUtils.getSelectAllIds(request, request.getCondition(),
|
ServiceUtils.getSelectAllIds(request, request.getCondition(),
|
||||||
(query) -> extTestCaseMapper.selectIds(query));
|
(query) -> extTestCaseMapper.selectIds(query));
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
package io.metersphere.utils;
|
package io.metersphere.utils;
|
||||||
|
|
||||||
import io.metersphere.base.domain.ProjectVersion;
|
|
||||||
import io.metersphere.base.domain.TestCaseTest;
|
import io.metersphere.base.domain.TestCaseTest;
|
||||||
import io.metersphere.base.domain.TestCaseTestExample;
|
import io.metersphere.base.domain.TestCaseTestExample;
|
||||||
import io.metersphere.dto.TestCaseBatchEditDTO;
|
|
||||||
import io.metersphere.dto.TestCaseDTO;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -28,6 +25,7 @@ public class BatchProcessingUtil {
|
||||||
List<String> handleList = stringList.subList(0, BATCH_PROCESS_QUANTITY);
|
List<String> handleList = stringList.subList(0, BATCH_PROCESS_QUANTITY);
|
||||||
consumer.accept(handleList);
|
consumer.accept(handleList);
|
||||||
stringList.removeAll(handleList);
|
stringList.removeAll(handleList);
|
||||||
|
|
||||||
//记录循环次数,防止出现死循环
|
//记录循环次数,防止出现死循环
|
||||||
foreachIndex++;
|
foreachIndex++;
|
||||||
}
|
}
|
||||||
|
@ -108,25 +106,4 @@ public class BatchProcessingUtil {
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void testCaseBatchProcess(List<TestCaseDTO> testCaseDTOS, ProjectVersion projectVersion, Consumer<TestCaseBatchEditDTO> consumer) {
|
|
||||||
if (CollectionUtils.isNotEmpty(testCaseDTOS)) {
|
|
||||||
int foreachIndex = 0;
|
|
||||||
int foreachCount = testCaseDTOS.size() / BATCH_PROCESS_QUANTITY;
|
|
||||||
while (BATCH_PROCESS_QUANTITY < testCaseDTOS.size() || (foreachIndex > foreachCount)) {
|
|
||||||
List<TestCaseDTO> handleList = testCaseDTOS.subList(0, BATCH_PROCESS_QUANTITY);
|
|
||||||
TestCaseBatchEditDTO handleDTO = new TestCaseBatchEditDTO(handleList, projectVersion);
|
|
||||||
consumer.accept(handleDTO);
|
|
||||||
testCaseDTOS.removeAll(handleList);
|
|
||||||
|
|
||||||
//记录循环次数,防止出现死循环
|
|
||||||
foreachIndex++;
|
|
||||||
}
|
|
||||||
//处理剩余数据
|
|
||||||
if (CollectionUtils.isNotEmpty(testCaseDTOS)) {
|
|
||||||
TestCaseBatchEditDTO handleDTO = new TestCaseBatchEditDTO(testCaseDTOS, projectVersion);
|
|
||||||
consumer.accept(handleDTO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,11 +194,6 @@
|
||||||
ref="commentEditInput"
|
ref="commentEditInput"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<span v-if="form.type === 'version'"
|
|
||||||
style="font-size:12px">
|
|
||||||
{{ $t("case.batch_edit_version") }}
|
|
||||||
</span>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<template v-slot:footer>
|
<template v-slot:footer>
|
||||||
<el-button @click="dialogVisible = false" size="small">{{
|
<el-button @click="dialogVisible = false" size="small">{{
|
||||||
|
@ -221,15 +216,18 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MsDialogFooter from "metersphere-frontend/src/components/MsDialogFooter";
|
import MsDialogFooter from "metersphere-frontend/src/components/MsDialogFooter";
|
||||||
import {listenGoBack, removeGoBackListener,} from "metersphere-frontend/src/utils";
|
import {
|
||||||
|
listenGoBack,
|
||||||
|
removeGoBackListener,
|
||||||
|
} from "metersphere-frontend/src/utils";
|
||||||
import EnvPopover from "@/business/plan/env/EnvPopover";
|
import EnvPopover from "@/business/plan/env/EnvPopover";
|
||||||
import MsTag from "metersphere-frontend/src/components/MsTag";
|
import MsTag from "metersphere-frontend/src/components/MsTag";
|
||||||
import {ENV_TYPE} from "metersphere-frontend/src/utils/constants";
|
import { ENV_TYPE } from "metersphere-frontend/src/utils/constants";
|
||||||
import CustomFiledComponent from "metersphere-frontend/src/components/template/CustomFiledComponent";
|
import CustomFiledComponent from "metersphere-frontend/src/components/template/CustomFiledComponent";
|
||||||
import MsInputTag from "metersphere-frontend/src/components/MsInputTag";
|
import MsInputTag from "metersphere-frontend/src/components/MsInputTag";
|
||||||
import {getOwnerProjects} from "@/business/utils/sdk-utils";
|
import { getOwnerProjects } from "@/business/utils/sdk-utils";
|
||||||
import {getApiScenarioEnvByProjectId} from "@/api/remote/api/api-automation";
|
import { getApiScenarioEnvByProjectId } from "@/api/remote/api/api-automation";
|
||||||
import {getCustomField} from "@/api/custom-field";
|
import { getCustomField } from "@/api/custom-field";
|
||||||
import CommentEditInput from "@/business/review/view/components/commnet/CommentEditInput";
|
import CommentEditInput from "@/business/review/view/components/commnet/CommentEditInput";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -12,8 +12,7 @@
|
||||||
<ms-new-ui-search :condition.sync="condition" @search="search" style="float: left" />
|
<ms-new-ui-search :condition.sync="condition" @search="search" style="float: left" />
|
||||||
|
|
||||||
<!-- 版本切换组件 -->
|
<!-- 版本切换组件 -->
|
||||||
<version-select ref="versionSelect" v-xpack :default-version="defaultVersion" :project-id="projectId"
|
<version-select v-xpack :project-id="projectId" :default-version="defaultVersion" @changeVersion="changeVersion" />
|
||||||
@changeVersion="changeVersion"/>
|
|
||||||
|
|
||||||
<!-- 高级搜索框 -->
|
<!-- 高级搜索框 -->
|
||||||
<ms-table-adv-search :condition.sync="condition" @search="search" ref="advanceSearch"/>
|
<ms-table-adv-search :condition.sync="condition" @search="search" ref="advanceSearch"/>
|
||||||
|
@ -659,16 +658,6 @@ export default {
|
||||||
id: "tags",
|
id: "tags",
|
||||||
name: this.$t('commons.tag')
|
name: this.$t('commons.tag')
|
||||||
})
|
})
|
||||||
if (this.enableVersionColumn) {
|
|
||||||
this.typeArr.push({
|
|
||||||
id: "version",
|
|
||||||
name: this.$t('commons.version')
|
|
||||||
})
|
|
||||||
let versionOptions = this.$refs.versionSelect.versionOptions;
|
|
||||||
// console.info("version-options", versionOptions);
|
|
||||||
this.valueArr['version'] = versionOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCustomFieldBatchEditOption(template.customFields, this.typeArr, this.valueArr, this.members);
|
getCustomFieldBatchEditOption(template.customFields, this.typeArr, this.valueArr, this.members);
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.$refs.table) {
|
if (this.$refs.table) {
|
||||||
|
@ -1122,9 +1111,6 @@ export default {
|
||||||
param.type = form.type;
|
param.type = form.type;
|
||||||
param.appendTag = form.appendTag;
|
param.appendTag = form.appendTag;
|
||||||
param.tagList = form.tags;
|
param.tagList = form.tags;
|
||||||
} else if (form.type === 'version') {
|
|
||||||
param.type = form.type;
|
|
||||||
param.versionId = form.value;
|
|
||||||
}
|
}
|
||||||
testCaseBatchEdit(param)
|
testCaseBatchEdit(param)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
|
@ -171,7 +171,6 @@ const message = {
|
||||||
batch_remove_confirm: "Confirm remove {0} item use case?",
|
batch_remove_confirm: "Confirm remove {0} item use case?",
|
||||||
},
|
},
|
||||||
enter_issues_content: "Please enter the defect content...",
|
enter_issues_content: "Please enter the defect content...",
|
||||||
batch_edit_version: "The specified update version exists data will be forced to cover, please operate with caution!",
|
|
||||||
},
|
},
|
||||||
attachment: {
|
attachment: {
|
||||||
preview: "Preview",
|
preview: "Preview",
|
||||||
|
|
|
@ -170,7 +170,6 @@ const message = {
|
||||||
batch_remove_confirm: "确定移除{0}项用例?",
|
batch_remove_confirm: "确定移除{0}项用例?",
|
||||||
},
|
},
|
||||||
enter_issues_content: "请输入缺陷内容...",
|
enter_issues_content: "请输入缺陷内容...",
|
||||||
batch_edit_version: "指定的更新版本存在数据会被强制覆盖,请谨慎操作!",
|
|
||||||
},
|
},
|
||||||
attachment: {
|
attachment: {
|
||||||
preview: "预览",
|
preview: "预览",
|
||||||
|
|
|
@ -170,7 +170,6 @@ const message = {
|
||||||
batch_remove_confirm: "確定移除{0}項用例?",
|
batch_remove_confirm: "確定移除{0}項用例?",
|
||||||
},
|
},
|
||||||
enter_issues_content: "輸入缺陷內容...",
|
enter_issues_content: "輸入缺陷內容...",
|
||||||
batch_edit_version: "指定的更新版本存在數據會被強制覆蓋,請謹慎操作!",
|
|
||||||
},
|
},
|
||||||
attachment: {
|
attachment: {
|
||||||
preview: "預覽",
|
preview: "預覽",
|
||||||
|
|
Loading…
Reference in New Issue