diff --git a/api-test/backend/src/main/java/io/metersphere/controller/plan/TestPlanApiCaseController.java b/api-test/backend/src/main/java/io/metersphere/controller/plan/TestPlanApiCaseController.java index 5da3252803..58869caa67 100644 --- a/api-test/backend/src/main/java/io/metersphere/controller/plan/TestPlanApiCaseController.java +++ b/api-test/backend/src/main/java/io/metersphere/controller/plan/TestPlanApiCaseController.java @@ -158,6 +158,11 @@ public class TestPlanApiCaseController { return testPlanApiCaseService.getApiCaseEnv(planId); } + @GetMapping("/get/project/ids/{planId}") + public List getApiCaseProjectIds(@PathVariable("planId") String planId) { + return testPlanApiCaseService.getApiCaseProjectIds(planId); + } + @GetMapping("/is/executing/{planId}") public Boolean isExecuting(@PathVariable("planId") String planId) { return testPlanApiCaseService.isExecuting(planId); diff --git a/api-test/backend/src/main/java/io/metersphere/controller/plan/TestPlanScenarioCaseController.java b/api-test/backend/src/main/java/io/metersphere/controller/plan/TestPlanScenarioCaseController.java index 70ae0cddbd..e0f79c2568 100644 --- a/api-test/backend/src/main/java/io/metersphere/controller/plan/TestPlanScenarioCaseController.java +++ b/api-test/backend/src/main/java/io/metersphere/controller/plan/TestPlanScenarioCaseController.java @@ -175,6 +175,11 @@ public class TestPlanScenarioCaseController { return testPlanScenarioCaseService.getApiScenarioEnv(planId); } + @GetMapping("/get/project/ids/{planId}") + public List getApiScenarioProjectIds(@PathVariable("planId") String planId) { + return testPlanScenarioCaseService.getApiScenarioProjectIds(planId); + } + @PostMapping("/plan/report") public ApiPlanReportDTO buildApiReport(@RequestBody ApiPlanReportRequest request) { return testPlanScenarioCaseService.buildApiReport(request); diff --git a/api-test/backend/src/main/java/io/metersphere/service/plan/TestPlanApiCaseService.java b/api-test/backend/src/main/java/io/metersphere/service/plan/TestPlanApiCaseService.java index e18a091aa1..4d726e1f00 100644 --- a/api-test/backend/src/main/java/io/metersphere/service/plan/TestPlanApiCaseService.java +++ b/api-test/backend/src/main/java/io/metersphere/service/plan/TestPlanApiCaseService.java @@ -817,4 +817,18 @@ public class TestPlanApiCaseService { List results = apiDefinitionExecResultMapper.selectByExampleWithBLOBs(example); return results; } + + public List getApiCaseProjectIds(String planId) { + TestPlanApiCaseExample caseExample = new TestPlanApiCaseExample(); + caseExample.createCriteria().andTestPlanIdEqualTo(planId); + List testPlanApiCases = testPlanApiCaseMapper.selectByExample(caseExample); + List apiCaseIds = testPlanApiCases.stream().map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(apiCaseIds)) { + return new ArrayList<>(); + } + ApiTestCaseExample example = new ApiTestCaseExample(); + example.createCriteria().andIdIn(apiCaseIds); + List apiTestCases = apiTestCaseMapper.selectByExample(example); + return apiTestCases.stream().map(ApiTestCase::getProjectId).collect(Collectors.toList()); + } } diff --git a/api-test/backend/src/main/java/io/metersphere/service/plan/TestPlanScenarioCaseService.java b/api-test/backend/src/main/java/io/metersphere/service/plan/TestPlanScenarioCaseService.java index f412017812..673eac2f64 100644 --- a/api-test/backend/src/main/java/io/metersphere/service/plan/TestPlanScenarioCaseService.java +++ b/api-test/backend/src/main/java/io/metersphere/service/plan/TestPlanScenarioCaseService.java @@ -1245,4 +1245,18 @@ public class TestPlanScenarioCaseService { public String selectProjectId(String testPlanId) { return extTestPlanScenarioCaseMapper.selectProjectId(testPlanId); } + + public List getApiScenarioProjectIds(String planId) { + TestPlanApiScenarioExample scenarioExample = new TestPlanApiScenarioExample(); + scenarioExample.createCriteria().andTestPlanIdEqualTo(planId); + List testPlanApiScenarios = testPlanApiScenarioMapper.selectByExample(scenarioExample); + List scenarioIds = testPlanApiScenarios.stream().map(TestPlanApiScenario::getApiScenarioId).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(scenarioIds)) { + return new ArrayList<>(); + } + ApiScenarioExample example = new ApiScenarioExample(); + example.createCriteria().andIdIn(scenarioIds); + List apiScenarios = apiScenarioMapper.selectByExample(example); + return apiScenarios.stream().map(ApiScenario::getProjectId).collect(Collectors.toList()); + } } diff --git a/project-management/frontend/src/business/menu/file/edit/EditFileMetadata.vue b/project-management/frontend/src/business/menu/file/edit/EditFileMetadata.vue index d47de77e62..49d16e3ac5 100644 --- a/project-management/frontend/src/business/menu/file/edit/EditFileMetadata.vue +++ b/project-management/frontend/src/business/menu/file/edit/EditFileMetadata.vue @@ -121,11 +121,7 @@ :label="$t('api_test.automation.tag')" prop="tags" > - + { + this.$emit("getProjectFiles"); + this.showPanel = "baseInfo"; + this.visible = false; + }); }, open(data, size, page, t) { this.showPanel = "baseInfo"; diff --git a/project-management/frontend/src/business/menu/file/list/FileMetadataList.vue b/project-management/frontend/src/business/menu/file/list/FileMetadataList.vue index c52ed686f3..b9fae12be0 100644 --- a/project-management/frontend/src/business/menu/file/list/FileMetadataList.vue +++ b/project-management/frontend/src/business/menu/file/list/FileMetadataList.vue @@ -1,15 +1,21 @@ @@ -175,8 +212,11 @@ import MsTablePagination from "metersphere-frontend/src/components/pagination/TablePagination"; import MsTableButton from "metersphere-frontend/src/components/MsTableButton"; import MsDialogFooter from "metersphere-frontend/src/components/MsDialogFooter"; -import {getCurrentProjectID, getCurrentUserId} from "metersphere-frontend/src/utils/token"; -import {operationConfirm} from "metersphere-frontend/src/utils"; +import { + getCurrentProjectID, + getCurrentUserId, +} from "metersphere-frontend/src/utils/token"; +import { operationConfirm } from "metersphere-frontend/src/utils"; import MsTableOperatorButton from "metersphere-frontend/src/components/MsTableOperatorButton"; import MsTableHeader from "../header/FileHeader"; import MsContainer from "metersphere-frontend/src/components/MsContainer"; @@ -195,7 +235,7 @@ import { downloadFileZip, downloadMetaData, getAllTypeFileMeta, - getFileMetaPages + getFileMetaPages, } from "../../../../api/file"; export default { @@ -221,7 +261,7 @@ export default { nodeTree: Array, moduleType: { type: String, - default: 'module', + default: "module", }, }, data() { @@ -237,23 +277,23 @@ export default { metadataArr: [], condition: {}, projectId: getCurrentProjectID(), - height: 'calc(100vh - 160px)', + height: "calc(100vh - 160px)", typeFilters: [], buttons: [ { - name: this.$t('file_manage.batch_delete'), + name: this.$t("file_manage.batch_delete"), handleClick: this.handleDeleteBatch, - permissions: ['PROJECT_FILE:READ+BATCH+DELETE'] + permissions: ["PROJECT_FILE:READ+BATCH+DELETE"], }, { - name: this.$t('file_manage.batch_download'), + name: this.$t("file_manage.batch_download"), handleClick: this.exportZip, - permissions: ['PROJECT_FILE:READ+BATCH+DOWNLOAD'] + permissions: ["PROJECT_FILE:READ+BATCH+DOWNLOAD"], }, { - name: this.$t('file_manage.batch_move'), + name: this.$t("file_manage.batch_move"), handleClick: this.handleBatchMove, - permissions: ['PROJECT_FILE:READ+BATCH+MOVE'] + permissions: ["PROJECT_FILE:READ+BATCH+MOVE"], }, ], showView: "list", @@ -273,7 +313,7 @@ export default { this.showView = value; }, refreshModule() { - this.$emit('refreshModule'); + this.$emit("refreshModule"); }, refreshList() { this.$emit("refreshList"); @@ -289,7 +329,7 @@ export default { }, myFile() { if (!this.condition.filters) { - this.condition.filters = {createUser: [getCurrentUserId()]}; + this.condition.filters = { createUser: [getCurrentUserId()] }; } else { this.condition.filters.createUser = [getCurrentUserId()]; } @@ -297,11 +337,16 @@ export default { this.getProjectFiles(); }, getProjectFiles() { - this.tableLoading = getFileMetaPages(this.projectId, this.currentPage, this.pageSize, this.condition).then(res => { + this.tableLoading = getFileMetaPages( + this.projectId, + this.currentPage, + this.pageSize, + this.condition + ).then((res) => { let data = res.data; this.total = data.itemCount; this.metadataArr = data.listObject; - this.metadataArr.forEach(item => { + this.metadataArr.forEach((item) => { if (item.tags && item.tags.length > 0) { item.tags = JSON.parse(item.tags); } @@ -322,7 +367,7 @@ export default { return false; } if (file.size / 1024 / 1024 > 500) { - this.$warning(this.$t('api_test.request.body_upload_limit_size')); + this.$warning(this.$t("api_test.request.body_upload_limit_size")); return false; } return true; @@ -333,26 +378,31 @@ export default { createUser: getCurrentUserId(), updateUser: getCurrentUserId(), projectId: this.projectId, - moduleId: this.moduleId + moduleId: this.moduleId, }; this.cardLoading = createFileMeta(file, request).then(() => { - this.$success(this.$t('commons.save_success')); + this.$success(this.$t("commons.save_success")); this.getProjectFiles(); this.refreshModule(); }); }, handleExceed() { - this.$error(this.$t('load_test.file_size_limit')); + this.$error(this.$t("load_test.file_size_limit")); }, handleView(row) { - this.$refs.editFileMetadata.open(row, this.pageSize, this.currentPage, this.total); + this.$refs.editFileMetadata.open( + row, + this.pageSize, + this.currentPage, + this.total + ); }, getTagToolTips(tags) { try { let showTips = ""; - tags.forEach(item => { + tags.forEach((item) => { showTips += item + ","; - }) + }); return showTips.substr(0, showTips.length - 1); } catch (e) { return ""; @@ -378,54 +428,64 @@ export default { }, exportZip() { let array = []; - this.$refs.table.selectRows.forEach(item => { + this.$refs.table.selectRows.forEach((item) => { let request = JSON.parse(JSON.stringify(item)); request.tags = ""; array.push(request); - }) - let request = {projectId: getCurrentProjectID, requests: array}; + }); + let request = { projectId: getCurrentProjectID, requests: array }; downloadFileZip(request); // this.$fileDownloadPost("/file/metadata/download/zip", request, "文件集.zip"); }, handleDeleteBatch() { - operationConfirm(this, this.$t('project.file_delete_tip', [this.$refs.table.selectIds.length + " 条 "]), () => { - batchDeleteMetaData(this.$refs.table.selectIds).then(() => { - this.$refs.table.clear(); - this.$success(this.$t('commons.delete_success')); - this.getProjectFiles(); - this.refreshModule(); - }) - }); + operationConfirm( + this, + this.$t("project.file_delete_tip", [ + this.$refs.table.selectIds.length + " 条 ", + ]), + () => { + batchDeleteMetaData(this.$refs.table.selectIds).then(() => { + this.$refs.table.clear(); + this.$success(this.$t("commons.delete_success")); + this.getProjectFiles(); + this.refreshModule(); + }); + } + ); }, handleDelete(row) { if (row && row.confirm) { deleteFileMetaById(row.id).then(() => { - this.$success(this.$t('commons.delete_success')); + this.$success(this.$t("commons.delete_success")); this.getProjectFiles(); this.refreshModule(); }); return; } - operationConfirm(this, this.$t('project.file_delete_tip', [row.name]), () => { - deleteFileMetaById(row.id).then(() => { - this.$success(this.$t('commons.delete_success')); - this.getProjectFiles(); - this.refreshModule(); - }); - }); + operationConfirm( + this, + this.$t("project.file_delete_tip", [row.name]), + () => { + deleteFileMetaById(row.id).then(() => { + this.$success(this.$t("commons.delete_success")); + this.getProjectFiles(); + this.refreshModule(); + }); + } + ); }, getTypes() { this.typeFilters = []; - getAllTypeFileMeta().then(res => { - res.data.forEach(item => { - this.typeFilters.push({text: item, value: item}); - }) + getAllTypeFileMeta().then((res) => { + res.data.forEach((item) => { + this.typeFilters.push({ text: item, value: item }); + }); }); }, moduleChange(ids) { if (!this.condition.filters) { - this.condition.filters = {moduleIds: ids}; + this.condition.filters = { moduleIds: ids }; } else { this.condition.filters.moduleIds = ids; } @@ -437,8 +497,8 @@ export default { }, moveSave(param) { // this.buildBatchParam(param); - } - } + }, + }, }; diff --git a/test-track/backend/src/main/java/io/metersphere/controller/TestPlanController.java b/test-track/backend/src/main/java/io/metersphere/controller/TestPlanController.java index 2a03aea7c8..e549627258 100644 --- a/test-track/backend/src/main/java/io/metersphere/controller/TestPlanController.java +++ b/test-track/backend/src/main/java/io/metersphere/controller/TestPlanController.java @@ -227,6 +227,11 @@ public class TestPlanController { return testPlanService.getPlanCaseEnv(plan.getId()); } + @PostMapping("/case/relevance/project/ids") + public List getRelevanceProjectIds(@RequestBody TestPlan plan) { + return testPlanService.getRelevanceProjectIds(plan.getId()); + } + @PostMapping("/edit/run/config") public void updateRunModeConfig(@RequestBody TestPlanRunRequest testplanRunRequest) { diff --git a/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanService.java b/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanService.java index 01e4cbc553..e31861e574 100644 --- a/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanService.java +++ b/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanService.java @@ -2059,7 +2059,7 @@ public class TestPlanService { } if (serviceIdSet.contains(MicroServiceName.UI_TEST)) { List apiDefinitionLists = planTestPlanUiScenarioCaseService.selectExtForPlanReport(reportId); - if(CollectionUtils.isNotEmpty(apiDefinitionLists)){ + if (CollectionUtils.isNotEmpty(apiDefinitionLists)) { UiScenarioReportWithBLOBs apiDefinition = apiDefinitionLists.get(0); convertEnvConfig(apiDefinition.getEnvConfig(), testPlanExtReportDTO); getResourcePool(apiDefinition.getActuator(), testPlanExtReportDTO); @@ -2068,4 +2068,17 @@ public class TestPlanService { } return testPlanExtReportDTO; } + + public List getRelevanceProjectIds(String planId) { + List projectIds = new ArrayList<>(); + List apiCaseProjectIds = planTestPlanApiCaseService.getApiCaseProjectIds(planId); + List apiScenarioProjectIds = planTestPlanScenarioCaseService.getApiScenarioProjectIds(planId); + if (DiscoveryUtil.hasService(MicroServiceName.UI_TEST)) { + List uiScenarioProjectIds = planTestPlanUiScenarioCaseService.getUiScenarioProjectIds(planId); + projectIds.addAll(uiScenarioProjectIds); + } + projectIds.addAll(apiCaseProjectIds); + projectIds.addAll(apiScenarioProjectIds); + return projectIds.stream().distinct().collect(Collectors.toList()); + } } diff --git a/test-track/backend/src/main/java/io/metersphere/plan/service/remote/api/PlanTestPlanApiCaseService.java b/test-track/backend/src/main/java/io/metersphere/plan/service/remote/api/PlanTestPlanApiCaseService.java index 90e593e214..0ce57537bf 100644 --- a/test-track/backend/src/main/java/io/metersphere/plan/service/remote/api/PlanTestPlanApiCaseService.java +++ b/test-track/backend/src/main/java/io/metersphere/plan/service/remote/api/PlanTestPlanApiCaseService.java @@ -131,6 +131,10 @@ public class PlanTestPlanApiCaseService extends ApiTestService { return (Map>) microService.getForData(serviceName, BASE_UEL + "/get/env/" + planId); } + public List getApiCaseProjectIds(String planId) { + return (List) microService.getForData(serviceName, BASE_UEL + "/get/project/ids/" + planId); + } + public Boolean isCaseExecuting(String planId) { return (Boolean) microService.getForData(serviceName, BASE_UEL + "/is/executing/" + planId); } diff --git a/test-track/backend/src/main/java/io/metersphere/plan/service/remote/api/PlanTestPlanScenarioCaseService.java b/test-track/backend/src/main/java/io/metersphere/plan/service/remote/api/PlanTestPlanScenarioCaseService.java index 1e9b4e6f19..e9344fd0e8 100644 --- a/test-track/backend/src/main/java/io/metersphere/plan/service/remote/api/PlanTestPlanScenarioCaseService.java +++ b/test-track/backend/src/main/java/io/metersphere/plan/service/remote/api/PlanTestPlanScenarioCaseService.java @@ -143,6 +143,10 @@ public class PlanTestPlanScenarioCaseService extends ApiTestService { return microService.getForData(serviceName, BASE_UEL + "/get/env/" + planId, Map.class); } + public List getApiScenarioProjectIds(String planId) { + return microService.getForData(serviceName, BASE_UEL + "/get/project/ids/" + planId, List.class); + } + public ApiPlanReportDTO getApiReport(ApiPlanReportRequest request) { return microService.postForData(serviceName, BASE_UEL + "/plan/report", request, ApiPlanReportDTO.class); } diff --git a/test-track/backend/src/main/java/io/metersphere/plan/service/remote/ui/PlanTestPlanUiScenarioCaseService.java b/test-track/backend/src/main/java/io/metersphere/plan/service/remote/ui/PlanTestPlanUiScenarioCaseService.java index bbd04cbbfd..a4cf43759e 100644 --- a/test-track/backend/src/main/java/io/metersphere/plan/service/remote/ui/PlanTestPlanUiScenarioCaseService.java +++ b/test-track/backend/src/main/java/io/metersphere/plan/service/remote/ui/PlanTestPlanUiScenarioCaseService.java @@ -157,4 +157,8 @@ public class PlanTestPlanUiScenarioCaseService extends UiTestService { public Map> getUiScenarioEnv(String planId) { return microService.getForData(serviceName, BASE_URL + "/get/env/" + planId, Map.class); } + + public List getUiScenarioProjectIds(String planId) { + return microService.getForData(serviceName, BASE_URL + "/get/project/ids/" + planId, List.class); + } } diff --git a/test-track/backend/src/main/java/io/metersphere/service/IssuesService.java b/test-track/backend/src/main/java/io/metersphere/service/IssuesService.java index 5e93dd1c5f..34024fd15b 100644 --- a/test-track/backend/src/main/java/io/metersphere/service/IssuesService.java +++ b/test-track/backend/src/main/java/io/metersphere/service/IssuesService.java @@ -1081,21 +1081,25 @@ public class IssuesService { private void deleteSyncAttachment(AttachmentModuleRelationMapper batchAttachmentModuleRelationMapper, Set jiraAttachmentSet, List allMsAttachments) { - // 删除Jira中不存在的附件 - if (CollectionUtils.isNotEmpty(allMsAttachments)) { - List deleteMsAttachments = allMsAttachments.stream() - .filter(msAttachment -> !jiraAttachmentSet.contains(msAttachment.getName())) - .collect(Collectors.toList()); - deleteMsAttachments.forEach(fileAttachmentMetadata -> { - List ids = List.of(fileAttachmentMetadata.getId()); - AttachmentModuleRelationExample example = new AttachmentModuleRelationExample(); - example.createCriteria().andAttachmentIdIn(ids).andRelationTypeEqualTo(AttachmentType.ISSUE.type()); - // 删除MS附件及关联数据 - attachmentService.deleteAttachmentByIds(ids); - attachmentService.deleteFileAttachmentByIds(ids); - batchAttachmentModuleRelationMapper.deleteByExample(example); - }); - } + try { + // 删除Jira中不存在的附件 + if (CollectionUtils.isNotEmpty(allMsAttachments)) { + List deleteMsAttachments = allMsAttachments.stream() + .filter(msAttachment -> !jiraAttachmentSet.contains(msAttachment.getName())) + .collect(Collectors.toList()); + deleteMsAttachments.forEach(fileAttachmentMetadata -> { + List ids = List.of(fileAttachmentMetadata.getId()); + AttachmentModuleRelationExample example = new AttachmentModuleRelationExample(); + example.createCriteria().andAttachmentIdIn(ids).andRelationTypeEqualTo(AttachmentType.ISSUE.type()); + // 删除MS附件及关联数据 + attachmentService.deleteAttachmentByIds(ids); + attachmentService.deleteFileAttachmentByIds(ids); + batchAttachmentModuleRelationMapper.deleteByExample(example); + }); + } + } catch (Exception e) { + LogUtil.error(e); + } } private void saveAttachmentModuleRelation(Platform platform, String issueId, @@ -1871,7 +1875,9 @@ public class IssuesService { xpackIssueService.syncThirdPartyIssues(project, syncRequest); - syncAllPluginIssueAttachment(project, syncRequest); + if (platformPluginService.isPluginPlatform(project.getPlatform())) { + syncAllPluginIssueAttachment(project, syncRequest); + } } catch (Exception e) { LogUtil.error(e); MSException.throwException(e); diff --git a/test-track/frontend/src/api/remote/plan/test-plan.js b/test-track/frontend/src/api/remote/plan/test-plan.js index bd663bd004..ed209ce08e 100644 --- a/test-track/frontend/src/api/remote/plan/test-plan.js +++ b/test-track/frontend/src/api/remote/plan/test-plan.js @@ -289,12 +289,16 @@ export function updateSchedule(param){ return post(BASE_URL + 'schedule/update',param); } -export function getApiScenarioEnv(param){ - return post(BASE_URL + 'api/scenario/env',param); +export function getApiScenarioEnv(param) { + return post(BASE_URL + 'api/scenario/env', param); } -export function getPlanCaseEnv(param){ - return post(BASE_URL + 'case/env',param); +export function getPlanCaseEnv(param) { + return post(BASE_URL + 'case/env', param); +} + +export function getPlanCaseProjectIds(param) { + return post(BASE_URL + 'case/relevance/project/ids', param); } export function run(testId, reportId) { diff --git a/test-track/frontend/src/business/plan/common/TestPlanRunModeWithEnv.vue b/test-track/frontend/src/business/plan/common/TestPlanRunModeWithEnv.vue index b4d40a763a..eee3536ba5 100644 --- a/test-track/frontend/src/business/plan/common/TestPlanRunModeWithEnv.vue +++ b/test-track/frontend/src/business/plan/common/TestPlanRunModeWithEnv.vue @@ -200,7 +200,7 @@ import {getCurrentProjectID, getOwnerProjects} from "@/business/utils/sdk-utils" import {getQuotaValidResourcePools} from "@/api/remote/resource-pool"; import EnvGroupPopover from "@/business/plan/env/EnvGroupPopover"; import {getApiCaseEnv} from "@/api/remote/plan/test-plan-api-case"; -import {getApiScenarioEnv, getPlanCaseEnv} from "@/api/remote/plan/test-plan"; +import {getApiScenarioEnv, getPlanCaseEnv, getPlanCaseProjectIds} from "@/api/remote/plan/test-plan"; import EnvGroupWithOption from "../env/EnvGroupWithOption"; import EnvironmentGroup from "@/business/plan/env/EnvironmentGroupList"; import EnvSelectPopover from "@/business/plan/env/EnvSelectPopover"; @@ -402,9 +402,23 @@ export default { this.projectIds.add(d); } } - this.$refs.envSelectPopover.open(); + if (this.projectIds.size === 0) { + param = {id: this.planId}; + getPlanCaseProjectIds(param).then((res) => { + let data = res.data; + if (data) { + for (let i = 0; i < data.length; i++) { + this.projectIds.add(data[i]); + } + } + this.$refs.envSelectPopover.open(); + }); + } else { + this.$refs.envSelectPopover.open(); + } }); } + }, handleCommand(command) { if (