diff --git a/backend/framework/sdk/src/main/resources/i18n/plan.properties b/backend/framework/sdk/src/main/resources/i18n/plan.properties index 4c125264d3..7bcde51042 100644 --- a/backend/framework/sdk/src/main/resources/i18n/plan.properties +++ b/backend/framework/sdk/src/main/resources/i18n/plan.properties @@ -94,4 +94,5 @@ test_plan_report_name.not_blank=测试计划报告名称不能为空 test_plan_not_exist=测试计划不存在 test_plan.report_id.not_blank=测试计划报告ID不能为空 test_plan.report.share_id.not_blank=测试计划报告分享ID不能为空 -no_plan_to_archive=没有可归档的计划/计划组 \ No newline at end of file +no_plan_to_archive=没有可归档的计划/计划组 +test_plan.is.archived=测试计划已归档 \ No newline at end of file diff --git a/backend/framework/sdk/src/main/resources/i18n/plan_en_US.properties b/backend/framework/sdk/src/main/resources/i18n/plan_en_US.properties index 94c370bc90..0b05a35c5a 100644 --- a/backend/framework/sdk/src/main/resources/i18n/plan_en_US.properties +++ b/backend/framework/sdk/src/main/resources/i18n/plan_en_US.properties @@ -106,4 +106,5 @@ run_functional_case=Run functional case test_plan_not_exist=The test plan does not exist test_plan.report_id.not_blank=The test plan report ID cannot be empty test_plan.report.share_id.not_blank=The test plan report share ID cannot be empty -no_plan_to_archive=No plans/plan groups to archive \ No newline at end of file +no_plan_to_archive=No plans/plan groups to archive +test_plan.is.archived=Test plan has been archived \ No newline at end of file diff --git a/backend/framework/sdk/src/main/resources/i18n/plan_zh_CN.properties b/backend/framework/sdk/src/main/resources/i18n/plan_zh_CN.properties index db79209a0e..d1248873bf 100644 --- a/backend/framework/sdk/src/main/resources/i18n/plan_zh_CN.properties +++ b/backend/framework/sdk/src/main/resources/i18n/plan_zh_CN.properties @@ -106,4 +106,5 @@ run_functional_case=执行功能用例 test_plan_not_exist=测试计划不存在 test_plan.report_id.not_blank=测试计划报告ID不能为空 test_plan.report.share_id.not_blank=测试计划报告分享ID不能为空 -no_plan_to_archive=没有可归档的计划/计划组 \ No newline at end of file +no_plan_to_archive=没有可归档的计划/计划组 +test_plan.is.archived=测试计划已归档 \ No newline at end of file diff --git a/backend/framework/sdk/src/main/resources/i18n/plan_zh_TW.properties b/backend/framework/sdk/src/main/resources/i18n/plan_zh_TW.properties index caca09659f..8141b279aa 100644 --- a/backend/framework/sdk/src/main/resources/i18n/plan_zh_TW.properties +++ b/backend/framework/sdk/src/main/resources/i18n/plan_zh_TW.properties @@ -106,4 +106,5 @@ run_functional_case=執行功能用例 test_plan_not_exist=測試計劃不存在 test_plan.report_id.not_blank=測試計劃報告ID不能爲空 test_plan.report.share_id.not_blank=測試計劃報告分享ID不能爲空 -no_plan_to_archive=沒有可歸檔的計劃/計劃組 \ No newline at end of file +no_plan_to_archive=沒有可歸檔的計劃/計劃組 +test_plan.is.archived=測試計劃已歸檔 \ No newline at end of file diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanController.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanController.java index c96957a1cf..b459997d4b 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanController.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanController.java @@ -140,6 +140,7 @@ public class TestPlanController { @CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project") public void delete(@Validated @RequestBody TestPlanBatchProcessRequest request) throws Exception { testPlanManagementService.checkModuleIsOpen(request.getProjectId(), TestPlanResourceConfig.CHECK_TYPE_PROJECT, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN)); + testPlanService.filterArchivedIds(request); testPlanService.batchDelete(request, SessionUtils.getUserId(), "/test-plan/batch-delete", HttpMethodConstants.POST.name()); } @@ -149,6 +150,7 @@ public class TestPlanController { @CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project") public void batchCopy(@Validated @RequestBody TestPlanBatchRequest request) { testPlanManagementService.checkModuleIsOpen(request.getProjectId(), TestPlanResourceConfig.CHECK_TYPE_PROJECT, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN)); + testPlanService.filterArchivedIds(request); testPlanService.batchCopy(request, SessionUtils.getUserId(), "/test-plan/batch-copy", HttpMethodConstants.POST.name()); } @@ -158,6 +160,7 @@ public class TestPlanController { @CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project") public void batchMove(@Validated @RequestBody TestPlanBatchRequest request) { testPlanManagementService.checkModuleIsOpen(request.getProjectId(), TestPlanResourceConfig.CHECK_TYPE_PROJECT, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN)); + testPlanService.filterArchivedIds(request); testPlanService.batchMove(request, SessionUtils.getUserId(), "/test-plan/batch-move", HttpMethodConstants.POST.name()); } @@ -176,6 +179,7 @@ public class TestPlanController { @CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan") public void association(@Validated @RequestBody TestPlanAssociationRequest request) { testPlanManagementService.checkModuleIsOpen(request.getTestPlanId(), TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN_FUNCTIONAL_CASE)); + testPlanService.checkTestPlanNotArchived(request.getTestPlanId()); testPlanService.association(request); } @@ -186,6 +190,7 @@ public class TestPlanController { @Log(type = OperationLogType.UPDATE, expression = "#msClass.batchEditLog(#request)", msClass = TestPlanLogService.class) public void batchEdit(@Validated @RequestBody TestPlanBatchEditRequest request) { testPlanManagementService.checkModuleIsOpen(request.getProjectId(), TestPlanResourceConfig.CHECK_TYPE_PROJECT, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN)); + testPlanService.filterArchivedIds(request); testPlanService.batchEdit(request, SessionUtils.getUserId()); } } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java index 3870684ed8..2d3252b5ef 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java @@ -38,4 +38,6 @@ public interface ExtTestPlanMapper { void batchUpdate(@Param("testPlan") TestPlan testPlan, @Param("ids") List ids); List selectIdByProjectId(String projectId); + + List selectNotArchivedIds(@Param("ids") List selectIds); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml index 2022fb5307..8ac1b8ee31 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml @@ -392,6 +392,13 @@ FROM test_plan WHERE project_id = #{0} + diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java index 2b6b6b2df5..51d47400c1 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java @@ -39,6 +39,8 @@ import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.stream.Collectors; +import static io.metersphere.sdk.constants.TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED; + @Service @Transactional(rollbackFor = Exception.class) public class TestPlanService extends TestPlanBaseUtilsService { @@ -104,7 +106,6 @@ public class TestPlanService extends TestPlanBaseUtilsService { private TestPlan savePlanDTO(TestPlanCreateRequest createOrCopyRequest, String operator, String id) { //检查模块的合法性 checkModule(createOrCopyRequest.getModuleId()); - TestPlan createTestPlan = new TestPlan(); BeanUtils.copyBean(createTestPlan, createOrCopyRequest); // 5.21,查询需求文档、测试用例:测试计划名称允许重复 @@ -148,6 +149,7 @@ public class TestPlanService extends TestPlanBaseUtilsService { * @param requestMethod */ public void delete(String id, String operator, String requestUrl, String requestMethod) { + this.checkTestPlanNotArchived(id); TestPlan testPlan = testPlanMapper.selectByPrimaryKey(id); if (StringUtils.equals(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) { // 计划组的删除暂时预留 @@ -287,6 +289,7 @@ public class TestPlanService extends TestPlanBaseUtilsService { * @return */ public TestPlan update(TestPlanUpdateRequest request, String userId, String requestUrl, String requestMethod) { + this.checkTestPlanNotArchived(request.getId()); TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getId()); if (!ObjectUtils.allNull(request.getName(), request.getModuleId(), request.getTags(), request.getPlannedEndTime(), request.getPlannedStartTime(), request.getDescription(), request.getTestPlanGroupId())) { TestPlan updateTestPlan = new TestPlan(); @@ -358,9 +361,9 @@ public class TestPlanService extends TestPlanBaseUtilsService { if (StringUtils.equalsAnyIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) { //测试计划组归档 updateGroupStatus(testPlan.getId(), userId); - } else { + } else if (StringUtils.equals(testPlan.getStatus(), TestPlanConstants.TEST_PLAN_STATUS_COMPLETED)) { //测试计划 - testPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED); + testPlan.setStatus(TEST_PLAN_STATUS_ARCHIVED); testPlan.setUpdateUser(userId); testPlan.setUpdateTime(System.currentTimeMillis()); testPlanMapper.updateByPrimaryKeySelective(testPlan); @@ -378,7 +381,7 @@ public class TestPlanService extends TestPlanBaseUtilsService { List batchArchivedIds = request.getSelectIds(); if (CollectionUtils.isNotEmpty(batchArchivedIds)) { TestPlanExample example = new TestPlanExample(); - example.createCriteria().andIdIn(batchArchivedIds); + example.createCriteria().andIdIn(batchArchivedIds).andStatusEqualTo(TestPlanConstants.TEST_PLAN_STATUS_COMPLETED); List archivedPlanList = testPlanMapper.selectByExample(example); Map> plans = archivedPlanList.stream().collect(Collectors.groupingBy(TestPlan::getType)); testPlanBatchArchivedService.batchArchived(plans, request, currentUser); @@ -404,7 +407,7 @@ public class TestPlanService extends TestPlanBaseUtilsService { if (CollectionUtils.isEmpty(ids)) { throw new MSException(Translator.get("test_plan.group.not_plan")); } - extTestPlanMapper.batchUpdateStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED, userId, System.currentTimeMillis(), ids); + extTestPlanMapper.batchUpdateStatus(TEST_PLAN_STATUS_ARCHIVED, userId, System.currentTimeMillis(), ids); } /** @@ -664,4 +667,19 @@ public class TestPlanService extends TestPlanBaseUtilsService { this.deleteByList(testPlanIdList); }); } + + // 过滤掉已归档的测试计划 + public void filterArchivedIds(TestPlanBatchProcessRequest request) { + if (CollectionUtils.isNotEmpty(request.getSelectIds())) { + request.setSelectIds(extTestPlanMapper.selectNotArchivedIds(request.getSelectIds())); + } + } + + public void checkTestPlanNotArchived(String testPlanId) { + TestPlanExample example = new TestPlanExample(); + example.createCriteria().andIdEqualTo(testPlanId).andStatusEqualTo(TEST_PLAN_STATUS_ARCHIVED); + if (testPlanMapper.countByExample(example) > 0) { + throw new MSException(Translator.get("test_plan.is.archived")); + } + } } diff --git a/frontend/src/views/api-test/management/components/moduleTree.vue b/frontend/src/views/api-test/management/components/moduleTree.vue index 6611a289c7..e9f1f22737 100644 --- a/frontend/src/views/api-test/management/components/moduleTree.vue +++ b/frontend/src/views/api-test/management/components/moduleTree.vue @@ -102,7 +102,7 @@ class="mb-[16px]" allow-clear /> - +