parent
4a12fd797b
commit
8e49e466a5
|
@ -64,7 +64,6 @@ public class ApiAutomationController {
|
|||
public void update(@RequestPart("request") SaveApiScenarioRequest request, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
|
||||
apiAutomationService.update(request, bodyFiles);
|
||||
}
|
||||
|
||||
@GetMapping("/delete/{id}")
|
||||
public void delete(@PathVariable String id) {
|
||||
apiAutomationService.delete(id);
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.metersphere.api.dto.definition.request.ScheduleInfoSwaggerUrlRequest;
|
|||
import io.metersphere.api.dto.swaggerurl.SwaggerTaskResult;
|
||||
import io.metersphere.api.dto.swaggerurl.SwaggerUrlRequest;
|
||||
import io.metersphere.api.service.ApiDefinitionService;
|
||||
import io.metersphere.api.service.EsbApiParamService;
|
||||
import io.metersphere.base.domain.ApiDefinition;
|
||||
import io.metersphere.base.domain.Schedule;
|
||||
import io.metersphere.commons.constants.RoleConstants;
|
||||
|
@ -24,6 +25,7 @@ import io.metersphere.controller.request.ScheduleRequest;
|
|||
import io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.service.ScheduleService;
|
||||
import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -45,6 +47,8 @@ public class ApiDefinitionController {
|
|||
private ApiDefinitionService apiDefinitionService;
|
||||
@Resource
|
||||
private CheckPermissionService checkPermissionService;
|
||||
@Resource
|
||||
private EsbApiParamService esbApiParamService;
|
||||
|
||||
@PostMapping("/list/{goPage}/{pageSize}")
|
||||
public Pager<List<ApiDefinitionResult>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody ApiDefinitionRequest request) {
|
||||
|
@ -97,6 +101,15 @@ public class ApiDefinitionController {
|
|||
apiDefinitionService.deleteBatch(ids);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/updateEsbRequest")
|
||||
public SaveApiDefinitionRequest updateEsbRequest(@RequestBody SaveApiDefinitionRequest request) {
|
||||
if(StringUtils.equals(request.getMethod(),"ESB")){
|
||||
//ESB的接口类型数据,采用TCP方式去发送。并将方法类型改为TCP。 并修改发送数据
|
||||
request = esbApiParamService.updateEsbRequest(request);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
@PostMapping("/deleteBatchByParams")
|
||||
public void deleteBatchByParams(@RequestBody ApiBatchRequest request) {
|
||||
apiDefinitionService.deleteByParams(request);
|
||||
|
|
|
@ -145,7 +145,9 @@ public class ApiTestCaseService {
|
|||
}
|
||||
|
||||
public ApiTestCaseWithBLOBs get(String id) {
|
||||
return apiTestCaseMapper.selectByPrimaryKey(id);
|
||||
ApiTestCaseWithBLOBs returnBlobs = apiTestCaseMapper.selectByPrimaryKey(id);
|
||||
esbApiParamService.handleApiEsbParams(returnBlobs);
|
||||
return returnBlobs;
|
||||
}
|
||||
|
||||
public ApiTestCase create(SaveApiTestCaseRequest request, List<MultipartFile> bodyFiles) {
|
||||
|
@ -435,6 +437,9 @@ public class ApiTestCaseService {
|
|||
|
||||
public Map<String, String> getRequest(ApiTestCaseRequest request) {
|
||||
List<ApiTestCaseWithBLOBs> list = extApiTestCaseMapper.getRequest(request);
|
||||
for (ApiTestCaseWithBLOBs model : list) {
|
||||
esbApiParamService.handleApiEsbParams(model);
|
||||
}
|
||||
return list.stream().collect(Collectors.toMap(ApiTestCaseWithBLOBs::getId, ApiTestCaseWithBLOBs::getRequest));
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import io.metersphere.api.dto.definition.SaveApiDefinitionRequest;
|
|||
import io.metersphere.api.dto.definition.SaveApiTestCaseRequest;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler;
|
||||
import io.metersphere.api.dto.scenario.KeyValue;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
import io.metersphere.base.domain.EsbApiParamsExample;
|
||||
import io.metersphere.base.domain.EsbApiParamsWithBLOBs;
|
||||
import io.metersphere.base.mapper.EsbApiParamsMapper;
|
||||
|
@ -110,25 +111,76 @@ public class EsbApiParamService {
|
|||
if (esbParamBlobs == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (StringUtils.isNotEmpty(res.getRequest())) {
|
||||
JSONObject jsonObj = JSONObject.parseObject(res.getRequest());
|
||||
|
||||
JSONArray esbDataArray = JSONArray.parseArray(esbParamBlobs.getDataStruct());
|
||||
jsonObj.put("esbDataStruct", esbDataArray);
|
||||
|
||||
JSONArray responseDataArray = JSONArray.parseArray(esbParamBlobs.getResponseDataStruct());
|
||||
jsonObj.put("backEsbDataStruct", responseDataArray);
|
||||
|
||||
JSONObject backedScriptObj = JSONObject.parseObject(esbParamBlobs.getBackedScript());
|
||||
jsonObj.put("backScript", backedScriptObj);
|
||||
|
||||
jsonObj.put("esbFrontedScript", esbParamBlobs.getFrontedScript());
|
||||
|
||||
JSONObject jsonObj = this.addEsbInfoToJsonString(esbParamBlobs, res.getRequest());
|
||||
if (jsonObj != null) {
|
||||
res.setRequest(jsonObj.toJSONString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
// try {
|
||||
// if (StringUtils.isNotEmpty(res.getRequest())) {
|
||||
// JSONObject jsonObj = JSONObject.parseObject(res.getRequest());
|
||||
//
|
||||
// JSONArray esbDataArray = JSONArray.parseArray(esbParamBlobs.getDataStruct());
|
||||
// jsonObj.put("esbDataStruct", esbDataArray);
|
||||
//
|
||||
// JSONArray responseDataArray = JSONArray.parseArray(esbParamBlobs.getResponseDataStruct());
|
||||
// jsonObj.put("backEsbDataStruct", responseDataArray);
|
||||
//
|
||||
// JSONObject backedScriptObj = JSONObject.parseObject(esbParamBlobs.getBackedScript());
|
||||
// jsonObj.put("backScript", backedScriptObj);
|
||||
//
|
||||
// jsonObj.put("esbFrontedScript", esbParamBlobs.getFrontedScript());
|
||||
//
|
||||
// res.setRequest(jsonObj.toJSONString());
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// }
|
||||
}
|
||||
|
||||
public void handleApiEsbParams(ApiTestCaseWithBLOBs res) {
|
||||
EsbApiParamsWithBLOBs esbParamBlobs = this.getEsbParamBLOBsByResourceID(res.getId());
|
||||
if (esbParamBlobs == null) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isNotEmpty(res.getRequest())) {
|
||||
JSONObject jsonObj = this.addEsbInfoToJsonString(esbParamBlobs, res.getRequest());
|
||||
if (jsonObj != null) {
|
||||
res.setRequest(jsonObj.toJSONString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private JSONObject addEsbInfoToJsonString(EsbApiParamsWithBLOBs esbParamBlobs, String requestString) {
|
||||
JSONObject returnObj = null;
|
||||
try {
|
||||
returnObj = JSONObject.parseObject(requestString);
|
||||
|
||||
JSONArray esbDataArray = JSONArray.parseArray(esbParamBlobs.getDataStruct());
|
||||
if (esbDataArray == null) {
|
||||
returnObj.put("esbDataStruct", "");
|
||||
} else {
|
||||
returnObj.put("esbDataStruct", esbDataArray);
|
||||
}
|
||||
|
||||
JSONArray responseDataArray = JSONArray.parseArray(esbParamBlobs.getResponseDataStruct());
|
||||
if (responseDataArray == null) {
|
||||
returnObj.put("backEsbDataStruct", "");
|
||||
} else {
|
||||
returnObj.put("backEsbDataStruct", responseDataArray);
|
||||
}
|
||||
|
||||
returnObj.put("esbFrontedScript", esbParamBlobs.getFrontedScript());
|
||||
|
||||
JSONObject backedScriptObj = JSONObject.parseObject(esbParamBlobs.getBackedScript());
|
||||
returnObj.put("backScript", backedScriptObj);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return returnObj;
|
||||
}
|
||||
|
||||
public void handleApiEsbParams(ApiTestCaseResult res) {
|
||||
|
@ -136,23 +188,30 @@ public class EsbApiParamService {
|
|||
if (esbParamBlobs == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (StringUtils.isNotEmpty(res.getRequest())) {
|
||||
JSONObject jsonObj = JSONObject.parseObject(res.getRequest());
|
||||
JSONArray esbDataArray = JSONArray.parseArray(esbParamBlobs.getDataStruct());
|
||||
jsonObj.put("esbDataStruct", esbDataArray);
|
||||
jsonObj.put("esbFrontedScript", esbParamBlobs.getFrontedScript());
|
||||
|
||||
JSONArray responseDataArray = JSONArray.parseArray(esbParamBlobs.getResponseDataStruct());
|
||||
jsonObj.put("backEsbDataStruct", responseDataArray);
|
||||
|
||||
JSONObject jsonObj = this.addEsbInfoToJsonString(esbParamBlobs, res.getRequest());
|
||||
if (jsonObj != null) {
|
||||
res.setRequest(jsonObj.toJSONString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
// try {
|
||||
// if (StringUtils.isNotEmpty(res.getRequest())) {
|
||||
// JSONObject jsonObj = JSONObject.parseObject(res.getRequest());
|
||||
// JSONArray esbDataArray = JSONArray.parseArray(esbParamBlobs.getDataStruct());
|
||||
// jsonObj.put("esbDataStruct", esbDataArray);
|
||||
// jsonObj.put("esbFrontedScript", esbParamBlobs.getFrontedScript());
|
||||
//
|
||||
// JSONArray responseDataArray = JSONArray.parseArray(esbParamBlobs.getResponseDataStruct());
|
||||
// jsonObj.put("backEsbDataStruct", responseDataArray);
|
||||
//
|
||||
// res.setRequest(jsonObj.toJSONString());
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// }
|
||||
}
|
||||
|
||||
public SaveApiDefinitionRequest handleEsbRequest(SaveApiDefinitionRequest request) {
|
||||
public SaveApiDefinitionRequest updateEsbRequest(SaveApiDefinitionRequest request) {
|
||||
try {
|
||||
//修改reqeust.parameters
|
||||
//用户交互感受:ESB的发送数据以报文模板为主框架,同时前端不再有key-value的表格数据填充。
|
||||
|
@ -162,8 +221,27 @@ public class EsbApiParamService {
|
|||
MsTCPSampler tcpSampler = (MsTCPSampler) request.getRequest();
|
||||
List<KeyValue> keyValueList = this.genKeyValueListByDataStruct(tcpSampler, request.getEsbDataStruct());
|
||||
tcpSampler.setParameters(keyValueList);
|
||||
request.setRequest(tcpSampler);
|
||||
}
|
||||
//更新EsbApiParams类
|
||||
// EsbApiParamsWithBLOBs esbApiParams = this.createEsbApiParam(request.getId(), request.getEsbDataStruct(), request.getBackEsbDataStruct(), request.getBackScript());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return request;
|
||||
}
|
||||
public SaveApiDefinitionRequest handleEsbRequest(SaveApiDefinitionRequest request) {
|
||||
try {
|
||||
//修改reqeust.parameters
|
||||
//用户交互感受:ESB的发送数据以报文模板为主框架,同时前端不再有key-value的表格数据填充。
|
||||
//业务逻辑: 发送ESB接口数据时,使用报文模板中的数据,同时报文模板中的${取值}目的是为了拼接数据结构(比如xml的子节点)
|
||||
//代码实现: 此处打算解析前端传来的EsbDataStruct数据结构,将数据结构按照报文模板中的${取值}为最高优先级组装keyValue对象。这样Jmeter会自动拼装为合适的xml
|
||||
if (StringUtils.isNotEmpty(request.getEsbDataStruct())) {
|
||||
MsTCPSampler tcpSampler = (MsTCPSampler) request.getRequest();
|
||||
tcpSampler.setProtocol("ESB");
|
||||
List<KeyValue> keyValueList = this.genKeyValueListByDataStruct(tcpSampler, request.getEsbDataStruct());
|
||||
tcpSampler.setParameters(keyValueList);
|
||||
}
|
||||
|
||||
//更新EsbApiParams类
|
||||
EsbApiParamsWithBLOBs esbApiParams = this.createEsbApiParam(request.getId(), request.getEsbDataStruct(), request.getBackEsbDataStruct(), request.getBackScript());
|
||||
} catch (Exception e) {
|
||||
|
@ -172,6 +250,43 @@ public class EsbApiParamService {
|
|||
return request;
|
||||
}
|
||||
|
||||
// public RunDefinitionRequest handleEsbRequest(RunDefinitionRequest request) {
|
||||
// try {
|
||||
// //修改reqeust.parameters
|
||||
// //用户交互感受:ESB的发送数据以报文模板为主框架,同时前端不再有key-value的表格数据填充。
|
||||
// //业务逻辑: 发送ESB接口数据时,使用报文模板中的数据,同时报文模板中的${取值}目的是为了拼接数据结构(比如xml的子节点)
|
||||
// //代码实现: 此处打算解析前端传来的EsbDataStruct数据结构,将数据结构按照报文模板中的${取值}为最高优先级组装keyValue对象。这样Jmeter会自动拼装为合适的xml
|
||||
// if (StringUtils.isNotEmpty(request.getEsbDataStruct())) {
|
||||
// if(request.getTestElement() instanceof MsTestPlan){
|
||||
// MsTestPlan testPlan = (MsTestPlan)request.getTestElement();
|
||||
// for (MsTestElement testElement: testPlan.getHashTree()) {
|
||||
// if(testElement instanceof MsThreadGroup){
|
||||
// MsThreadGroup group = (MsThreadGroup)testElement;
|
||||
// for (MsTestElement groupElement: testPlan.getHashTree()) {
|
||||
// if(groupElement instanceof MsScenario){
|
||||
// MsScenario scenario = (MsScenario)groupElement;
|
||||
// for (MsTestElement scenarioElement: scenario.getHashTree()) {
|
||||
// if(scenarioElement instanceof MsTCPSampler){
|
||||
// MsTCPSampler tcpSampler = (MsTCPSampler) scenarioElement;
|
||||
// List<KeyValue> keyValueList = this.genKeyValueListByDataStruct(tcpSampler, request.getEsbDataStruct());
|
||||
// tcpSampler.setParameters(keyValueList);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //更新EsbApiParams类
|
||||
// EsbApiParamsWithBLOBs esbApiParams = this.createEsbApiParam(request.getId(), request.getEsbDataStruct(), request.getBackEsbDataStruct(), request.getBackScript());
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return request;
|
||||
// }
|
||||
|
||||
//通过esb数据结构生成keyValue集合,以及发送参数
|
||||
private List<KeyValue> genKeyValueListByDataStruct(MsTCPSampler tcpSampler, String esbDataStruct) {
|
||||
List<KeyValue> keyValueList = new ArrayList<>();
|
||||
|
|
|
@ -50,6 +50,7 @@ import MsMainContainer from "../../../../common/components/MsMainContainer";
|
|||
import ScenarioRelevanceApiList from "./RelevanceApiList";
|
||||
import RelevanceDialog from "../../../../track/plan/view/comonents/base/RelevanceDialog";
|
||||
import TestCaseRelevanceBase from "@/business/components/track/plan/view/comonents/base/TestCaseRelevanceBase";
|
||||
import {getUUID} from "@/common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "ApiRelevance",
|
||||
|
@ -97,6 +98,29 @@ export default {
|
|||
apiCases.forEach((item) => {
|
||||
item.request = response.data[item.id];
|
||||
item.projectId = this.projectId;
|
||||
|
||||
let requestObj = JSON.parse(item.request);
|
||||
if(requestObj.esbDataStruct != null ){
|
||||
//ESB接口
|
||||
let param = {};
|
||||
param.request = requestObj;
|
||||
param.method = "ESB";
|
||||
param.esbDataStruct = JSON.stringify(requestObj.esbDataStruct);
|
||||
if(requestObj.backEsbDataStruct != null){
|
||||
param.backEsbDataStruct = JSON.stringify(requestObj.backEsbDataStruct);
|
||||
}else{
|
||||
param.backEsbDataStruct = "";
|
||||
}
|
||||
|
||||
this.$post("/api/definition/updateEsbRequest", param, response => {
|
||||
if(response.data!=null){
|
||||
if(response.data.request!=null){
|
||||
item.request = JSON.stringify(response.data.request);
|
||||
param.method = "TCP";
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
this.$emit('save', apiCases, 'CASE', reference);
|
||||
this.$refs.baseRelevance.close();
|
||||
|
|
|
@ -32,7 +32,9 @@
|
|||
<p class="tip">{{ $t('api_test.definition.request.req_param') }} </p>
|
||||
<ms-api-request-form :isShowEnable="true" :referenced="true" :headers="request.headers " :request="request"
|
||||
v-if="request.protocol==='HTTP' || request.type==='HTTPSamplerProxy'"/>
|
||||
<ms-tcp-basis-parameters :request="request" v-if="request.protocol==='TCP'|| request.type==='TCPSampler'" :showScript="false"/>
|
||||
<esb-definition v-xpack :request="request" :showScript="false" v-if="this.showXpackCompnent&&request.esbDataStruct!=null" ref="esbDefinition"/>
|
||||
<ms-tcp-basis-parameters :request="request" v-if="(request.protocol==='TCP'|| request.type==='TCPSampler')&&request.esbDataStruct==null " :showScript="false"/>
|
||||
|
||||
<ms-sql-basis-parameters :request="request" v-if="request.protocol==='SQL'|| request.type==='JDBCSampler'"
|
||||
:showScript="false"/>
|
||||
<ms-dubbo-basis-parameters :request="request"
|
||||
|
@ -49,7 +51,13 @@
|
|||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<api-response-component :currentProtocol="request.protocol" :result="request.requestResult" v-else/>
|
||||
<div v-else-if="showXpackCompnent&&request.backEsbDataStruct != null">
|
||||
<esb-definition-response :currentProtocol="request.protocol" :request="request" :is-api-component="false"
|
||||
:show-options-button="false" :show-header="true" :result="request.requestResult"/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<api-response-component :currentProtocol="request.protocol" :result="request.requestResult"/>
|
||||
</div>
|
||||
|
||||
<!-- 保存操作 -->
|
||||
<el-button type="primary" size="small" class="ms-btn-flot" @click="saveTestCase(item)"
|
||||
|
@ -75,6 +83,9 @@
|
|||
import ApiBaseComponent from "../common/ApiBaseComponent";
|
||||
import ApiResponseComponent from "./ApiResponseComponent";
|
||||
import CustomizeReqInfo from "@/business/components/api/automation/scenario/common/CustomizeReqInfo";
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
const esbDefinition = (requireComponent!=null&&requireComponent.keys().length) > 0 ? requireComponent("./apiDefinition/EsbDefinition.vue") : {};
|
||||
const esbDefinitionResponse = (requireComponent!=null&&requireComponent.keys().length) > 0 ? requireComponent("./apiDefinition/EsbDefinitionResponse.vue") : {};
|
||||
|
||||
export default {
|
||||
name: "MsApiComponent",
|
||||
|
@ -101,7 +112,9 @@
|
|||
components: {
|
||||
CustomizeReqInfo,
|
||||
ApiBaseComponent, ApiResponseComponent,
|
||||
MsSqlBasisParameters, MsTcpBasisParameters, MsDubboBasisParameters, MsApiRequestForm, MsRequestResultTail, MsRun
|
||||
MsSqlBasisParameters, MsTcpBasisParameters, MsDubboBasisParameters, MsApiRequestForm, MsRequestResultTail, MsRun,
|
||||
"esbDefinition": esbDefinition.default,
|
||||
"esbDefinitionResponse": esbDefinitionResponse.default
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -109,6 +122,7 @@
|
|||
reportId: "",
|
||||
runData: [],
|
||||
isShowInput: false,
|
||||
showXpackCompnent:false,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
@ -121,6 +135,7 @@
|
|||
}
|
||||
// 加载引用对象数据
|
||||
this.getApiInfo();
|
||||
console.log(JSON.stringify(this.request));
|
||||
if (this.request.protocol === 'HTTP') {
|
||||
this.setUrl(this.request.url);
|
||||
this.setUrl(this.request.path);
|
||||
|
@ -134,6 +149,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
if (requireComponent != null && JSON.stringify(esbDefinition) != '{}'&& JSON.stringify(esbDefinitionResponse) != '{}') {
|
||||
this.showXpackCompnent = true;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
displayColor() {
|
||||
|
@ -284,7 +302,7 @@
|
|||
let debugData = {
|
||||
id: this.currentScenario.id, name: this.currentScenario.name, type: "scenario",
|
||||
variables: this.currentScenario.variables, referenced: 'Created', headers: this.currentScenario.headers,
|
||||
enableCookieShare: this.enableCookieShare, environmentId: this.currentEnvironmentId, hashTree: [this.request]
|
||||
enableCookieShare: this.enableCookieShare, environmentId: this.currentEnvironmentId, hashTree: [this.request],
|
||||
};
|
||||
this.runData.push(debugData);
|
||||
/*触发执行操作*/
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
getComponent(type) {
|
||||
if (type === ELEMENT_TYPE.JSR223PreProcessor) {
|
||||
this.title = this.$t('api_test.definition.request.pre_script');
|
||||
this.titleColor = "#B8741A";
|
||||
this.titleColor = "#b8741a";
|
||||
this.backgroundColor = "#F9F1EA";
|
||||
return "MsJsr233Processor";
|
||||
} else if (type === ELEMENT_TYPE.JSR223PostProcessor) {
|
||||
|
|
|
@ -131,8 +131,6 @@ export default {
|
|||
if(this.request.backScript != null){
|
||||
this.basisData.backScript = JSON.stringify(this.request.backScript);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
this.$emit('saveApi', this.basisData);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue