diff --git a/backend/src/main/java/io/metersphere/base/mapper/TestCaseMapper.java b/backend/src/main/java/io/metersphere/base/mapper/TestCaseMapper.java index b543e87a27..dfd93796ff 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/TestCaseMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/TestCaseMapper.java @@ -4,6 +4,8 @@ import io.metersphere.base.domain.TestCase; import io.metersphere.base.domain.TestCaseExample; import io.metersphere.base.domain.TestCaseWithBLOBs; import java.util.List; + +import io.metersphere.controller.request.BaseQueryRequest; import org.apache.ibatis.annotations.Param; public interface TestCaseMapper { @@ -34,4 +36,6 @@ public interface TestCaseMapper { int updateByPrimaryKeyWithBLOBs(TestCaseWithBLOBs record); int updateByPrimaryKey(TestCase record); -} \ No newline at end of file + + List selectIdsByQuery(BaseQueryRequest query); +} diff --git a/backend/src/main/java/io/metersphere/base/mapper/TestCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/TestCaseMapper.xml index 4c7c1e56e1..5d0e459524 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/TestCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/TestCaseMapper.xml @@ -94,8 +94,8 @@ - id, node_id, node_path, project_id, `name`, `type`, maintainer, priority, `method`, - create_time, update_time, test_id, sort, num, other_test_name, review_status, tags, + id, node_id, node_path, project_id, `name`, `type`, maintainer, priority, `method`, + create_time, update_time, test_id, sort, num, other_test_name, review_status, tags, demand_id, demand_name, follow_people, `status`, custom_num, step_model, create_user @@ -132,7 +132,7 @@ - + + update test_case @@ -683,4 +686,4 @@ create_user = #{createUser,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR} - \ No newline at end of file + 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 eaa5285860..564c058723 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 @@ -90,4 +90,6 @@ public interface ExtTestCaseMapper { List getTestCaseByIds(@Param("ids")List ids); void updateTestCaseCustomNumByProjectId(@Param("projectId") String projectId); + + List selectRelateIdsByQuery(@Param("request") BaseQueryRequest query); } 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 03b91c2d3b..d056d5264a 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 @@ -116,8 +116,9 @@ + diff --git a/backend/src/main/java/io/metersphere/track/request/testcase/PlanCaseRelevanceRequest.java b/backend/src/main/java/io/metersphere/track/request/testcase/PlanCaseRelevanceRequest.java index adc3db14a3..ad61bf65d6 100644 --- a/backend/src/main/java/io/metersphere/track/request/testcase/PlanCaseRelevanceRequest.java +++ b/backend/src/main/java/io/metersphere/track/request/testcase/PlanCaseRelevanceRequest.java @@ -14,6 +14,8 @@ public class PlanCaseRelevanceRequest { */ private String planId; + private List ids; + /** * 当选择关联全部用例时把加载条件送到后台,从后台查询 */ diff --git a/backend/src/main/java/io/metersphere/track/request/testcase/QueryTestCaseRequest.java b/backend/src/main/java/io/metersphere/track/request/testcase/QueryTestCaseRequest.java index 93230b9558..33e791b26d 100644 --- a/backend/src/main/java/io/metersphere/track/request/testcase/QueryTestCaseRequest.java +++ b/backend/src/main/java/io/metersphere/track/request/testcase/QueryTestCaseRequest.java @@ -1,13 +1,10 @@ package io.metersphere.track.request.testcase; -import io.metersphere.base.domain.TestCase; import io.metersphere.controller.request.BaseQueryRequest; -import io.metersphere.controller.request.OrderRequest; import lombok.Getter; import lombok.Setter; import java.util.List; -import java.util.Map; @Getter @Setter diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java index b0dbdac8c8..bbdfbeccd5 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -444,46 +444,33 @@ public class TestPlanService { public void testPlanRelevance(PlanCaseRelevanceRequest request) { - List testCaseIds = request.getTestCaseIds(); + ServiceUtils.getSelectAllIds(request, request.getRequest(), + (query) -> extTestCaseMapper.selectRelateIdsByQuery(query)); + + List testCaseIds = request.getIds(); if (testCaseIds.isEmpty()) { return; } - // 如果是关联全部指令则根据条件查询未关联的案例 - if (testCaseIds.get(0).equals("all")) { - List testCases = extTestCaseMapper.getTestCaseByNotInPlan(request.getRequest()); - if (!testCases.isEmpty()) { - testCaseIds = testCases.stream().map(testCase -> testCase.getId()).collect(Collectors.toList()); - } - } TestCaseExample testCaseExample = new TestCaseExample(); testCaseExample.createCriteria().andIdIn(testCaseIds); - Map testCaseMap = - testCaseMapper.selectByExampleWithBLOBs(testCaseExample) - .stream() - .collect(Collectors.toMap(TestCase::getId, testcase -> testcase)); - SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); TestPlanTestCaseMapper batchMapper = sqlSession.getMapper(TestPlanTestCaseMapper.class); - if (!testCaseIds.isEmpty()) { - testCaseIds.forEach(caseId -> { - TestCaseWithBLOBs testCase = testCaseMap.get(caseId); - TestPlanTestCaseWithBLOBs testPlanTestCase = new TestPlanTestCaseWithBLOBs(); - testPlanTestCase.setId(UUID.randomUUID().toString()); - testPlanTestCase.setCreateUser(SessionUtils.getUserId()); - testPlanTestCase.setExecutor(SessionUtils.getUser().getId()); - testPlanTestCase.setCaseId(caseId); - testPlanTestCase.setCreateTime(System.currentTimeMillis()); - testPlanTestCase.setUpdateTime(System.currentTimeMillis()); - testPlanTestCase.setPlanId(request.getPlanId()); - testPlanTestCase.setStatus(TestPlanStatus.Prepare.name()); - testPlanTestCase.setResults(testCase.getSteps()); - batchMapper.insert(testPlanTestCase); - }); - } + testCaseIds.forEach(caseId -> { + TestPlanTestCaseWithBLOBs testPlanTestCase = new TestPlanTestCaseWithBLOBs(); + testPlanTestCase.setId(UUID.randomUUID().toString()); + testPlanTestCase.setCreateUser(SessionUtils.getUserId()); + testPlanTestCase.setExecutor(SessionUtils.getUser().getId()); + testPlanTestCase.setCaseId(caseId); + testPlanTestCase.setCreateTime(System.currentTimeMillis()); + testPlanTestCase.setUpdateTime(System.currentTimeMillis()); + testPlanTestCase.setPlanId(request.getPlanId()); + testPlanTestCase.setStatus(TestPlanStatus.Prepare.name()); + batchMapper.insert(testPlanTestCase); + }); sqlSession.flushStatements(); //同步添加关联的接口和测试用例 @@ -548,11 +535,8 @@ public class TestPlanService { if (testPlanApiScenarioMapper.countByExample(example) <= 0) { testPlanApiScenarioMapper.insert(t); } - } }); - - }); } } diff --git a/frontend/src/business/components/common/components/table/MsTable.vue b/frontend/src/business/components/common/components/table/MsTable.vue index 394ab9dae4..582bc04131 100644 --- a/frontend/src/business/components/common/components/table/MsTable.vue +++ b/frontend/src/business/components/common/components/table/MsTable.vue @@ -77,6 +77,7 @@ export default { return { selectDataCounts: 0, selectRows: new Set(), + selectIds: [] }; }, props: { @@ -159,11 +160,6 @@ export default { this.selectDataCounts = 0; }, }, - computed: { - selectIds() { - return Array.from(this.selectRows).map(o => o.id); - } - }, methods: { openCustomHeader() { this.$emit("openCustomHeader"); @@ -177,6 +173,7 @@ export default { _handleSelect(this, selection, row, this.selectRows); setUnSelectIds(this.data, this.condition, this.selectRows); this.selectDataCounts = getSelectDataCounts(this.condition, this.total, this.selectRows); + this.selectIds = Array.from(this.selectRows).map(o => o.id); }, isSelectDataAll(data) { this.condition.selectAll = data; @@ -235,23 +232,24 @@ export default { this.$emit('pageChange'); }, clear() { - this.selectRows.clear(); - this.selectDataCounts = 0; + this.clearSelectRows(); }, checkTableRowIsSelect() { checkTableRowIsSelect(this, this.condition, this.data, this.$refs.table, this.selectRows); }, clearSelection() { - this.selectRows = new Set(); - if (this.$refs.table) { - this.$refs.table.clearSelection(); - } + this.clearSelectRows(); }, getSelectRows() { return this.selectRows; }, clearSelectRows() { - this.selectRows = new Set(); + this.selectRows.clear(); + this.selectIds = []; + this.selectDataCounts = 0; + if (this.$refs.table) { + this.$refs.table.clearSelection(); + } }, } }; diff --git a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseEdit.vue b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseEdit.vue index 5ea15945ef..4bfc185fc7 100644 --- a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseEdit.vue +++ b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseEdit.vue @@ -337,7 +337,11 @@ export default { this.result = this.$get('/test/plan/case/get/' + testCase.id, response => { let item = {}; Object.assign(item, response.data); - item.results = JSON.parse(item.results); + if (item.results) { + item.results = JSON.parse(item.results); + } else { + item.results = [item.steps.length]; + } if (item.issues) { item.issues = JSON.parse(item.issues); } else { diff --git a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue index 57d1d9f713..b37d66b978 100644 --- a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue @@ -83,23 +83,8 @@ - - - - + :key="index"> - + - - + + + + - - - - + + + sortable + :label="$t('test_track.case.priority')"> - - - - - + -
{{ $t('test_track.review_view.last_page') }}
-
共 {{ total }} 条
+ + + + + + + + + + + + + + + @@ -76,15 +94,21 @@ import TypeTableItem from "../../../../common/tableItems/planview/TypeTableItem" import MsTableSearchBar from "../../../../../common/components/MsTableSearchBar"; import MsTableAdvSearchBar from "../../../../../common/components/search/MsTableAdvSearchBar"; import MsTableHeader from "../../../../../common/components/MsTableHeader"; -import {TEST_CASE_CONFIGS} from "../../../../../common/components/search/search-components"; -import elTableInfiniteScroll from 'el-table-infinite-scroll'; import TestCaseRelevanceBase from "../base/TestCaseRelevanceBase"; -import {_filter} from "@/common/js/tableUtils"; +import {buildPagePath, getPageDate, getPageInfo} from "@/common/js/tableUtils"; +import MsTableColumn from "@/business/components/common/components/table/Ms-table-column"; +import MsTable from "@/business/components/common/components/table/MsTable"; +import MsTablePagination from "@/business/components/common/pagination/TablePagination"; +import MsTag from "@/business/components/common/components/MsTag"; export default { name: "TestCaseFunctionalRelevance", components: { + MsTag, + MsTablePagination, + MsTable, + MsTableColumn, TestCaseRelevanceBase, NodeTree, PriorityTableItem, @@ -93,212 +117,138 @@ export default { MsTableAdvSearchBar, MsTableHeader, }, - directives: { - 'el-table-infinite-scroll': elTableInfiniteScroll + data() { + return { + result: {}, + treeNodes: [], + selectNodeIds: [], + selectNodeNames: [], + projectId: '', + projectName: '', + projects: [], + page: getPageInfo(), + customNum: false, + priorityFilters: [ + {text: 'P0', value: 'P0'}, + {text: 'P1', value: 'P1'}, + {text: 'P2', value: 'P2'}, + {text: 'P3', value: 'P3'} + ] + }; + }, + props: { + planId: { + type: String + } + }, + watch: { + planId() { + this.page.condition.planId = this.planId; }, - data() { - return { - result: {}, - isCheckAll: false, - testCases: [], - selectIds: new Set(), - treeNodes: [], - selectNodeIds: [], - selectNodeNames: [], - projectId: '', - projectName: '', - projects: [], - pageSize: 50, - currentPage: 1, - total: 0, - lineStatus: true, - condition: { - components: TEST_CASE_CONFIGS - }, - priorityFilters: [ - {text: 'P0', value: 'P0'}, - {text: 'P1', value: 'P1'}, - {text: 'P2', value: 'P2'}, - {text: 'P3', value: 'P3'} - ], - typeFilters: [ - {text: this.$t('commons.functional'), value: 'functional'}, - {text: this.$t('commons.performance'), value: 'performance'}, - {text: this.$t('commons.api'), value: 'api'} - ] - }; + selectNodeIds() { + this.search(); }, - props: { - planId: { - type: String + projectId() { + this.page.condition.projectId = this.projectId; + this.getProjectNode(); + this.search(); + this.getProject(); + } + }, + methods: { + open() { + this.$refs.baseRelevance.open(); + if (this.$refs.table) { + this.$refs.table.clear(); } }, - watch: { - planId() { - this.condition.planId = this.planId; - }, - selectNodeIds() { - this.search(); - }, - projectId() { - this.condition.projectId = this.projectId; - this.getProjectNode(); - this.search(); - } + setProject(projectId) { + this.projectId = projectId; }, - updated() { - this.toggleSelection(this.testCases); - }, - methods: { - - open() { - this.$refs.baseRelevance.open(); - }, - - setProject(projectId) { - this.projectId = projectId; - }, - - saveCaseRelevance(item) { - let param = {}; - param.planId = this.planId; - param.testCaseIds = [...this.selectIds]; - param.request = this.condition; - param.checked = item - // 选择全选则全部加入到评审,无论是否加载完全部 - if (this.testCases.length === param.testCaseIds.length) { - param.testCaseIds = ['all']; + getProject() { + this.$get("/project/get/" + this.projectId, result => { + let data = result.data; + if (data) { + this.customNum = data.customNum; } - this.result = this.$post('/test/plan/relevance', param, () => { - this.selectIds.clear(); - this.$success(this.$t('commons.save_success')); - - this.$refs.baseRelevance.close(); - - this.$emit('refresh'); + }) + }, + saveCaseRelevance(item) { + let param = {}; + param.planId = this.planId; + param.ids = this.$refs.table.selectIds; + param.request = this.page.condition; + param.checked = item + this.result = this.$post('/test/plan/relevance', param, () => { + this.$success(this.$t('commons.save_success')); + this.$refs.baseRelevance.close(); + this.$emit('refresh'); + }); + }, + search() { + this.getTestCases(); + }, + getTestCases() { + let condition = this.page.condition; + if (this.planId) { + condition.planId = this.planId; + } + if (this.selectNodeIds && this.selectNodeIds.length > 0) { + condition.nodeIds = this.selectNodeIds; + } else { + condition.nodeIds = []; + } + if (this.projectId) { + condition.projectId = this.projectId; + this.page.result = this.$post(buildPagePath('/test/case/relate', this.page), condition, response => { + getPageDate(response, this.page); + let data = this.page.data; + data.forEach(item => { + item.checked = false; + item.tags = JSON.parse(item.tags); + }); }); - }, - buildPagePath(path) { - return path + "/" + this.currentPage + "/" + this.pageSize; - }, - search() { - this.currentPage = 1; - this.testCases = []; - this.getTestCases(true); - }, - getTestCases(flag) { - if (this.planId) { - this.condition.planId = this.planId; - } - if (this.selectNodeIds && this.selectNodeIds.length > 0) { - this.condition.nodeIds = this.selectNodeIds; - } else { - this.condition.nodeIds = []; - } - if (this.projectId) { - this.condition.projectId = this.projectId; - this.result = this.$post(this.buildPagePath('/test/case/relate'), this.condition, response => { - let data = response.data; - this.total = data.itemCount; - let tableData = data.listObject; - tableData.forEach(item => { - item.checked = false; - }); - flag ? this.testCases = tableData : this.testCases = this.testCases.concat(tableData); - // 去重处理 - let hash = {}; - this.testCases = this.testCases.reduce((item, next) => { - if (!hash[next.id]) { - hash[next.id] = true - item.push(next) - } - return item - }, []) - - this.lineStatus = tableData.length === 50 && this.testCases.length < this.total; - }); - } - }, - handleSelectAll(selection) { - if (selection.length > 0) { - this.testCases.forEach(item => { - this.selectIds.add(item.id); - }); - } else { - this.testCases.forEach(item => { - if (this.selectIds.has(item.id)) { - this.selectIds.delete(item.id); - } - }); - } - }, - handleSelectionChange(selection, row) { - if (this.selectIds.has(row.id)) { - this.selectIds.delete(row.id); - } else { - this.selectIds.add(row.id); - } - }, - nodeChange(node, nodeIds, nodeNames) { - this.selectNodeIds = nodeIds; - this.selectNodeNames = nodeNames; - }, - refresh() { - this.close(); - }, - scrollLoading() { - if (this.lineStatus) { - this.currentPage += 1; - this.getTestCases(); - } - }, - getAllNodeTreeByPlanId() { - if (this.planId) { - let param = { - testPlanId: this.planId, - projectId: this.projectId - }; - this.result = this.$post("/case/node/list/all/plan", param, response => { - this.treeNodes = response.data; - }); - } - }, - close() { - this.lineStatus = false; - this.selectIds.clear(); - this.selectNodeIds = []; - this.selectNodeNames = []; - }, - filter(filters) { - _filter(filters, this.condition); - this.search(); - }, - toggleSelection(rows) { - rows.forEach(row => { - this.selectIds.forEach(id => { - if (row.id === id) { - // true 是为选中 - this.$refs.table.toggleRowSelection(row, true) - } - }) - }) - }, - getProjectNode(projectId) { - const index = this.projects.findIndex(project => project.id === projectId); - if (index !== -1) { - this.projectName = this.projects[index].name; - } - if (projectId) { - this.projectId = projectId; - } - this.$refs.nodeTree.result = this.$post("/case/node/list/all/plan", - {testPlanId: this.planId, projectId: this.projectId}, response => { - this.treeNodes = response.data; - }); - this.selectNodeIds = []; } + }, + nodeChange(node, nodeIds, nodeNames) { + this.selectNodeIds = nodeIds; + this.selectNodeNames = nodeNames; + }, + refresh() { + this.close(); + }, + getAllNodeTreeByPlanId() { + if (this.planId) { + let param = { + testPlanId: this.planId, + projectId: this.projectId + }; + this.result = this.$post("/case/node/list/all/plan", param, response => { + this.treeNodes = response.data; + }); + } + }, + close() { + this.selectNodeIds = []; + this.selectNodeNames = []; + this.$refs.table.clear(); + }, + getProjectNode(projectId) { + const index = this.projects.findIndex(project => project.id === projectId); + if (index !== -1) { + this.projectName = this.projects[index].name; + } + if (projectId) { + this.projectId = projectId; + } + this.$refs.nodeTree.result = this.$post("/case/node/list/all/plan", + {testPlanId: this.planId, projectId: this.projectId}, response => { + this.treeNodes = response.data; + }); + this.selectNodeIds = []; } } +}