diff --git a/backend/src/main/java/io/metersphere/base/mapper/TestCaseTestMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/TestCaseTestMapper.xml index ee7ee42e10..417ed040f4 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/TestCaseTestMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/TestCaseTestMapper.xml @@ -140,11 +140,22 @@ SELECT - atc.id, atc.project_id , atc.name , atc.num , atc.`level`, atc.step_total, atc.status, atc.tags - from api_scenario atc - left join test_case_test tct on atc.id = tct.test_id - where tct.test_id is NULL and atc.status != 'Trash' + atc.id, + atc.project_id, + atc. NAME, + atc.num, + atc.`level`, + atc.step_total, + atc. STATUS, + atc.tags, + project_version.id versionId, + project_version.name versionName + FROM + api_scenario atc + LEFT JOIN test_case_test tct ON atc.id = tct.test_id + LEFT JOIN project_version ON atc.project_id = project_version.project_id + AND project_version.id = atc.version_id + WHERE + tct.test_id IS NULL + AND atc. STATUS != 'Trash' and atc.project_id = #{request.projectId} @@ -386,6 +439,30 @@ #{nodeId} + + and atc.version_id = #{request.versionId} + + + and atc.ref_id = #{request.refId} + + + AND ( + atc.version_id = (SELECT project_version.id + FROM api_scenario tmp + JOIN project_version + ON tmp.project_id = project_version.project_id AND tmp.version_id = project_version.id AND latest = TRUE + WHERE ref_id = atc.ref_id + LIMIT 1) + OR + atc.version_id = (SELECT tmp.version_id + FROM api_scenario tmp + WHERE ref_id = atc.ref_id + GROUP BY ref_id + HAVING max(latest) = 0 + ORDER BY tmp.update_time DESC + LIMIT 1) + ) + @@ -393,14 +470,42 @@ + + + + + + and atc.version_id in + + #{value} + + + + + + + diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.java index 82183685f9..a5c8becb22 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.java @@ -125,7 +125,7 @@ public interface ExtTestCaseMapper { Long getPreOrder(@Param("projectId") String projectId, @Param("baseOrder") Long baseOrder); - List getTestCase(@Param("request") QueryTestCaseRequest request); + List getTestCase(@Param("request") QueryTestCaseRequest request); List getTestCaseForGraph(@Param("ids") Set ids); diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml index 4e54e75cba..7c6efa8595 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml @@ -831,10 +831,23 @@ order by `order` desc limit 1; - + SELECT + test_case.id, + test_case. NAME, + test_case.priority, + test_case.type, + test_case.review_status, + test_case.num, + test_case.custom_num, + test_case.tags, + test_case.create_time, + test_case.update_time, + project_version.name versionName, + project_version.id versionId + FROM + test_case AS test_case + left join project_version on project_version.project_id = test_case.project_id and project_version.id = test_case.version_id diff --git a/backend/src/main/java/io/metersphere/dto/RelationshipEdgeDTO.java b/backend/src/main/java/io/metersphere/dto/RelationshipEdgeDTO.java index 3802ae3014..b6ab18f2df 100644 --- a/backend/src/main/java/io/metersphere/dto/RelationshipEdgeDTO.java +++ b/backend/src/main/java/io/metersphere/dto/RelationshipEdgeDTO.java @@ -11,4 +11,5 @@ public class RelationshipEdgeDTO extends RelationshipEdge { private String status; private String creator; private String versionId; + private String versionName; } diff --git a/backend/src/main/java/io/metersphere/dto/TestCaseTestDao.java b/backend/src/main/java/io/metersphere/dto/TestCaseTestDao.java index 2a86c8a97d..fb3c18e6c5 100644 --- a/backend/src/main/java/io/metersphere/dto/TestCaseTestDao.java +++ b/backend/src/main/java/io/metersphere/dto/TestCaseTestDao.java @@ -9,4 +9,6 @@ import lombok.Setter; public class TestCaseTestDao extends TestCaseTest { private String name; private String num; + private String projectName; + private String versionName; } diff --git a/backend/src/main/java/io/metersphere/track/controller/TestCaseController.java b/backend/src/main/java/io/metersphere/track/controller/TestCaseController.java index 6bddf4def7..cfe83f5966 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestCaseController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestCaseController.java @@ -140,7 +140,7 @@ public class TestCaseController { } @PostMapping("/relationship/relate/{goPage}/{pageSize}") - public Pager> getRelationshipRelateList(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryTestCaseRequest request) { + public Pager> getRelationshipRelateList(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryTestCaseRequest request) { return testCaseService.getRelationshipRelateList(request, goPage, pageSize); } diff --git a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java index 550d97518c..5c85d1f0bc 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java @@ -164,6 +164,8 @@ public class TestCaseService { private RelationshipEdgeMapper relationshipEdgeMapper; @Resource private ExtProjectVersionMapper extProjectVersionMapper; + @Resource + private ProjectVersionMapper projectVersionMapper; private void setNode(TestCaseWithBLOBs testCase) { if (StringUtils.isEmpty(testCase.getNodeId()) || "default-module".equals(testCase.getNodeId())) { @@ -1187,7 +1189,7 @@ public class TestCaseService { for (TestCaseExcelData model : datas) { List list = new ArrayList<>(); - Map customDataMaps = Optional.ofNullable(model.getCustomDatas()).orElse(new HashMap<>()); + Map customDataMaps = Optional.ofNullable(model.getCustomDatas()).orElse(new HashMap<>()); for (String head : headList) { if (StringUtils.equalsAnyIgnoreCase(head, "ID")) { @@ -1220,7 +1222,7 @@ public class TestCaseService { list.add(model.getStepModel()); } else if (StringUtils.equalsAnyIgnoreCase(head, "Priority", "用例等級", "用例等级")) { list.add(model.getPriority()); - } else if(StringUtils.equalsAnyIgnoreCase(head,"Case status","用例状态","用例狀態")){ + } else if (StringUtils.equalsAnyIgnoreCase(head, "Case status", "用例状态", "用例狀態")) { list.add(model.getStatus()); } else if (StringUtils.equalsAnyIgnoreCase(head, "Maintainer(ID)", "责任人(ID)", "維護人(ID)")) { list.add(model.getMaintainer()); @@ -2218,29 +2220,51 @@ public class TestCaseService { List apiLoadTests = performanceTestService.getLoadCaseByIds( getTestIds(testCaseTests, "performance") ); + List projectIds = apiCases.stream().map(c -> c.getProjectId()).collect(Collectors.toList()); + projectIds.addAll(apiScenarios.stream().map(s -> s.getProjectId()).collect(Collectors.toList())); + projectIds.addAll(apiLoadTests.stream().map(s -> s.getProjectId()).collect(Collectors.toList())); + projectIds = projectIds.stream().distinct().collect(Collectors.toList()); + + List versionIds = apiCases.stream().map(c -> c.getVersionId()).collect(Collectors.toList()); + versionIds.addAll(apiScenarios.stream().map(s -> s.getVersionId()).collect(Collectors.toList())); + versionIds.addAll(apiLoadTests.stream().map(l -> l.getVersionId()).collect(Collectors.toList())); + versionIds = versionIds.stream().distinct().collect(Collectors.toList()); + + ProjectExample projectExample = new ProjectExample(); + projectExample.createCriteria().andIdIn(projectIds); + List projects = projectMapper.selectByExample(projectExample); + Map projectNameMap = projects.stream().collect(Collectors.toMap(Project::getId, Project::getName)); + + ProjectVersionExample versionExample = new ProjectVersionExample(); + versionExample.createCriteria().andIdIn(versionIds); + List projectVersions = projectVersionMapper.selectByExample(versionExample); + Map verisonNameMap = projectVersions.stream().collect(Collectors.toMap(ProjectVersion::getId, ProjectVersion::getName)); + List testCaseTestList = new ArrayList<>(); apiCases.forEach(item -> { - getTestCaseTestDaoList("testcase", item.getNum(), item.getName(), item.getId(), + getTestCaseTestDaoList("testcase", item.getNum(), item.getName(), item.getId(), projectNameMap.get(item.getProjectId()), verisonNameMap.get(item.getVersionId()), testCaseTestList, testCaseTestsMap); }); apiScenarios.forEach(item -> { - getTestCaseTestDaoList("automation", item.getNum(), item.getName(), item.getId(), + getTestCaseTestDaoList("automation", item.getNum(), item.getName(), item.getId(), projectNameMap.get(item.getProjectId()), verisonNameMap.get(item.getVersionId()), testCaseTestList, testCaseTestsMap); }); apiLoadTests.forEach(item -> { - getTestCaseTestDaoList("performance", item.getNum(), item.getName(), item.getId(), + getTestCaseTestDaoList("performance", item.getNum(), item.getName(), item.getId(), projectNameMap.get(item.getProjectId()), verisonNameMap.get(item.getVersionId()), testCaseTestList, testCaseTestsMap); }); return testCaseTestList; } - public void getTestCaseTestDaoList(String type, Object num, String name, String testId, + public void getTestCaseTestDaoList(String type, Object num, String name, String testId, String projectName, String versionName, List testCaseTestList, Map testCaseTestsMap) { TestCaseTestDao testCaseTestDao = new TestCaseTestDao(); BeanUtils.copyBean(testCaseTestDao, testCaseTestsMap.get(testId)); testCaseTestDao.setNum(num.toString()); testCaseTestDao.setName(name); testCaseTestDao.setTestType(type); + testCaseTestDao.setProjectName(projectName); + testCaseTestDao.setVersionName(versionName); testCaseTestList.add(testCaseTestDao); } @@ -2283,7 +2307,7 @@ public class TestCaseService { testCaseMapper::updateByPrimaryKeySelective); } - public Pager> getRelationshipRelateList(QueryTestCaseRequest request, int goPage, int pageSize) { + public Pager> getRelationshipRelateList(QueryTestCaseRequest request, int goPage, int pageSize) { setDefaultOrder(request); List relationshipIds = relationshipEdgeService.getRelationshipIds(request.getId()); request.setTestCaseContainIds(relationshipIds); @@ -2301,6 +2325,15 @@ public class TestCaseService { example.createCriteria().andIdIn(ids).andStatusNotEqualTo("Trash"); List testCaseList = testCaseMapper.selectByExampleWithBLOBs(example); buildUserInfo(testCaseList); + + Map verionNameMap = new HashMap<>(); + List versionIds = testCaseList.stream().map(TestCase::getVersionId).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(versionIds)) { + ProjectVersionRequest pvr = new ProjectVersionRequest(); + pvr.setProjectId(testCaseList.get(0).getProjectId()); + List projectVersions = extProjectVersionMapper.selectProjectVersionList(pvr); + verionNameMap = projectVersions.stream().collect(Collectors.toMap(ProjectVersionDTO::getId, ProjectVersionDTO::getName)); + } Map caseMap = testCaseList.stream().collect(Collectors.toMap(TestCase::getId, i -> i)); List results = new ArrayList<>(); for (RelationshipEdge relationshipEdge : relationshipEdges) { @@ -2320,6 +2353,7 @@ public class TestCaseService { relationshipEdgeDTO.setTargetNum(testCase.getNum()); relationshipEdgeDTO.setTargetCustomNum(testCase.getCustomNum()); relationshipEdgeDTO.setStatus(testCase.getStatus()); + relationshipEdgeDTO.setVersionName(verionNameMap.get(testCase.getVersionId())); results.add(relationshipEdgeDTO); } return results; diff --git a/frontend/src/business/components/api/automation/scenario/api/RelevanceApiList.vue b/frontend/src/business/components/api/automation/scenario/api/RelevanceApiList.vue index dcd58fc850..954203e5f0 100644 --- a/frontend/src/business/components/api/automation/scenario/api/RelevanceApiList.vue +++ b/frontend/src/business/components/api/automation/scenario/api/RelevanceApiList.vue @@ -11,6 +11,7 @@ { - this.versionEnable = response.data; - }); }, methods: { getTableData() { diff --git a/frontend/src/business/components/api/definition/components/complete/ApiTableList.vue b/frontend/src/business/components/api/definition/components/complete/ApiTableList.vue index 127575c9ea..22b3d89024 100644 --- a/frontend/src/business/components/api/definition/components/complete/ApiTableList.vue +++ b/frontend/src/business/components/api/definition/components/complete/ApiTableList.vue @@ -13,7 +13,6 @@ operator-width="170px" @refresh="initTable" ref="apitable"> - @@ -18,6 +19,7 @@ :read-only="readOnly" :api-definition-id="resourceId" :relationship-type="relationshipType" + :version-enable="versionEnable" @setCount="setCount" @deleteRelationship="handleDelete" ref="testCaseRelationshipList"/> @@ -53,7 +55,8 @@ export default { readOnly: Boolean, relationshipType: String, title: String, - resourceType: String + resourceType: String, + versionEnable: Boolean, }, methods: { getTableData() { diff --git a/frontend/src/business/components/track/case/TestCase.vue b/frontend/src/business/components/track/case/TestCase.vue index ae70f15072..c7675a6e48 100644 --- a/frontend/src/business/components/track/case/TestCase.vue +++ b/frontend/src/business/components/track/case/TestCase.vue @@ -35,6 +35,7 @@ :tree-nodes="treeNodes" :trash-enable="true" :current-version="currentTrashVersion" + :version-enable="versionEnable" @refreshTable="refresh" @testCaseEdit="editTestCase" @testCaseCopy="copyTestCase" @@ -55,6 +56,7 @@ :tree-nodes="treeNodes" :trash-enable="false" :public-enable="true" + :version-enable="versionEnable" @refreshTable="refresh" @testCaseEdit="editTestCase" @testCaseEditShow="editTestCaseShow" @@ -88,6 +90,7 @@ :trash-enable="false" :public-enable="false" :current-version="currentVersion" + :version-enable="versionEnable" @refreshTable="refresh" @testCaseEdit="editTestCase" @testCaseCopy="copyTestCase" @@ -118,6 +121,7 @@
{ + this.versionEnable = response.data; + }); + } + }, } }; diff --git a/frontend/src/business/components/track/case/components/RelationshipFunctionalRelevance.vue b/frontend/src/business/components/track/case/components/RelationshipFunctionalRelevance.vue index 770053bf6b..575cfdf40e 100644 --- a/frontend/src/business/components/track/case/components/RelationshipFunctionalRelevance.vue +++ b/frontend/src/business/components/track/case/components/RelationshipFunctionalRelevance.vue @@ -5,6 +5,7 @@ :get-table-data="getTestCases" :get-node-tree="getTreeNodes" :save="saveCaseRelevance" + :version-enable="versionEnable" ref="functionalRelevance"> @@ -35,6 +36,7 @@ export default { type: String }, relationshipType: String, + versionEnable: Boolean }, watch: { caseId() { diff --git a/frontend/src/business/components/track/case/components/TestCaseApiRelate.vue b/frontend/src/business/components/track/case/components/TestCaseApiRelate.vue index 1dd90eaa84..1938b8f09b 100644 --- a/frontend/src/business/components/track/case/components/TestCaseApiRelate.vue +++ b/frontend/src/business/components/track/case/components/TestCaseApiRelate.vue @@ -21,6 +21,7 @@ :current-protocol="currentProtocol" :select-node-ids="selectNodeIds" :project-id="projectId" + :versionEnable="versionEnable" ref="apiCaseList"/> @@ -52,6 +53,10 @@ export default { props: { caseId: { type: String + }, + versionEnable: { + type: Boolean, + default: false } }, methods: { diff --git a/frontend/src/business/components/track/case/components/TestCaseEdit.vue b/frontend/src/business/components/track/case/components/TestCaseEdit.vue index 846a7b8d1b..916692a39a 100644 --- a/frontend/src/business/components/track/case/components/TestCaseEdit.vue +++ b/frontend/src/business/components/track/case/components/TestCaseEdit.vue @@ -114,7 +114,7 @@ + :label-width="formLabelWidth" :case-id="form.id" :version-enable="versionEnable" ref="otherInfo"/> {{ $t('test_track.review.comment') }}: @@ -313,7 +313,7 @@ export default { newData: null, selectedOtherInfo: null, currentProjectId: "" , - casePublic: false + casePublic: false, }; }, props: { @@ -332,7 +332,8 @@ export default { type: Boolean, default: false, }, - activeName: String + activeName: String, + versionEnable: Boolean, }, computed: { projectIds() { diff --git a/frontend/src/business/components/track/case/components/TestCaseEditOtherInfo.vue b/frontend/src/business/components/track/case/components/TestCaseEditOtherInfo.vue index bdd136785d..27aad20a63 100644 --- a/frontend/src/business/components/track/case/components/TestCaseEditOtherInfo.vue +++ b/frontend/src/business/components/track/case/components/TestCaseEditOtherInfo.vue @@ -6,7 +6,7 @@ - + @@ -37,7 +37,7 @@ - + @@ -90,7 +90,7 @@ export default { DependenciesList, TestCaseTestRelate, FormRichTextItem, TestCaseIssueRelate, TestCaseAttachment, MsRichText, TestCaseRichText}, - props: ['form', 'labelWidth', 'caseId', 'readOnly', 'projectId', 'isTestPlan', 'planId'], + props: ['form', 'labelWidth', 'caseId', 'readOnly', 'projectId', 'isTestPlan', 'planId', 'versionEnable'], data() { return { result: {}, diff --git a/frontend/src/business/components/track/case/components/TestCaseList.vue b/frontend/src/business/components/track/case/components/TestCaseList.vue index 4420fbfbbc..2296e5f1f0 100644 --- a/frontend/src/business/components/track/case/components/TestCaseList.vue +++ b/frontend/src/business/components/track/case/components/TestCaseList.vue @@ -144,6 +144,7 @@ @@ -42,6 +43,10 @@ export default { props: { caseId: { type: String + }, + versionEnable: { + type: Boolean, + default: false } }, methods: { diff --git a/frontend/src/business/components/track/case/components/TestCaseRelateApiList.vue b/frontend/src/business/components/track/case/components/TestCaseRelateApiList.vue index 8b8c7c2f3d..1231a65a1c 100644 --- a/frontend/src/business/components/track/case/components/TestCaseRelateApiList.vue +++ b/frontend/src/business/components/track/case/components/TestCaseRelateApiList.vue @@ -1,59 +1,74 @@ + @@ -32,7 +33,11 @@ export default { props: { planId: { type: String - } + }, + versionEnable: { + type: Boolean, + default: false + }, }, watch: { planId() { diff --git a/frontend/src/business/components/track/plan/view/comonents/load/TestCaseLoadRelevance.vue b/frontend/src/business/components/track/plan/view/comonents/load/TestCaseLoadRelevance.vue index 4950dfc96e..f2841cb363 100644 --- a/frontend/src/business/components/track/plan/view/comonents/load/TestCaseLoadRelevance.vue +++ b/frontend/src/business/components/track/plan/view/comonents/load/TestCaseLoadRelevance.vue @@ -45,6 +45,7 @@ @@ -22,6 +23,7 @@ @@ -54,7 +56,8 @@ export default { props: [ 'planId', 'redirectCharType', - 'clickType' + 'clickType', + 'versionEnable', ], watch: { planId() { diff --git a/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue b/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue index e4b375a463..747c247cb0 100644 --- a/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue @@ -46,6 +46,7 @@ sortable> + :clickType="clickType" :review-id="reviewId" :version-enable="versionEnable" + ref="testReviewFunction"/>
@@ -35,6 +36,7 @@ import MsTestPlanHeaderBar from "@/business/components/track/plan/view/comonents import TestReviewFunction from "@/business/components/track/review/view/components/TestReviewFunction"; import TestReviewApi from "@/business/components/track/review/view/components/TestReviewApi"; import TestReviewLoad from "@/business/components/track/review/view/components/TestReviewLoad"; +import {getCurrentProjectID, hasLicense} from "@/common/js/utils"; export default { name: "TestCaseReviewView", @@ -65,6 +67,8 @@ export default { redirectCharType: '', //报表跳转过来的参数-通过哪种数据跳转的 clickType: '', + projectId: null, + versionEnable: false, } }, computed: { @@ -85,6 +89,7 @@ export default { mounted() { this.initData(); this.openTestCaseEdit(this.$route.path); + this.checkVersionEnable(); }, beforeRouteLeave(to, from, next) { if (!this.$refs.testReviewFunction) { @@ -122,6 +127,7 @@ export default { } }, initData() { + this.projectId = getCurrentProjectID(); this.getTestReviews(); this.getNodeTreeByReviewId(); }, @@ -170,7 +176,17 @@ export default { this.$nextTick(() => { this.isMenuShow = true; }); - } + }, + checkVersionEnable() { + if (!this.projectId) { + return; + } + if (hasLicense()) { + this.$get('/project/version/enable/' + this.projectId, response => { + this.versionEnable = response.data; + }); + } + }, } } diff --git a/frontend/src/business/components/track/review/view/components/TestReviewFunction.vue b/frontend/src/business/components/track/review/view/components/TestReviewFunction.vue index 8dc6f9b18e..ff872dd93a 100644 --- a/frontend/src/business/components/track/review/view/components/TestReviewFunction.vue +++ b/frontend/src/business/components/track/review/view/components/TestReviewFunction.vue @@ -30,6 +30,7 @@ :review-id="reviewId" :clickType="clickType" :current-version="currentVersion" + :version-enable="versionEnable" ref="testPlanTestCaseList"/> @@ -32,6 +34,8 @@ import MsTestPlanCommonComponent from "@/business/components/track/plan/view/com import NodeTree from "@/business/components/track/common/NodeTree"; import TestPlanLoadCaseList from "@/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList"; import TestCaseLoadRelevance from "@/business/components/track/plan/view/comonents/load/TestCaseLoadRelevance"; +import {hasLicense} from "@/common/js/utils"; + export default { name: "TestReviewLoad", components: { @@ -46,7 +50,9 @@ export default { selectNodeIds: [], selectParentNodes: [], selectProjectId: "", + projectId: null, treeNodes: [], + versionEnable: false, } }, props: [ @@ -61,6 +67,7 @@ export default { }, mounted() { this.initData(); + this.checkVersionEnable(); }, methods: { refresh() { @@ -90,6 +97,16 @@ export default { }); } }, + checkVersionEnable() { + if (!this.projectId) { + return; + } + if (hasLicense()) { + this.$get('/project/version/enable/' + this.projectId, response => { + this.versionEnable = response.data; + }); + } + }, } } diff --git a/frontend/src/business/components/track/review/view/components/TestReviewTestCaseList.vue b/frontend/src/business/components/track/review/view/components/TestReviewTestCaseList.vue index a70226bf1f..2732e0a9f1 100644 --- a/frontend/src/business/components/track/review/view/components/TestReviewTestCaseList.vue +++ b/frontend/src/business/components/track/review/view/components/TestReviewTestCaseList.vue @@ -16,7 +16,6 @@ @refresh="initTableData"/> -