From 5d9cf69916c806eaf3ba2bc6a6280550f0eaccff Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Thu, 21 Jan 2021 17:43:02 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=9C=BA=E6=99=AF=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E7=BC=96=E8=BE=91=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ApiAutomationController.java | 6 + .../automation/SaveApiScenarioRequest.java | 13 +++ .../api/service/ApiAutomationService.java | 48 +++++++- .../service/TestPlanScenarioCaseService.java | 12 ++ .../automation/scenario/ApiScenarioList.vue | 110 ++++++++++++++++-- .../api/test/components/jar/JarConfig.vue | 3 +- .../track/case/components/BatchEdit.vue | 17 ++- 7 files changed, 192 insertions(+), 17 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java index b460a2c9e0..c23f768f05 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java @@ -101,6 +101,12 @@ public class ApiAutomationController { return apiAutomationService.run(request); } + @PostMapping("/batch/edit") + @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) + public void bathEdit(@RequestBody SaveApiScenarioRequest request) { + apiAutomationService.bathEdit(request); + } + @PostMapping("/getReference") public ReferenceDTO getReference(@RequestBody ApiScenarioRequest request) { return apiAutomationService.getReference(request); diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/SaveApiScenarioRequest.java b/backend/src/main/java/io/metersphere/api/dto/automation/SaveApiScenarioRequest.java index 92f8843220..1f73ee1804 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/SaveApiScenarioRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/SaveApiScenarioRequest.java @@ -19,6 +19,8 @@ public class SaveApiScenarioRequest { private String apiScenarioModuleId; + private String environmentId; + private String modulePath; private String name; @@ -40,4 +42,15 @@ public class SaveApiScenarioRequest { private MsTestElement scenarioDefinition; List bodyUploadIds; + + private List scenarioIds; + + private boolean isSelectAllDate; + + private List filters; + + private List moduleIds; + + private List unSelectIds; + } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java index 3b990d587a..2c3c25b5e6 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -24,10 +24,7 @@ import io.metersphere.base.mapper.ext.ExtTestPlanMapper; import io.metersphere.base.mapper.ext.ExtTestPlanScenarioCaseMapper; import io.metersphere.commons.constants.*; import io.metersphere.commons.exception.MSException; -import io.metersphere.commons.utils.DateUtils; -import io.metersphere.commons.utils.LogUtil; -import io.metersphere.commons.utils.ServiceUtils; -import io.metersphere.commons.utils.SessionUtils; +import io.metersphere.commons.utils.*; import io.metersphere.i18n.Translator; import io.metersphere.job.sechedule.ApiScenarioTestJob; import io.metersphere.service.ScheduleService; @@ -35,6 +32,7 @@ import io.metersphere.track.dto.TestPlanDTO; import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest; import io.metersphere.track.request.testcase.QueryTestPlanRequest; import io.metersphere.track.request.testplan.FileOperationRequest; +import io.metersphere.track.service.TestPlanScenarioCaseService; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.session.ExecutorType; @@ -45,6 +43,7 @@ import org.apache.jorphan.collections.ListedHashTree; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -81,6 +80,9 @@ public class ApiAutomationService { SqlSessionFactory sqlSessionFactory; @Resource private ApiScenarioReportMapper apiScenarioReportMapper; + @Resource + @Lazy + private TestPlanScenarioCaseService testPlanScenarioCaseService; public List list(ApiScenarioRequest request) { request = this.initRequest(request,true,true); @@ -199,6 +201,7 @@ public class ApiAutomationService { public void delete(String id) { //及连删除外键表 this.preDelete(id); + testPlanScenarioCaseService.deleteByScenarioId(id); apiScenarioMapper.deleteByPrimaryKey(id); } @@ -589,6 +592,12 @@ public class ApiAutomationService { return apiScenarioMapper.selectByExample(example); } + public List selectByIdsWithBLOBs(List ids) { + ApiScenarioExample example = new ApiScenarioExample(); + example.createCriteria().andIdIn(ids); + return apiScenarioMapper.selectByExampleWithBLOBs(example); + } + public void createSchedule(Schedule request) { Schedule schedule = scheduleService.buildApiTestSchedule(request); schedule.setJob(ApiScenarioTestJob.class.getName()); @@ -641,4 +650,35 @@ public class ApiAutomationService { dto.setXml(jmx); return dto; } + + public void bathEdit(SaveApiScenarioRequest request) { + if (request.isSelectAllDate()) { + request.setScenarioIds(this.getAllScenarioIdsByFontedSelect( + request.getModuleIds(), request.getName(), request.getProjectId(), request.getFilters(), request.getUnSelectIds())); + } + if (StringUtils.isNotBlank(request.getEnvironmentId())) { + bathEditEnv(request); + return; + } + ApiScenarioExample apiScenarioExample = new ApiScenarioExample(); + apiScenarioExample.createCriteria().andIdIn(request.getScenarioIds()); + ApiScenarioWithBLOBs apiScenarioWithBLOBs = new ApiScenarioWithBLOBs(); + BeanUtils.copyBean(apiScenarioWithBLOBs, request); + apiScenarioWithBLOBs.setUpdateTime(System.currentTimeMillis()); + apiScenarioMapper.updateByExampleSelective( + apiScenarioWithBLOBs, + apiScenarioExample); + } + + public void bathEditEnv(SaveApiScenarioRequest request) { + if (StringUtils.isNotBlank(request.getEnvironmentId())) { + List apiScenarios = selectByIdsWithBLOBs(request.getScenarioIds()); + apiScenarios.forEach(item -> { + JSONObject object = JSONObject.parseObject(item.getScenarioDefinition()); + object.put("environmentId", request.getEnvironmentId()); + item.setScenarioDefinition(JSONObject.toJSONString(object)); + apiScenarioMapper.updateByPrimaryKeySelective(item); + }); + } + } } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java index 683fe4cee1..e4a081ea73 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java @@ -120,4 +120,16 @@ public class TestPlanScenarioCaseService { request.setPlanId(planId); deleteApiCaseBath(request); } + + public void bathDeleteByScenarioIds(List ids) { + TestPlanApiScenarioExample example = new TestPlanApiScenarioExample(); + example.createCriteria().andApiScenarioIdIn(ids); + testPlanApiScenarioMapper.deleteByExample(example); + } + + public void deleteByScenarioId(String id) { + TestPlanApiScenarioExample example = new TestPlanApiScenarioExample(); + example.createCriteria().andApiScenarioIdEqualTo(id); + testPlanApiScenarioMapper.deleteByExample(example); + } } diff --git a/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue b/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue index c781436248..7d66476206 100644 --- a/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue +++ b/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue @@ -102,6 +102,12 @@ + + + + @@ -120,10 +126,15 @@ import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton"; import PriorityTableItem from "../../../track/common/tableItems/planview/PriorityTableItem"; import PlanStatusTableItem from "../../../track/common/tableItems/plan/PlanStatusTableItem"; + import BatchEdit from "../../../track/case/components/BatchEdit"; + import {WORKSPACE_ID} from "../../../../../common/js/constants"; + import EnvironmentSelect from "../../definition/components/environment/EnvironmentSelect"; export default { name: "MsApiScenarioList", components: { + EnvironmentSelect, + BatchEdit, PlanStatusTableItem, PriorityTableItem, MsTableSelectAll, @@ -176,13 +187,42 @@ buttons: [ { name: this.$t('api_test.automation.batch_add_plan'), handleClick: this.handleBatchAddCase - }, { + }, + { + name: this.$t('test_track.case.batch_edit_case'), handleClick: this.handleBatchEdit + }, + { name: this.$t('api_test.automation.batch_execute'), handleClick: this.handleBatchExecute - } + }, + + // { + // name: this.$t('test_track.case.batch_move_case'), handleClick: this.handleBatchMove + // } ], isSelectAllDate: false, unSelection: [], selectDataCounts: 0, + typeArr: [ + {id: 'level', name: this.$t('test_track.case.priority')}, + {id: 'status', name: this.$t('test_track.plan.plan_status')}, + {id: 'principal', name: this.$t('api_test.definition.request.responsible'), optionMethod: this.getPrincipalOptions}, + {id: 'environmentId', name: this.$t('api_test.definition.request.run_env'), optionMethod: this.getEnvsOptions}, + ], + valueArr: { + level: [ + {name: 'P0', id: 'P0'}, + {name: 'P1', id: 'P1'}, + {name: 'P2', id: 'P2'}, + {name: 'P3', id: 'P3'} + ], + status: [ + {name: this.$t('test_track.plan.plan_status_prepare'), id: 'Prepare'}, + {name: this.$t('test_track.plan.plan_status_running'), id: 'Underway'}, + {name: this.$t('test_track.plan.plan_status_completed'), id: 'Completed'} + ], + principal: [], + environmentId: [] + }, } }, created() { @@ -279,6 +319,57 @@ handleBatchAddCase() { this.planVisible = true; }, + handleDeleteBatch() { + this.$alert(this.$t('test_track.case.delete_confirm') + "?", '', { + confirmButtonText: this.$t('commons.confirm'), + callback: (action) => { + if (action === 'confirm') { + let ids = Array.from(this.selectRows).map(row => row.id); + this.$post('/test/case/batch/delete', {ids: ids}, () => { + this.selectRows.clear(); + this.$emit("refresh"); + this.$success(this.$t('commons.delete_success')); + // 发送广播,刷新 head 上的最新列表 + }); + } + } + }); + }, + handleBatchEdit() { + this.$refs.batchEdit.open(this.selectDataCounts); + }, + handleBatchMove() { + this.$emit("batchMove", Array.from(this.selectRows).map(row => row.id)); + }, + batchEdit(form) { + let arr = this.selection; + let ids = this.selection; + let param = {}; + param[form.type] = form.value; + this.buildBatchParam(param); + this.$post('/api/automation/batch/edit', param, () => { + this.$success(this.$t('commons.save_success')); + this.search(); + }); + }, + getPrincipalOptions(option) { + let workspaceId = localStorage.getItem(WORKSPACE_ID); + this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => { + option.push(...response.data); + }); + }, + getEnvsOptions(option) { + this.$get('/api/environment/list/' + this.projectId, response => { + option.push(...response.data); + option.forEach(environment => { + if (!(environment.config instanceof Object)) { + environment.config = JSON.parse(environment.config); + } + environment.name = environment.name + (environment.config.httpConfig.socket ? + (': ' + environment.config.httpConfig.protocol + '://' + environment.config.httpConfig.socket) : ''); + }); + }); + }, addTestPlan(plans) { let obj = {planIds: plans, scenarioIds: this.selection}; @@ -316,18 +407,19 @@ }); } }, + buildBatchParam(param) { + param.scenarioIds = this.selection; + param.projectId = getCurrentProjectID(); + param.selectAllDate = this.isSelectAllDate; + param.unSelectIds = this.unSelection; + param = Object.assign(param, this.condition); + }, handleBatchExecute() { this.infoDb = false; let url = "/api/automation/run/batch"; let run = {}; - let scenarioIds = this.selection; run.id = getUUID(); - run.scenarioIds = scenarioIds; - run.projectId = getCurrentProjectID(); - run.selectAllDate = this.isSelectAllDate; - run.unSelectIds = this.unSelection; - - run = Object.assign(run, this.condition); + this.buildBatchParam(run); this.$post(url, run, response => { let data = response.data; this.runVisible = false; diff --git a/frontend/src/business/components/api/test/components/jar/JarConfig.vue b/frontend/src/business/components/api/test/components/jar/JarConfig.vue index 657a4e772b..3380217048 100644 --- a/frontend/src/business/components/api/test/components/jar/JarConfig.vue +++ b/frontend/src/business/components/api/test/components/jar/JarConfig.vue @@ -9,13 +9,12 @@