Merge remote-tracking branch 'origin/master'

This commit is contained in:
song.tianyang 2021-01-21 18:36:21 +08:00
commit 683d538b4b
22 changed files with 377 additions and 62 deletions

View File

@ -101,6 +101,12 @@ public class ApiAutomationController {
return apiAutomationService.run(request); 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") @PostMapping("/getReference")
public ReferenceDTO getReference(@RequestBody ApiScenarioRequest request) { public ReferenceDTO getReference(@RequestBody ApiScenarioRequest request) {
return apiAutomationService.getReference(request); return apiAutomationService.getReference(request);

View File

@ -19,6 +19,8 @@ public class SaveApiScenarioRequest {
private String apiScenarioModuleId; private String apiScenarioModuleId;
private String environmentId;
private String modulePath; private String modulePath;
private String name; private String name;
@ -40,4 +42,15 @@ public class SaveApiScenarioRequest {
private MsTestElement scenarioDefinition; private MsTestElement scenarioDefinition;
List<String> bodyUploadIds; List<String> bodyUploadIds;
private List<String> scenarioIds;
private boolean isSelectAllDate;
private List<String> filters;
private List<String> moduleIds;
private List<String> unSelectIds;
} }

View File

@ -3,6 +3,7 @@ package io.metersphere.api.dto.scenario;
import io.metersphere.api.dto.scenario.request.BodyFile; import io.metersphere.api.dto.scenario.request.BodyFile;
import io.metersphere.commons.json.JSONSchemaGenerator; import io.metersphere.commons.json.JSONSchemaGenerator;
import lombok.Data; import lombok.Data;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy; import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
import org.apache.jmeter.protocol.http.util.HTTPFileArg; import org.apache.jmeter.protocol.http.util.HTTPFileArg;
@ -81,12 +82,16 @@ public class Body {
private HTTPFileArg[] httpFileArgs(String requestId) { private HTTPFileArg[] httpFileArgs(String requestId) {
List<HTTPFileArg> list = new ArrayList<>(); List<HTTPFileArg> list = new ArrayList<>();
this.getKvs().stream().filter(KeyValue::isFile).filter(KeyValue::isEnable).forEach(keyValue -> { if (CollectionUtils.isNotEmpty(this.getKvs())) {
setFileArg(list, keyValue.getFiles(), keyValue, requestId); this.getKvs().stream().filter(KeyValue::isFile).filter(KeyValue::isEnable).forEach(keyValue -> {
}); setFileArg(list, keyValue.getFiles(), keyValue, requestId);
this.getBinary().stream().filter(KeyValue::isFile).filter(KeyValue::isEnable).forEach(keyValue -> { });
setFileArg(list, keyValue.getFiles(), keyValue, requestId); }
}); if (CollectionUtils.isNotEmpty(this.getBinary())) {
this.getBinary().stream().filter(KeyValue::isFile).filter(KeyValue::isEnable).forEach(keyValue -> {
setFileArg(list, keyValue.getFiles(), keyValue, requestId);
});
}
return list.toArray(new HTTPFileArg[0]); return list.toArray(new HTTPFileArg[0]);
} }

View File

@ -24,10 +24,7 @@ import io.metersphere.base.mapper.ext.ExtTestPlanMapper;
import io.metersphere.base.mapper.ext.ExtTestPlanScenarioCaseMapper; import io.metersphere.base.mapper.ext.ExtTestPlanScenarioCaseMapper;
import io.metersphere.commons.constants.*; import io.metersphere.commons.constants.*;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.DateUtils; import io.metersphere.commons.utils.*;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
import io.metersphere.job.sechedule.ApiScenarioTestJob; import io.metersphere.job.sechedule.ApiScenarioTestJob;
import io.metersphere.service.ScheduleService; 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.ApiCaseRelevanceRequest;
import io.metersphere.track.request.testcase.QueryTestPlanRequest; import io.metersphere.track.request.testcase.QueryTestPlanRequest;
import io.metersphere.track.request.testplan.FileOperationRequest; import io.metersphere.track.request.testplan.FileOperationRequest;
import io.metersphere.track.service.TestPlanScenarioCaseService;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.ExecutorType;
@ -45,6 +43,7 @@ import org.apache.jorphan.collections.ListedHashTree;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.Element; import org.dom4j.Element;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -81,6 +80,9 @@ public class ApiAutomationService {
SqlSessionFactory sqlSessionFactory; SqlSessionFactory sqlSessionFactory;
@Resource @Resource
private ApiScenarioReportMapper apiScenarioReportMapper; private ApiScenarioReportMapper apiScenarioReportMapper;
@Resource
@Lazy
private TestPlanScenarioCaseService testPlanScenarioCaseService;
public List<ApiScenarioDTO> list(ApiScenarioRequest request) { public List<ApiScenarioDTO> list(ApiScenarioRequest request) {
request = this.initRequest(request,true,true); request = this.initRequest(request,true,true);
@ -199,6 +201,7 @@ public class ApiAutomationService {
public void delete(String id) { public void delete(String id) {
//及连删除外键表 //及连删除外键表
this.preDelete(id); this.preDelete(id);
testPlanScenarioCaseService.deleteByScenarioId(id);
apiScenarioMapper.deleteByPrimaryKey(id); apiScenarioMapper.deleteByPrimaryKey(id);
} }
@ -600,6 +603,12 @@ public class ApiAutomationService {
return apiScenarioMapper.selectByExample(example); return apiScenarioMapper.selectByExample(example);
} }
public List<ApiScenarioWithBLOBs> selectByIdsWithBLOBs(List<String> ids) {
ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andIdIn(ids);
return apiScenarioMapper.selectByExampleWithBLOBs(example);
}
public void createSchedule(Schedule request) { public void createSchedule(Schedule request) {
Schedule schedule = scheduleService.buildApiTestSchedule(request); Schedule schedule = scheduleService.buildApiTestSchedule(request);
schedule.setJob(ApiScenarioTestJob.class.getName()); schedule.setJob(ApiScenarioTestJob.class.getName());
@ -652,4 +661,35 @@ public class ApiAutomationService {
dto.setXml(jmx); dto.setXml(jmx);
return dto; 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<ApiScenarioWithBLOBs> 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);
});
}
}
} }

View File

@ -18,6 +18,7 @@ import io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler;
import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler; import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler;
import io.metersphere.api.dto.definition.request.timer.MsConstantTimer; import io.metersphere.api.dto.definition.request.timer.MsConstantTimer;
import io.metersphere.api.dto.scenario.Body; import io.metersphere.api.dto.scenario.Body;
import io.metersphere.api.dto.scenario.KeyValue;
import io.metersphere.api.dto.scenario.Scenario; import io.metersphere.api.dto.scenario.Scenario;
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
import io.metersphere.api.dto.scenario.request.*; import io.metersphere.api.dto.scenario.request.*;
@ -108,12 +109,40 @@ public class HistoricalDataUpgradeService {
URL urlObject = new URL(request1.getUrl()); URL urlObject = new URL(request1.getUrl());
String envPath = StringUtils.equals(urlObject.getPath(), "/") ? "" : urlObject.getPath(); String envPath = StringUtils.equals(urlObject.getPath(), "/") ? "" : urlObject.getPath();
request1.setPath(envPath); request1.setPath(envPath);
request1.setUrl(null);
} catch (Exception ex) { } catch (Exception ex) {
LogUtil.error(ex.getMessage()); LogUtil.error(ex.getMessage());
} }
} else {
request1.setUrl(null);
} }
if (request1.getBody() != null && request1.getBody().isOldKV()) { if (request1.getBody() != null) {
request1.getBody().setType(Body.FORM_DATA); request1.getBody().setBinary(new ArrayList<>());
if (request1.getBody().isOldKV()) {
request1.getBody().setType(Body.FORM_DATA);
}
if ("json".equals(request1.getBody().getFormat())) {
request1.getBody().setType(Body.JSON);
if (CollectionUtils.isEmpty(request1.getHeaders())) {
List<KeyValue> headers = new LinkedList<>();
headers.add(new KeyValue("Content-Type", "application/json"));
request1.setHeaders(headers);
} else {
boolean isJsonType = false;
for (KeyValue keyValue : request1.getHeaders()) {
if ("Content-Type".equals(keyValue.getName())) {
isJsonType = true;
break;
}
}
if (!isJsonType) {
request1.getHeaders().add(new KeyValue("Content-Type", "application/json"));
}
}
}
if ("xml".equals(request1.getBody().getFormat())) {
request1.getBody().setType(Body.XML);
}
} }
BeanUtils.copyBean(element, request1); BeanUtils.copyBean(element, request1);
((MsHTTPSamplerProxy) element).setProtocol(RequestType.HTTP); ((MsHTTPSamplerProxy) element).setProtocol(RequestType.HTTP);
@ -292,7 +321,7 @@ public class HistoricalDataUpgradeService {
copyDir(dir, BODY_FILE_DIR); copyDir(dir, BODY_FILE_DIR);
} }
private void createApiScenarioWithBLOBs(SaveHistoricalDataUpgrade saveHistoricalDataUpgrade, Scenario oldScenario, String scenarioDefinition, ApiScenarioMapper mapper) { private void createApiScenarioWithBLOBs(SaveHistoricalDataUpgrade saveHistoricalDataUpgrade, Scenario oldScenario, String scenarioDefinition, ApiScenarioMapper mapper, int num) {
if (StringUtils.isEmpty(oldScenario.getName())) { if (StringUtils.isEmpty(oldScenario.getName())) {
oldScenario.setName("默认名称-" + DateUtils.getTimeStr(System.currentTimeMillis())); oldScenario.setName("默认名称-" + DateUtils.getTimeStr(System.currentTimeMillis()));
} }
@ -310,7 +339,6 @@ public class HistoricalDataUpgradeService {
scenario.setUpdateTime(System.currentTimeMillis()); scenario.setUpdateTime(System.currentTimeMillis());
scenario.setStatus(ScenarioStatus.Underway.name()); scenario.setStatus(ScenarioStatus.Underway.name());
scenario.setUserId(SessionUtils.getUserId()); scenario.setUserId(SessionUtils.getUserId());
scenario.setNum(getNextNum(saveHistoricalDataUpgrade.getProjectId()));
mapper.updateByPrimaryKeySelective(scenario); mapper.updateByPrimaryKeySelective(scenario);
} else { } else {
scenario = new ApiScenarioWithBLOBs(); scenario = new ApiScenarioWithBLOBs();
@ -328,7 +356,7 @@ public class HistoricalDataUpgradeService {
scenario.setUpdateTime(System.currentTimeMillis()); scenario.setUpdateTime(System.currentTimeMillis());
scenario.setStatus(ScenarioStatus.Underway.name()); scenario.setStatus(ScenarioStatus.Underway.name());
scenario.setUserId(SessionUtils.getUserId()); scenario.setUserId(SessionUtils.getUserId());
scenario.setNum(getNextNum(saveHistoricalDataUpgrade.getProjectId())); scenario.setNum(num);
mapper.insert(scenario); mapper.insert(scenario);
} }
} }
@ -342,6 +370,7 @@ public class HistoricalDataUpgradeService {
List<ApiTest> blobs = apiTestMapper.selectByExampleWithBLOBs(example); List<ApiTest> blobs = apiTestMapper.selectByExampleWithBLOBs(example);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiScenarioMapper mapper = sqlSession.getMapper(ApiScenarioMapper.class); ApiScenarioMapper mapper = sqlSession.getMapper(ApiScenarioMapper.class);
int num = getNextNum(saveHistoricalDataUpgrade.getProjectId());
for (ApiTest test : blobs) { for (ApiTest test : blobs) {
// 附件迁移 // 附件迁移
createBodyFiles(test.getId()); createBodyFiles(test.getId());
@ -352,7 +381,8 @@ public class HistoricalDataUpgradeService {
for (Scenario scenario : scenarios) { for (Scenario scenario : scenarios) {
MsScenario scenario1 = createScenario(scenario); MsScenario scenario1 = createScenario(scenario);
String scenarioDefinition = JSON.toJSONString(scenario1); String scenarioDefinition = JSON.toJSONString(scenario1);
createApiScenarioWithBLOBs(saveHistoricalDataUpgrade, scenario, scenarioDefinition, mapper); num++;
createApiScenarioWithBLOBs(saveHistoricalDataUpgrade, scenario, scenarioDefinition, mapper, num);
} }
} }
} }
@ -365,14 +395,16 @@ public class HistoricalDataUpgradeService {
environmentDTOMap = new HashMap<>(); environmentDTOMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(environments)) { if (CollectionUtils.isNotEmpty(environments)) {
environments.forEach(environment -> { environments.forEach(environment -> {
EnvironmentConfig envConfig = JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class); if (environment != null && environment.getConfig() != null) {
if (CollectionUtils.isNotEmpty(envConfig.getDatabaseConfigs())) { EnvironmentConfig envConfig = JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class);
envConfig.getDatabaseConfigs().forEach(item -> { if (CollectionUtils.isNotEmpty(envConfig.getDatabaseConfigs())) {
EnvironmentDTO dto = new EnvironmentDTO(); envConfig.getDatabaseConfigs().forEach(item -> {
dto.setDatabaseConfig(item); EnvironmentDTO dto = new EnvironmentDTO();
dto.setEnvironmentId(environment.getId()); dto.setDatabaseConfig(item);
environmentDTOMap.put(item.getId(), dto); dto.setEnvironmentId(environment.getId());
}); environmentDTOMap.put(item.getId(), dto);
});
}
} }
}); });
} }

View File

@ -125,4 +125,16 @@ public class TestPlanScenarioCaseService {
request.setPlanId(planId); request.setPlanId(planId);
deleteApiCaseBath(request); deleteApiCaseBath(request);
} }
public void bathDeleteByScenarioIds(List<String> 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);
}
} }

View File

@ -102,6 +102,12 @@
</div> </div>
</el-card> </el-card>
<batch-edit ref="batchEdit" @batchEdit="batchEdit" :typeArr="typeArr" :value-arr="valueArr" :dialog-title="$t('test_track.case.batch_edit_case')">
<template v-slot:value>
<environment-select :current-data="{}" :project-id="projectId"/>
</template>
</batch-edit>
</div> </div>
</template> </template>
@ -120,10 +126,15 @@
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton"; import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton";
import PriorityTableItem from "../../../track/common/tableItems/planview/PriorityTableItem"; import PriorityTableItem from "../../../track/common/tableItems/planview/PriorityTableItem";
import PlanStatusTableItem from "../../../track/common/tableItems/plan/PlanStatusTableItem"; 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 { export default {
name: "MsApiScenarioList", name: "MsApiScenarioList",
components: { components: {
EnvironmentSelect,
BatchEdit,
PlanStatusTableItem, PlanStatusTableItem,
PriorityTableItem, PriorityTableItem,
MsTableSelectAll, MsTableSelectAll,
@ -176,13 +187,42 @@
buttons: [ buttons: [
{ {
name: this.$t('api_test.automation.batch_add_plan'), handleClick: this.handleBatchAddCase 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('api_test.automation.batch_execute'), handleClick: this.handleBatchExecute
} },
// {
// name: this.$t('test_track.case.batch_move_case'), handleClick: this.handleBatchMove
// }
], ],
isSelectAllDate: false, isSelectAllDate: false,
unSelection: [], unSelection: [],
selectDataCounts: 0, 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() { created() {
@ -279,6 +319,57 @@
handleBatchAddCase() { handleBatchAddCase() {
this.planVisible = true; 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) { addTestPlan(plans) {
let obj = {planIds: plans, scenarioIds: this.selection}; 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() { handleBatchExecute() {
this.infoDb = false; this.infoDb = false;
let url = "/api/automation/run/batch"; let url = "/api/automation/run/batch";
let run = {}; let run = {};
let scenarioIds = this.selection;
run.id = getUUID(); run.id = getUUID();
run.scenarioIds = scenarioIds; this.buildBatchParam(run);
run.projectId = getCurrentProjectID();
run.selectAllDate = this.isSelectAllDate;
run.unSelectIds = this.unSelection;
run = Object.assign(run, this.condition);
this.$post(url, run, response => { this.$post(url, run, response => {
let data = response.data; let data = response.data;
this.runVisible = false; this.runVisible = false;

View File

@ -57,7 +57,7 @@
<!-- 添加/编辑测试窗口--> <!-- 添加/编辑测试窗口-->
<div v-else-if="item.type=== 'ADD'" class="ms-api-div"> <div v-else-if="item.type=== 'ADD'" class="ms-api-div">
<ms-api-config @runTest="runTest" @saveApi="saveApi" @createRootModel="createRootModel" ref="apiConfig" <ms-api-config :syncTabs="syncTabs" @runTest="runTest" @saveApi="saveApi" @createRootModel="createRootModel" ref="apiConfig"
:current-api="item.api" :current-api="item.api"
:currentProtocol="currentProtocol" :currentProtocol="currentProtocol"
:moduleOptions="moduleOptions"/> :moduleOptions="moduleOptions"/>
@ -76,13 +76,13 @@
<!-- 测试--> <!-- 测试-->
<div v-else-if="item.type=== 'TEST'" class="ms-api-div"> <div v-else-if="item.type=== 'TEST'" class="ms-api-div">
<ms-run-test-http-page :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi" <ms-run-test-http-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi"
@refresh="refresh" v-if="currentProtocol==='HTTP'"/> @refresh="refresh" v-if="currentProtocol==='HTTP'"/>
<ms-run-test-tcp-page :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi" <ms-run-test-tcp-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi"
@refresh="refresh" v-if="currentProtocol==='TCP'"/> @refresh="refresh" v-if="currentProtocol==='TCP'"/>
<ms-run-test-sql-page :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi" <ms-run-test-sql-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi"
@refresh="refresh" v-if="currentProtocol==='SQL'"/> @refresh="refresh" v-if="currentProtocol==='SQL'"/>
<ms-run-test-dubbo-page :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi" <ms-run-test-dubbo-page :syncTabs="syncTabs" :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi"
@refresh="refresh" v-if="currentProtocol==='DUBBO'"/> @refresh="refresh" v-if="currentProtocol==='DUBBO'"/>
</div> </div>
</el-tab-pane> </el-tab-pane>
@ -184,7 +184,8 @@
type: "list", type: "list",
closable: false closable: false
}], }],
isApiListEnable: true isApiListEnable: true,
syncTabs: [],
} }
}, },
watch: { watch: {

View File

@ -3,16 +3,16 @@
<div class="card-container"> <div class="card-container">
<!-- HTTP 请求参数 --> <!-- HTTP 请求参数 -->
<ms-edit-complete-http-api @runTest="runTest" @saveApi="saveApi" @createRootModelInTree="createRootModelInTree" :request="request" :response="response" <ms-edit-complete-http-api @runTest="runTest" @saveApi="saveApi" @createRootModelInTree="createRootModelInTree" :request="request" :response="response"
:basisData="currentApi" :moduleOptions="moduleOptions" v-if="currentProtocol === 'HTTP'"/> :basisData="currentApi" :moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'HTTP'"/>
<!-- TCP --> <!-- TCP -->
<ms-edit-complete-tcp-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi" <ms-edit-complete-tcp-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi"
:moduleOptions="moduleOptions" v-if="currentProtocol === 'TCP'"/> :moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'TCP'"/>
<!--DUBBO--> <!--DUBBO-->
<ms-edit-complete-dubbo-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi" <ms-edit-complete-dubbo-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi"
:moduleOptions="moduleOptions" v-if="currentProtocol === 'DUBBO'"/> :moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'DUBBO'"/>
<!--SQL--> <!--SQL-->
<ms-edit-complete-sql-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi" <ms-edit-complete-sql-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi"
:moduleOptions="moduleOptions" v-if="currentProtocol === 'SQL'"/> :moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'SQL'"/>
</div> </div>
</template> </template>
@ -45,6 +45,7 @@
currentApi: {}, currentApi: {},
moduleOptions: {}, moduleOptions: {},
currentProtocol: String, currentProtocol: String,
syncTabs: Array,
}, },
created() { created() {
this.projectId = getCurrentProjectID(); this.projectId = getCurrentProjectID();
@ -75,7 +76,7 @@
this.$emit('runTest', data); this.$emit('runTest', data);
}) })
}, },
createRootModelInTree(){ createRootModelInTree() {
this.$emit("createRootModel"); this.$emit("createRootModel");
}, },
getMaintainerOptions() { getMaintainerOptions() {

View File

@ -44,8 +44,30 @@
isReadOnly: { isReadOnly: {
type: Boolean, type: Boolean,
default: false default: false
},
syncTabs: Array,
},
watch: {
syncTabs() {
if (this.basisData && this.syncTabs && this.syncTabs.includes(this.basisData.id)) {
//
let url = "/api/definition/get/";
this.$get(url + this.basisData.id, response => {
if (response.data) {
let request = JSON.parse(response.data.request);
let index = this.syncTabs.findIndex(item => {
if (item === this.basisData.id) {
return true;
}
})
this.syncTabs.splice(index, 1);
Object.assign(this.request, request);
}
});
}
} }
}, },
data() { data() {
return {validated: false} return {validated: false}
}, },

View File

@ -149,7 +149,29 @@
options: API_STATUS, options: API_STATUS,
} }
}, },
props: {moduleOptions: {}, request: {}, response: {}, basisData: {}}, props: {moduleOptions: {}, request: {}, response: {}, basisData: {}, syncTabs: Array},
watch: {
syncTabs() {
if (this.basisData && this.syncTabs && this.syncTabs.includes(this.basisData.id)) {
//
let url = "/api/definition/get/";
this.$get(url + this.basisData.id, response => {
if (response.data) {
let request = JSON.parse(response.data.request);
let index = this.syncTabs.findIndex(item => {
if (item === this.basisData.id) {
return true;
}
})
this.syncTabs.splice(index, 1);
this.httpForm.path = response.data.path;
this.httpForm.method = response.data.method;
Object.assign(this.request, request);
}
});
}
}
},
methods: { methods: {
runTest() { runTest() {
this.$refs['httpForm'].validate((valid) => { this.$refs['httpForm'].validate((valid) => {

View File

@ -43,9 +43,29 @@ export default {
isReadOnly: { isReadOnly: {
type: Boolean, type: Boolean,
default: false default: false
},
syncTabs:{},
},
watch: {
syncTabs() {
if (this.basisData && this.syncTabs && this.syncTabs.includes(this.basisData.id)) {
//
let url = "/api/definition/get/";
this.$get(url + this.basisData.id, response => {
if (response.data) {
let request = JSON.parse(response.data.request);
let index = this.syncTabs.findIndex(item => {
if (item === this.basisData.id) {
return true;
}
})
this.syncTabs.splice(index, 1);
Object.assign(this.request, request);
}
});
}
} }
}, },
data() { data() {
return {validated: false} return {validated: false}
}, },

View File

@ -42,14 +42,34 @@ export default {
isReadOnly: { isReadOnly: {
type: Boolean, type: Boolean,
default: false default: false
} },
syncTabs:Array,
}, },
data() { data() {
return { return {
validated: false, validated: false,
} }
}, },
watch: {
syncTabs() {
if (this.basisData && this.syncTabs && this.syncTabs.includes(this.basisData.id)) {
//
let url = "/api/definition/get/";
this.$get(url + this.basisData.id, response => {
if (response.data) {
let request = JSON.parse(response.data.request);
let index = this.syncTabs.findIndex(item => {
if (item === this.basisData.id) {
return true;
}
})
this.syncTabs.splice(index, 1);
Object.assign(this.request, request);
}
});
}
}
},
methods: { methods: {
callback() { callback() {
this.validated = true; this.validated = true;

View File

@ -89,7 +89,7 @@
reportId: "", reportId: "",
} }
}, },
props: {apiData: {}, currentProtocol: String,}, props: {apiData: {}, currentProtocol: String,syncTabs: Array},
methods: { methods: {
handleCommand(e) { handleCommand(e) {
switch (e) { switch (e) {
@ -173,6 +173,9 @@
let bodyFiles = this.getBodyUploadFiles(); let bodyFiles = this.getBodyUploadFiles();
this.$fileUpload(url, null, bodyFiles, this.api, () => { this.$fileUpload(url, null, bodyFiles, this.api, () => {
this.$success(this.$t('commons.save_success')); this.$success(this.$t('commons.save_success'));
if (this.syncTabs.indexOf(this.api.id) === -1) {
this.syncTabs.push(this.api.id);
}
this.$emit('saveApi', this.api); this.$emit('saveApi', this.api);
}); });
}, },
@ -228,7 +231,8 @@
} }
}, },
created() { created() {
this.api = this.apiData; //
this.api = JSON.parse(JSON.stringify(this.apiData));
this.api.protocol = this.currentProtocol; this.api.protocol = this.currentProtocol;
this.currentRequest = this.api.request; this.currentRequest = this.api.request;
this.getEnvironments(); this.getEnvironments();

View File

@ -113,7 +113,7 @@
projectId: "", projectId: "",
} }
}, },
props: {apiData: {}, currentProtocol: String,}, props: {apiData: {}, currentProtocol: String, syncTabs: Array},
methods: { methods: {
handleCommand(e) { handleCommand(e) {
switch (e) { switch (e) {
@ -205,6 +205,9 @@
this.$fileUpload(url, null, bodyFiles, this.api, () => { this.$fileUpload(url, null, bodyFiles, this.api, () => {
this.$success(this.$t('commons.save_success')); this.$success(this.$t('commons.save_success'));
this.$emit('saveApi', this.api); this.$emit('saveApi', this.api);
if (this.syncTabs.indexOf(this.api.id) === -1) {
this.syncTabs.push(this.api.id);
}
}); });
}, },
selectTestCase(item) { selectTestCase(item) {
@ -230,7 +233,8 @@
}, },
created() { created() {
this.projectId = getCurrentProjectID(); this.projectId = getCurrentProjectID();
this.api = this.apiData; //
this.api = JSON.parse(JSON.stringify(this.apiData));
this.api.protocol = this.currentProtocol; this.api.protocol = this.currentProtocol;
this.currentRequest = this.api.request; this.currentRequest = this.api.request;
this.getResult(); this.getResult();

View File

@ -89,7 +89,7 @@
reportId: "", reportId: "",
} }
}, },
props: {apiData: {}, currentProtocol: String,}, props: {apiData: {}, currentProtocol: String,syncTabs: Array},
methods: { methods: {
handleCommand(e) { handleCommand(e) {
switch (e) { switch (e) {
@ -172,6 +172,9 @@
let bodyFiles = this.getBodyUploadFiles(); let bodyFiles = this.getBodyUploadFiles();
this.$fileUpload(url, null, bodyFiles, this.api, () => { this.$fileUpload(url, null, bodyFiles, this.api, () => {
this.$success(this.$t('commons.save_success')); this.$success(this.$t('commons.save_success'));
if (this.syncTabs.indexOf(this.api.id) === -1) {
this.syncTabs.push(this.api.id);
}
this.$emit('saveApi', this.api); this.$emit('saveApi', this.api);
}); });
}, },
@ -227,7 +230,8 @@
} }
}, },
created() { created() {
this.api = this.apiData; //
this.api = JSON.parse(JSON.stringify(this.apiData));
this.api.protocol = this.currentProtocol; this.api.protocol = this.currentProtocol;
this.currentRequest = this.api.request; this.currentRequest = this.api.request;
this.getEnvironments(); this.getEnvironments();

View File

@ -90,7 +90,7 @@
projectId: "" projectId: ""
} }
}, },
props: {apiData: {}, currentProtocol: String,}, props: {apiData: {}, currentProtocol: String,syncTabs: Array},
methods: { methods: {
handleCommand(e) { handleCommand(e) {
switch (e) { switch (e) {
@ -173,6 +173,9 @@
let bodyFiles = this.getBodyUploadFiles(); let bodyFiles = this.getBodyUploadFiles();
this.$fileUpload(url, null, bodyFiles, this.api, () => { this.$fileUpload(url, null, bodyFiles, this.api, () => {
this.$success(this.$t('commons.save_success')); this.$success(this.$t('commons.save_success'));
if (this.syncTabs.indexOf(this.api.id) === -1) {
this.syncTabs.push(this.api.id);
}
this.$emit('saveApi', this.api); this.$emit('saveApi', this.api);
}); });
}, },
@ -194,7 +197,8 @@
} }
}, },
created() { created() {
this.api = this.apiData; //
this.api = JSON.parse(JSON.stringify(this.apiData));
this.api.protocol = this.currentProtocol; this.api.protocol = this.currentProtocol;
this.currentRequest = this.api.request; this.currentRequest = this.api.request;
this.projectId = getCurrentProjectID(); this.projectId = getCurrentProjectID();

View File

@ -9,13 +9,12 @@
<script> <script>
import MsDialogFooter from "../../../../common/components/MsDialogFooter"; import MsDialogFooter from "../../../../common/components/MsDialogFooter";
import ApiEnvironmentConfig from "../ApiEnvironmentConfig";
import {listenGoBack, removeGoBackListener} from "../../../../../../common/js/utils"; import {listenGoBack, removeGoBackListener} from "../../../../../../common/js/utils";
import MsJarConfigList from "./JarConfigList"; import MsJarConfigList from "./JarConfigList";
import MsJarConfigFrom from "./JarConfigFrom"; import MsJarConfigFrom from "./JarConfigFrom";
export default { export default {
name: "MsJarConfig", name: "MsJarConfig",
components: {MsJarConfigFrom, MsJarConfigList, ApiEnvironmentConfig, MsDialogFooter}, components: {MsJarConfigFrom, MsJarConfigList, MsDialogFooter},
data() { data() {
return { return {
visible: false, visible: false,

View File

@ -2,7 +2,7 @@
<div id="app" v-loading="loading"> <div id="app" v-loading="loading">
<el-tabs v-model="activeName" @tab-click="handleClick"> <el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane :label="$t('organization.message.template')" name="apiTemplate"> <el-tab-pane :label="$t('organization.message.template')" name="apiTemplate">
<el-button type="primary" size="mini" style="margin-left: 10px" @click="openOneClickOperation">导入</el-button> <el-button type="primary" size="mini" style="margin: 10px 10px 0px" @click="openOneClickOperation">导入</el-button>
<div style="min-height: 200px"> <div style="min-height: 200px">
<json-schema-editor class="schema" :value="schema" lang="zh_CN" custom/> <json-schema-editor class="schema" :value="schema" lang="zh_CN" custom/>
</div> </div>

View File

@ -3,6 +3,7 @@
title="导入" title="导入"
:visible.sync="importVisible" :visible.sync="importVisible"
width="50%" width="50%"
append-to-body
show-close show-close
:close-on-click-modal="false" :close-on-click-modal="false"
@closed="handleClose"> @closed="handleClose">

View File

@ -46,7 +46,7 @@
<json-schema-editor :value="{items:pickValue.items}" :deep="deep+1" disabled isItem :root="false" class="children" :lang="lang" :custom="custom"/> <json-schema-editor :value="{items:pickValue.items}" :deep="deep+1" disabled isItem :root="false" class="children" :lang="lang" :custom="custom"/>
</template> </template>
<!-- 高级设置--> <!-- 高级设置-->
<el-dialog :close-on-click-modal="false" :title="$t('schema.adv_setting')" :visible.sync="modalVisible" :destroy-on-close="true" <el-dialog append-to-body :close-on-click-modal="false" :title="$t('schema.adv_setting')" :visible.sync="modalVisible" :destroy-on-close="true"
@close="handleClose"> @close="handleClose">
<p class="tip">基础设置 </p> <p class="tip">基础设置 </p>
<el-form :inline="true" v-model="advancedValue" class="ms-advanced-search-form"> <el-form :inline="true" v-model="advancedValue" class="ms-advanced-search-form">

View File

@ -76,9 +76,13 @@
} }
}); });
}, },
open() { open(size) {
this.dialogVisible = true; this.dialogVisible = true;
this.size = this.$parent.selectRows.size; if (size) {
this.size = size;
} else {
this.size = this.$parent.selectRows.size;
}
listenGoBack(this.handleClose); listenGoBack(this.handleClose);
}, },
handleClose() { handleClose() {
@ -90,6 +94,15 @@
this.$set(this.form, "value", ""); this.$set(this.form, "value", "");
this.filterable = val === "maintainer" || val === "executor"; this.filterable = val === "maintainer" || val === "executor";
this.options = this.valueArr[val]; this.options = this.valueArr[val];
this.typeArr.forEach(item => {
if (item.id === val) {
if (item.optionMethod) {
this.options = [];
item.optionMethod(this.options);
}
return;
}
});
} }
} }
} }