parent
8bb649c91e
commit
26b271ece1
|
@ -7,6 +7,7 @@ import io.metersphere.api.dto.ApiTestImportRequest;
|
|||
import io.metersphere.api.dto.automation.ApiScenarioRequest;
|
||||
import io.metersphere.api.dto.automation.ReferenceDTO;
|
||||
import io.metersphere.api.dto.definition.*;
|
||||
import io.metersphere.api.dto.definition.information.ApiDetailedInformationDTO;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||
import io.metersphere.api.dto.definition.request.assertions.document.DocumentElement;
|
||||
import io.metersphere.api.dto.scenario.Body;
|
||||
|
@ -177,6 +178,12 @@ public class ApiDefinitionController {
|
|||
return apiDefinitionService.getById(id);
|
||||
}
|
||||
|
||||
@GetMapping("/get/apiDetail/{id}")
|
||||
@RequiresPermissions("PROJECT_API_DEFINITION:READ")
|
||||
public ApiDetailedInformationDTO getApiDetail(@PathVariable String id) {
|
||||
return apiDefinitionService.getApiDetail(id);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/run/debug", consumes = {"multipart/form-data"})
|
||||
@MsAuditLog(module = OperLogModule.API_DEFINITION, type = OperLogConstants.DEBUG, title = "#request.name", project = "#request.projectId")
|
||||
public MsExecResponseDTO runDebug(@RequestPart("request") RunDefinitionRequest request, @RequestPart(value = "files", required = false) List<MultipartFile> bodyFiles) {
|
||||
|
|
|
@ -65,7 +65,7 @@ public class ShareInfoController {
|
|||
model.setId(id);
|
||||
model.setName(id);
|
||||
}
|
||||
ApiDocumentInfoDTO returnDTO = shareInfoService.conversionModelToDTO(model,userIdMap);
|
||||
ApiDocumentInfoDTO returnDTO = apiDefinitionService.conversionModelToDTO(model,userIdMap);
|
||||
returnList.add(returnDTO);
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ public class ShareInfoController {
|
|||
ApiDocumentInfoDTO returnDTO = new ApiDocumentInfoDTO();
|
||||
try {
|
||||
Map<String, User> userIdMap = userService.queryName();
|
||||
returnDTO = shareInfoService.conversionModelToDTO(apiModel,userIdMap);
|
||||
returnDTO = apiDefinitionService.conversionModelToDTO(apiModel,userIdMap);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package io.metersphere.api.dto.definition.information;
|
||||
|
||||
import io.metersphere.api.dto.definition.ApiDefinitionResult;
|
||||
import io.metersphere.api.dto.share.ApiDocumentInfoDTO;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ApiDetailedInformationDTO {
|
||||
private ApiDefinitionResult apiDefinition;
|
||||
private ApiDocumentInfoDTO apiInfo;
|
||||
}
|
|
@ -17,6 +17,7 @@ public class ApiDocumentInfoDTO {
|
|||
private String uri;
|
||||
private String name;
|
||||
private String status;
|
||||
private String protocol;
|
||||
|
||||
private String tags;
|
||||
private String modules;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.api.service;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
|
@ -10,6 +11,7 @@ import io.metersphere.api.dto.automation.ApiScenarioRequest;
|
|||
import io.metersphere.api.dto.automation.ReferenceDTO;
|
||||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||
import io.metersphere.api.dto.definition.*;
|
||||
import io.metersphere.api.dto.definition.information.ApiDetailedInformationDTO;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImportParserFactory;
|
||||
import io.metersphere.api.dto.definition.parse.Swagger3Parser;
|
||||
|
@ -19,6 +21,7 @@ import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler;
|
|||
import io.metersphere.api.dto.mockconfig.MockConfigImportDTO;
|
||||
import io.metersphere.api.dto.scenario.Scenario;
|
||||
import io.metersphere.api.dto.scenario.request.RequestType;
|
||||
import io.metersphere.api.dto.share.ApiDocumentInfoDTO;
|
||||
import io.metersphere.api.dto.swaggerurl.SwaggerTaskResult;
|
||||
import io.metersphere.api.dto.swaggerurl.SwaggerUrlRequest;
|
||||
import io.metersphere.api.exec.api.ApiExecuteService;
|
||||
|
@ -29,6 +32,7 @@ import io.metersphere.base.mapper.*;
|
|||
import io.metersphere.base.mapper.ext.*;
|
||||
import io.metersphere.commons.constants.*;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.json.JSONSchemaGenerator;
|
||||
import io.metersphere.commons.json.JSONSchemaToDocumentUtils;
|
||||
import io.metersphere.commons.json.JSONToDocumentUtils;
|
||||
import io.metersphere.commons.utils.*;
|
||||
|
@ -121,6 +125,8 @@ public class ApiDefinitionService {
|
|||
@Resource
|
||||
private ApiDefinitionFollowMapper apiDefinitionFollowMapper;
|
||||
@Resource
|
||||
private UserService userService;
|
||||
@Resource
|
||||
@Lazy
|
||||
private TestPlanService testPlanService;
|
||||
@Resource
|
||||
|
@ -2033,4 +2039,345 @@ public class ApiDefinitionService {
|
|||
}
|
||||
}
|
||||
|
||||
public ApiDetailedInformationDTO getApiDetail(String id) {
|
||||
ApiDetailedInformationDTO informationDTO = new ApiDetailedInformationDTO();
|
||||
|
||||
ApiDefinitionResult result = this.getById(id);
|
||||
|
||||
ApiDocumentInfoDTO returnDTO = new ApiDocumentInfoDTO();
|
||||
try {
|
||||
Map<String, User> userIdMap = userService.queryName();
|
||||
ApiDefinitionWithBLOBs definition = apiDefinitionMapper.selectByPrimaryKey(id);
|
||||
returnDTO = this.conversionModelToDTO(definition,userIdMap);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
|
||||
informationDTO.setApiDefinition(result);
|
||||
informationDTO.setApiInfo(returnDTO);
|
||||
return informationDTO;
|
||||
}
|
||||
|
||||
public ApiDocumentInfoDTO conversionModelToDTO(ApiDefinitionWithBLOBs apiModel, Map<String,User> userIdMap) {
|
||||
ApiDocumentInfoDTO apiInfoDTO = new ApiDocumentInfoDTO();
|
||||
JSONArray previewJsonArray = new JSONArray();
|
||||
if (apiModel != null) {
|
||||
apiInfoDTO.setId(apiModel.getId());
|
||||
apiInfoDTO.setName(apiModel.getName());
|
||||
apiInfoDTO.setMethod(apiModel.getMethod());
|
||||
apiInfoDTO.setUri(apiModel.getPath());
|
||||
apiInfoDTO.setStatus(apiModel.getStatus());
|
||||
apiInfoDTO.setProtocol(apiModel.getProtocol());
|
||||
|
||||
if(StringUtils.isNotEmpty(apiModel.getTags())){
|
||||
JSONArray tagsArr = JSONArray.parseArray(apiModel.getTags());
|
||||
List<String> tagList = new ArrayList<>();
|
||||
for(int i = 0;i < tagsArr.size();i ++){
|
||||
tagList.add(tagsArr.getString(i));
|
||||
}
|
||||
if(!tagList.isEmpty()){
|
||||
apiInfoDTO.setTags(StringUtils.join(tagList,","));
|
||||
}
|
||||
}
|
||||
|
||||
apiInfoDTO.setResponsibler(userIdMap.get(apiModel.getUserId()) == null? apiModel.getUserId() : userIdMap.get(apiModel.getUserId()).getName());
|
||||
apiInfoDTO.setCreateUser(userIdMap.get(apiModel.getCreateUser()) == null? apiModel.getCreateUser() : userIdMap.get(apiModel.getCreateUser()).getName());
|
||||
apiInfoDTO.setDesc(apiModel.getDescription());
|
||||
ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||
apiInfoDTO.setModules(apiModuleService.getModuleNameById(apiModel.getModuleId()));
|
||||
|
||||
if (apiModel.getRequest() != null) {
|
||||
JSONObject requestObj = this.genJSONObject(apiModel.getRequest());
|
||||
if (requestObj != null) {
|
||||
if (requestObj.containsKey("headers")) {
|
||||
JSONArray requestHeadDataArr = new JSONArray();
|
||||
//head赋值
|
||||
JSONArray headArr = requestObj.getJSONArray("headers");
|
||||
for (int index = 0; index < headArr.size(); index++) {
|
||||
JSONObject headObj = headArr.getJSONObject(index);
|
||||
if (headObj != null && headObj.containsKey("name") && headObj.containsKey("value")) {
|
||||
requestHeadDataArr.add(headObj);
|
||||
}
|
||||
}
|
||||
apiInfoDTO.setRequestHead(requestHeadDataArr.toJSONString());
|
||||
}
|
||||
//url参数赋值
|
||||
JSONArray urlParamArr = new JSONArray();
|
||||
if (requestObj.containsKey("arguments")) {
|
||||
try {
|
||||
JSONArray headArr = requestObj.getJSONArray("arguments");
|
||||
for (int index = 0; index < headArr.size(); index++) {
|
||||
|
||||
JSONObject headObj = headArr.getJSONObject(index);
|
||||
if (headObj.containsKey("name") && headObj.containsKey("value")) {
|
||||
urlParamArr.add(headObj);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
//rest参数设置
|
||||
JSONArray restParamArr = new JSONArray();
|
||||
if (requestObj.containsKey("rest")) {
|
||||
try {
|
||||
//urlParam -- rest赋值
|
||||
JSONArray headArr = requestObj.getJSONArray("rest");
|
||||
for (int index = 0; index < headArr.size(); index++) {
|
||||
JSONObject headObj = headArr.getJSONObject(index);
|
||||
if (headObj.containsKey("name")) {
|
||||
restParamArr.add(headObj);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
apiInfoDTO.setUrlParams(urlParamArr.toJSONString());
|
||||
apiInfoDTO.setRestParams(restParamArr.toJSONString());
|
||||
//请求体参数类型
|
||||
if (requestObj.containsKey("body")) {
|
||||
try {
|
||||
JSONObject bodyObj = requestObj.getJSONObject("body");
|
||||
if (bodyObj.containsKey("type")) {
|
||||
String type = bodyObj.getString("type");
|
||||
if (StringUtils.equals(type, "WWW_FORM")) {
|
||||
apiInfoDTO.setRequestBodyParamType("x-www-from-urlencoded");
|
||||
} else if (StringUtils.equals(type, "Form Data")) {
|
||||
apiInfoDTO.setRequestBodyParamType("form-data");
|
||||
} else {
|
||||
apiInfoDTO.setRequestBodyParamType(type);
|
||||
}
|
||||
|
||||
if (StringUtils.equals(type, "JSON")) {
|
||||
//判断是否是JsonSchema
|
||||
boolean isJsonSchema = false;
|
||||
if (bodyObj.containsKey("format")) {
|
||||
String foramtValue = String.valueOf(bodyObj.get("format"));
|
||||
if (StringUtils.equals("JSON-SCHEMA", foramtValue)) {
|
||||
isJsonSchema = true;
|
||||
}
|
||||
}
|
||||
if (isJsonSchema) {
|
||||
apiInfoDTO.setRequestBodyParamType("JSON-SCHEMA");
|
||||
apiInfoDTO.setJsonSchemaBody(bodyObj);
|
||||
if (bodyObj.containsKey("jsonSchema")) {
|
||||
JSONObject jsonSchemaObj = bodyObj.getJSONObject("jsonSchema");
|
||||
apiInfoDTO.setRequestPreviewData(JSON.parse(JSONSchemaGenerator.getJson(jsonSchemaObj.toJSONString())));
|
||||
}
|
||||
} else {
|
||||
if (bodyObj.containsKey("raw")) {
|
||||
String raw = bodyObj.getString("raw");
|
||||
apiInfoDTO.setRequestBodyStrutureData(raw);
|
||||
//转化jsonObje 或者 jsonArray
|
||||
this.setPreviewData(previewJsonArray, raw);
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equalsAny(type, "XML", "Raw")) {
|
||||
if (bodyObj.containsKey("raw")) {
|
||||
String raw = bodyObj.getString("raw");
|
||||
apiInfoDTO.setRequestBodyStrutureData(raw);
|
||||
this.setPreviewData(previewJsonArray, raw);
|
||||
}
|
||||
} else if (StringUtils.equalsAny(type, "Form Data", "WWW_FORM")) {
|
||||
if (bodyObj.containsKey("kvs")) {
|
||||
JSONArray bodyParamArr = new JSONArray();
|
||||
JSONArray kvsArr = bodyObj.getJSONArray("kvs");
|
||||
Map<String, String> previewObjMap = new LinkedHashMap<>();
|
||||
for (int i = 0; i < kvsArr.size(); i++) {
|
||||
JSONObject kv = kvsArr.getJSONObject(i);
|
||||
if (kv.containsKey("name")) {
|
||||
String value = "";
|
||||
if (kv.containsKey("value")) {
|
||||
value = String.valueOf(kv.get("value"));
|
||||
}
|
||||
bodyParamArr.add(kv);
|
||||
previewObjMap.put(String.valueOf(kv.get("name")), value);
|
||||
}
|
||||
}
|
||||
this.setPreviewData(previewJsonArray, JSONObject.toJSONString(previewObjMap));
|
||||
apiInfoDTO.setRequestBodyFormData(bodyParamArr.toJSONString());
|
||||
}
|
||||
} else if (StringUtils.equals(type, "BINARY")) {
|
||||
if (bodyObj.containsKey("binary")) {
|
||||
List<Map<String, String>> bodyParamList = new ArrayList<>();
|
||||
JSONArray kvsArr = bodyObj.getJSONArray("binary");
|
||||
|
||||
Map<String, String> previewObjMap = new LinkedHashMap<>();
|
||||
for (int i = 0; i < kvsArr.size(); i++) {
|
||||
JSONObject kv = kvsArr.getJSONObject(i);
|
||||
if (kv.containsKey("description") && kv.containsKey("files")) {
|
||||
Map<String, String> bodyMap = new HashMap<>();
|
||||
String name = kv.getString("description");
|
||||
JSONArray fileArr = kv.getJSONArray("files");
|
||||
String value = "";
|
||||
for (int j = 0; j < fileArr.size(); j++) {
|
||||
JSONObject fileObj = fileArr.getJSONObject(j);
|
||||
if (fileObj.containsKey("name")) {
|
||||
value += fileObj.getString("name") + " ;";
|
||||
}
|
||||
}
|
||||
bodyMap.put("name", name);
|
||||
bodyMap.put("value", value);
|
||||
bodyMap.put("contentType", "File");
|
||||
bodyParamList.add(bodyMap);
|
||||
|
||||
previewObjMap.put(String.valueOf(name), String.valueOf(value));
|
||||
|
||||
}
|
||||
}
|
||||
this.setPreviewData(previewJsonArray, JSONObject.toJSONString(previewObjMap));
|
||||
apiInfoDTO.setRequestBodyFormData(JSONArray.toJSONString(bodyParamList));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//赋值响应头
|
||||
if (apiModel.getResponse() != null) {
|
||||
JSONObject responseJsonObj = this.genJSONObject(apiModel.getResponse());
|
||||
if (responseJsonObj != null && responseJsonObj.containsKey("headers")) {
|
||||
try {
|
||||
JSONArray responseHeadDataArr = new JSONArray();
|
||||
JSONArray headArr = responseJsonObj.getJSONArray("headers");
|
||||
for (int index = 0; index < headArr.size(); index++) {
|
||||
JSONObject headObj = headArr.getJSONObject(index);
|
||||
if (headObj.containsKey("name") && headObj.containsKey("value")) {
|
||||
responseHeadDataArr.add(headObj);
|
||||
}
|
||||
}
|
||||
apiInfoDTO.setResponseHead(responseHeadDataArr.toJSONString());
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
// 赋值响应体
|
||||
if (responseJsonObj != null && responseJsonObj.containsKey("body")) {
|
||||
try {
|
||||
JSONObject bodyObj = responseJsonObj.getJSONObject("body");
|
||||
if (bodyObj.containsKey("type")) {
|
||||
String type = bodyObj.getString("type");
|
||||
if (StringUtils.equals(type, "WWW_FORM")) {
|
||||
apiInfoDTO.setResponseBodyParamType("x-www-from-urlencoded");
|
||||
} else if (StringUtils.equals(type, "Form Data")) {
|
||||
apiInfoDTO.setResponseBodyParamType("form-data");
|
||||
} else {
|
||||
apiInfoDTO.setResponseBodyParamType(type);
|
||||
}
|
||||
if (StringUtils.equalsAny(type, "JSON", "XML", "Raw")) {
|
||||
|
||||
//判断是否是JsonSchema
|
||||
boolean isJsonSchema = false;
|
||||
if (bodyObj.containsKey("format")) {
|
||||
String foramtValue = String.valueOf(bodyObj.get("format"));
|
||||
if (StringUtils.equals("JSON-SCHEMA", foramtValue)) {
|
||||
isJsonSchema = true;
|
||||
}
|
||||
}
|
||||
if (isJsonSchema) {
|
||||
// apiInfoDTO.setRequestBodyParamType("JSON-SCHEMA");
|
||||
apiInfoDTO.setResponseBodyParamType("JSON-SCHEMA");
|
||||
apiInfoDTO.setJsonSchemaResponseBody(bodyObj);
|
||||
// apiInfoDTO.setJsonSchemaBody(bodyObj);
|
||||
} else {
|
||||
if (bodyObj.containsKey("raw")) {
|
||||
String raw = bodyObj.getString("raw");
|
||||
apiInfoDTO.setResponseBodyStrutureData(raw);
|
||||
//转化jsonObje 或者 jsonArray
|
||||
this.setPreviewData(previewJsonArray, raw);
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equalsAny(type, "Form Data", "WWW_FORM")) {
|
||||
if (bodyObj.containsKey("kvs")) {
|
||||
JSONArray bodyParamArr = new JSONArray();
|
||||
JSONArray kvsArr = bodyObj.getJSONArray("kvs");
|
||||
for (int i = 0; i < kvsArr.size(); i++) {
|
||||
JSONObject kv = kvsArr.getJSONObject(i);
|
||||
if (kv.containsKey("name")) {
|
||||
bodyParamArr.add(kv);
|
||||
}
|
||||
}
|
||||
apiInfoDTO.setResponseBodyFormData(bodyParamArr.toJSONString());
|
||||
}
|
||||
} else if (StringUtils.equals(type, "BINARY")) {
|
||||
if (bodyObj.containsKey("binary")) {
|
||||
List<Map<String, String>> bodyParamList = new ArrayList<>();
|
||||
JSONArray kvsArr = bodyObj.getJSONArray("kvs");
|
||||
for (int i = 0; i < kvsArr.size(); i++) {
|
||||
JSONObject kv = kvsArr.getJSONObject(i);
|
||||
if (kv.containsKey("description") && kv.containsKey("files")) {
|
||||
Map<String, String> bodyMap = new HashMap<>();
|
||||
|
||||
String name = kv.getString("description");
|
||||
JSONArray fileArr = kv.getJSONArray("files");
|
||||
String value = "";
|
||||
for (int j = 0; j < fileArr.size(); j++) {
|
||||
JSONObject fileObj = fileArr.getJSONObject(j);
|
||||
if (fileObj.containsKey("name")) {
|
||||
value += fileObj.getString("name") + " ;";
|
||||
}
|
||||
}
|
||||
bodyMap.put("name", name);
|
||||
bodyMap.put("value", value);
|
||||
bodyParamList.add(bodyMap);
|
||||
}
|
||||
}
|
||||
apiInfoDTO.setResponseBodyFormData(JSONArray.toJSONString(bodyParamList));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// 赋值响应码
|
||||
if (responseJsonObj != null && responseJsonObj.containsKey("statusCode")) {
|
||||
try {
|
||||
JSONArray responseStatusDataArr = new JSONArray();
|
||||
JSONArray statusArr = responseJsonObj.getJSONArray("statusCode");
|
||||
for (int index = 0; index < statusArr.size(); index++) {
|
||||
JSONObject statusObj = statusArr.getJSONObject(index);
|
||||
if (statusObj.containsKey("name") && statusObj.containsKey("value")) {
|
||||
responseStatusDataArr.add(statusObj);
|
||||
}
|
||||
}
|
||||
apiInfoDTO.setResponseCode(responseStatusDataArr.toJSONString());
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!previewJsonArray.isEmpty()) {
|
||||
apiInfoDTO.setRequestPreviewData(previewJsonArray);
|
||||
}
|
||||
apiInfoDTO.setSelectedFlag(true);
|
||||
return apiInfoDTO;
|
||||
}
|
||||
|
||||
private void setPreviewData(JSONArray previewArray, String data) {
|
||||
try {
|
||||
JSONObject previewObj = JSONObject.parseObject(data);
|
||||
previewArray.add(previewObj);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
try {
|
||||
previewArray = JSONArray.parseArray(data);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
private JSONObject genJSONObject(String request) {
|
||||
JSONObject returnObj = null;
|
||||
try {
|
||||
returnObj = JSONObject.parseObject(request);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return returnObj;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,331 +110,6 @@ public class ShareInfoService {
|
|||
return true;
|
||||
}
|
||||
|
||||
public ApiDocumentInfoDTO conversionModelToDTO(ApiDefinitionWithBLOBs apiModel, Map<String,User> userIdMap) {
|
||||
ApiDocumentInfoDTO apiInfoDTO = new ApiDocumentInfoDTO();
|
||||
JSONArray previewJsonArray = new JSONArray();
|
||||
if (apiModel != null) {
|
||||
apiInfoDTO.setId(apiModel.getId());
|
||||
apiInfoDTO.setName(apiModel.getName());
|
||||
apiInfoDTO.setMethod(apiModel.getMethod());
|
||||
apiInfoDTO.setUri(apiModel.getPath());
|
||||
apiInfoDTO.setStatus(apiModel.getStatus());
|
||||
|
||||
if(StringUtils.isNotEmpty(apiModel.getTags())){
|
||||
JSONArray tagsArr = JSONArray.parseArray(apiModel.getTags());
|
||||
List<String> tagList = new ArrayList<>();
|
||||
for(int i = 0;i < tagsArr.size();i ++){
|
||||
tagList.add(tagsArr.getString(i));
|
||||
}
|
||||
if(!tagList.isEmpty()){
|
||||
apiInfoDTO.setTags(StringUtils.join(tagList,","));
|
||||
}
|
||||
}
|
||||
|
||||
apiInfoDTO.setResponsibler(userIdMap.get(apiModel.getUserId()) == null? apiModel.getUserId() : userIdMap.get(apiModel.getUserId()).getName());
|
||||
apiInfoDTO.setCreateUser(userIdMap.get(apiModel.getCreateUser()) == null? apiModel.getCreateUser() : userIdMap.get(apiModel.getCreateUser()).getName());
|
||||
apiInfoDTO.setDesc(apiModel.getDescription());
|
||||
ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||
apiInfoDTO.setModules(apiModuleService.getModuleNameById(apiModel.getModuleId()));
|
||||
|
||||
if (apiModel.getRequest() != null) {
|
||||
JSONObject requestObj = this.genJSONObject(apiModel.getRequest());
|
||||
if (requestObj != null) {
|
||||
if (requestObj.containsKey("headers")) {
|
||||
JSONArray requestHeadDataArr = new JSONArray();
|
||||
//head赋值
|
||||
JSONArray headArr = requestObj.getJSONArray("headers");
|
||||
for (int index = 0; index < headArr.size(); index++) {
|
||||
JSONObject headObj = headArr.getJSONObject(index);
|
||||
if (headObj != null && headObj.containsKey("name") && headObj.containsKey("value")) {
|
||||
requestHeadDataArr.add(headObj);
|
||||
}
|
||||
}
|
||||
apiInfoDTO.setRequestHead(requestHeadDataArr.toJSONString());
|
||||
}
|
||||
//url参数赋值
|
||||
JSONArray urlParamArr = new JSONArray();
|
||||
if (requestObj.containsKey("arguments")) {
|
||||
try {
|
||||
JSONArray headArr = requestObj.getJSONArray("arguments");
|
||||
for (int index = 0; index < headArr.size(); index++) {
|
||||
|
||||
JSONObject headObj = headArr.getJSONObject(index);
|
||||
if (headObj.containsKey("name") && headObj.containsKey("value")) {
|
||||
urlParamArr.add(headObj);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
//rest参数设置
|
||||
JSONArray restParamArr = new JSONArray();
|
||||
if (requestObj.containsKey("rest")) {
|
||||
try {
|
||||
//urlParam -- rest赋值
|
||||
JSONArray headArr = requestObj.getJSONArray("rest");
|
||||
for (int index = 0; index < headArr.size(); index++) {
|
||||
JSONObject headObj = headArr.getJSONObject(index);
|
||||
if (headObj.containsKey("name")) {
|
||||
restParamArr.add(headObj);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
apiInfoDTO.setUrlParams(urlParamArr.toJSONString());
|
||||
apiInfoDTO.setRestParams(restParamArr.toJSONString());
|
||||
//请求体参数类型
|
||||
if (requestObj.containsKey("body")) {
|
||||
try {
|
||||
JSONObject bodyObj = requestObj.getJSONObject("body");
|
||||
if (bodyObj.containsKey("type")) {
|
||||
String type = bodyObj.getString("type");
|
||||
if (StringUtils.equals(type, "WWW_FORM")) {
|
||||
apiInfoDTO.setRequestBodyParamType("x-www-from-urlencoded");
|
||||
} else if (StringUtils.equals(type, "Form Data")) {
|
||||
apiInfoDTO.setRequestBodyParamType("form-data");
|
||||
} else {
|
||||
apiInfoDTO.setRequestBodyParamType(type);
|
||||
}
|
||||
|
||||
if (StringUtils.equals(type, "JSON")) {
|
||||
//判断是否是JsonSchema
|
||||
boolean isJsonSchema = false;
|
||||
if (bodyObj.containsKey("format")) {
|
||||
String foramtValue = String.valueOf(bodyObj.get("format"));
|
||||
if (StringUtils.equals("JSON-SCHEMA", foramtValue)) {
|
||||
isJsonSchema = true;
|
||||
}
|
||||
}
|
||||
if (isJsonSchema) {
|
||||
apiInfoDTO.setRequestBodyParamType("JSON-SCHEMA");
|
||||
apiInfoDTO.setJsonSchemaBody(bodyObj);
|
||||
if (bodyObj.containsKey("jsonSchema")) {
|
||||
JSONObject jsonSchemaObj = bodyObj.getJSONObject("jsonSchema");
|
||||
apiInfoDTO.setRequestPreviewData(JSON.parse(JSONSchemaGenerator.getJson(jsonSchemaObj.toJSONString())));
|
||||
}
|
||||
} else {
|
||||
if (bodyObj.containsKey("raw")) {
|
||||
String raw = bodyObj.getString("raw");
|
||||
apiInfoDTO.setRequestBodyStrutureData(raw);
|
||||
//转化jsonObje 或者 jsonArray
|
||||
this.setPreviewData(previewJsonArray, raw);
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equalsAny(type, "XML", "Raw")) {
|
||||
if (bodyObj.containsKey("raw")) {
|
||||
String raw = bodyObj.getString("raw");
|
||||
apiInfoDTO.setRequestBodyStrutureData(raw);
|
||||
this.setPreviewData(previewJsonArray, raw);
|
||||
}
|
||||
} else if (StringUtils.equalsAny(type, "Form Data", "WWW_FORM")) {
|
||||
if (bodyObj.containsKey("kvs")) {
|
||||
JSONArray bodyParamArr = new JSONArray();
|
||||
JSONArray kvsArr = bodyObj.getJSONArray("kvs");
|
||||
Map<String, String> previewObjMap = new LinkedHashMap<>();
|
||||
for (int i = 0; i < kvsArr.size(); i++) {
|
||||
JSONObject kv = kvsArr.getJSONObject(i);
|
||||
if (kv.containsKey("name")) {
|
||||
String value = "";
|
||||
if (kv.containsKey("value")) {
|
||||
value = String.valueOf(kv.get("value"));
|
||||
}
|
||||
bodyParamArr.add(kv);
|
||||
previewObjMap.put(String.valueOf(kv.get("name")), value);
|
||||
}
|
||||
}
|
||||
this.setPreviewData(previewJsonArray, JSONObject.toJSONString(previewObjMap));
|
||||
apiInfoDTO.setRequestBodyFormData(bodyParamArr.toJSONString());
|
||||
}
|
||||
} else if (StringUtils.equals(type, "BINARY")) {
|
||||
if (bodyObj.containsKey("binary")) {
|
||||
List<Map<String, String>> bodyParamList = new ArrayList<>();
|
||||
JSONArray kvsArr = bodyObj.getJSONArray("binary");
|
||||
|
||||
Map<String, String> previewObjMap = new LinkedHashMap<>();
|
||||
for (int i = 0; i < kvsArr.size(); i++) {
|
||||
JSONObject kv = kvsArr.getJSONObject(i);
|
||||
if (kv.containsKey("description") && kv.containsKey("files")) {
|
||||
Map<String, String> bodyMap = new HashMap<>();
|
||||
String name = kv.getString("description");
|
||||
JSONArray fileArr = kv.getJSONArray("files");
|
||||
String value = "";
|
||||
for (int j = 0; j < fileArr.size(); j++) {
|
||||
JSONObject fileObj = fileArr.getJSONObject(j);
|
||||
if (fileObj.containsKey("name")) {
|
||||
value += fileObj.getString("name") + " ;";
|
||||
}
|
||||
}
|
||||
bodyMap.put("name", name);
|
||||
bodyMap.put("value", value);
|
||||
bodyMap.put("contentType", "File");
|
||||
bodyParamList.add(bodyMap);
|
||||
|
||||
previewObjMap.put(String.valueOf(name), String.valueOf(value));
|
||||
|
||||
}
|
||||
}
|
||||
this.setPreviewData(previewJsonArray, JSONObject.toJSONString(previewObjMap));
|
||||
apiInfoDTO.setRequestBodyFormData(JSONArray.toJSONString(bodyParamList));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//赋值响应头
|
||||
if (apiModel.getResponse() != null) {
|
||||
JSONObject responseJsonObj = this.genJSONObject(apiModel.getResponse());
|
||||
if (responseJsonObj != null && responseJsonObj.containsKey("headers")) {
|
||||
try {
|
||||
JSONArray responseHeadDataArr = new JSONArray();
|
||||
JSONArray headArr = responseJsonObj.getJSONArray("headers");
|
||||
for (int index = 0; index < headArr.size(); index++) {
|
||||
JSONObject headObj = headArr.getJSONObject(index);
|
||||
if (headObj.containsKey("name") && headObj.containsKey("value")) {
|
||||
responseHeadDataArr.add(headObj);
|
||||
}
|
||||
}
|
||||
apiInfoDTO.setResponseHead(responseHeadDataArr.toJSONString());
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
// 赋值响应体
|
||||
if (responseJsonObj != null && responseJsonObj.containsKey("body")) {
|
||||
try {
|
||||
JSONObject bodyObj = responseJsonObj.getJSONObject("body");
|
||||
if (bodyObj.containsKey("type")) {
|
||||
String type = bodyObj.getString("type");
|
||||
if (StringUtils.equals(type, "WWW_FORM")) {
|
||||
apiInfoDTO.setResponseBodyParamType("x-www-from-urlencoded");
|
||||
} else if (StringUtils.equals(type, "Form Data")) {
|
||||
apiInfoDTO.setResponseBodyParamType("form-data");
|
||||
} else {
|
||||
apiInfoDTO.setResponseBodyParamType(type);
|
||||
}
|
||||
if (StringUtils.equalsAny(type, "JSON", "XML", "Raw")) {
|
||||
|
||||
//判断是否是JsonSchema
|
||||
boolean isJsonSchema = false;
|
||||
if (bodyObj.containsKey("format")) {
|
||||
String foramtValue = String.valueOf(bodyObj.get("format"));
|
||||
if (StringUtils.equals("JSON-SCHEMA", foramtValue)) {
|
||||
isJsonSchema = true;
|
||||
}
|
||||
}
|
||||
if (isJsonSchema) {
|
||||
// apiInfoDTO.setRequestBodyParamType("JSON-SCHEMA");
|
||||
apiInfoDTO.setResponseBodyParamType("JSON-SCHEMA");
|
||||
apiInfoDTO.setJsonSchemaResponseBody(bodyObj);
|
||||
// apiInfoDTO.setJsonSchemaBody(bodyObj);
|
||||
} else {
|
||||
if (bodyObj.containsKey("raw")) {
|
||||
String raw = bodyObj.getString("raw");
|
||||
apiInfoDTO.setResponseBodyStrutureData(raw);
|
||||
//转化jsonObje 或者 jsonArray
|
||||
this.setPreviewData(previewJsonArray, raw);
|
||||
}
|
||||
}
|
||||
// if (bodyObj.containsKey("raw")) {
|
||||
// String raw = bodyObj.getString("raw");
|
||||
// apiInfoDTO.setResponseBodyStrutureData(raw);
|
||||
// }
|
||||
} else if (StringUtils.equalsAny(type, "Form Data", "WWW_FORM")) {
|
||||
if (bodyObj.containsKey("kvs")) {
|
||||
JSONArray bodyParamArr = new JSONArray();
|
||||
JSONArray kvsArr = bodyObj.getJSONArray("kvs");
|
||||
for (int i = 0; i < kvsArr.size(); i++) {
|
||||
JSONObject kv = kvsArr.getJSONObject(i);
|
||||
if (kv.containsKey("name")) {
|
||||
bodyParamArr.add(kv);
|
||||
}
|
||||
}
|
||||
apiInfoDTO.setResponseBodyFormData(bodyParamArr.toJSONString());
|
||||
}
|
||||
} else if (StringUtils.equals(type, "BINARY")) {
|
||||
if (bodyObj.containsKey("binary")) {
|
||||
List<Map<String, String>> bodyParamList = new ArrayList<>();
|
||||
JSONArray kvsArr = bodyObj.getJSONArray("kvs");
|
||||
for (int i = 0; i < kvsArr.size(); i++) {
|
||||
JSONObject kv = kvsArr.getJSONObject(i);
|
||||
if (kv.containsKey("description") && kv.containsKey("files")) {
|
||||
Map<String, String> bodyMap = new HashMap<>();
|
||||
|
||||
String name = kv.getString("description");
|
||||
JSONArray fileArr = kv.getJSONArray("files");
|
||||
String value = "";
|
||||
for (int j = 0; j < fileArr.size(); j++) {
|
||||
JSONObject fileObj = fileArr.getJSONObject(j);
|
||||
if (fileObj.containsKey("name")) {
|
||||
value += fileObj.getString("name") + " ;";
|
||||
}
|
||||
}
|
||||
bodyMap.put("name", name);
|
||||
bodyMap.put("value", value);
|
||||
bodyParamList.add(bodyMap);
|
||||
}
|
||||
}
|
||||
apiInfoDTO.setResponseBodyFormData(JSONArray.toJSONString(bodyParamList));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// 赋值响应码
|
||||
if (responseJsonObj != null && responseJsonObj.containsKey("statusCode")) {
|
||||
try {
|
||||
JSONArray responseStatusDataArr = new JSONArray();
|
||||
JSONArray statusArr = responseJsonObj.getJSONArray("statusCode");
|
||||
for (int index = 0; index < statusArr.size(); index++) {
|
||||
JSONObject statusObj = statusArr.getJSONObject(index);
|
||||
if (statusObj.containsKey("name") && statusObj.containsKey("value")) {
|
||||
responseStatusDataArr.add(statusObj);
|
||||
}
|
||||
}
|
||||
apiInfoDTO.setResponseCode(responseStatusDataArr.toJSONString());
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!previewJsonArray.isEmpty()) {
|
||||
apiInfoDTO.setRequestPreviewData(previewJsonArray);
|
||||
}
|
||||
apiInfoDTO.setSelectedFlag(true);
|
||||
return apiInfoDTO;
|
||||
}
|
||||
|
||||
private JSONObject genJSONObject(String request) {
|
||||
JSONObject returnObj = null;
|
||||
try {
|
||||
returnObj = JSONObject.parseObject(request);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return returnObj;
|
||||
}
|
||||
|
||||
private void setPreviewData(JSONArray previewArray, String data) {
|
||||
try {
|
||||
JSONObject previewObj = JSONObject.parseObject(data);
|
||||
previewArray.add(previewObj);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
try {
|
||||
previewArray = JSONArray.parseArray(data);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 api接口文档分享信息
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
package io.metersphere.api.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import io.metersphere.api.dto.automation.TcpTreeTableDataStruct;
|
||||
import io.metersphere.api.dto.automation.parse.TcpTreeTableDataParser;
|
||||
import io.metersphere.api.dto.definition.SaveApiDefinitionRequest;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler;
|
||||
import io.metersphere.api.dto.scenario.KeyValue;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -52,7 +56,11 @@ public class TcpApiParamService {
|
|||
if (testElement instanceof MsTCPSampler) {
|
||||
tcpSampler = (MsTCPSampler) testElement;
|
||||
String reportType = tcpSampler.getReportType();
|
||||
if (StringUtils.isNotEmpty(reportType)) {
|
||||
if (CollectionUtils.isNotEmpty(tcpSampler.getEsbDataStruct())) {
|
||||
EsbApiParamService esbApiParamService = CommonBeanFactory.getBean(EsbApiParamService.class);
|
||||
List<KeyValue> keyValueList = esbApiParamService.genKeyValueListByDataStruct(tcpSampler, JSONArray.toJSONString(tcpSampler.getEsbDataStruct()));
|
||||
tcpSampler.setParameters(keyValueList);
|
||||
}else if (StringUtils.isNotEmpty(reportType)) {
|
||||
switch (reportType) {
|
||||
case "raw":
|
||||
tcpSampler.setRequest(tcpSampler.getRawDataStruct());
|
||||
|
|
|
@ -495,6 +495,9 @@ export default {
|
|||
if (projectData && projectData.apiQuickMenu === 'api') {
|
||||
this.handleTabAdd("ADD");
|
||||
} else {
|
||||
let newApi = {
|
||||
|
||||
};
|
||||
this.handleTabsEdit(this.$t('api_test.definition.request.fast_debug'), "debug");
|
||||
}
|
||||
})
|
||||
|
|
|
@ -0,0 +1,974 @@
|
|||
<template>
|
||||
<div>
|
||||
<ms-environment-select
|
||||
:project-id="projectId"
|
||||
:is-read-only="false"
|
||||
:useEnvironment='useEnvironment'
|
||||
@setEnvironment="setEnvironment"
|
||||
class="ms-api-button"
|
||||
ref="environmentSelect"/>
|
||||
<el-tabs v-model="apiDefaultTab" @edit="closeConfirm" class="api-base-view-tab" @tab-click="addTab">
|
||||
<el-tab-pane name="trash" :label="$t('commons.trash')" v-show="trashEnable">
|
||||
<api-test-base-container>
|
||||
<ms-api-module
|
||||
slot="aside"
|
||||
:show-operator="true"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
@protocolChange="handleProtocolChange"
|
||||
@refreshTable="refresh"
|
||||
@exportAPI="exportAPI"
|
||||
@debug="debug"
|
||||
@saveAsEdit="editApi"
|
||||
@setModuleOptions="setModuleOptions"
|
||||
@setNodeTree="setNodeTree"
|
||||
@enableTrash="enableTrash"
|
||||
@schedule="handleTabsEdit($t('api_test.api_import.timing_synchronization'), 'SCHEDULE')"
|
||||
:type="'edit'"
|
||||
page-source="definition"
|
||||
:total='total'
|
||||
:current-version="currentVersion"
|
||||
ref="nodeTree"/>
|
||||
<div slot="mainContainer">
|
||||
<ms-tab-button
|
||||
v-if="this.trashTabInfo.type === 'list'"
|
||||
:active-dom.sync="trashActiveDom"
|
||||
:left-tip="$t('api_test.definition.api_title')"
|
||||
:right-tip="$t('api_test.definition.case_title')"
|
||||
:middle-button-enable="false"
|
||||
left-content="API"
|
||||
right-content="CASE"
|
||||
>
|
||||
<template v-slot:version>
|
||||
<version-select v-xpack :project-id="projectId" :version-id="trashVersion"
|
||||
@changeVersion="changeVersion"/>
|
||||
</template>
|
||||
<!-- 列表集合 -->
|
||||
<ms-api-list
|
||||
v-if="trashActiveDom==='left'"
|
||||
@runTest="runTest"
|
||||
@refreshTree="refreshTree"
|
||||
@getTrashApi="getTrashApi"
|
||||
:module-tree="nodeTree"
|
||||
:module-options="moduleOptions"
|
||||
:current-protocol="currentProtocol"
|
||||
:current-version="currentVersion"
|
||||
:visible="visible"
|
||||
:currentRow="currentRow"
|
||||
:select-node-ids="selectNodeIds"
|
||||
:trash-enable="true"
|
||||
:queryDataType="queryDataType"
|
||||
:selectDataRange="selectDataRange"
|
||||
:is-read-only="isReadOnly"
|
||||
@changeSelectDataRangeAll="changeSelectDataRangeAll"
|
||||
@editApi="editApi"
|
||||
@handleCase="handleCase"
|
||||
@showExecResult="showExecResult"
|
||||
@refreshTable="refresh"
|
||||
:init-api-table-opretion="initApiTableOpretion"
|
||||
@updateInitApiTableOpretion="updateInitApiTableOpretion"
|
||||
ref="trashApiList"/>
|
||||
<!--测试用例列表-->
|
||||
<api-case-simple-list
|
||||
v-if="trashActiveDom==='right'"
|
||||
:current-protocol="currentProtocol"
|
||||
:current-version="currentVersion"
|
||||
:visible="visible"
|
||||
:currentRow="currentRow"
|
||||
:select-node-ids="selectNodeIds"
|
||||
:trash-enable="true"
|
||||
:queryDataType="queryDataType"
|
||||
:is-read-only="isReadOnly"
|
||||
@changeSelectDataRangeAll="changeSelectDataRangeAll"
|
||||
@handleCase="handleCase"
|
||||
@refreshTable="refresh"
|
||||
@showExecResult="showExecResult"
|
||||
ref="trashCaseList"/>
|
||||
</ms-tab-button>
|
||||
</div>
|
||||
</api-test-base-container>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane name="default" :label="$t('api_test.definition.api_title')">
|
||||
<api-test-base-container>
|
||||
<ms-api-module
|
||||
slot="aside"
|
||||
:show-operator="true"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
@protocolChange="handleProtocolChange"
|
||||
@refreshTable="refresh"
|
||||
@exportAPI="exportAPI"
|
||||
@debug="debug"
|
||||
@saveAsEdit="editApi"
|
||||
@setModuleOptions="setModuleOptions"
|
||||
@setNodeTree="setNodeTree"
|
||||
@enableTrash="enableTrash"
|
||||
@schedule="handleTabsEdit($t('api_test.api_import.timing_synchronization'), 'SCHEDULE')"
|
||||
:type="'edit'"
|
||||
page-source="definition"
|
||||
:total='total'
|
||||
:current-version="currentVersion"
|
||||
ref="nodeTree"/>
|
||||
<div slot="mainContainer">
|
||||
<ms-tab-button
|
||||
:active-dom.sync="activeDom"
|
||||
:left-tip="$t('api_test.definition.api_title')"
|
||||
:right-tip="$t('api_test.definition.doc_title')"
|
||||
:middle-tip="$t('api_test.definition.case_title')"
|
||||
left-content="API"
|
||||
middle-content="CASE"
|
||||
:right-content="$t('api_test.definition.doc_title')"
|
||||
:right-button-enable="currentProtocol === 'HTTP' "
|
||||
>
|
||||
<template v-slot:version>
|
||||
<version-select v-xpack :project-id="projectId" @changeVersion="changeVersion"/>
|
||||
</template>
|
||||
<ms-api-list
|
||||
v-if="activeDom==='left'"
|
||||
@getTrashApi="getTrashApi"
|
||||
:module-tree="nodeTree"
|
||||
:module-options="moduleOptions"
|
||||
:current-protocol="currentProtocol"
|
||||
:current-version="currentVersion"
|
||||
:visible="visible"
|
||||
:currentRow="currentRow"
|
||||
:select-node-ids="selectNodeIds"
|
||||
:trash-enable="false"
|
||||
:queryDataType="queryDataType"
|
||||
:selectDataRange="selectDataRange"
|
||||
:is-read-only="isReadOnly"
|
||||
@runTest="runTest"
|
||||
@handleTestCase="handleTestCase"
|
||||
@refreshTree="refreshTree"
|
||||
@changeSelectDataRangeAll="changeSelectDataRangeAll"
|
||||
@editApi="editApi"
|
||||
@showApi="showApi"
|
||||
@copyApi="copyApi"
|
||||
@handleCase="handleCase"
|
||||
@showExecResult="showExecResult"
|
||||
@refreshTable="refresh"
|
||||
:init-api-table-opretion="initApiTableOpretion"
|
||||
@updateInitApiTableOpretion="updateInitApiTableOpretion"
|
||||
ref="apiDefList"/>
|
||||
<!--测试用例列表-->
|
||||
<api-case-simple-list
|
||||
v-if="activeDom==='middle'"
|
||||
:current-protocol="currentProtocol"
|
||||
:current-version="currentVersion"
|
||||
:visible="visible"
|
||||
:currentRow="currentRow"
|
||||
:select-node-ids="selectNodeIds"
|
||||
:trash-enable="false"
|
||||
:queryDataType="queryDataType"
|
||||
:is-read-only="isReadOnly"
|
||||
@changeSelectDataRangeAll="changeSelectDataRangeAll"
|
||||
@handleCase="handleCase"
|
||||
@refreshTable="refresh"
|
||||
@showExecResult="showExecResult"
|
||||
ref="caseList"/>
|
||||
<api-documents-page
|
||||
class="api-doc-page"
|
||||
v-if="activeDom==='right' && currentProtocol==='HTTP'"
|
||||
:project-id="projectId"
|
||||
:trash-enable="trashEnable"
|
||||
:version-id="currentVersion"
|
||||
:module-ids="selectNodeIds"
|
||||
ref="documentsPage"/>
|
||||
</ms-tab-button>
|
||||
</div>
|
||||
</api-test-base-container>
|
||||
</el-tab-pane>
|
||||
|
||||
|
||||
<el-tab-pane v-for="(item) in apiTabs"
|
||||
:key="item.name"
|
||||
:label="item.title"
|
||||
:closable="item.closable"
|
||||
:name="item.name">
|
||||
<template v-slot:version>
|
||||
<version-select v-xpack :project-id="projectId" @changeVersion="changeVersion"/>
|
||||
</template>
|
||||
<!-- 列表集合 -->
|
||||
|
||||
<!-- 添加/编辑测试窗口-->
|
||||
<div v-if="item.type=== 'ADD' ||item.type=== 'Case' ||item.type === 'TEST'||item.type === 'debug'"
|
||||
class="ms-api-div">
|
||||
<api-info-container :api-id="item.api.id" :current-api="item.api" :project-id="projectId"
|
||||
:module-options="moduleOptions" :current-protocol="currentProtocol"
|
||||
@saveApi="saveApi" @updateApiStatus="updateApiStatus" @saveApiAndCase="saveApiAndCase" @saveCaseCallback="saveCaseCallback"
|
||||
:operation-type="item.api.operationType"></api-info-container>
|
||||
</div>
|
||||
<!-- 定时任务 -->
|
||||
<div v-if="item.type=== 'SCHEDULE'" class="ms-api-div">
|
||||
<api-schedule :param="param" :module-options="nodeTree" ref="apiSchedules"/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane name="add" v-if="hasPermission('PROJECT_API_DEFINITION:READ+CREATE_API')">
|
||||
<template v-slot:label>
|
||||
<el-dropdown @command="handleCommand">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini"/>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="debug" v-permission="['PROJECT_API_DEFINITION:READ+DEBUG']">
|
||||
{{ $t('api_test.definition.request.fast_debug') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="ADD" v-permission="['PROJECT_API_DEFINITION:READ+CREATE_API']">
|
||||
{{ $t('api_test.definition.request.title') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="CLOSE_ALL">{{ $t('api_test.definition.request.close_all_label') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
import MsApiModule from "@/business/components/api/definition/components/module/ApiModule";
|
||||
import ApiTestBaseContainer from "@/business/components/common/layout/ApiTestBaseContainer";
|
||||
import {getCurrentProjectID, getCurrentUser, getCurrentUserId, getUUID, hasPermission} from "@/common/js/utils";
|
||||
import MsContainer from "@/business/components/common/components/MsContainer";
|
||||
import MsApiList from "@/business/components/api/definition/components/list/ApiList";
|
||||
import MsTabButton from "@/business/components/common/components/MsTabButton";
|
||||
import VersionSelect from "@/business/components/xpack/version/VersionSelect";
|
||||
import MsEditCompleteContainer from "@/business/components/api/definition/components/EditCompleteContainer";
|
||||
import ApiInfoContainer from "@/business/components/api/definition/components/apiinfo/ApiInfoContainer";
|
||||
import ApiCaseSimpleList from "@/business/components/api/definition/components/list/ApiCaseSimpleList";
|
||||
import MsEnvironmentSelect from "@/business/components/api/definition/components/case/MsEnvironmentSelect";
|
||||
|
||||
import MsDebugHttpPage from "./components/debug/DebugHttpPage";
|
||||
import MsDebugJdbcPage from "./components/debug/DebugJdbcPage";
|
||||
import MsDebugTcpPage from "./components/debug/DebugTcpPage";
|
||||
import MsDebugDubboPage from "./components/debug/DebugDubboPage";
|
||||
import MsRunTestHttpPage from "./components/runtest/RunTestHTTPPage";
|
||||
import MsRunTestTcpPage from "./components/runtest/RunTestTCPPage";
|
||||
import MsRunTestSqlPage from "./components/runtest/RunTestSQLPage";
|
||||
import MsRunTestDubboPage from "./components/runtest/RunTestDubboPage";
|
||||
import {createComponent} from "@/business/components/api/definition/components/jmeter/components";
|
||||
|
||||
|
||||
export default {
|
||||
name: "ApiDefinitionBaseView",
|
||||
components: {
|
||||
MsApiModule, ApiTestBaseContainer, MsContainer, MsApiList, MsTabButton, VersionSelect, MsEditCompleteContainer,
|
||||
MsDebugHttpPage, MsDebugJdbcPage, MsDebugTcpPage, MsDebugDubboPage,
|
||||
MsRunTestHttpPage, MsRunTestTcpPage, MsRunTestSqlPage, MsRunTestDubboPage,
|
||||
ApiInfoContainer, ApiCaseSimpleList, MsEnvironmentSelect
|
||||
},
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
currentRow: {
|
||||
type: Object,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
redirectID: '',
|
||||
total: 0,
|
||||
renderComponent: true,
|
||||
selectDataRange: 'all',
|
||||
showCasePage: true,
|
||||
apiDefaultTab: 'default',
|
||||
currentProtocol: 'HTTP',
|
||||
currentModule: null,
|
||||
selectNodeIds: [],
|
||||
currentApi: {},
|
||||
moduleOptions: [],
|
||||
trashEnable: false,
|
||||
apiTabs: [],
|
||||
trashTabInfo: {
|
||||
title: this.$t('api_test.definition.api_title'),
|
||||
name: 'default',
|
||||
type: "list",
|
||||
closable: false
|
||||
},
|
||||
activeDom: "left",
|
||||
trashActiveDom: "left",
|
||||
syncTabs: [],
|
||||
nodeTree: [],
|
||||
currentModulePath: "",
|
||||
//影响API表格刷新的操作。 为了防止高频率刷新模块列表用。如果是模块更新而造成的表格刷新,则不回调模块刷新方法
|
||||
initApiTableOpretion: 'init',
|
||||
param: {},
|
||||
useEnvironment: String,
|
||||
activeTab: "api",
|
||||
currentVersion: null,
|
||||
trashVersion: null,
|
||||
project: null,
|
||||
};
|
||||
},
|
||||
activated() {
|
||||
},
|
||||
watch: {
|
||||
currentProtocol() {
|
||||
if (this.activeDom === 'right') {
|
||||
this.activeDom = 'left';
|
||||
}
|
||||
this.handleCommand("CLOSE_ALL");
|
||||
},
|
||||
selectNodeIds() {
|
||||
this.apiDefaultTab = "default";
|
||||
},
|
||||
redirectID() {
|
||||
this.renderComponent = false;
|
||||
this.$nextTick(() => {
|
||||
// 在 DOM 中添加 my-component 组件
|
||||
this.renderComponent = true;
|
||||
});
|
||||
},
|
||||
'$route'(to, from) { // 路由改变时,把接口定义界面中的 ctrl s 保存快捷键监听移除
|
||||
if (to.path.indexOf('/api/definition') === -1) {
|
||||
if (this.$refs && this.$refs.apiConfig) {
|
||||
this.$refs.apiConfig.forEach(item => {
|
||||
item.removeListener();
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.initBaseData();
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
computed: {
|
||||
queryDataType: function () {
|
||||
let routeParam = this.$route.params.dataType;
|
||||
let redirectIDParam = this.$route.params.redirectID;
|
||||
this.changeRedirectParam(redirectIDParam);
|
||||
return routeParam;
|
||||
},
|
||||
isReadOnly() {
|
||||
return false;
|
||||
},
|
||||
projectId() {
|
||||
return getCurrentProjectID();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
initBaseData() {
|
||||
this.$get('/project/get/' + this.projectId, res => {
|
||||
let projectData = res.data;
|
||||
if (projectData) {
|
||||
this.project = projectData;
|
||||
}
|
||||
})
|
||||
},
|
||||
setEnvironment(data) {
|
||||
if (data) {
|
||||
this.useEnvironment = data.id;
|
||||
this.$store.state.useEnvironment = data.id;
|
||||
this.addEnv(data.id);
|
||||
}
|
||||
},
|
||||
addEnv(envId) {
|
||||
this.$post('/api/definition/env/create', {userId: getCurrentUserId(), envId: envId}, response => {
|
||||
});
|
||||
},
|
||||
getTrashApi() {
|
||||
this.$get("/api/module/trashCount/" + this.projectId + "/" + this.currentProtocol, response => {
|
||||
this.total = response.data;
|
||||
});
|
||||
},
|
||||
updateApiStatus(operationType, apiName) {
|
||||
for (let index in this.apiTabs) {
|
||||
let tab = this.apiTabs[index];
|
||||
if (tab.name === this.apiDefaultTab) {
|
||||
tab.api.operationType = operationType;
|
||||
if (operationType === 'edit') {
|
||||
tab.title = this.$t('api_test.definition.request.edit_api') + "-" + apiName;
|
||||
} else {
|
||||
tab.title = this.$t('api_test.definition.request.show_api') + "-" + apiName;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
getEnv() {
|
||||
this.$get("/api/definition/env/get/" + getCurrentUserId() + "/" + getCurrentProjectID(), response => {
|
||||
let env = response.data;
|
||||
if (env) {
|
||||
this.$store.state.useEnvironment = env.envId;
|
||||
this.useEnvironment = env.envId;
|
||||
} else {
|
||||
this.$store.state.useEnvironment = "";
|
||||
this.useEnvironment = "";
|
||||
}
|
||||
});
|
||||
},
|
||||
hasPermission,
|
||||
getPath(id, arr) {
|
||||
if (id === null) {
|
||||
return null;
|
||||
}
|
||||
if (arr) {
|
||||
arr.forEach(item => {
|
||||
if (item.id === id) {
|
||||
this.currentModulePath = item.path;
|
||||
}
|
||||
if (item.children && item.children.length > 0) {
|
||||
this.getPath(id, item.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
changeRedirectParam(redirectIDParam) {
|
||||
this.redirectID = redirectIDParam;
|
||||
},
|
||||
createApiStruct() {
|
||||
let request = {};
|
||||
let method = this.currentProtocol;
|
||||
let response = {};
|
||||
if (this.currentProtocol === 'HTTP') {
|
||||
method = "GET";
|
||||
request = createComponent("HTTPSamplerProxy");
|
||||
if (!request.path) {
|
||||
request.path = "";
|
||||
}
|
||||
response.type = "HTTP";
|
||||
response.headers = [];
|
||||
response.statusCode = [];
|
||||
response.body = {
|
||||
"binary": [],
|
||||
"json": false,
|
||||
"kV": false,
|
||||
"kvs": [],
|
||||
"oldKV": true,
|
||||
"type": "KeyValue",
|
||||
"valid": false,
|
||||
"xml": false
|
||||
};
|
||||
} else if (this.currentProtocol === 'TCP') {
|
||||
request = createComponent("TCPSampler");
|
||||
} else if (this.currentProtocol === 'JDBC' || this.currentProtocol === 'SQL') {
|
||||
request = createComponent("JDBCSampler");
|
||||
} else if (this.currentProtocol === 'DUBBO') {
|
||||
request = createComponent("DubboSampler");
|
||||
}
|
||||
let newApi = {
|
||||
id: getUUID(),
|
||||
operationType: 'debug',
|
||||
protocol: this.currentProtocol,
|
||||
environmentId: "",
|
||||
path: "",
|
||||
method: method,
|
||||
request: request,
|
||||
response: response,
|
||||
};
|
||||
return newApi;
|
||||
},
|
||||
addTab(tab) {
|
||||
if (tab.name === 'add') {
|
||||
if (this.project && this.project.apiQuick === 'api') {
|
||||
this.handleTabAdd("ADD");
|
||||
} else {
|
||||
let newApiStruct = this.createApiStruct();
|
||||
this.handleTabsEdit(this.$t('api_test.definition.request.fast_debug'), "debug", newApiStruct);
|
||||
}
|
||||
} else if (tab.name === 'trash') {
|
||||
if (this.$refs.trashApiList) {
|
||||
this.$refs.trashApiList.initTable();
|
||||
}
|
||||
if (this.$refs.trashCaseList) {
|
||||
this.$refs.trashCaseList.initTable();
|
||||
}
|
||||
} else if (tab.name === 'default') {
|
||||
this.refresh();
|
||||
}
|
||||
if (this.$refs.apiConfig) {
|
||||
this.$refs.apiConfig.forEach(item => {
|
||||
if (item) {
|
||||
item.removeListener();
|
||||
}
|
||||
}); // 删除所有tab的 ctrl + s 监听
|
||||
let tabs = this.apiTabs;
|
||||
let index = tabs.findIndex(item => item.name === tab.name); // 找到当前选中tab的index
|
||||
if (index !== -1 && this.$refs.apiConfig[index - 1]) {
|
||||
this.$refs.apiConfig[index - 1].addListener(); // 为选中tab添加 ctrl + s 监听(index-1的原因是要除去第一个固有tab)
|
||||
}
|
||||
}
|
||||
},
|
||||
handleCommand(e) {
|
||||
switch (e) {
|
||||
case "ADD":
|
||||
this.handleTabAdd(e);
|
||||
break;
|
||||
case "TEST":
|
||||
this.handleTabsEdit(this.$t("commons.api"), e);
|
||||
break;
|
||||
case "CLOSE_ALL":
|
||||
this.handleTabClose();
|
||||
break;
|
||||
default:
|
||||
this.handleTabsEdit(this.$t('api_test.definition.request.fast_debug'), "debug");
|
||||
break;
|
||||
}
|
||||
},
|
||||
handleApiAndCaseTabAdd(e, api) {
|
||||
if (!this.projectId) {
|
||||
this.$warning(this.$t('commons.check_project_tip'));
|
||||
return;
|
||||
}
|
||||
this.currentModulePath = "";
|
||||
if (this.nodeTree && this.nodeTree.length > 0) {
|
||||
api.moduleId = this.nodeTree[0].id;
|
||||
this.getPath(this.nodeTree[0].id, this.moduleOptions);
|
||||
api.modulePath = this.currentModulePath;
|
||||
}
|
||||
if (this.selectNodeIds && this.selectNodeIds.length > 0) {
|
||||
api.moduleId = this.selectNodeIds[0];
|
||||
this.getPath(this.selectNodeIds[0], this.moduleOptions);
|
||||
api.modulePath = this.currentModulePath;
|
||||
}
|
||||
this.handleTabsEdit(this.$t('test_track.case.create_case'), e, api);
|
||||
},
|
||||
handleTabAdd(e) {
|
||||
if (!this.projectId) {
|
||||
this.$warning(this.$t('commons.check_project_tip'));
|
||||
return;
|
||||
}
|
||||
|
||||
let request = {};
|
||||
let method = this.currentProtocol;
|
||||
let response = {};
|
||||
if (this.currentProtocol === 'HTTP') {
|
||||
method = "GET";
|
||||
request = createComponent("HTTPSamplerProxy");
|
||||
if (!request.path) {
|
||||
request.path = "";
|
||||
}
|
||||
response.type = "HTTP";
|
||||
response.headers = [];
|
||||
response.statusCode = [];
|
||||
response.body = {
|
||||
"binary": [],
|
||||
"json": false,
|
||||
"kV": false,
|
||||
"kvs": [],
|
||||
"oldKV": true,
|
||||
"type": "KeyValue",
|
||||
"valid": false,
|
||||
"xml": false
|
||||
};
|
||||
} else if (this.currentProtocol === 'TCP') {
|
||||
request = createComponent("TCPSampler");
|
||||
} else if (this.currentProtocol === 'JDBC' || this.currentProtocol === 'SQL') {
|
||||
request = createComponent("JDBCSampler");
|
||||
} else if (this.currentProtocol === 'DUBBO') {
|
||||
request = createComponent("DubboSampler");
|
||||
}
|
||||
let api = {
|
||||
status: "Underway",
|
||||
method: method,
|
||||
userId: getCurrentUser().id,
|
||||
url: "",
|
||||
id: getUUID(),
|
||||
protocol: this.currentProtocol,
|
||||
environmentId: "",
|
||||
remark: "",
|
||||
operationType: "create",
|
||||
moduleId: 'default-module',
|
||||
modulePath: "/" + this.$t("commons.module_title"),
|
||||
request: request,
|
||||
response: response
|
||||
};
|
||||
this.currentModulePath = "";
|
||||
if (this.nodeTree && this.nodeTree.length > 0) {
|
||||
api.moduleId = this.nodeTree[0].id;
|
||||
this.getPath(this.nodeTree[0].id, this.moduleOptions);
|
||||
api.modulePath = this.currentModulePath;
|
||||
}
|
||||
|
||||
if (this.selectNodeIds && this.selectNodeIds.length > 0) {
|
||||
api.moduleId = this.selectNodeIds[0];
|
||||
this.getPath(this.selectNodeIds[0], this.moduleOptions);
|
||||
api.modulePath = this.currentModulePath;
|
||||
}
|
||||
this.handleTabsEdit(this.$t('api_test.definition.request.title'), e, api);
|
||||
},
|
||||
handleTabClose() {
|
||||
let message = "";
|
||||
let tab = this.apiTabs;
|
||||
delete tab[0];
|
||||
tab.forEach(t => {
|
||||
if (t.type === 'ADD' && t.api && this.$store.state.apiMap.has(t.api.id) && (this.$store.state.apiMap.get(t.api.id).get("responseChange") === true || this.$store.state.apiMap.get(t.api.id).get("requestChange") === true ||
|
||||
this.$store.state.apiMap.get(t.api.id).get("fromChange") === true)) {
|
||||
message += t.api.name + ",";
|
||||
}
|
||||
});
|
||||
if (message !== "") {
|
||||
this.$alert(this.$t('commons.api') + " [ " + message.substr(0, message.length - 1) + " ] " + this.$t('commons.confirm_info'), '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
this.$store.state.apiMap.clear();
|
||||
this.apiTabs = [];
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.apiTabs = [];
|
||||
}
|
||||
this.apiDefaultTab = "default";
|
||||
},
|
||||
closeConfirm(targetName) {
|
||||
let tab = this.apiTabs;
|
||||
tab.forEach(t => {
|
||||
if (t.name === targetName) {
|
||||
if (t.api && this.$store.state.apiMap.size > 0 && this.$store.state.apiMap.has(t.api.id)) {
|
||||
if (this.$store.state.apiMap.get(t.api.id).get("responseChange") === true || this.$store.state.apiMap.get(t.api.id).get("requestChange") === true ||
|
||||
this.$store.state.apiMap.get(t.api.id).get("fromChange") === true) {
|
||||
this.$alert(this.$t('commons.api') + " [ " + t.api.name + " ] " + this.$t('commons.confirm_info'), '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
this.$store.state.apiMap.delete(t.api.id);
|
||||
this.handleTabRemove(targetName);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.handleTabRemove(targetName);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
handleTabRemove(targetName) {
|
||||
let tabs = this.apiTabs;
|
||||
let activeName = this.apiDefaultTab;
|
||||
if (activeName === targetName) {
|
||||
tabs.forEach((tab, index) => {
|
||||
if (tab.name === targetName) {
|
||||
let nextTab = tabs[index + 1] || tabs[index - 1];
|
||||
if (nextTab) {
|
||||
activeName = nextTab.name;
|
||||
} else {
|
||||
activeName = "default";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
this.apiDefaultTab = activeName;
|
||||
this.apiTabs = tabs.filter(tab => tab.name !== targetName);
|
||||
this.refresh();
|
||||
},
|
||||
//创建左侧树的根目录模块
|
||||
createRootModel() {
|
||||
this.$refs.nodeTree.createRootModel();
|
||||
},
|
||||
handleMockTabsConfig(targetName, action, param) {
|
||||
if (!this.projectId) {
|
||||
this.$warning(this.$t('commons.check_project_tip'));
|
||||
return;
|
||||
}
|
||||
if (targetName === undefined || targetName === null) {
|
||||
targetName = this.$t('api_test.definition.request.title');
|
||||
}
|
||||
let newTabName = getUUID();
|
||||
this.apiTabs.push({
|
||||
title: targetName,
|
||||
name: newTabName,
|
||||
closable: true,
|
||||
type: action,
|
||||
mock: param,
|
||||
});
|
||||
this.apiDefaultTab = newTabName;
|
||||
},
|
||||
handleTabsEdit(targetName, action, api) {
|
||||
if (action === "debug" && !api) {
|
||||
api = this.createApiStruct();
|
||||
}
|
||||
if (!this.projectId) {
|
||||
this.$warning(this.$t('commons.check_project_tip'));
|
||||
return;
|
||||
}
|
||||
if (targetName === undefined || targetName === null) {
|
||||
targetName = this.$t('api_test.definition.request.title');
|
||||
}
|
||||
let newTabName = getUUID();
|
||||
if(action === "Case"){
|
||||
newTabName = api.id;
|
||||
}
|
||||
this.apiTabs.push({
|
||||
title: targetName,
|
||||
name: newTabName,
|
||||
closable: true,
|
||||
type: action,
|
||||
api: api,
|
||||
});
|
||||
if (action === "ADD") {
|
||||
this.activeTab = "api";
|
||||
}
|
||||
this.apiDefaultTab = newTabName;
|
||||
},
|
||||
debug(id) {
|
||||
this.handleTabsEdit(this.$t('api_test.definition.request.fast_debug'), "debug", id);
|
||||
},
|
||||
init() {
|
||||
let routeTestCase = this.$route.params.apiDefinition;
|
||||
if (routeTestCase) {
|
||||
this.editApi(routeTestCase);
|
||||
}
|
||||
let dataRange = this.$route.params.dataSelectRange;
|
||||
let dataType = this.$route.params.dataType;
|
||||
if (dataRange) {
|
||||
let selectParamArr = dataRange.split("edit:");
|
||||
if (selectParamArr.length === 2) {
|
||||
let scenarioId = selectParamArr[1];
|
||||
if (dataType === 'api') {
|
||||
this.$get('/api/definition/get/' + scenarioId, (response) => {
|
||||
this.editApi(response.data);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
showApi(row) {
|
||||
this.editApi(row, true);
|
||||
},
|
||||
editApi(row, isShowApi) {
|
||||
const index = this.apiTabs.find(p => p.api && p.api.id === row.id);
|
||||
if (!index) {
|
||||
let name = "";
|
||||
if (row.isCopy) {
|
||||
name = "copy" + "_" + row.name;
|
||||
row.name = "copy" + "_" + row.name;
|
||||
} else {
|
||||
if (row.name) {
|
||||
if (isShowApi) {
|
||||
name = this.$t('api_test.definition.request.show_api') + "-" + row.name;
|
||||
} else {
|
||||
name = this.$t('api_test.definition.request.edit_api') + "-" + row.name;
|
||||
}
|
||||
} else {
|
||||
name = this.$t('api_test.definition.request.title');
|
||||
}
|
||||
}
|
||||
this.activeTab = "api";
|
||||
if (row !== null && row.tags !== 'null' && row.tags !== '' && row.tags !== undefined) {
|
||||
if (Object.prototype.toString.call(row.tags).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object'
|
||||
&& Object.prototype.toString.call(row.tags).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'array') {
|
||||
row.tags = JSON.parse(row.tags);
|
||||
}
|
||||
}
|
||||
if (isShowApi) {
|
||||
row.operationType = "show";
|
||||
} else {
|
||||
row.operationType = "edit";
|
||||
}
|
||||
this.handleTabsEdit(name, "ADD", row);
|
||||
} else {
|
||||
this.apiDefaultTab = index.name;
|
||||
}
|
||||
},
|
||||
copyApi(row) {
|
||||
let name = "";
|
||||
if (row.isCopy) {
|
||||
name = "copy" + "_" + row.name;
|
||||
row.name = "copy" + "_" + row.name;
|
||||
}
|
||||
this.activeTab = "api";
|
||||
if (row !== null && row.tags !== 'null' && row.tags !== '' && row.tags !== undefined) {
|
||||
if (Object.prototype.toString.call(row.tags).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object'
|
||||
&& Object.prototype.toString.call(row.tags).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'array') {
|
||||
row.tags = JSON.parse(row.tags);
|
||||
}
|
||||
}
|
||||
this.handleTabsEdit(name, "ADD", row);
|
||||
},
|
||||
handleCase(api) {
|
||||
this.currentApi = api;
|
||||
this.showCasePage = false;
|
||||
},
|
||||
apiCaseClose() {
|
||||
this.showCasePage = true;
|
||||
},
|
||||
exportAPI(type, nodeTree) {
|
||||
if (this.activeDom !== 'left') {
|
||||
this.$warning('用例列表暂不支持导出,请切换成接口列表');
|
||||
return;
|
||||
}
|
||||
this.$refs.apiDefList[0].exportApi(type, nodeTree);
|
||||
},
|
||||
refreshModule() {
|
||||
this.$refs.nodeTree.list();
|
||||
},
|
||||
refresh(data) {
|
||||
if (this.$refs.caseList && this.$refs.caseList[0]) {
|
||||
this.$refs.caseList[0].initTable();
|
||||
}
|
||||
if (this.$refs.trashApiList) {
|
||||
this.$refs.trashApiList.initTable();
|
||||
}
|
||||
if (this.$refs.trashCaseList) {
|
||||
this.$refs.trashCaseList.initTable();
|
||||
}
|
||||
if (this.$refs.nodeTree) {
|
||||
this.$refs.nodeTree.list();
|
||||
}
|
||||
if (this.$refs.apiDefList) {
|
||||
if (this.$refs.apiDefList[0]) {
|
||||
this.$refs.apiDefList[0].initTable();
|
||||
} else {
|
||||
this.$refs.apiDefList.initTable();
|
||||
}
|
||||
}
|
||||
if (this.$refs.documentsPage && this.$refs.documentsPage[0]) {
|
||||
this.$refs.documentsPage[0].initApiDocSimpleList();
|
||||
}
|
||||
//this.$refs.nodeTree.list();
|
||||
},
|
||||
refreshTree() {
|
||||
this.$refs.nodeTree.list();
|
||||
},
|
||||
setTabTitle(data) {
|
||||
for (let index in this.apiTabs) {
|
||||
let tab = this.apiTabs[index];
|
||||
if (tab.name === this.apiDefaultTab) {
|
||||
tab.api.operationType = "show";
|
||||
tab.api.request = JSON.stringify(data.request);
|
||||
tab.api.response = JSON.stringify(data.response);
|
||||
tab.api.method = data.method;
|
||||
tab.title = this.$t('api_test.definition.request.show_api') + "-" + data.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
runTest(data) {
|
||||
this.activeTab = "test";
|
||||
this.handleTabsEdit(this.$t("commons.api"), "TEST", data);
|
||||
this.setTabTitle(data);
|
||||
},
|
||||
handleTestCase(row) {
|
||||
this.activeTab = "testCase";
|
||||
let name = "";
|
||||
if (row.name) {
|
||||
name = this.$t('api_test.definition.request.edit_api') + "-" + row.name;
|
||||
} else {
|
||||
name = this.$t('api_test.definition.request.title');
|
||||
}
|
||||
if (row !== null && row.tags !== 'null' && row.tags !== '' && row.tags !== undefined) {
|
||||
if (Object.prototype.toString.call(row.tags).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object'
|
||||
&& Object.prototype.toString.call(row.tags).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'array') {
|
||||
row.tags = JSON.parse(row.tags);
|
||||
}
|
||||
}
|
||||
this.handleTabsEdit(name, "TEST", row);
|
||||
},
|
||||
mockConfig(data) {
|
||||
let targetName = this.$t("commons.mock") + "-" + data.apiName;
|
||||
this.handleMockTabsConfig(targetName, "MOCK", data);
|
||||
},
|
||||
saveApi(data) {
|
||||
this.setTabTitle(data);
|
||||
},
|
||||
|
||||
showExecResult(row) {
|
||||
this.debug(row);
|
||||
},
|
||||
nodeChange(node, nodeIds, pNodes) {
|
||||
this.initApiTableOpretion = "selectNodeIds";
|
||||
this.selectNodeIds = nodeIds;
|
||||
},
|
||||
handleProtocolChange(protocol) {
|
||||
this.initApiTableOpretion = "currentProtocol";
|
||||
this.currentProtocol = protocol;
|
||||
},
|
||||
setModuleOptions(data) {
|
||||
this.moduleOptions = data;
|
||||
},
|
||||
setNodeTree(data) {
|
||||
this.nodeTree = data;
|
||||
},
|
||||
changeSelectDataRangeAll(tableType) {
|
||||
this.$route.params.dataSelectRange = 'all';
|
||||
},
|
||||
enableTrash(data) {
|
||||
this.initApiTableOpretion = "trashEnable";
|
||||
this.trashEnable = data;
|
||||
this.trashVersion = this.currentVersion
|
||||
if (data) {
|
||||
this.apiDefaultTab = "trash";
|
||||
} else {
|
||||
this.apiDefaultTab = "default";
|
||||
}
|
||||
},
|
||||
updateInitApiTableOpretion(param) {
|
||||
this.initApiTableOpretion = param;
|
||||
},
|
||||
changeVersion(currentVersion) {
|
||||
this.trashVersion = null;
|
||||
this.currentVersion = currentVersion || null;
|
||||
},
|
||||
saveApiAndCase(apiStruct) {
|
||||
apiStruct.operationType = "addApiAndCase";
|
||||
apiStruct.id = getUUID();
|
||||
this.handleApiAndCaseTabAdd("Case", apiStruct);
|
||||
},
|
||||
saveCaseCallback(apiStruct){
|
||||
this.closeConfirm(apiStruct.id);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.ms-api-div {
|
||||
overflow-y: auto;
|
||||
height: calc(100vh - 125px)
|
||||
}
|
||||
|
||||
/deep/ .el-main {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/deep/ .api-base-view-tab > .el-tabs__header {
|
||||
width: calc(100% - 230px);
|
||||
margin: 0px 5px 0px 5px
|
||||
}
|
||||
|
||||
/deep/ .api-base-view-tab > .el-tabs__nav-scroll {
|
||||
width: calc(100% - 10px);
|
||||
}
|
||||
|
||||
/deep/ .el-card {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
/deep/ .api-component {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.ms-api-button {
|
||||
position: absolute;
|
||||
top: 86px;
|
||||
right: 10px;
|
||||
padding: 0;
|
||||
background: 0 0;
|
||||
border: none;
|
||||
outline: 0;
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
font-size: 16px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/deep/ .el-table__empty-block {
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
padding-right: 100%;
|
||||
}
|
||||
|
||||
.version-select {
|
||||
padding-left: 10px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,314 @@
|
|||
<template>
|
||||
<div v-if="operationType === 'edit' || operationType === 'create'|| operationType === 'debug'">
|
||||
<api-definition-edit v-loading="loading" :api="currentApi" :module-options="moduleOptions"
|
||||
:protocol="protocol" :project-id="projectId" :is-edit="operationType !== 'debug'"
|
||||
@saveApiAndCase="saveApiAndCase" @saveApi="saveApi"/>
|
||||
</div>
|
||||
<div v-else-if="operationType === 'addApiAndCase'">
|
||||
<api-case-edit v-loading="loading" :api="currentApi" :module-options="moduleOptions"
|
||||
:protocol="protocol" :project-id="projectId" :is-edit="operationType !== 'debug'"
|
||||
@saveApi="saveApiBeforeCase"/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<api-definition-information v-show="apiInfo && apiInfo.id" v-loading="loading"
|
||||
:api-id="apiId"
|
||||
:project-id="projectId" :current-protocol="protocol"
|
||||
:current-api="currentApi" :api-info="apiInfo"
|
||||
@editApi="editApi"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ApiTestBaseContainer from "@/business/components/common/layout/ApiTestBaseContainer";
|
||||
import ApiInformation from "@/business/components/api/definition/components/document/components/ApiInformation";
|
||||
import ApiDefinitionEdit from "@/business/components/api/definition/components/apiinfo/edit/ApiDefinitionEdit";
|
||||
import ApiDefinitionInformation
|
||||
from "@/business/components/api/definition/components/apiinfo/information/ApiDefinitionInformation";
|
||||
import {getUUID} from "@/common/js/utils";
|
||||
import ApiBaseInfo from "@/business/components/api/definition/components/apiinfo/edit/ApiBaseInfo";
|
||||
import ApiTestInfo from "@/business/components/api/definition/components/apiinfo/edit/ApiTestInfo";
|
||||
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
|
||||
import ApiCaseEdit from "@/business/components/api/definition/components/apiinfo/edit/ApiCaseEdit";
|
||||
|
||||
export default {
|
||||
name: "ApiInfoContainer",
|
||||
components: {
|
||||
ApiTestInfo,
|
||||
ApiBaseInfo,
|
||||
ApiDefinitionInformation,
|
||||
ApiTestBaseContainer,
|
||||
ApiInformation,
|
||||
ApiDefinitionEdit,
|
||||
ApiCaseEdit
|
||||
},
|
||||
props: {
|
||||
isEdit: Boolean,
|
||||
operationType: String,
|
||||
apiId: String,
|
||||
projectId: String,
|
||||
currentApi: {},
|
||||
currentProtocol: String,
|
||||
moduleOptions: [],
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
apiInfo: {},
|
||||
api: {},
|
||||
loading: true,
|
||||
protocol: "",
|
||||
apiIsEditing: false,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initData();
|
||||
},
|
||||
watch: {
|
||||
operationType() {
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
editApi() {
|
||||
this.$emit("updateApiStatus", "edit", this.api.name);
|
||||
},
|
||||
initData() {
|
||||
this.loading = true;
|
||||
if (this.operationType === "debug" || this.operationType === "create") {
|
||||
this.protocol = this.currentApi.protocol;
|
||||
this.loading = false;
|
||||
} else if (this.operationType === 'addApiAndCase') {
|
||||
this.protocol = this.currentApi.protocol;
|
||||
this.loading = false;
|
||||
} else if (this.apiId) {
|
||||
this.$get("/api/definition/get/apiDetail/" + this.apiId, response => {
|
||||
if (response.data) {
|
||||
if (response.data.apiInfo) {
|
||||
this.apiInfo = response.data.apiInfo;
|
||||
}
|
||||
if (response.data.apiDefinition) {
|
||||
this.api = response.data.apiDefinition;
|
||||
this.protocol = this.api.protocol;
|
||||
}
|
||||
}
|
||||
this.loading = false;
|
||||
}, () => {
|
||||
this.loading = false;
|
||||
});
|
||||
} else {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
saveApi(apiStruct) {
|
||||
let bodyFiles = this.getBodyUploadFiles(apiStruct);
|
||||
apiStruct.requestId = apiStruct.request.id;
|
||||
if (apiStruct.request) {
|
||||
// 历史数据处理
|
||||
if (apiStruct.request.authManager) {
|
||||
apiStruct.request.authManager.clazzName = TYPE_TO_C.get("AuthManager");
|
||||
}
|
||||
this.sort(apiStruct.request.hashTree);
|
||||
}
|
||||
|
||||
this.setParameter(apiStruct);
|
||||
let reqUrl = "/api/definition/update";
|
||||
if (apiStruct.operationType === 'create') {
|
||||
reqUrl = "/api/definition/create";
|
||||
}
|
||||
this.loading = true;
|
||||
this.$fileUpload(reqUrl, null, bodyFiles, apiStruct, (response) => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.currentApi.isCopy = false;
|
||||
// 创建了新版本的api,之后id变了,ref_id 保存了原始id
|
||||
apiStruct.id = response.data.id;
|
||||
apiStruct.remark = response.data.remark;
|
||||
this.loading = false;
|
||||
if (!this.apiId) {
|
||||
this.apiId = apiStruct.id;
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.$emit('saveApi', apiStruct);
|
||||
});
|
||||
}, () => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
saveApiAndCase(apiStruct) {
|
||||
this.$emit("saveApiAndCase", apiStruct);
|
||||
},
|
||||
sort(stepArray) {
|
||||
if (stepArray) {
|
||||
for (let i in stepArray) {
|
||||
if (!stepArray[i].clazzName) {
|
||||
stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type);
|
||||
}
|
||||
if (stepArray[i].type === "Assertions" && !stepArray[i].document) {
|
||||
stepArray[i].document = {
|
||||
type: "JSON",
|
||||
data: {xmlFollowAPI: false, jsonFollowAPI: false, json: [], xml: []}
|
||||
};
|
||||
}
|
||||
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
|
||||
this.sort(stepArray[i].hashTree);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
saveApiBeforeCase(api) {
|
||||
let apiData = JSON.parse(JSON.stringify(api));
|
||||
let apiCase = JSON.parse(JSON.stringify(api));
|
||||
apiData.moduleId = module;
|
||||
apiData.modulePath = "/" + this.$t('commons.module_title');
|
||||
this.setParameter(apiData);
|
||||
let bodyFiles = this.getBodyUploadFiles(apiData);
|
||||
apiData.response = null;
|
||||
this.loading = true;
|
||||
this.$fileUpload("/api/definition/create", null, bodyFiles, apiData, () => {
|
||||
apiCase.apiDefinitionId = apiData.id;
|
||||
apiCase.id = getUUID();
|
||||
apiCase.name = apiData.name;
|
||||
apiCase.priority = this.currentApi.priority;
|
||||
apiCase.tags = apiData.tags;
|
||||
apiCase.description = apiData.description;
|
||||
this.saveCase(apiCase, api);
|
||||
}, () => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
saveCase(newCase, api) {
|
||||
let tmp = newCase;
|
||||
tmp.request.body = newCase.request.body;
|
||||
let bodyFiles = this.getBodyUploadFiles(tmp);
|
||||
tmp.projectId = this.projectId;
|
||||
tmp.active = true;
|
||||
tmp.request.id = getUUID();
|
||||
tmp.id = tmp.request.id;
|
||||
tmp.request.path = this.api.path;
|
||||
tmp.versionId = this.api.versionId;
|
||||
if (tmp.request.protocol !== "dubbo://" && tmp.request.protocol !== "DUBBO") {
|
||||
tmp.request.method = this.api.method;
|
||||
}
|
||||
|
||||
if (tmp.request.esbDataStruct != null) {
|
||||
tmp.esbDataStruct = JSON.stringify(tmp.request.esbDataStruct);
|
||||
}
|
||||
if (tmp.request.backEsbDataStruct != null) {
|
||||
tmp.backEsbDataStruct = JSON.stringify(tmp.request.backEsbDataStruct);
|
||||
}
|
||||
|
||||
if (tmp.tags instanceof Array) {
|
||||
tmp.tags = JSON.stringify(tmp.tags);
|
||||
} else if (!tmp.tags || tmp.tags === "") {
|
||||
tmp.tags = "[]";
|
||||
}
|
||||
if (tmp.request) {
|
||||
tmp.request.clazzName = TYPE_TO_C.get(tmp.request.type);
|
||||
if (tmp.request.authManager) {
|
||||
tmp.request.authManager.clazzName = TYPE_TO_C.get(tmp.request.authManager.type);
|
||||
}
|
||||
this.sort(tmp.request.hashTree);
|
||||
}
|
||||
if (tmp.response) {
|
||||
tmp.response = JSON.stringify(tmp.response);
|
||||
}
|
||||
let url = "/api/testcase/create";
|
||||
this.result = this.$fileUpload(url, null, bodyFiles, tmp, (response) => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.$emit("saveCaseCallback", api);
|
||||
this.loading = false;
|
||||
}, (error) => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
setParameter(apiStruct) {
|
||||
apiStruct.name = this.currentApi.name;
|
||||
apiStruct.moduleId = this.currentApi.moduleId;
|
||||
apiStruct.userId = this.currentApi.userId;
|
||||
apiStruct.status = this.currentApi.status;
|
||||
apiStruct.tags = this.currentApi.tags;
|
||||
apiStruct.description = this.currentApi.description;
|
||||
|
||||
if (!apiStruct.isCopy) {
|
||||
apiStruct.isCopy = false;
|
||||
}
|
||||
if (apiStruct.request) {
|
||||
if (apiStruct.protocol !== "DUBBO") {
|
||||
apiStruct.request.method = apiStruct.method;
|
||||
}
|
||||
apiStruct.request.path = apiStruct.path;
|
||||
apiStruct.request.useEnvironment = undefined;
|
||||
}
|
||||
if (!apiStruct.follows) {
|
||||
apiStruct.follows = [];
|
||||
}
|
||||
|
||||
if (apiStruct.tags instanceof Array) {
|
||||
apiStruct.tags = JSON.stringify(apiStruct.tags);
|
||||
}
|
||||
|
||||
if (!apiStruct.method) {
|
||||
apiStruct.method = this.currentProtocol;
|
||||
}
|
||||
apiStruct.projectId = this.projectId;
|
||||
apiStruct.request.name = this.currentApi.name;
|
||||
apiStruct.protocol = this.currentProtocol;
|
||||
if (this.currentProtocol === "DUBBO" || this.currentProtocol === "dubbo://") {
|
||||
apiStruct.request.protocol = "dubbo://";
|
||||
} else {
|
||||
apiStruct.request.protocol = this.currentProtocol;
|
||||
}
|
||||
if (apiStruct.isCopy) {
|
||||
apiStruct.id = this.apiId;
|
||||
} else {
|
||||
if (apiStruct.id) {
|
||||
apiStruct.request.id = apiStruct.id;
|
||||
} else {
|
||||
apiStruct.id = apiStruct.request.id;
|
||||
}
|
||||
}
|
||||
if (this.currentProtocol !== 'HTTP') {
|
||||
apiStruct.response = null;
|
||||
}
|
||||
},
|
||||
getBodyUploadFiles(data) {
|
||||
let bodyUploadFiles = [];
|
||||
data.bodyUploadIds = [];
|
||||
let request = data.request;
|
||||
if (request.body) {
|
||||
if (request.body.kvs) {
|
||||
request.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
item.name = item.file.name;
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (request.body.binary) {
|
||||
request.body.binary.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
data.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return bodyUploadFiles;
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,166 @@
|
|||
<template>
|
||||
<!-- 基础信息 -->
|
||||
<div class="base-info">
|
||||
<el-card class="box-card" style="border: 0px">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{ $t('test_track.plan_view.base_info') }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<el-form :model="api" :rules="rule" ref="httpForm" label-width="80px" label-position="left">
|
||||
<!--模块-->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
|
||||
<ms-select-tree size="small" :data="moduleOptions" :defaultKey="api.moduleId" @getValue="setModule" :disabled="true"
|
||||
:obj="moduleObj" clearable checkStrictly/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!--名称-->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('commons.name')" prop="name">
|
||||
<el-input class="ms-http-input" size="small" v-model="api.name"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--责任人-->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('api_test.definition.request.responsible')" prop="userId">
|
||||
<el-select v-model="api.userId"
|
||||
:placeholder="$t('api_test.definition.request.responsible')" filterable size="small"
|
||||
class="ms-http-select">
|
||||
<el-option
|
||||
v-for="item in maintainerOptions"
|
||||
:key="item.id"
|
||||
:label="item.name + ' (' + item.id + ')'"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--状态-->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('commons.status')" prop="status">
|
||||
<el-select class="ms-http-select" size="small" v-model="api.status">
|
||||
<el-option v-for="item in options" :key="item.id" :label="$t(item.label)" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--用例等级-->
|
||||
<el-row>
|
||||
<el-form-item :label="$t('api_test.automation.case_level')" prop="priority">
|
||||
<el-select size="mini" v-model="api.priority" class="ms-api-select">
|
||||
<el-option v-for="grd in priorities" :key="grd.id" :label="grd.name" :value="grd.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<!--标签-->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('commons.tag')" prop="tag" class="not-unique-form-item">
|
||||
<ms-input-tag :currentScenario="api" ref="tag" v-model="api.tags"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--描述-->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('commons.description')" prop="description" class="not-unique-form-item">
|
||||
<el-input class="ms-http-textarea"
|
||||
v-model="api.description"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1, maxRows: 10}"
|
||||
:rows="1" size="small"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import {getCurrentProjectID} from "@/common/js/utils";
|
||||
import {API_STATUS, PRIORITY, REQ_METHOD} from "@/business/components/api/definition/model/JsonData";
|
||||
import MsSelectTree from "@/business/components/common/select-tree/SelectTree";
|
||||
import MsInputTag from "@/business/components/api/automation/scenario/MsInputTag";
|
||||
|
||||
export default {
|
||||
name: "ApiBaseCaseInfo",
|
||||
components: {MsSelectTree, MsInputTag},
|
||||
props: {
|
||||
api: {},
|
||||
moduleOptions: [],
|
||||
isCase: Boolean,
|
||||
currentProtocol: String,
|
||||
},
|
||||
data() {
|
||||
let validateURL = (rule, value, callback) => {
|
||||
if (!this.httpForm.path.startsWith("/") || this.httpForm.path.match(/\s/) != null) {
|
||||
callback(this.$t('api_test.definition.request.path_valid_info'));
|
||||
}
|
||||
callback();
|
||||
};
|
||||
return {
|
||||
rule: {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
|
||||
{max: 100, message: this.$t('test_track.length_less_than') + '100', trigger: 'blur'}
|
||||
],
|
||||
path: [{required: true, message: this.$t('api_test.definition.request.path_info'), trigger: 'blur'}, {
|
||||
validator: validateURL,
|
||||
trigger: 'blur'
|
||||
}],
|
||||
priority: [{required: true, message: this.$t('test_track.case.input_priority'), trigger: 'change'}],
|
||||
userId: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||
moduleId: [{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
|
||||
status: [{required: true, message: this.$t('commons.please_select'), trigger: 'change'}],
|
||||
},
|
||||
maintainerOptions: [],
|
||||
reqOptions: REQ_METHOD,
|
||||
options: API_STATUS,
|
||||
priorities: PRIORITY,
|
||||
moduleObj: {
|
||||
id: 'id',
|
||||
label: 'name',
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getMaintainerOptions();
|
||||
},
|
||||
methods: {
|
||||
getMaintainerOptions() {
|
||||
this.$post('/user/project/member/tester/list', {projectId: getCurrentProjectID()}, response => {
|
||||
this.maintainerOptions = response.data;
|
||||
});
|
||||
},
|
||||
setModule(id, data) {
|
||||
this.api.moduleId = id;
|
||||
this.api.modulePath = data.path;
|
||||
},
|
||||
validateForm(){
|
||||
let validateResult = false;
|
||||
this.$refs['httpForm'].validate((valid) => {
|
||||
validateResult = valid;
|
||||
});
|
||||
return validateResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/deep/ .not-unique-form-item > .el-form-item__label {
|
||||
width: 62px !important;
|
||||
margin-left: 8px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,155 @@
|
|||
<template>
|
||||
<!-- 基础信息 -->
|
||||
<div class="base-info">
|
||||
<el-card class="box-card" style="border: 0px">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{ $t('test_track.plan_view.base_info') }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<el-form :model="api" :rules="rule" ref="httpForm" label-width="70px" label-position="left">
|
||||
<!--名称-->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('commons.name')" prop="name">
|
||||
<el-input class="ms-http-input" size="small" v-model="api.name"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--模块-->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
|
||||
<ms-select-tree size="small" :data="moduleOptions" :defaultKey="api.moduleId" @getValue="setModule"
|
||||
:obj="moduleObj" clearable checkStrictly/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--责任人-->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('api_test.definition.request.responsible')" prop="userId">
|
||||
<el-select v-model="api.userId"
|
||||
:placeholder="$t('api_test.definition.request.responsible')" filterable size="small"
|
||||
class="ms-http-select">
|
||||
<el-option
|
||||
v-for="item in maintainerOptions"
|
||||
:key="item.id"
|
||||
:label="item.name + ' (' + item.id + ')'"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--状态-->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('commons.status')" prop="status">
|
||||
<el-select class="ms-http-select" size="small" v-model="api.status">
|
||||
<el-option v-for="item in options" :key="item.id" :label="$t(item.label)" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--标签-->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('commons.tag')" prop="tag" class="not-unique-form-item">
|
||||
<ms-input-tag :currentScenario="api" ref="tag" v-model="api.tags"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--描述-->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('commons.description')" prop="description" class="not-unique-form-item">
|
||||
<el-input class="ms-http-textarea"
|
||||
v-model="api.description"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1, maxRows: 10}"
|
||||
:rows="1" size="small"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import {getCurrentProjectID} from "@/common/js/utils";
|
||||
import {API_STATUS, REQ_METHOD} from "@/business/components/api/definition/model/JsonData";
|
||||
import MsSelectTree from "@/business/components/common/select-tree/SelectTree";
|
||||
import MsInputTag from "@/business/components/api/automation/scenario/MsInputTag";
|
||||
|
||||
export default {
|
||||
name: "ApiBaseInfo",
|
||||
components: {MsSelectTree, MsInputTag},
|
||||
props: {
|
||||
api: {},
|
||||
moduleOptions: [],
|
||||
isCase: Boolean,
|
||||
currentProtocol: String,
|
||||
},
|
||||
data() {
|
||||
let validateURL = (rule, value, callback) => {
|
||||
if (!this.httpForm.path.startsWith("/") || this.httpForm.path.match(/\s/) != null) {
|
||||
callback(this.$t('api_test.definition.request.path_valid_info'));
|
||||
}
|
||||
callback();
|
||||
};
|
||||
return {
|
||||
rule: {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
|
||||
{max: 100, message: this.$t('test_track.length_less_than') + '100', trigger: 'blur'}
|
||||
],
|
||||
path: [{required: true, message: this.$t('api_test.definition.request.path_info'), trigger: 'blur'}, {
|
||||
validator: validateURL,
|
||||
trigger: 'blur'
|
||||
}],
|
||||
userId: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||
moduleId: [{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
|
||||
status: [{required: true, message: this.$t('commons.please_select'), trigger: 'change'}],
|
||||
},
|
||||
maintainerOptions: [],
|
||||
reqOptions: REQ_METHOD,
|
||||
options: API_STATUS,
|
||||
moduleObj: {
|
||||
id: 'id',
|
||||
label: 'name',
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getMaintainerOptions();
|
||||
},
|
||||
methods: {
|
||||
getMaintainerOptions() {
|
||||
this.$post('/user/project/member/tester/list', {projectId: getCurrentProjectID()}, response => {
|
||||
this.maintainerOptions = response.data;
|
||||
});
|
||||
},
|
||||
setModule(id, data) {
|
||||
this.api.moduleId = id;
|
||||
this.api.modulePath = data.path;
|
||||
},
|
||||
validateForm(){
|
||||
let validateResult = false;
|
||||
this.$refs['httpForm'].validate((valid) => {
|
||||
validateResult = valid;
|
||||
});
|
||||
return validateResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/deep/ .not-unique-form-item > .el-form-item__label {
|
||||
width: 62px !important;
|
||||
margin-left: 8px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,49 @@
|
|||
<template>
|
||||
<api-test-base-container :show-aside="isEdit">
|
||||
<template v-slot:aside>
|
||||
<api-base-case-info :api="api" :module-options="moduleOptions" ref="apiBaseInfo"/>
|
||||
</template>
|
||||
<template v-slot:mainContainer>
|
||||
<api-test-info :project-id="projectId" :current-protocol="protocol" :api="api" :is-edit="isEdit"
|
||||
@saveApiAndCase="saveApiAndCase"
|
||||
@saveApi="saveApi"></api-test-info>
|
||||
</template>
|
||||
</api-test-base-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ApiTestBaseContainer from "@/business/components/common/layout/ApiTestBaseContainer";
|
||||
import ApiBaseInfo from "@/business/components/api/definition/components/apiinfo/edit/ApiBaseInfo";
|
||||
import ApiTestInfo from "@/business/components/api/definition/components/apiinfo/edit/ApiTestInfo";
|
||||
import ApiBaseCaseInfo from "@/business/components/api/definition/components/apiinfo/edit/ApiBaseCaseInfo";
|
||||
|
||||
export default {
|
||||
name: "ApiCaseEdit",
|
||||
components: {
|
||||
ApiBaseCaseInfo,
|
||||
ApiTestBaseContainer, ApiBaseInfo, ApiTestInfo
|
||||
},
|
||||
props: {
|
||||
api: {},
|
||||
moduleOptions: [],
|
||||
projectId: String,
|
||||
protocol: String,
|
||||
isEdit:Boolean,
|
||||
},
|
||||
methods: {
|
||||
saveApi(apiStruct) {
|
||||
let baseInfoCheck = this.$refs.apiBaseInfo.validateForm();
|
||||
if(baseInfoCheck){
|
||||
this.$emit("saveApi", apiStruct);
|
||||
}
|
||||
},
|
||||
saveApiAndCase(apiStruct){
|
||||
this.$emit("saveApiAndCase",apiStruct);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,48 @@
|
|||
<template>
|
||||
<api-test-base-container :show-aside="isEdit">
|
||||
<template v-slot:aside>
|
||||
<api-base-info :api="api" :module-options="moduleOptions" :current-protocol="protocol" ref="apiBaseInfo"></api-base-info>
|
||||
</template>
|
||||
<template v-slot:mainContainer>
|
||||
<api-test-info :project-id="projectId" :current-protocol="protocol" :api="api" :is-edit="isEdit"
|
||||
@saveApiAndCase="saveApiAndCase"
|
||||
@saveApi="saveApi"></api-test-info>
|
||||
</template>
|
||||
</api-test-base-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ApiTestBaseContainer from "@/business/components/common/layout/ApiTestBaseContainer";
|
||||
import ApiBaseInfo from "@/business/components/api/definition/components/apiinfo/edit/ApiBaseInfo";
|
||||
import ApiTestInfo from "@/business/components/api/definition/components/apiinfo/edit/ApiTestInfo";
|
||||
|
||||
export default {
|
||||
name: "ApiDefinitionEdit",
|
||||
components: {
|
||||
ApiTestBaseContainer, ApiBaseInfo, ApiTestInfo
|
||||
},
|
||||
props: {
|
||||
api: {},
|
||||
moduleOptions: [],
|
||||
projectId: String,
|
||||
protocol: String,
|
||||
isEdit:Boolean,
|
||||
isLoading:Boolean,
|
||||
},
|
||||
methods: {
|
||||
saveApi(apiStruct) {
|
||||
let baseInfoCheck = this.$refs.apiBaseInfo.validateForm();
|
||||
if(baseInfoCheck){
|
||||
this.$emit("saveApi", apiStruct);
|
||||
}
|
||||
},
|
||||
saveApiAndCase(apiStruct){
|
||||
this.$emit("saveApiAndCase",apiStruct);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,229 @@
|
|||
<template>
|
||||
<div style="margin:5px 5px 5px 5px">
|
||||
<http-base-info
|
||||
:syncTabs="syncTabs"
|
||||
:currentProtocol="currentProtocol"
|
||||
:api-data="api"
|
||||
:project-id="projectId"
|
||||
:is-edit="isEdit"
|
||||
@refresh="refresh"
|
||||
@saveApiAndCase="saveApiAndCase"
|
||||
ref="httpTestPage"
|
||||
v-if="currentProtocol==='HTTP'">
|
||||
<template v-slot:rightHeader>
|
||||
<div v-show="isEdit" class="ms-opt-btn">
|
||||
<el-button type="primary" size="small" @click="saveApi" title="ctrl + s"
|
||||
v-permission="['PROJECT_API_DEFINITION:READ+EDIT_API']">{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</http-base-info>
|
||||
|
||||
<tcp-base-info
|
||||
:syncTabs="syncTabs"
|
||||
:currentProtocol="currentProtocol"
|
||||
:api-data="api"
|
||||
:project-id="projectId"
|
||||
:is-edit="isEdit"
|
||||
@refresh="refresh"
|
||||
@saveApiAndCase="saveApiAndCase"
|
||||
ref="tcpTestPage"
|
||||
v-else-if="currentProtocol==='TCP'"
|
||||
>
|
||||
<template v-slot:rightHeader>
|
||||
<div v-show="isEdit" class="ms-opt-btn">
|
||||
<el-button type="primary" size="small" @click="saveApi" title="ctrl + s"
|
||||
v-permission="['PROJECT_API_DEFINITION:READ+EDIT_API']">{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</tcp-base-info>
|
||||
|
||||
<sql-base-info
|
||||
:syncTabs="syncTabs"
|
||||
:currentProtocol="currentProtocol"
|
||||
:api-data="api"
|
||||
:project-id="projectId"
|
||||
:is-edit="isEdit"
|
||||
@refresh="refresh"
|
||||
@saveApiAndCase="saveApiAndCase"
|
||||
ref="sqlTestPage"
|
||||
v-else-if="currentProtocol==='SQL'"
|
||||
>
|
||||
<template v-slot:rightHeader>
|
||||
<div v-show="isEdit" class="ms-opt-btn">
|
||||
<el-button type="primary" size="small" @click="saveApi" title="ctrl + s"
|
||||
v-permission="['PROJECT_API_DEFINITION:READ+EDIT_API']">{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</sql-base-info>
|
||||
|
||||
<dubbo-base-info
|
||||
:syncTabs="syncTabs"
|
||||
:currentProtocol="currentProtocol"
|
||||
:api-data="api"
|
||||
:project-id="projectId"
|
||||
:is-edit="isEdit"
|
||||
ref="dubboTestPage"
|
||||
@saveApiAndCase="saveApiAndCase"
|
||||
@refresh="refresh"
|
||||
v-else-if="currentProtocol==='DUBBO'"
|
||||
>
|
||||
<template v-slot:rightHeader>
|
||||
<div v-show="isEdit" class="ms-opt-btn">
|
||||
<el-button type="primary" size="small" @click="saveApi" title="ctrl + s"
|
||||
v-permission="['PROJECT_API_DEFINITION:READ+EDIT_API']">{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</dubbo-base-info>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HttpBaseInfo from "@/business/components/api/definition/components/apiinfo/edit/compnents/HttpBaseInfo";
|
||||
import TcpBaseInfo from "@/business/components/api/definition/components/apiinfo/edit/compnents/TcpBaseInfo";
|
||||
import SqlBaseInfo from "@/business/components/api/definition/components/apiinfo/edit/compnents/SqlBaseInfo";
|
||||
import DubboBaseInfo from "@/business/components/api/definition/components/apiinfo/edit/compnents/DubboBaseInfo";
|
||||
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
|
||||
import _ from 'lodash';
|
||||
import {Body} from "@/business/components/api/definition/model/ApiTestModel";
|
||||
|
||||
export default {
|
||||
name: "ApiTestInfo",
|
||||
components: {HttpBaseInfo, TcpBaseInfo, SqlBaseInfo, DubboBaseInfo},
|
||||
props: {
|
||||
api: {},
|
||||
projectId: String,
|
||||
currentProtocol: String,
|
||||
syncTabs: Array,
|
||||
isEdit: Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formCheckResult: false,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.formatApi();
|
||||
},
|
||||
methods: {
|
||||
refresh() {
|
||||
this.$emit("refresh");
|
||||
},
|
||||
formatApi() {
|
||||
if (this.api.request !== null && this.api.request !== 'null' && this.api.request !== undefined) {
|
||||
if (Object.prototype.toString.call(this.api.request).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
|
||||
this.api.request = JSON.parse(this.api.request);
|
||||
if (this.currentProtocol === 'HTTP') {
|
||||
if (this.api.request.body && !this.api.request.body.type) {
|
||||
let tempRequest = _.cloneDeep(this.api.request);
|
||||
tempRequest.body = {type: null};
|
||||
this.api.request = tempRequest;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.api && this.api.request && !this.api.request.hashTree) {
|
||||
this.api.request.hashTree = [];
|
||||
}
|
||||
if (this.currentProtocol === "HTTP") {
|
||||
if (this.api && this.api.request && this.api.request.body && !this.api.request.body.binary) {
|
||||
this.api.request.body.binary = [];
|
||||
}
|
||||
}
|
||||
if (this.currentProtocol === "TCP" || this.currentProtocol === "SQL") {
|
||||
if (this.api && this.api.request && !this.api.request.variables) {
|
||||
this.api.request.variables = [];
|
||||
}
|
||||
}
|
||||
if (this.api.request) {
|
||||
this.api.request.clazzName = TYPE_TO_C.get(this.api.request.type);
|
||||
this.sort(this.api.request.hashTree);
|
||||
}
|
||||
|
||||
if (this.api.response !== null && this.api.response !== 'null' && this.api.response !== undefined) {
|
||||
if (Object.prototype.toString.call(this.api.response).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
|
||||
this.api.response = JSON.parse(this.api.response);
|
||||
}
|
||||
} else {
|
||||
this.api.response = {headers: [], body: new Body(), statusCode: [], type: "HTTP"};
|
||||
}
|
||||
// 处理导入数据缺失问题
|
||||
if (this.api.response.body) {
|
||||
let body = new Body();
|
||||
Object.assign(body, this.api.response.body);
|
||||
if (!body.binary) {
|
||||
body.binary = [];
|
||||
}
|
||||
if (!body.kvs) {
|
||||
body.kvs = [];
|
||||
}
|
||||
if (!body.binary) {
|
||||
body.binary = [];
|
||||
}
|
||||
this.api.response.body = body;
|
||||
}
|
||||
},
|
||||
sort(stepArray) {
|
||||
if (stepArray) {
|
||||
for (let i in stepArray) {
|
||||
if (!stepArray[i].clazzName) {
|
||||
stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type);
|
||||
}
|
||||
if (stepArray[i].type === "Assertions" && !stepArray[i].document) {
|
||||
stepArray[i].document = {
|
||||
type: "JSON",
|
||||
data: {xmlFollowAPI: false, jsonFollowAPI: false, json: [], xml: []}
|
||||
};
|
||||
}
|
||||
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
|
||||
this.sort(stepArray[i].hashTree);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
getApi() {
|
||||
this.formCheckResult = false;
|
||||
let newApiInfo = null;
|
||||
if (this.currentProtocol === 'HTTP' && this.$refs.httpTestPage) {
|
||||
this.formCheckResult = this.$refs.httpTestPage.validateForm();
|
||||
newApiInfo = this.$refs.httpTestPage.getApi();
|
||||
} else if (this.currentProtocol === 'TCP' && this.$refs.tcpTestPage) {
|
||||
this.formCheckResult = true;
|
||||
newApiInfo = this.$refs.tcpTestPage.getApi();
|
||||
} else if (this.currentProtocol === 'SQL' && this.$refs.sqlTestPage) {
|
||||
this.formCheckResult = true;
|
||||
newApiInfo = this.$refs.sqlTestPage.getApi();
|
||||
} else if (this.currentProtocol === 'DUBBO' && this.$refs.dubboTestPage) {
|
||||
this.formCheckResult = true;
|
||||
newApiInfo = this.$refs.dubboTestPage.getApi();
|
||||
}
|
||||
return newApiInfo;
|
||||
},
|
||||
saveApi() {
|
||||
let newApiInfo = this.getApi();
|
||||
if (this.formCheckResult && newApiInfo) {
|
||||
newApiInfo.path = newApiInfo.request.path;
|
||||
this.$emit("saveApi", newApiInfo);
|
||||
}
|
||||
},
|
||||
saveApiAndCase(apiStruct) {
|
||||
this.$emit("saveApiAndCase", apiStruct);
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/deep/ .ms-opt-btn {
|
||||
position: fixed;
|
||||
right: 50px;
|
||||
z-index: 1;
|
||||
top: 128px;
|
||||
float: right;
|
||||
margin-right: 20px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,330 @@
|
|||
<template>
|
||||
|
||||
<div class="card-container">
|
||||
<div v-if="versionEnable">
|
||||
<slot name="rightHeader"></slot>
|
||||
</div>
|
||||
<el-card class="card-content">
|
||||
<div>
|
||||
<p class="tip" style="display: inline-block">{{ $t('api_test.definition.request.req_param') }} </p>
|
||||
<el-button size="small" type="primary" v-if="apiData.operationType==='create'||apiData.operationType==='edit'"
|
||||
@click="runTest">
|
||||
{{ $t('commons.test') }}
|
||||
</el-button>
|
||||
<!-- 操作按钮 -->
|
||||
<el-dropdown split-button type="primary" class="ms-api-buttion" @click="handleCommand('add')"
|
||||
@command="handleCommand" size="small" style="margin-left: 20px" v-else-if="!runLoading">
|
||||
{{ $t('commons.test') }}
|
||||
<el-dropdown-menu slot="dropdown" v-if="isEdit">
|
||||
<el-dropdown-item command="load_case">{{ $t('api_test.definition.request.load_case') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="save_as_case">{{ $t('api_test.definition.request.save_as_case') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="update_api">{{ $t('api_test.definition.request.update_api') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="save_as_api">{{ $t('api_test.definition.request.save_as') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
<el-dropdown-menu slot="dropdown" v-else>
|
||||
<el-dropdown-item command="save_as_case">{{ $t('api_test.definition.request.save_as_case') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-button size="small" type="primary" v-else @click.once="stop" style="margin-left: 20px">
|
||||
{{ $t('report.stop_btn') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-loading="loading">
|
||||
<!-- TCP 请求参数 -->
|
||||
<ms-basis-parameters :request="api.request" :show-script="false" ref="requestForm" :response="responseData"/>
|
||||
|
||||
<!--返回结果-->
|
||||
<!-- HTTP 请求返回数据 -->
|
||||
<p class="tip">{{ $t('api_test.definition.request.res_param') }} </p>
|
||||
<ms-request-result-tail :response="responseData" ref="runResult"/>
|
||||
</div>
|
||||
<api-other-info :api="api" ref="apiOtherInfo"/>
|
||||
</el-card>
|
||||
|
||||
<!-- 加载用例 -->
|
||||
<ms-api-case-list @apiCaseClose="apiCaseClose" @refresh="refresh" @selectTestCase="selectTestCase" :currentApi="api"
|
||||
:loaded="loaded" :refreshSign="refreshSign" :createCase="createCase"
|
||||
ref="caseList"/>
|
||||
|
||||
<!-- 环境 -->
|
||||
<api-environment-config ref="environmentConfig" @close="environmentConfigClose"/>
|
||||
<!-- 执行组件 -->
|
||||
<ms-run :debug="false" :environment="api.environment" :reportId="reportId" :run-data="runData"
|
||||
@runRefresh="runRefresh" @errorRefresh="errorRefresh" ref="runTest"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getUUID, hasLicense} from "@/common/js/utils";
|
||||
import MsApiCaseList from "@/business/components/api/definition/components/case/ApiCaseList";
|
||||
import MsContainer from "@/business/components/common/components/MsContainer";
|
||||
import MsBottomContainer from "@/business/components/api/definition/components/BottomContainer";
|
||||
import {parseEnvironment} from "@/business/components/api/definition/model/EnvironmentModel";
|
||||
import ApiEnvironmentConfig from "@/business/components/api/definition/components/environment/ApiEnvironmentConfig";
|
||||
import MsRequestResultTail from "@/business/components/api/definition/components/response/RequestResultTail";
|
||||
import MsRun from "@/business/components/api/definition/components/Run";
|
||||
import MsBasisParameters from "@/business/components/api/definition/components/request/dubbo/BasisParameters";
|
||||
import {REQ_METHOD} from "@/business/components/api/definition/model/JsonData";
|
||||
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
|
||||
import ApiOtherInfo from "@/business/components/api/definition/components/complete/ApiOtherInfo";
|
||||
|
||||
export default {
|
||||
name: "DubboBaseInfo",
|
||||
components: {
|
||||
MsApiCaseList,
|
||||
MsContainer,
|
||||
MsBottomContainer,
|
||||
MsRequestResultTail,
|
||||
ApiEnvironmentConfig,
|
||||
MsRun,
|
||||
MsBasisParameters,
|
||||
ApiOtherInfo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
api: {},
|
||||
loaded: false,
|
||||
loading: false,
|
||||
currentRequest: {},
|
||||
createCase: "",
|
||||
refreshSign: "",
|
||||
responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []},
|
||||
reqOptions: REQ_METHOD,
|
||||
environments: [],
|
||||
rules: {
|
||||
method: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||
url: [{required: true, message: this.$t('api_test.definition.request.path_info'), trigger: 'blur'}],
|
||||
environmentId: [{required: true, message: this.$t('api_test.definition.request.run_env'), trigger: 'change'}],
|
||||
},
|
||||
runData: [],
|
||||
reportId: "",
|
||||
runLoading: false,
|
||||
versionEnable: false,
|
||||
}
|
||||
},
|
||||
props: {apiData: {}, currentProtocol: String, syncTabs: Array, projectId: String, isEdit: Boolean},
|
||||
methods: {
|
||||
handleCommand(e) {
|
||||
switch (e) {
|
||||
case "load_case":
|
||||
return this.loadCase();
|
||||
case "save_as_case":
|
||||
return this.saveAsCase();
|
||||
case "update_api":
|
||||
return this.updateApi();
|
||||
case "save_as_api":
|
||||
return this.saveAsApi();
|
||||
default:
|
||||
return this.runTest();
|
||||
}
|
||||
},
|
||||
refresh() {
|
||||
this.$emit('refresh');
|
||||
},
|
||||
runTest() {
|
||||
this.runLoading = true;
|
||||
this.loading = true;
|
||||
this.api.request.name = this.api.id;
|
||||
this.api.protocol = this.currentProtocol;
|
||||
this.runData = [];
|
||||
this.runData.push(this.api.request);
|
||||
/*触发执行操作*/
|
||||
this.reportId = getUUID().substring(0, 8);
|
||||
},
|
||||
runRefresh(data) {
|
||||
this.responseData = data;
|
||||
this.loading = false;
|
||||
this.runLoading = false;
|
||||
},
|
||||
errorRefresh() {
|
||||
this.loading = false;
|
||||
this.runLoading = false;
|
||||
},
|
||||
saveAs() {
|
||||
this.$emit('saveAs', this.api);
|
||||
},
|
||||
loadCase() {
|
||||
this.refreshSign = getUUID();
|
||||
this.$refs.caseList.open();
|
||||
this.visible = true;
|
||||
},
|
||||
apiCaseClose() {
|
||||
this.visible = false;
|
||||
},
|
||||
getBodyUploadFiles() {
|
||||
let bodyUploadFiles = [];
|
||||
this.api.bodyUploadIds = [];
|
||||
let request = this.api.request;
|
||||
if (request.body) {
|
||||
request.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
this.api.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return bodyUploadFiles;
|
||||
},
|
||||
saveAsCase() {
|
||||
//用于触发创建操作
|
||||
this.$emit('saveApiAndCase', this.api);
|
||||
},
|
||||
saveAsApi() {
|
||||
let data = {};
|
||||
let req = this.api.request;
|
||||
req.id = getUUID();
|
||||
data.request = JSON.stringify(req);
|
||||
data.method = this.api.method;
|
||||
data.status = this.api.status;
|
||||
data.userId = this.api.userId;
|
||||
data.description = this.api.description;
|
||||
this.$emit('saveAsApi', data);
|
||||
this.$emit('refresh');
|
||||
},
|
||||
compatibleHistory(stepArray) {
|
||||
if (stepArray) {
|
||||
for (let i in stepArray) {
|
||||
if (!stepArray[i].clazzName) {
|
||||
stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type);
|
||||
}
|
||||
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
|
||||
this.compatibleHistory(stepArray[i].hashTree);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
updateApi() {
|
||||
let url = "/api/definition/update";
|
||||
let bodyFiles = this.getBodyUploadFiles();
|
||||
if (Object.prototype.toString.call(this.api.response).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
|
||||
this.api.response = JSON.parse(this.api.response);
|
||||
}
|
||||
if (this.api.tags instanceof Array) {
|
||||
this.api.tags = JSON.stringify(this.api.tags);
|
||||
}
|
||||
// 历史数据兼容处理
|
||||
if (this.api.request) {
|
||||
this.api.request.clazzName = TYPE_TO_C.get(this.api.request.type);
|
||||
this.compatibleHistory(this.api.request.hashTree);
|
||||
}
|
||||
this.$fileUpload(url, null, bodyFiles, this.api, () => {
|
||||
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);
|
||||
});
|
||||
},
|
||||
selectTestCase(item) {
|
||||
if (item != null) {
|
||||
this.api.request = item.request;
|
||||
} else {
|
||||
this.api.request = this.currentRequest;
|
||||
}
|
||||
},
|
||||
getEnvironments() {
|
||||
this.$get('/api/environment/list/' + this.projectId, response => {
|
||||
this.environments = response.data;
|
||||
this.environments.forEach(environment => {
|
||||
parseEnvironment(environment);
|
||||
});
|
||||
let hasEnvironment = false;
|
||||
for (let i in this.environments) {
|
||||
if (this.environments[i].id === this.api.environmentId) {
|
||||
this.api.environment = this.environments[i];
|
||||
hasEnvironment = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasEnvironment) {
|
||||
this.api.environmentId = '';
|
||||
this.api.environment = undefined;
|
||||
}
|
||||
});
|
||||
},
|
||||
openEnvironmentConfig() {
|
||||
this.$refs.environmentConfig.open(this.projectId);
|
||||
},
|
||||
environmentChange(value) {
|
||||
for (let i in this.environments) {
|
||||
if (this.environments[i].id === value) {
|
||||
this.api.request.useEnvironment = this.environments[i].id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
environmentConfigClose() {
|
||||
this.getEnvironments();
|
||||
},
|
||||
getResult() {
|
||||
if (this.api.id) {
|
||||
let url = "/api/definition/report/getReport/" + this.api.id;
|
||||
this.$get(url, response => {
|
||||
if (response.data) {
|
||||
let data = JSON.parse(response.data.content);
|
||||
this.responseData = data;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
stop() {
|
||||
let url = "/api/automation/stop/" + this.reportId;
|
||||
this.$get(url, () => {
|
||||
this.runLoading = false;
|
||||
this.loading = false;
|
||||
this.$success(this.$t('report.test_stop_success'));
|
||||
});
|
||||
},
|
||||
checkVersionEnable() {
|
||||
if (!this.projectId) {
|
||||
return;
|
||||
}
|
||||
if (hasLicense()) {
|
||||
this.$get('/project/version/enable/' + this.projectId, response => {
|
||||
this.versionEnable = response.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
getApi() {
|
||||
return this.api;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 深度复制
|
||||
this.api = JSON.parse(JSON.stringify(this.apiData));
|
||||
this.api.protocol = this.currentProtocol;
|
||||
this.currentRequest = this.api.request;
|
||||
this.runLoading = false;
|
||||
this.getEnvironments();
|
||||
this.getResult();
|
||||
this.checkVersionEnable();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ms-htt-width {
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.environment-button {
|
||||
margin-left: 20px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
/deep/ .el-drawer {
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,501 @@
|
|||
<template>
|
||||
|
||||
<div class="card-container">
|
||||
<div v-if="versionEnable">
|
||||
<slot name="rightHeader"></slot>
|
||||
</div>
|
||||
<el-card class="card-content">
|
||||
|
||||
<el-form :model="api" :rules="rules" ref="apiData" :inline="true" label-position="right">
|
||||
|
||||
<p class="tip">{{ $t('test_track.plan_view.base_info') }} </p>
|
||||
<!-- 请求方法 -->
|
||||
<el-form-item :label="$t('api_report.request')" prop="request.method">
|
||||
<el-select v-model="api.request.method" style="width: 100px" size="small">
|
||||
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 执行环境 -->
|
||||
<el-form-item prop="environmentId">
|
||||
<environment-select :current-data="api" :project-id="projectId" ref="environmentSelect"/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 请求地址 -->
|
||||
<el-form-item prop="request.path">
|
||||
<el-input :placeholder="$t('api_test.definition.request.path_info')" v-model="api.request.path"
|
||||
class="ms-htt-width"
|
||||
size="small" :disabled="false"/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-form-item>
|
||||
<!--新建接口-->
|
||||
<el-button size="small" type="primary" v-if="apiData.operationType==='create'||apiData.operationType==='edit'"
|
||||
@click="runTest">
|
||||
{{ $t('commons.test') }}
|
||||
</el-button>
|
||||
<!--编辑接口-->
|
||||
<el-dropdown split-button type="primary" class="ms-api-buttion" @click="handleCommand('add')"
|
||||
@command="handleCommand" size="small" v-else-if="!runLoading">
|
||||
{{ $t('commons.test') }}
|
||||
<el-dropdown-menu slot="dropdown" v-if="isEdit">
|
||||
<el-dropdown-item command="load_case">{{ $t('api_test.definition.request.load_case') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="save_as_case">{{ $t('api_test.definition.request.save_as_case') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="update_api">{{
|
||||
$t('api_test.definition.request.update_api')
|
||||
}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="save_as_api">{{ $t('api_test.definition.request.save_as') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
<el-dropdown-menu slot="dropdown" v-else>
|
||||
<el-dropdown-item command="save_as_case">{{ $t('api_test.definition.request.save_as_case') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
||||
<el-button size="small" type="primary" v-else @click.once="stop">{{ $t('report.stop_btn') }}</el-button>
|
||||
|
||||
<el-button size="small" type="primary" @click.stop @click="generate"
|
||||
style="margin-left: 10px"
|
||||
v-if="hasPermission('PROJECT_API_DEFINITION:READ+CREATE_API') && hasLicense()">
|
||||
{{ $t('commons.generate_test_data') }}
|
||||
</el-button>
|
||||
|
||||
</el-form-item>
|
||||
|
||||
|
||||
</el-form>
|
||||
<div v-loading="loading">
|
||||
<p class="tip">{{ $t('api_test.definition.request.req_param') }} </p>
|
||||
<!-- HTTP 请求参数 -->
|
||||
<ms-api-request-form :isShowEnable="true" :definition-test="true" :headers="api.request.headers"
|
||||
:response="responseData"
|
||||
v-if="loadRequest"
|
||||
:show-script="false"
|
||||
:request="api.request" ref="apiRequestForm"/>
|
||||
<!--返回结果-->
|
||||
<!-- HTTP 请求返回数据 -->
|
||||
<div v-if="isEdit">
|
||||
<ms-form-divider :title="$t('api_test.definition.request.res_param')"/>
|
||||
<ms-response-text :response="api.response"/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p class="tip">{{ $t('api_test.definition.request.res_param') }} </p>
|
||||
<ms-request-result-tail :response="responseData" ref="runResult"/>
|
||||
</div>
|
||||
</div>
|
||||
<api-other-info :api="api" ref="apiOtherInfo"/>
|
||||
</el-card>
|
||||
|
||||
<!-- 加载用例 -->
|
||||
<ms-api-case-list @selectTestCase="selectTestCase" @refresh="refresh"
|
||||
:loaded="loaded"
|
||||
:refreshSign="refreshSign"
|
||||
:createCase="createCase"
|
||||
:currentApi="api"
|
||||
ref="caseList"/>
|
||||
|
||||
<!-- 执行组件 -->
|
||||
<ms-run :debug="false" :environment="api.environment" :reportId="reportId" :run-data="runData" :env-map="envMap"
|
||||
@runRefresh="runRefresh" @errorRefresh="errorRefresh" ref="runTest"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsApiRequestForm from "@/business/components/api/definition/components/request/http/ApiHttpRequestForm";
|
||||
import {getCurrentUser, getUUID, hasLicense, hasPermission} from "@/common/js/utils";
|
||||
import MsApiCaseList from "@/business/components/api/definition/components/case/ApiCaseList";
|
||||
import MsContainer from "@/business/components/common/components/MsContainer";
|
||||
import MsRequestResultTail from "@/business/components/api/definition/components/response/RequestResultTail";
|
||||
import MsRun from "@/business/components/api/definition/components/Run";
|
||||
import {REQ_METHOD} from "@/business/components/api/definition/model/JsonData";
|
||||
import EnvironmentSelect from "@/business/components/api/definition/components/environment/EnvironmentSelect";
|
||||
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
|
||||
import MsResponseText from "@/business/components/api/definition/components/response/ResponseText";
|
||||
import MsFormDivider from "@/business/components/common/components/MsFormDivider";
|
||||
import ApiOtherInfo from "@/business/components/api/definition/components/complete/ApiOtherInfo";
|
||||
|
||||
export default {
|
||||
name: "HttpBaseInfo",
|
||||
components: {
|
||||
EnvironmentSelect,
|
||||
MsApiRequestForm,
|
||||
MsApiCaseList,
|
||||
MsContainer,
|
||||
MsRequestResultTail,
|
||||
MsRun,
|
||||
MsResponseText,
|
||||
MsFormDivider,
|
||||
ApiOtherInfo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
api: {},
|
||||
loaded: false,
|
||||
loading: false,
|
||||
loadRequest: true,
|
||||
createCase: "",
|
||||
currentRequest: {},
|
||||
refreshSign: "",
|
||||
responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []},
|
||||
reqOptions: REQ_METHOD,
|
||||
rules: {
|
||||
'request.method': [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||
'request.path': [{required: true, message: this.$t('api_test.definition.request.path_info'), trigger: 'blur'}],
|
||||
},
|
||||
runData: [],
|
||||
reportId: "",
|
||||
envMap: new Map,
|
||||
runLoading: false,
|
||||
versionEnable: false,
|
||||
}
|
||||
},
|
||||
props: {apiData: {}, currentProtocol: String, syncTabs: Array, projectId: String, isEdit: Boolean},
|
||||
computed: {
|
||||
'api.environmentId'() {
|
||||
return this.$store.state.useEnvironment;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$store.state.useEnvironment': function () {
|
||||
this.api.environmentId = this.$store.state.useEnvironment;
|
||||
},
|
||||
responseData() {
|
||||
this.updateRequest();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
hasPermission, hasLicense,
|
||||
generate() {
|
||||
this.$refs.apiRequestForm.generate();
|
||||
},
|
||||
setRequestParam(param, isEnvironmentMock) {
|
||||
this.init();
|
||||
if (param) {
|
||||
if (param.headers) {
|
||||
this.api.request.headers = param.headers;
|
||||
}
|
||||
if (param.arguments !== null && param.arguments.length > 0) {
|
||||
for (let i = 0; i < param.arguments.length; i++) {
|
||||
if (!param.arguments[i].required) {
|
||||
param.arguments[i].required = true;
|
||||
}
|
||||
}
|
||||
this.api.request.arguments = param.arguments;
|
||||
}
|
||||
if (param.body) {
|
||||
if (param.body.kvs) {
|
||||
for (let i = 0; i < param.body.kvs.length; i++) {
|
||||
if (!param.body.kvs[i].required) {
|
||||
param.body.kvs[i].required = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.api.request.body = param.body;
|
||||
}
|
||||
if (param.rest) {
|
||||
for (let i = 0; i < param.rest.length; i++) {
|
||||
if (!param.rest[i].required) {
|
||||
param.rest[i].required = true;
|
||||
}
|
||||
}
|
||||
this.api.request.rest = param.rest;
|
||||
}
|
||||
}
|
||||
if (isEnvironmentMock) {
|
||||
this.$nextTick(() => {
|
||||
let url = "/api/definition/getMockEnvironment/";
|
||||
this.$get(url + this.projectId, response => {
|
||||
let mockEnvironment = response.data;
|
||||
if (mockEnvironment !== null) {
|
||||
this.$refs.environmentSelect.setEnvironment(mockEnvironment.id);
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
this.loadRequest = false;
|
||||
this.$nextTick(() => {
|
||||
this.loadRequest = true;
|
||||
})
|
||||
},
|
||||
handleCommand(e) {
|
||||
switch (e) {
|
||||
case "load_case":
|
||||
return this.loadCase();
|
||||
case "save_as_case":
|
||||
return this.saveAsNewCase();
|
||||
case "update_api":
|
||||
return this.updateApi();
|
||||
case "save_as_api":
|
||||
return this.saveAsApi();
|
||||
default:
|
||||
return this.runTest();
|
||||
}
|
||||
},
|
||||
updateRequest() {
|
||||
if (this.responseData) {
|
||||
let result = this.responseData.responseResult;
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
//解析返回编码
|
||||
if (result.responseCode) {
|
||||
let statusCodeArr = [{
|
||||
enable: true,
|
||||
file: false,
|
||||
name: result.responseCode,
|
||||
required: true,
|
||||
value: result.responseCode
|
||||
}];
|
||||
this.api.response.statusCode = statusCodeArr;
|
||||
}
|
||||
//解析返回请求头
|
||||
if (result.headers) {
|
||||
let headers = result.headers.split("\n");
|
||||
let headerArr = [];
|
||||
headers.forEach(item => {
|
||||
let headerRow = item.split(":");
|
||||
if (headerRow.length >= 2) {
|
||||
let headerKey = headerRow[0];
|
||||
let headerValue = "";
|
||||
for (let i = 1; i < headerRow.length; i++) {
|
||||
headerValue += headerRow[i];
|
||||
if (i !== (headerRow.length - 1)) {
|
||||
headerValue += ":";
|
||||
}
|
||||
}
|
||||
let headerItem = {enable: true, file: false, name: headerKey, required: true, value: headerValue};
|
||||
headerArr.push(headerItem);
|
||||
}
|
||||
});
|
||||
if (headerArr.length > 0) {
|
||||
this.api.response.headers = headerArr;
|
||||
}
|
||||
}
|
||||
//解析返回体(raw格式)
|
||||
if (this.api.response.body) {
|
||||
this.api.response.body.type = "Raw";
|
||||
this.api.response.body.raw = result.body;
|
||||
}
|
||||
}
|
||||
},
|
||||
validateForm() {
|
||||
let validResult = false;
|
||||
this.$refs['apiData'].validate((valid) => {
|
||||
validResult = valid;
|
||||
});
|
||||
return validResult;
|
||||
},
|
||||
runTest() {
|
||||
if (!this.api.environmentId || this.api.environmentId === '') {
|
||||
this.$error(this.$t('workspace.env_group.please_select_env'));
|
||||
return false;
|
||||
}
|
||||
this.$refs['apiData'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.runLoading = true;
|
||||
this.loading = true;
|
||||
this.api.request.name = this.api.id;
|
||||
this.api.request.url = undefined;
|
||||
this.api.request.useEnvironment = this.api.environmentId;
|
||||
this.api.protocol = this.currentProtocol;
|
||||
this.runData = [];
|
||||
this.runData.push(this.api.request);
|
||||
/*触发执行操作*/
|
||||
this.reportId = getUUID().substring(0, 8);
|
||||
}
|
||||
})
|
||||
},
|
||||
saveAsNewCase() {
|
||||
this.$refs['apiData'].validate((valid) => {
|
||||
if (valid) {
|
||||
let request = this.api.request;
|
||||
request.id = getUUID();
|
||||
this.protocol = this.currentProtocol;
|
||||
this.api.path = request.path;
|
||||
this.api.method = request.method;
|
||||
this.api.id = request.id;
|
||||
this.api.request = request;
|
||||
this.api.userId = getCurrentUser().id;
|
||||
this.api.status = "Underway";
|
||||
this.api.protocol = this.currentProtocol;
|
||||
this.api.saved = true;
|
||||
this.$emit("saveApiAndCase", this.api)
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
},
|
||||
errorRefresh() {
|
||||
this.loading = false;
|
||||
this.runLoading = false;
|
||||
},
|
||||
runRefresh(data) {
|
||||
this.responseData = {type: 'HTTP', responseResult: {responseCode: ""}, subRequestResults: []};
|
||||
if (data) {
|
||||
this.responseData = data;
|
||||
}
|
||||
this.loading = false;
|
||||
this.runLoading = false;
|
||||
},
|
||||
saveAs() {
|
||||
this.$emit('saveAs', this.api);
|
||||
},
|
||||
loadCase() {
|
||||
this.refreshSign = getUUID();
|
||||
this.loaded = true;
|
||||
this.$refs.caseList.open();
|
||||
},
|
||||
apiCaseClose() {
|
||||
this.visible = false;
|
||||
},
|
||||
getBodyUploadFiles() {
|
||||
let bodyUploadFiles = [];
|
||||
this.api.bodyUploadIds = [];
|
||||
let request = this.api.request;
|
||||
if (request.body) {
|
||||
request.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
item.name = item.file.name;
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return bodyUploadFiles;
|
||||
},
|
||||
saveAsCase() {
|
||||
//用于触发创建操作
|
||||
this.$emit('saveAsCase', this.api);
|
||||
},
|
||||
saveAsApi() {
|
||||
let data = {};
|
||||
let req = this.api.request;
|
||||
req.id = getUUID();
|
||||
data.request = JSON.stringify(req);
|
||||
data.method = req.method;
|
||||
data.path = req.path;
|
||||
data.url = this.api.url;
|
||||
data.status = this.api.status;
|
||||
data.userId = this.api.userId;
|
||||
data.description = this.api.description;
|
||||
this.$emit('saveAsApi', data);
|
||||
},
|
||||
compatibleHistory(stepArray) {
|
||||
if (stepArray) {
|
||||
for (let i in stepArray) {
|
||||
if (!stepArray[i].clazzName) {
|
||||
stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type);
|
||||
}
|
||||
if (stepArray[i] && stepArray[i].authManager && !stepArray[i].authManager.clazzName) {
|
||||
stepArray[i].authManager.clazzName = TYPE_TO_C.get(stepArray[i].authManager.type);
|
||||
}
|
||||
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
|
||||
this.compatibleHistory(stepArray[i].hashTree);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
updateApi() {
|
||||
let url = "/api/definition/update";
|
||||
let bodyFiles = this.getBodyUploadFiles();
|
||||
this.api.method = this.api.request.method;
|
||||
this.api.path = this.api.request.path;
|
||||
if (Object.prototype.toString.call(this.api.response).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
|
||||
this.api.response = JSON.parse(this.api.response);
|
||||
}
|
||||
if (this.api.tags instanceof Array) {
|
||||
this.api.tags = JSON.stringify(this.api.tags);
|
||||
}
|
||||
// 历史数据兼容处理
|
||||
if (this.api.request) {
|
||||
this.api.request.clazzName = TYPE_TO_C.get(this.api.request.type);
|
||||
this.compatibleHistory(this.api.request.hashTree);
|
||||
}
|
||||
this.$fileUpload(url, null, bodyFiles, this.api, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.$emit('saveApi', this.api);
|
||||
if (this.syncTabs.indexOf(this.api.id) === -1) {
|
||||
this.syncTabs.push(this.api.id);
|
||||
}
|
||||
});
|
||||
},
|
||||
selectTestCase(item) {
|
||||
if (item != null) {
|
||||
this.api.request = item.request;
|
||||
} else {
|
||||
this.api.request = this.currentRequest;
|
||||
}
|
||||
},
|
||||
|
||||
refresh() {
|
||||
this.$emit('refresh');
|
||||
},
|
||||
getResult() {
|
||||
if (this.api.id) {
|
||||
let url = "/api/definition/report/getReport/" + this.api.id;
|
||||
this.$get(url, response => {
|
||||
if (response.data) {
|
||||
let data = JSON.parse(response.data.content);
|
||||
this.responseData = data;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
stop() {
|
||||
let url = "/api/automation/stop/" + this.reportId;
|
||||
this.$get(url, () => {
|
||||
this.runLoading = false;
|
||||
this.loading = false;
|
||||
this.$success(this.$t('report.test_stop_success'));
|
||||
});
|
||||
},
|
||||
checkVersionEnable() {
|
||||
if (!this.projectId) {
|
||||
return;
|
||||
}
|
||||
if (hasLicense()) {
|
||||
this.$get('/project/version/enable/' + this.projectId, response => {
|
||||
this.versionEnable = response.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
init() {
|
||||
// 深度复制
|
||||
this.api = JSON.parse(JSON.stringify(this.apiData));
|
||||
this.api.protocol = this.currentProtocol;
|
||||
this.currentRequest = this.api.request;
|
||||
if (!this.api.environmentId && this.$store.state.useEnvironment) {
|
||||
this.api.environmentId = this.$store.state.useEnvironment;
|
||||
}
|
||||
this.runLoading = false;
|
||||
this.checkVersionEnable();
|
||||
},
|
||||
getApi() {
|
||||
return this.api;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ms-htt-width {
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
/deep/ .el-drawer {
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,320 @@
|
|||
<template>
|
||||
|
||||
<div class="card-container">
|
||||
<div v-if="versionEnable">
|
||||
<slot name="rightHeader"></slot>
|
||||
</div>
|
||||
<el-card class="card-content">
|
||||
<el-row>
|
||||
<p class="tip" style="display: inline-block">{{ $t('api_test.definition.request.req_param') }} </p>
|
||||
<el-button size="small" type="primary" v-if="apiData.operationType==='create'||apiData.operationType==='edit'"
|
||||
@click="runTest">
|
||||
{{ $t('commons.test') }}
|
||||
</el-button>
|
||||
<!-- 操作按钮 -->
|
||||
<el-dropdown split-button type="primary" class="ms-api-buttion" @click="handleCommand('add')"
|
||||
@command="handleCommand" size="small" v-else-if="!runLoading" style="margin-left: 20px">
|
||||
{{ $t('commons.test') }}
|
||||
<el-dropdown-menu slot="dropdown" v-if="isEdit">
|
||||
<el-dropdown-item command="load_case">{{ $t('api_test.definition.request.load_case') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="save_as_case">{{ $t('api_test.definition.request.save_as_case') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="update_api">{{ $t('api_test.definition.request.update_api') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="save_as_api">{{ $t('api_test.definition.request.save_as') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
<el-dropdown-menu slot="dropdown" v-else>
|
||||
<el-dropdown-item command="save_as_case">{{ $t('api_test.definition.request.save_as_case') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-button size="small" type="primary" v-else @click.once="stop" style="margin-left: 20px">
|
||||
{{ $t('report.stop_btn') }}
|
||||
</el-button>
|
||||
</el-row>
|
||||
<div v-loading="loading">
|
||||
<ms-basis-parameters :show-script="false" :request="api.request" @callback="runTest" ref="requestForm"
|
||||
:response="responseData"/>
|
||||
<!--返回结果-->
|
||||
<!-- HTTP 请求返回数据 -->
|
||||
<p class="tip">{{ $t('api_test.definition.request.res_param') }} </p>
|
||||
<ms-request-result-tail :response="responseData" :currentProtocol="currentProtocol" ref="runResult"/>
|
||||
</div>
|
||||
<api-other-info :api="api" ref="apiOtherInfo"/>
|
||||
</el-card>
|
||||
|
||||
<!-- 加载用例 -->
|
||||
<ms-api-case-list @apiCaseClose="apiCaseClose" @refresh="refresh" @selectTestCase="selectTestCase" :currentApi="api"
|
||||
:refreshSign="refreshSign"
|
||||
:loaded="loaded" :createCase="createCase"
|
||||
ref="caseList"/>
|
||||
|
||||
<!-- 环境 -->
|
||||
<api-environment-config ref="environmentConfig" @close="environmentConfigClose"/>
|
||||
<!-- 执行组件 -->
|
||||
<ms-run :debug="false" :environment="api.environment" :reportId="reportId" :run-data="runData"
|
||||
@runRefresh="runRefresh" @errorRefresh="errorRefresh" ref="runTest"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getUUID, hasLicense} from "@/common/js/utils";
|
||||
import MsApiCaseList from "@/business/components/api/definition/components/case/ApiCaseList";
|
||||
import MsContainer from "@/business/components/common/components/MsContainer";
|
||||
import MsBottomContainer from "@/business/components/api/definition/components/BottomContainer";
|
||||
import ApiEnvironmentConfig from "@/business/components/api/definition/components/environment/ApiEnvironmentConfig";
|
||||
import {parseEnvironment} from "@/business/components/api/definition/model/EnvironmentModel";
|
||||
import MsRequestResultTail from "@/business/components/api/definition/components/response/RequestResultTail";
|
||||
import MsRun from "@/business/components/api/definition/components/Run";
|
||||
import MsBasisParameters from "@/business/components/api/definition/components/request/database/BasisParameters";
|
||||
import {REQ_METHOD} from "@/business/components/api/definition/model/JsonData";
|
||||
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
|
||||
import ApiOtherInfo from "@/business/components/api/definition/components/complete/ApiOtherInfo";
|
||||
|
||||
export default {
|
||||
name: "SqlBaseInfo",
|
||||
components: {
|
||||
MsApiCaseList,
|
||||
MsContainer,
|
||||
MsBottomContainer,
|
||||
MsRequestResultTail,
|
||||
ApiEnvironmentConfig,
|
||||
MsRun,
|
||||
MsBasisParameters,
|
||||
ApiOtherInfo
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
api: {},
|
||||
loaded: false,
|
||||
loading: false,
|
||||
currentRequest: {},
|
||||
responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []},
|
||||
reqOptions: REQ_METHOD,
|
||||
refreshSign: "",
|
||||
createCase: "",
|
||||
environments: [],
|
||||
rules: {
|
||||
method: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||
url: [{required: true, message: this.$t('api_test.definition.request.path_info'), trigger: 'blur'}],
|
||||
environmentId: [{required: true, message: this.$t('api_test.definition.request.run_env'), trigger: 'change'}],
|
||||
},
|
||||
runData: [],
|
||||
reportId: "",
|
||||
runLoading: false,
|
||||
versionEnable: false,
|
||||
}
|
||||
},
|
||||
props: {apiData: {}, currentProtocol: String, syncTabs: Array, projectId: String, isEdit: Boolean},
|
||||
methods: {
|
||||
handleCommand(e) {
|
||||
switch (e) {
|
||||
case "load_case":
|
||||
return this.loadCase();
|
||||
case "save_as_case":
|
||||
return this.saveAsCase();
|
||||
case "update_api":
|
||||
return this.updateApi();
|
||||
case "save_as_api":
|
||||
return this.saveAsApi();
|
||||
default:
|
||||
return this.$refs['requestForm'].validate();
|
||||
}
|
||||
},
|
||||
refresh() {
|
||||
this.$emit('refresh');
|
||||
},
|
||||
errorRefresh() {
|
||||
this.loading = false;
|
||||
this.runLoading = false;
|
||||
},
|
||||
runTest() {
|
||||
this.runLoading = true;
|
||||
this.loading = true;
|
||||
this.api.request.name = this.api.id;
|
||||
this.api.protocol = this.currentProtocol;
|
||||
this.runData = [];
|
||||
this.runData.push(this.api.request);
|
||||
/*触发执行操作*/
|
||||
this.reportId = getUUID().substring(0, 8);
|
||||
},
|
||||
runRefresh(data) {
|
||||
this.responseData = data;
|
||||
this.loading = false;
|
||||
this.runLoading = false;
|
||||
},
|
||||
saveAs() {
|
||||
this.$emit('saveAs', this.api);
|
||||
},
|
||||
loadCase() {
|
||||
this.refreshSign = getUUID();
|
||||
this.$refs.caseList.open();
|
||||
this.visible = true;
|
||||
},
|
||||
apiCaseClose() {
|
||||
this.visible = false;
|
||||
},
|
||||
getBodyUploadFiles() {
|
||||
let bodyUploadFiles = [];
|
||||
this.api.bodyUploadIds = [];
|
||||
let request = this.api.request;
|
||||
if (request.body) {
|
||||
request.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
this.api.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return bodyUploadFiles;
|
||||
},
|
||||
saveAsCase() {
|
||||
this.$emit('saveApiAndCase', this.api);
|
||||
},
|
||||
saveAsApi() {
|
||||
let data = {};
|
||||
let req = this.api.request;
|
||||
req.id = getUUID();
|
||||
data.request = JSON.stringify(req);
|
||||
data.method = this.api.method;
|
||||
data.status = this.api.status;
|
||||
data.userId = this.api.userId;
|
||||
data.description = this.api.description;
|
||||
this.$emit('saveAsApi', data);
|
||||
this.$emit('refresh');
|
||||
},
|
||||
compatibleHistory(stepArray) {
|
||||
if (stepArray) {
|
||||
for (let i in stepArray) {
|
||||
if (!stepArray[i].clazzName) {
|
||||
stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type);
|
||||
}
|
||||
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
|
||||
this.compatibleHistory(stepArray[i].hashTree);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
updateApi() {
|
||||
let url = "/api/definition/update";
|
||||
let bodyFiles = this.getBodyUploadFiles();
|
||||
if (Object.prototype.toString.call(this.api.response).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
|
||||
this.api.response = JSON.parse(this.api.response);
|
||||
}
|
||||
if (this.api.tags instanceof Array) {
|
||||
this.api.tags = JSON.stringify(this.api.tags);
|
||||
}
|
||||
// 历史数据兼容处理
|
||||
if (this.api.request) {
|
||||
this.api.request.clazzName = TYPE_TO_C.get(this.api.request.type);
|
||||
this.compatibleHistory(this.api.request.hashTree);
|
||||
}
|
||||
this.$fileUpload(url, null, bodyFiles, this.api, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
if (this.syncTabs.indexOf(this.api.id) === -1) {
|
||||
this.syncTabs.push(this.api.id);
|
||||
}
|
||||
this.$emit('refresh');
|
||||
});
|
||||
},
|
||||
selectTestCase(item) {
|
||||
if (item != null) {
|
||||
this.api.request = item.request;
|
||||
} else {
|
||||
this.api.request = this.currentRequest;
|
||||
}
|
||||
},
|
||||
getEnvironments() {
|
||||
this.$get('/api/environment/list/' + this.projectId, response => {
|
||||
this.environments = response.data;
|
||||
this.environments.forEach(environment => {
|
||||
parseEnvironment(environment);
|
||||
});
|
||||
let hasEnvironment = false;
|
||||
for (let i in this.environments) {
|
||||
if (this.environments[i].id === this.api.environmentId) {
|
||||
this.api.environment = this.environments[i];
|
||||
hasEnvironment = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasEnvironment) {
|
||||
this.api.environmentId = '';
|
||||
this.api.environment = undefined;
|
||||
}
|
||||
});
|
||||
},
|
||||
openEnvironmentConfig() {
|
||||
this.$refs.environmentConfig.open(this.projectId);
|
||||
},
|
||||
environmentChange(value) {
|
||||
for (let i in this.environments) {
|
||||
if (this.environments[i].id === value) {
|
||||
this.api.request.useEnvironment = this.environments[i].id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
environmentConfigClose() {
|
||||
this.getEnvironments();
|
||||
},
|
||||
getResult() {
|
||||
if (this.api.id) {
|
||||
let url = "/api/definition/report/getReport/" + this.api.id;
|
||||
this.$get(url, response => {
|
||||
if (response.data) {
|
||||
let data = JSON.parse(response.data.content);
|
||||
this.responseData = data;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
stop() {
|
||||
let url = "/api/automation/stop/" + this.reportId;
|
||||
this.$get(url, () => {
|
||||
this.runLoading = false;
|
||||
this.loading = false;
|
||||
this.$success(this.$t('report.test_stop_success'));
|
||||
});
|
||||
},
|
||||
checkVersionEnable() {
|
||||
if (!this.projectId) {
|
||||
return;
|
||||
}
|
||||
if (hasLicense()) {
|
||||
this.$get('/project/version/enable/' + this.projectId, response => {
|
||||
this.versionEnable = response.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
getApi() {
|
||||
return this.api;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 深度复制
|
||||
this.api = JSON.parse(JSON.stringify(this.apiData));
|
||||
this.api.protocol = this.currentProtocol;
|
||||
this.currentRequest = this.api.request;
|
||||
this.runLoading = false;
|
||||
this.getEnvironments();
|
||||
this.getResult();
|
||||
this.checkVersionEnable();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/deep/ .el-drawer {
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,391 @@
|
|||
<template>
|
||||
|
||||
<div class="card-container">
|
||||
<div v-if="versionEnable">
|
||||
<slot name="rightHeader"></slot>
|
||||
</div>
|
||||
<el-card class="card-content">
|
||||
|
||||
<el-form :model="api" :rules="rules" ref="apiData" :inline="true" label-position="right">
|
||||
|
||||
<!-- 执行环境 -->
|
||||
<el-form-item prop="environmentId">
|
||||
{{ $t('api_test.definition.request.run_env') }}:
|
||||
<environment-select :type="'TCP'" :current-data="api" :project-id="projectId" ref="environmentSelect"/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button size="small" type="primary" v-if="apiData.operationType==='create'||apiData.operationType==='edit'"
|
||||
@click="runTest">
|
||||
{{ $t('commons.test') }}
|
||||
</el-button>
|
||||
<!-- 操作按钮 -->
|
||||
<el-dropdown split-button type="primary" class="ms-api-buttion" @click="handleCommand('add')"
|
||||
@command="handleCommand" size="small" v-else-if="!runLoading">
|
||||
{{ $t('commons.test') }}
|
||||
<el-dropdown-menu slot="dropdown" v-if="isEdit">
|
||||
<el-dropdown-item command="load_case">{{ $t('api_test.definition.request.load_case') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="save_as_case">{{ $t('api_test.definition.request.save_as_case') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="update_api">{{
|
||||
$t('api_test.definition.request.update_api')
|
||||
}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="save_as_api">{{ $t('api_test.definition.request.save_as') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
<el-dropdown-menu slot="dropdown" v-else>
|
||||
<el-dropdown-item command="save_as_case">{{ $t('api_test.definition.request.save_as_case') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-button size="small" type="primary" v-else @click.once="stop">
|
||||
{{ $t('report.stop_btn') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<div>
|
||||
<p class="tip" style="display: inline-block">{{ $t('api_test.definition.request.req_param') }} </p>
|
||||
<el-select v-model="api.method" slot="prepend" style="width: 100px" size="small">
|
||||
<el-option v-for="item in methodTypes" :key="item.key" :label="item.value" :value="item.key"/>
|
||||
</el-select>
|
||||
</div>
|
||||
<!-- TCP 请求参数 -->
|
||||
<div v-if="api.method=='TCP'" v-loading="loading">
|
||||
<ms-tcp-format-parameters :show-script="false" :request="api.request" @callback="runTest"
|
||||
:response="responseData"
|
||||
ref="requestForm"/>
|
||||
<ms-request-result-tail :response="responseData" ref="runResult"/>
|
||||
</div>
|
||||
<div v-else-if="api.method=='ESB'" v-loading="loading">
|
||||
<esb-definition v-xpack v-if="showXpackCompnent" :show-script="false" :request="api.request"
|
||||
@callback="runTest" ref="requestForm"/>
|
||||
</div>
|
||||
<div v-if="api.method=='ESB'">
|
||||
<p class="tip">{{ $t('api_test.definition.request.res_param') }}</p>
|
||||
<esb-definition-response v-xpack v-if="showXpackCompnent" :is-api-component="false" :show-options-button="false"
|
||||
:request="api.request" :response-data="responseData"/>
|
||||
</div>
|
||||
</el-form>
|
||||
<api-other-info :api="api" ref="apiOtherInfo"/>
|
||||
</el-card>
|
||||
|
||||
<!-- 加载用例 -->
|
||||
<ms-api-case-list @apiCaseClose="apiCaseClose" @refresh="refresh" @selectTestCase="selectTestCase" :currentApi="api"
|
||||
:refreshSign="refreshSign"
|
||||
:loaded="loaded" :createCase="createCase"
|
||||
ref="caseList"/>
|
||||
|
||||
<!-- 执行组件 -->
|
||||
<ms-run :debug="false" :environment="api.environment" :reportId="reportId" :run-data="runData"
|
||||
@runRefresh="runRefresh" @errorRefresh="errorRefresh" ref="runTest"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getUUID, hasLicense} from "@/common/js/utils";
|
||||
|
||||
import MsTcpFormatParameters from "@/business/components/api/definition/components/request/tcp/TcpFormatParameters";
|
||||
import MsApiRequestForm from "@/business/components/api/definition/components/request/http/ApiHttpRequestForm";
|
||||
import MsApiCaseList from "@/business/components/api/definition/components/case/ApiCaseList";
|
||||
import MsContainer from "@/business/components/common/components/MsContainer";
|
||||
import MsBottomContainer from "@/business/components/api/definition/components/BottomContainer";
|
||||
import MsRequestResultTail from "@/business/components/api/definition/components/response/RequestResultTail";
|
||||
import MsRun from "@/business/components/api/definition/components/Run";
|
||||
import {REQ_METHOD} from "@/business/components/api/definition/model/JsonData";
|
||||
import EnvironmentSelect from "@/business/components/api/definition/components/environment/EnvironmentSelect";
|
||||
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
|
||||
import ApiOtherInfo from "@/business/components/api/definition/components/complete/ApiOtherInfo";
|
||||
|
||||
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: "TcpBaseInfo",
|
||||
components: {
|
||||
EnvironmentSelect,
|
||||
MsApiRequestForm,
|
||||
MsApiCaseList,
|
||||
MsContainer,
|
||||
MsBottomContainer,
|
||||
MsRequestResultTail,
|
||||
MsRun,
|
||||
MsTcpFormatParameters, ApiOtherInfo,
|
||||
"esbDefinition": esbDefinition.default,
|
||||
"esbDefinitionResponse": esbDefinitionResponse.default
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
api: {},
|
||||
loaded: false,
|
||||
loading: false,
|
||||
currentRequest: {},
|
||||
responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []},
|
||||
reqOptions: REQ_METHOD,
|
||||
environments: [],
|
||||
refreshSign: "",
|
||||
createCase: "",
|
||||
methodTypes: [
|
||||
{
|
||||
'key': "TCP",
|
||||
'value': this.$t('api_test.request.tcp.general_format'),
|
||||
}
|
||||
],
|
||||
rules: {
|
||||
environmentId: [{required: true, message: this.$t('api_test.definition.request.run_env'), trigger: 'change'}],
|
||||
},
|
||||
runData: [],
|
||||
reportId: "",
|
||||
showXpackCompnent: false,
|
||||
runLoading: false,
|
||||
versionEnable: false,
|
||||
}
|
||||
},
|
||||
props: {apiData: {}, currentProtocol: String, syncTabs: Array, projectId: String, isEdit: Boolean},
|
||||
methods: {
|
||||
setRequestParam(param, isEnvironmentMock) {
|
||||
this.init();
|
||||
if (this.api.method === "TCP" && param && this.api.request) {
|
||||
if (param.reportType) {
|
||||
this.api.request.reportType = param.reportType;
|
||||
}
|
||||
if (param.jsonDataStruct) {
|
||||
this.api.request.jsonDataStruct = param.jsonDataStruct;
|
||||
}
|
||||
if (param.rawDataStruct) {
|
||||
this.api.request.rawDataStruct = param.rawDataStruct;
|
||||
}
|
||||
if (param.xmlDataStruct) {
|
||||
this.api.request.xmlDataStruct = param.xmlDataStruct;
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.$refs.requestForm.reload();
|
||||
this.$refs.requestForm.setReportType(param.reportType);
|
||||
});
|
||||
}
|
||||
if (isEnvironmentMock) {
|
||||
this.$nextTick(() => {
|
||||
let url = "/api/definition/getMockEnvironment/";
|
||||
this.$get(url + this.projectId, response => {
|
||||
let mockEnvironment = response.data;
|
||||
if (mockEnvironment !== null) {
|
||||
this.$refs.environmentSelect.setEnvironment(mockEnvironment.id);
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
},
|
||||
handleCommand(e) {
|
||||
switch (e) {
|
||||
case "load_case":
|
||||
return this.loadCase();
|
||||
case "save_as_case":
|
||||
return this.saveAsCase();
|
||||
case "update_api":
|
||||
return this.updateApi();
|
||||
case "save_as_api":
|
||||
return this.saveAsApi();
|
||||
default:
|
||||
return this.$refs['requestForm'].validate();
|
||||
}
|
||||
},
|
||||
refresh() {
|
||||
this.$emit('refresh');
|
||||
},
|
||||
runTest() {
|
||||
this.$refs['apiData'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.runLoading = true;
|
||||
this.loading = true;
|
||||
this.api.request.name = this.api.id;
|
||||
this.api.protocol = this.currentProtocol;
|
||||
this.runData = [];
|
||||
this.runData.push(this.api.request);
|
||||
/*触发执行操作*/
|
||||
this.reportId = getUUID().substring(0, 8);
|
||||
}
|
||||
})
|
||||
},
|
||||
runRefresh(data) {
|
||||
this.responseData = data;
|
||||
this.loading = false;
|
||||
this.runLoading = false;
|
||||
},
|
||||
errorRefresh() {
|
||||
this.loading = false;
|
||||
this.runLoading = false;
|
||||
},
|
||||
saveAs() {
|
||||
this.$emit('saveAs', this.api);
|
||||
},
|
||||
loadCase() {
|
||||
this.refreshSign = getUUID();
|
||||
this.$refs.caseList.open();
|
||||
this.visible = true;
|
||||
},
|
||||
apiCaseClose() {
|
||||
this.visible = false;
|
||||
},
|
||||
getBodyUploadFiles() {
|
||||
let bodyUploadFiles = [];
|
||||
this.api.bodyUploadIds = [];
|
||||
let request = this.api.request;
|
||||
if (request.body) {
|
||||
request.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
this.api.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return bodyUploadFiles;
|
||||
},
|
||||
saveAsCase() {
|
||||
this.$emit('saveApiAndCase', this.api);
|
||||
},
|
||||
saveAsApi() {
|
||||
let data = {};
|
||||
let req = this.api.request;
|
||||
req.id = getUUID();
|
||||
data.request = JSON.stringify(req);
|
||||
data.method = this.api.method;
|
||||
data.status = this.api.status;
|
||||
data.userId = this.api.userId;
|
||||
data.description = this.api.description;
|
||||
this.$emit('saveAsApi', data);
|
||||
this.$emit('refresh');
|
||||
},
|
||||
compatibleHistory(stepArray) {
|
||||
if (stepArray) {
|
||||
for (let i in stepArray) {
|
||||
if (!stepArray[i].clazzName) {
|
||||
stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type);
|
||||
}
|
||||
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
|
||||
this.compatibleHistory(stepArray[i].hashTree);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
updateApi() {
|
||||
let url = "/api/definition/update";
|
||||
let bodyFiles = this.getBodyUploadFiles();
|
||||
if (Object.prototype.toString.call(this.api.response).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
|
||||
this.api.response = JSON.parse(this.api.response);
|
||||
}
|
||||
if (this.api.tags instanceof Array) {
|
||||
this.api.tags = JSON.stringify(this.api.tags);
|
||||
}
|
||||
if (this.api.method === 'ESB') {
|
||||
this.api.esbDataStruct = JSON.stringify(this.api.request.esbDataStruct);
|
||||
this.api.backEsbDataStruct = JSON.stringify(this.api.request.backEsbDataStruct);
|
||||
}
|
||||
// 历史数据兼容处理
|
||||
if (this.api.request) {
|
||||
this.api.request.clazzName = TYPE_TO_C.get(this.api.request.type);
|
||||
this.compatibleHistory(this.api.request.hashTree);
|
||||
}
|
||||
this.$fileUpload(url, null, bodyFiles, this.api, () => {
|
||||
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);
|
||||
});
|
||||
},
|
||||
selectTestCase(item) {
|
||||
if (item != null) {
|
||||
this.api.request = item.request;
|
||||
} else {
|
||||
this.api.request = this.currentRequest;
|
||||
}
|
||||
},
|
||||
getResult() {
|
||||
let url = "/api/definition/report/getReport/" + this.api.id;
|
||||
this.$get(url, response => {
|
||||
if (response.data) {
|
||||
let data = JSON.parse(response.data.content);
|
||||
this.responseData = data;
|
||||
}
|
||||
});
|
||||
},
|
||||
stop() {
|
||||
let url = "/api/automation/stop/" + this.reportId;
|
||||
this.$get(url, () => {
|
||||
this.runLoading = false;
|
||||
this.loading = false;
|
||||
this.$success(this.$t('report.test_stop_success'));
|
||||
});
|
||||
},
|
||||
checkVersionEnable() {
|
||||
if (!this.projectId) {
|
||||
return;
|
||||
}
|
||||
if (hasLicense()) {
|
||||
this.$get('/project/version/enable/' + this.projectId, response => {
|
||||
this.versionEnable = response.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
init() {
|
||||
// 深度复制
|
||||
this.api = JSON.parse(JSON.stringify(this.apiData));
|
||||
this.api.protocol = this.currentProtocol;
|
||||
if (!this.api.environmentId) {
|
||||
this.api.environmentId = this.$store.state.useEnvironment;
|
||||
}
|
||||
this.currentRequest = this.api.request;
|
||||
this.runLoading = false;
|
||||
this.getResult();
|
||||
if (requireComponent != null && JSON.stringify(esbDefinition) !== '{}') {
|
||||
this.showXpackCompnent = true;
|
||||
}
|
||||
this.checkVersionEnable();
|
||||
},
|
||||
getApi() {
|
||||
if (this.api.method === 'ESB') {
|
||||
this.api.esbDataStruct = JSON.stringify(this.api.request.esbDataStruct);
|
||||
this.api.backEsbDataStruct = JSON.stringify(this.api.request.backEsbDataStruct);
|
||||
}
|
||||
return this.api;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (requireComponent !== null && JSON.stringify(esbDefinition) !== '{}' && JSON.stringify(esbDefinitionResponse) !== '{}') {
|
||||
this.showXpackCompnent = true;
|
||||
if (hasLicense()) {
|
||||
if (this.methodTypes.length === 1) {
|
||||
let esbMethodType = {};
|
||||
esbMethodType.key = "ESB";
|
||||
esbMethodType.value = "ESB";
|
||||
this.methodTypes.push(esbMethodType);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ms-htt-width {
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.environment-button {
|
||||
margin-left: 20px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
/deep/ .el-drawer {
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,578 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-tabs v-model="activeName" type="card" class="api-info-tab" @tab-click="tabChange">
|
||||
<el-tab-pane label="API" name="api">
|
||||
<api-information :api-info="apiInfo" :api="currentApi" style="margin:5px 5px 5px 5px">
|
||||
<template v-slot:headerRight>
|
||||
<div style="float: right;margin-right: 20px; position: unset" class="ms-opt-btn">
|
||||
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!showFollow">
|
||||
<i class="el-icon-star-off"
|
||||
style="color: #783987; font-size: 25px; margin-right: 5px; position: relative; top: 5px; cursor: pointer "
|
||||
@click="saveFollow"/>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="showFollow">
|
||||
<i class="el-icon-star-on"
|
||||
style="color: #783987; font-size: 28px; margin-right: 5px; position: relative; top: 5px; cursor: pointer "
|
||||
@click="saveFollow"/>
|
||||
</el-tooltip>
|
||||
<el-link type="primary" style="margin-right: 5px" @click="openHis" v-if="apiInfo.id">
|
||||
{{ $t('operating_log.change_history') }}
|
||||
</el-link>
|
||||
<!-- 版本历史 -->
|
||||
<ms-version-history v-xpack
|
||||
ref="versionHistory"
|
||||
:version-data="versionData"
|
||||
:current-id="apiInfo.id"
|
||||
:test-users="maintainerOptions" :use-external-users="true"
|
||||
@compare="compare" @checkout="checkout" @create="create" @del="del"/>
|
||||
<el-button type="primary" size="small" @click="editApi" title="ctrl + s"
|
||||
v-permission="['PROJECT_API_DEFINITION:READ+EDIT_API']">{{ $t('commons.edit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</api-information>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="TEST" name="test">
|
||||
<div style="margin:5px 5px 5px 5px">
|
||||
<ms-run-test-http-page
|
||||
:syncTabs="syncTabs"
|
||||
:currentProtocol="currentProtocol"
|
||||
:api-data="currentApi"
|
||||
:project-id="projectId"
|
||||
@saveAsApi="editApi"
|
||||
@saveAsCase="saveAsCase"
|
||||
@refresh="refresh"
|
||||
ref="httpTestPage"
|
||||
v-if="currentProtocol==='HTTP'"
|
||||
/>
|
||||
<ms-run-test-tcp-page
|
||||
:syncTabs="syncTabs"
|
||||
:currentProtocol="currentProtocol"
|
||||
:api-data="currentApi"
|
||||
:project-id="projectId"
|
||||
@saveAsApi="editApi"
|
||||
@saveAsCase="saveAsCase"
|
||||
@refresh="refresh"
|
||||
ref="tcpTestPage"
|
||||
v-else-if="currentProtocol==='TCP'"
|
||||
/>
|
||||
<ms-run-test-sql-page
|
||||
:syncTabs="syncTabs"
|
||||
:currentProtocol="currentProtocol"
|
||||
:api-data="currentApi"
|
||||
:project-id="projectId"
|
||||
@saveAsApi="editApi"
|
||||
@saveAsCase="saveAsCase"
|
||||
@refresh="refresh"
|
||||
v-else-if="currentProtocol==='SQL'"
|
||||
/>
|
||||
<ms-run-test-dubbo-page
|
||||
:syncTabs="syncTabs"
|
||||
:currentProtocol="currentProtocol"
|
||||
:api-data="currentApi"
|
||||
:project-id="projectId"
|
||||
@saveAsApi="editApi"
|
||||
@saveAsCase="saveAsCase"
|
||||
@refresh="refresh"
|
||||
v-else-if="currentProtocol==='DUBBO'"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="CASE" name="testCase">
|
||||
<!--测试用例列表-->
|
||||
<api-case-simple-list
|
||||
class="api-case-simple-list"
|
||||
:apiDefinitionId="currentApi.id"
|
||||
:apiDefinition="currentApi"
|
||||
:current-version="currentApi.versionId"
|
||||
:trash-enable="false"
|
||||
:test-users="maintainerOptions" :use-external-users="true"
|
||||
@changeSelectDataRangeAll="changeSelectDataRangeAll"
|
||||
@handleCase="handleCase"
|
||||
@refreshTable="refresh"
|
||||
@showExecResult="showExecResult" style="margin:5px 5px 5px 5px"
|
||||
ref="trashCaseList"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="MOCK" name="mock" v-if="currentProtocol === 'HTTP' || currentProtocol === 'TCP'">
|
||||
<div style="margin:5px 5px 5px 5px">
|
||||
<mock-tab :base-mock-config-data="baseMockConfigData" @redirectToTest="redirectToTest"
|
||||
:version-name="currentApi.versionName" :api-id="apiInfo.id"
|
||||
:is-tcp="currentProtocol === 'TCP'"/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<ms-change-history ref="changeHistory"/>
|
||||
<!-- 加载用例 -->
|
||||
<ms-api-case-list
|
||||
:createCase="createCase"
|
||||
:test-users="maintainerOptions" :use-external-users="true"
|
||||
:currentApi="api"
|
||||
@reLoadCase="reLoadCase"
|
||||
ref="caseList"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsApiConfig from "@/business/components/api/definition/components/ApiConfig";
|
||||
import MsRunTestHttpPage from "@/business/components/api/definition/components/runtest/RunTestHTTPPage";
|
||||
import MsRunTestTcpPage from "@/business/components/api/definition/components/runtest/RunTestTCPPage";
|
||||
import MsRunTestSqlPage from "@/business/components/api/definition/components/runtest/RunTestSQLPage";
|
||||
import MsRunTestDubboPage from "@/business/components/api/definition/components/runtest/RunTestDubboPage";
|
||||
import MockTab from "@/business/components/api/definition/components/mock/MockTab";
|
||||
import TcpMockConfig from "@/business/components/api/definition/components/mock/TcpMockConfig";
|
||||
import ApiCaseSimpleList from "@/business/components/api/definition/components/list/ApiCaseSimpleList";
|
||||
import MsApiCaseList from "@/business/components/api/definition/components/case/ApiCaseList";
|
||||
import {getCurrentProjectID, getUUID, hasLicense} from "@/common/js/utils";
|
||||
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
|
||||
import _ from 'lodash';
|
||||
import ApiInformation from "@/business/components/api/definition/components/document/components/ApiInformation";
|
||||
import MsVersionHistory from "@/business/components/xpack/version/VersionHistory";
|
||||
import {createComponent} from "@/business/components/api/definition/components/jmeter/components";
|
||||
import MsChangeHistory from "@/business/components/history/ChangeHistory";
|
||||
|
||||
export default {
|
||||
name: "ApiDefinitionInformation",
|
||||
components: {
|
||||
MsApiConfig,
|
||||
MsRunTestHttpPage,
|
||||
MsRunTestTcpPage,
|
||||
MsRunTestSqlPage,
|
||||
MsRunTestDubboPage,
|
||||
MockTab,
|
||||
TcpMockConfig,
|
||||
ApiCaseSimpleList,
|
||||
MsApiCaseList,
|
||||
ApiInformation,
|
||||
MsVersionHistory,
|
||||
MsChangeHistory
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeName: "api",
|
||||
isShow: true,
|
||||
baseMockConfigData: {},
|
||||
showFollow: false,
|
||||
versionData: [],
|
||||
maintainerOptions: [],
|
||||
httpForm: {environmentId: "", path: "", tags: []},
|
||||
loading: false,
|
||||
createCase: "",
|
||||
api: {},
|
||||
};
|
||||
},
|
||||
props: {
|
||||
apiId: String,
|
||||
activeDom: String,
|
||||
isShowChangeButton: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
apiInfo: {},
|
||||
moduleOptions: {},
|
||||
currentApi: {},
|
||||
currentProtocol: String,
|
||||
syncTabs: Array,
|
||||
projectId: String,
|
||||
selectNodeIds: Array,
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.refreshButtonActiveClass(this.activeDom);
|
||||
if (this.currentApi.id && (this.currentProtocol === "HTTP" || this.currentProtocol === "TCP")) {
|
||||
this.mockSetting();
|
||||
}
|
||||
|
||||
this.getMaintainerOptions();
|
||||
if (!this.httpForm.environmentId) {
|
||||
this.httpForm.environmentId = "";
|
||||
}
|
||||
this.$get('/api/definition/follow/' + this.apiId, response => {
|
||||
this.httpForm.follows = response.data;
|
||||
for (let i = 0; i < response.data.length; i++) {
|
||||
if (response.data[i] === this.currentUser().id) {
|
||||
this.showFollow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.formatApi();
|
||||
if (hasLicense()) {
|
||||
this.getVersionHistory();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activeName() {
|
||||
if (this.activeName === "mock") {
|
||||
this.mockSetting();
|
||||
}
|
||||
},
|
||||
currentProtocol() {
|
||||
this.initMockEnvironment();
|
||||
},
|
||||
'$store.state.currentApiCase.case'() {
|
||||
if (this.$store.state.currentApiCase && this.$store.state.currentApiCase.api) {
|
||||
this.refreshButtonActiveClass("testCase");
|
||||
}
|
||||
},
|
||||
'$store.state.currentApiCase.mock'() {
|
||||
this.mockSetting();
|
||||
this.refreshButtonActiveClass("mock");
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
tabChange() {
|
||||
this.beforeChangeTab();
|
||||
this.refreshButtonActiveClass(this.activeName);
|
||||
},
|
||||
|
||||
reLoadCase() {
|
||||
this.$refs.trashCaseList.initTable();
|
||||
},
|
||||
sort(stepArray) {
|
||||
if (stepArray) {
|
||||
for (let i in stepArray) {
|
||||
if (!stepArray[i].clazzName) {
|
||||
stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type);
|
||||
}
|
||||
if (stepArray[i] && stepArray[i].authManager && !stepArray[i].authManager.clazzName) {
|
||||
stepArray[i].authManager.clazzName = TYPE_TO_C.get(stepArray[i].authManager.type);
|
||||
}
|
||||
if (stepArray[i].type === "Assertions" && !stepArray[i].document) {
|
||||
stepArray[i].document = {
|
||||
type: "JSON",
|
||||
data: {xmlFollowAPI: false, jsonFollowAPI: false, json: [], xml: []}
|
||||
};
|
||||
}
|
||||
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
|
||||
this.sort(stepArray[i].hashTree);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
formatApi() {
|
||||
if (this.currentApi.response !== null && this.currentApi.response !== 'null' && this.currentApi.response !== undefined) {
|
||||
if (Object.prototype.toString.call(this.currentApi.response).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
|
||||
this.currentApi.response = JSON.parse(this.currentApi.response);
|
||||
}
|
||||
}
|
||||
if (this.currentApi.request !== null && this.currentApi.request !== 'null' && this.currentApi.request !== undefined) {
|
||||
if (Object.prototype.toString.call(this.currentApi.request).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
|
||||
this.currentApi.request = JSON.parse(this.currentApi.request);
|
||||
if (this.currentApi.request.body && !this.currentApi.request.body.type) {
|
||||
let tempRequest = _.cloneDeep(this.currentApi.request);
|
||||
tempRequest.body = {type: null};
|
||||
this.currentApi.request = tempRequest;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.currentApi && this.currentApi.request && !this.currentApi.request.hashTree) {
|
||||
this.currentApi.request.hashTree = [];
|
||||
}
|
||||
if (this.currentApi && this.currentApi.request && this.currentApi.request.body && !this.currentApi.request.body.binary) {
|
||||
this.currentApi.request.body.binary = [];
|
||||
}
|
||||
if (this.currentApi.request) {
|
||||
this.currentApi.request.clazzName = TYPE_TO_C.get(this.currentApi.request.type);
|
||||
this.sort(this.currentApi.request.hashTree);
|
||||
}
|
||||
},
|
||||
mockSetting() {
|
||||
let mockParam = {};
|
||||
mockParam.projectId = this.projectId;
|
||||
if (this.currentApi.id) {
|
||||
mockParam.apiId = this.currentApi.id;
|
||||
this.$post('/mockConfig/genMockConfig', mockParam, response => {
|
||||
let mockConfig = response.data;
|
||||
mockConfig.apiName = this.currentApi.name;
|
||||
mockConfig.versionName = this.currentApi.versionName;
|
||||
this.baseMockConfigData = mockConfig;
|
||||
});
|
||||
}
|
||||
},
|
||||
runTest(data) {
|
||||
this.$emit("runTest", data);
|
||||
},
|
||||
saveApi(data) {
|
||||
if (data != null && data.tags !== 'null' && data.tags !== undefined) {
|
||||
if (Object.prototype.toString.call(data.tags) === "[object String]") {
|
||||
data.tags = JSON.parse(data.tags);
|
||||
}
|
||||
}
|
||||
Object.assign(this.currentApi, data);
|
||||
this.currentApi.isCopy = false;
|
||||
this.setTabTitle(data);
|
||||
this.refresh(data);
|
||||
},
|
||||
createRootModel() {
|
||||
this.$emit("createRootModel");
|
||||
},
|
||||
editApi(data) {
|
||||
this.$emit("editApi", data);
|
||||
},
|
||||
refresh() {
|
||||
this.$emit("refresh");
|
||||
},
|
||||
checkout(data) {
|
||||
Object.assign(this.currentApi, data);
|
||||
this.reload();
|
||||
},
|
||||
changeTab(tabType) {
|
||||
|
||||
},
|
||||
beforeChangeTab() {
|
||||
//关闭接口用例弹窗
|
||||
this.$refs.caseList.close();
|
||||
},
|
||||
redirectToTest(param) {
|
||||
this.refreshButtonActiveClass("test");
|
||||
this.$nextTick(() => {
|
||||
if (this.currentProtocol === "HTTP" && this.$refs.httpTestPage) {
|
||||
let requestParam = null;
|
||||
if (param.params) {
|
||||
requestParam = param.params;
|
||||
}
|
||||
this.$refs.httpTestPage.setRequestParam(requestParam, true);
|
||||
} else if (this.currentProtocol === "TCP" && this.$refs.tcpTestPage) {
|
||||
this.$refs.tcpTestPage.setRequestParam(param, true);
|
||||
}
|
||||
});
|
||||
},
|
||||
removeListener() {
|
||||
if (this.$refs && this.$refs.apiConfig) {
|
||||
this.$refs.apiConfig.removeListener();
|
||||
}
|
||||
},
|
||||
changeSelectDataRangeAll() {
|
||||
this.$emit("changeSelectDataRangeAll");
|
||||
},
|
||||
handleCase(api) {
|
||||
this.$emit("handleCase", api);
|
||||
},
|
||||
showExecResult(data) {
|
||||
this.$emit("showExecResult", data);
|
||||
},
|
||||
reload() {
|
||||
this.loading = true;
|
||||
this.$nextTick(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
saveAsCase(api) {
|
||||
this.createCase = getUUID();
|
||||
this.api = api;
|
||||
this.$refs.caseList.open();
|
||||
},
|
||||
refreshButtonActiveClass(tabType) {
|
||||
if (tabType === "testCase") {
|
||||
this.$store.state.currentApiCase = {case: true};
|
||||
} else if (tabType === "test") {
|
||||
this.$store.state.currentApiCase = undefined;
|
||||
} else if (tabType === "mock") {
|
||||
this.$store.state.currentApiCase = undefined;
|
||||
} else {
|
||||
this.syncApi();
|
||||
}
|
||||
if (tabType) {
|
||||
this.activeName = tabType;
|
||||
}
|
||||
},
|
||||
changeApi() {
|
||||
this.$store.state.currentApiCase = undefined;
|
||||
},
|
||||
syncApi() {
|
||||
if (this.syncTabs && this.syncTabs.length > 0 && this.syncTabs.includes(this.currentApi.id)) {
|
||||
// 标示接口在其他地方更新过,当前页面需要同步
|
||||
let url = "/api/definition/get/";
|
||||
this.$get(url + this.currentApi.id, response => {
|
||||
if (response.data) {
|
||||
let request = JSON.parse(response.data.request);
|
||||
let index = this.syncTabs.findIndex(item => {
|
||||
if (item === this.currentApi.id) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
this.syncTabs.splice(index, 1);
|
||||
this.currentApi.request = request;
|
||||
this.changeApi();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.changeApi();
|
||||
}
|
||||
},
|
||||
getVersionHistory() {
|
||||
this.$get('/api/definition/versions/' + this.apiInfo.id, response => {
|
||||
if (this.apiInfo.isCopy) {
|
||||
this.versionData = response.data.filter(v => v.versionId === this.apiInfo.versionId);
|
||||
} else {
|
||||
this.versionData = response.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
compare(row) {
|
||||
this.$get('/api/definition/get/' + row.id + "/" + this.apiInfo.refId, response => {
|
||||
this.$get('/api/definition/get/' + response.data.id, res => {
|
||||
if (res.data) {
|
||||
this.newData = res.data;
|
||||
this.dealWithTag(res.data);
|
||||
this.setRequest(res.data)
|
||||
if (!this.setRequest(res.data)) {
|
||||
this.oldRequest = createComponent("HTTPSamplerProxy");
|
||||
this.dialogVisible = true;
|
||||
}
|
||||
this.formatApi(res.data)
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
checkoutVersion(row) {
|
||||
let api = this.versionData.filter(v => v.versionId === row.id)[0];
|
||||
if (api.tags && api.tags.length > 0) {
|
||||
api.tags = JSON.parse(api.tags);
|
||||
}
|
||||
this.$emit("checkout", api);
|
||||
},
|
||||
create(row) {
|
||||
// 创建新版本
|
||||
this.apiInfo.versionId = row.id;
|
||||
this.apiInfo.versionName = row.name;
|
||||
this.$set(this.apiInfo, 'newVersionRemark', !!this.apiInfo.remark);
|
||||
this.$set(this.apiInfo, 'newVersionDeps', this.$refs.apiOtherInfo.relationshipCount > 0);
|
||||
if (this.$refs.apiOtherInfo.relationshipCount > 0 || this.apiInfo.remark) {
|
||||
this.createNewVersionVisible = true;
|
||||
} else {
|
||||
this.saveApi();
|
||||
}
|
||||
},
|
||||
del(row) {
|
||||
this.$alert(this.$t('api_test.definition.request.delete_confirm') + ' ' + row.name + " ?", '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
this.$get('/api/definition/delete/' + row.id + '/' + this.apiInfo.refId, () => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.getVersionHistory();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
saveFollow() {
|
||||
if (this.showFollow) {
|
||||
this.showFollow = false;
|
||||
for (let i = 0; i < this.httpForm.follows.length; i++) {
|
||||
if (this.httpForm.follows[i] === this.currentUser().id) {
|
||||
this.httpForm.follows.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this.apiInfo.id) {
|
||||
this.$post("/api/definition/update/follows/" + this.apiInfo.id, this.httpForm.follows, () => {
|
||||
this.$success(this.$t('commons.cancel_follow_success'));
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.showFollow = true;
|
||||
if (!this.httpForm.follows) {
|
||||
this.httpForm.follows = [];
|
||||
}
|
||||
this.httpForm.follows.push(this.currentUser().id);
|
||||
if (this.apiInfo.id) {
|
||||
this.$post("/api/definition/update/follows/" + this.apiInfo.id, this.httpForm.follows, () => {
|
||||
this.$success(this.$t('commons.follow_success'));
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
getMaintainerOptions() {
|
||||
this.$post('/user/project/member/tester/list', {projectId: getCurrentProjectID()}, response => {
|
||||
this.maintainerOptions = response.data;
|
||||
});
|
||||
},
|
||||
openHis() {
|
||||
this.$refs.changeHistory.open(this.httpForm.id, ["接口定义", "接口定義", "Api definition", "API_DEFINITION"]);
|
||||
},
|
||||
initMockEnvironment() {
|
||||
if (this.currentProtocol) {
|
||||
let protocol = this.currentProtocol;
|
||||
protocol = protocol.substring(0, protocol.indexOf(":"));
|
||||
let url = "/api/definition/getMockEnvironment/";
|
||||
this.$get(url + this.projectId, response => {
|
||||
this.mockEnvironment = response.data;
|
||||
let httpConfig = JSON.parse(this.mockEnvironment.config);
|
||||
if (httpConfig != null) {
|
||||
httpConfig = httpConfig.httpConfig;
|
||||
let httpType = httpConfig.defaultCondition;
|
||||
let conditions = httpConfig.conditions;
|
||||
conditions.forEach(condition => {
|
||||
if (condition.type === httpType) {
|
||||
this.mockBaseUrl = condition.protocol + "://" + condition.socket;
|
||||
this.newMockBaseUrl = this.mockBaseUrl;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.active {
|
||||
border: solid 1px #6d317c !important;
|
||||
background-color: var(--primary_color) !important;
|
||||
color: #FFFFFF !important;
|
||||
}
|
||||
|
||||
.case-button {
|
||||
border-left: solid 1px var(--primary_color);
|
||||
}
|
||||
|
||||
.item {
|
||||
border: solid 1px var(--primary_color);
|
||||
}
|
||||
|
||||
|
||||
.api-case-simple-list >>> .el-table {
|
||||
height: calc(100vh - 262px) !important;
|
||||
}
|
||||
|
||||
/deep/ .ms-opt-btn {
|
||||
position: fixed;
|
||||
right: 50px;
|
||||
z-index: 1;
|
||||
top: 128px;
|
||||
float: right;
|
||||
margin-right: 20px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
/*tab样式 start*/
|
||||
/deep/ .api-info-tab > .el-tabs__header {
|
||||
background-color: #F4F6F9;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/deep/ .api-info-tab > .el-tabs__header .el-tabs__item.is-top {
|
||||
border-color: #F4F6F9;
|
||||
color: #8F9198;
|
||||
}
|
||||
|
||||
/deep/ .api-info-tab > .el-tabs__header .el-tabs__item.is-active {
|
||||
background-color: #FFFFFF;
|
||||
color: var(--count_number);
|
||||
border: none;
|
||||
}
|
||||
|
||||
/deep/ .api-info-tab > .el-tabs__header .el-tabs__nav.is-top {
|
||||
border-color: #F4F6F9;
|
||||
}
|
||||
|
||||
/*tab样式 end*/
|
||||
</style>
|
||||
|
|
@ -345,6 +345,7 @@ export default {
|
|||
this.currentApi.request = item.request;
|
||||
this.currentApi.request.changeId = getUUID();
|
||||
}
|
||||
this.$emit("setSelectedCaseId",item.id);
|
||||
},
|
||||
changePriority(row) {
|
||||
if (row.id) {
|
||||
|
@ -464,6 +465,7 @@ export default {
|
|||
if (!hideAlert) {
|
||||
this.$emit('refresh');
|
||||
}
|
||||
this.$emit("saveCaseCallback");
|
||||
}
|
||||
}, (error) => {
|
||||
this.isSave = false;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
:api="api"
|
||||
@setEnvironment="setEnvironment"
|
||||
@addCase="addCase"
|
||||
@saveCase="saveCase(apiCaseList[0])"
|
||||
@saveCase="saveCase"
|
||||
:condition="condition"
|
||||
:priorities="priorities"
|
||||
:project-id="projectId"
|
||||
|
@ -17,8 +17,9 @@
|
|||
|
||||
<el-container v-if="!result.loading">
|
||||
<el-main>
|
||||
<div v-for="item in apiCaseList" :key="item.id ? item.id : item.uuid">
|
||||
<api-case-item
|
||||
:loading="singleLoading && singleRunId === apiCaseList[0].id || batchLoadingIds.indexOf(apiCaseList[0].id) > -1"
|
||||
:loading="singleLoading && singleRunId === item.id || batchLoadingIds.indexOf(item.id) > -1"
|
||||
@refresh="refresh"
|
||||
@singleRun="singleRun"
|
||||
@stop="stop"
|
||||
|
@ -27,6 +28,8 @@
|
|||
@showExecResult="showExecResult"
|
||||
@showHistory="showHistory"
|
||||
@reLoadCase="reLoadCase"
|
||||
@saveCaseCallback="close"
|
||||
@setSelectedCaseId="setSelectedCaseId"
|
||||
:environment="environment"
|
||||
:is-case-edit="isCaseEdit"
|
||||
:api="api"
|
||||
|
@ -34,7 +37,8 @@
|
|||
:loaded="loaded"
|
||||
:runResult="runResult"
|
||||
:maintainerOptions="maintainerOptions"
|
||||
:api-case="apiCaseList[0]" ref="apiCaseItem"/>
|
||||
:api-case="item" ref="apiCaseItem"/>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</ms-drawer>
|
||||
|
@ -64,6 +68,8 @@ export default {
|
|||
},
|
||||
props: {
|
||||
createCase: String,
|
||||
testUsers: Array,
|
||||
useExternalUsers: Boolean,
|
||||
loaded: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
|
@ -79,6 +85,7 @@ export default {
|
|||
environment: "",
|
||||
priorities: CASE_ORDER,
|
||||
apiCaseList: [],
|
||||
selectCaseId:"",
|
||||
batchLoadingIds: [],
|
||||
singleLoading: false,
|
||||
singleRunId: "",
|
||||
|
@ -107,6 +114,9 @@ export default {
|
|||
this.api = this.currentApi;
|
||||
this.sysAddition();
|
||||
},
|
||||
testUsers() {
|
||||
this.maintainerOptions = this.testUsers;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.api = this.currentApi;
|
||||
|
@ -127,13 +137,20 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
getMaintainerOptions() {
|
||||
this.$post('/user/project/member/tester/list', {projectId: getCurrentProjectID()}, response => {
|
||||
this.maintainerOptions = response.data;
|
||||
});
|
||||
setSelectedCaseId(caseId){
|
||||
this.selectCaseId = caseId;
|
||||
},
|
||||
close(){
|
||||
if(this.$refs.testCaseDrawer){
|
||||
getMaintainerOptions() {
|
||||
if (this.useExternalUsers) {
|
||||
this.maintainerOptions = this.testUsers;
|
||||
} else {
|
||||
this.$post('/user/project/member/tester/list', {projectId: getCurrentProjectID()}, response => {
|
||||
this.maintainerOptions = response.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
close() {
|
||||
if (this.$refs.testCaseDrawer) {
|
||||
this.$refs.testCaseDrawer.close();
|
||||
}
|
||||
},
|
||||
|
@ -196,8 +213,17 @@ export default {
|
|||
}
|
||||
this.visible = true;
|
||||
},
|
||||
saveCase(item, hideAlert) {
|
||||
this.$refs.apiCaseItem.saveTestCase(item, hideAlert);
|
||||
saveCase(hideAlert) {
|
||||
let index = 0;
|
||||
if(this.selectCaseId && this.selectCaseId !== ''){
|
||||
for(let i = 0; i < this.apiCaseList.length; i++){
|
||||
if(this.apiCaseList[i].id === this.selectCaseId){
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
let item = this.apiCaseList[index];
|
||||
this.$refs.apiCaseItem[index].saveTestCase(item, hideAlert);
|
||||
},
|
||||
saveApiAndCase(api) {
|
||||
if (api && api.url) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div style="margin-bottom: 50px;border-bottom-width: 2px" ref="baseDiv">
|
||||
<div style="font-size: 17px">
|
||||
<div style="font-size: 18px; margin-left: 15px">
|
||||
<el-popover
|
||||
v-if="projectId"
|
||||
placement="right"
|
||||
|
@ -16,10 +16,12 @@
|
|||
</el-popover>
|
||||
{{ apiInfo.name }}
|
||||
<span class="apiStatusTag">
|
||||
<api-status :value="apiInfo.status"/>
|
||||
</span>
|
||||
<api-status :value="apiInfo.status"/>
|
||||
</span>
|
||||
<slot name="headerRight"></slot>
|
||||
</div>
|
||||
<!--api请求信息-->
|
||||
|
||||
<!--api基础信息-->
|
||||
<el-row class="apiInfoRow">
|
||||
<div class="simpleFontClass">
|
||||
<el-tag size="medium"
|
||||
|
@ -40,39 +42,16 @@
|
|||
</el-row>
|
||||
</div>
|
||||
</el-row>
|
||||
<!--api请求头-->
|
||||
<api-info-collapse table-coloum-type="nameAndValue" :title="$t('api_test.definition.document.request_head')"
|
||||
:string-data="apiInfo.requestHead"/>
|
||||
<!--QUERY参数-->
|
||||
<api-info-collapse table-coloum-type="simple" :title="'QUERY'+$t('api_test.definition.document.request_param')"
|
||||
:string-data="apiInfo.urlParams"/>
|
||||
<!--REST参数-->
|
||||
<api-info-collapse table-coloum-type="simple" :title="'REST'+$t('api_test.definition.document.request_param')"
|
||||
:string-data="apiInfo.restParams"/>
|
||||
<!--api请求体 以及表格-->
|
||||
<api-info-collapse :is-request="true" :remarks="apiInfo.requestBodyParamType"
|
||||
:title="$t('api_test.definition.document.request_body')">
|
||||
<api-request-info slot="request" :api-info="apiInfo"></api-request-info>
|
||||
</api-info-collapse>
|
||||
|
||||
<!--响应头-->
|
||||
<api-info-collapse table-coloum-type="nameAndValue" :title="$t('api_test.definition.document.response_head')"
|
||||
:string-data="apiInfo.responseHead"/>
|
||||
<!--响应体-->
|
||||
<api-info-collapse :is-response="true" :remarks="apiInfo.responseBodyParamType"
|
||||
:title="$t('api_test.definition.document.response_body')">
|
||||
<api-response-info slot="response" :api-info="apiInfo"></api-response-info>
|
||||
</api-info-collapse>
|
||||
|
||||
<!--响应状态码-->
|
||||
<api-info-collapse :is-text="true" :string-data="getName(apiInfo.responseCode)"
|
||||
:title="$t('api_test.definition.document.response_code')"/>
|
||||
<http-information v-if="apiInfo.protocol==='HTTP'" :api-info="apiInfo"/>
|
||||
<tcp-information v-else-if="apiInfo.protocol==='TCP'" :api="apiObject"/>
|
||||
<sql-api-information v-else-if="apiInfo.protocol==='SQL'" :api="apiObject"/>
|
||||
<dubbo-information v-else-if="apiInfo.protocol==='DUBBO'" :api="apiObject"/>
|
||||
<el-divider></el-divider>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {API_METHOD_COLOUR} from "@/business/components/api/definition/model/JsonData";
|
||||
import MsCodeEdit from "@/business/components/common/components/MsCodeEdit";
|
||||
import ApiStatus from "@/business/components/api/definition/components/list/ApiStatus";
|
||||
import MsJsonCodeEdit from "@/business/components/common/json-schema/JsonSchemaEditor";
|
||||
|
@ -81,7 +60,15 @@ import {generateApiDocumentShareInfo} from "@/network/share";
|
|||
import ApiInfoCollapse from "@/business/components/api/definition/components/document/components/ApiInfoCollapse";
|
||||
import ApiRequestInfo from "@/business/components/api/definition/components/document/components/ApiRequestInfo";
|
||||
import ApiResponseInfo from "@/business/components/api/definition/components/document/components/ApiResponseInfo";
|
||||
|
||||
import HttpInformation
|
||||
from "@/business/components/api/definition/components/document/components/protocal/HttpInformation";
|
||||
import TcpInformation
|
||||
from "@/business/components/api/definition/components/document/components/protocal/TcpInformation";
|
||||
import DubboInformation
|
||||
from "@/business/components/api/definition/components/document/components/protocal/DubboInformation";
|
||||
import SqlApiInformation
|
||||
from "@/business/components/api/definition/components/document/components/protocal/SqlApiInformation";
|
||||
import {API_METHOD_COLOUR} from "@/business/components/api/definition/model/JsonData";
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
const apiDocumentBatchShare = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./share/ApiDocumentBatchShare.vue") : {};
|
||||
|
||||
|
@ -91,10 +78,12 @@ export default {
|
|||
Api,
|
||||
MsJsonCodeEdit,
|
||||
ApiStatus, MsCodeEdit, ApiInfoCollapse, ApiRequestInfo, ApiResponseInfo,
|
||||
HttpInformation,TcpInformation,DubboInformation,SqlApiInformation,
|
||||
"ApiDocumentBatchShare": apiDocumentBatchShare.default
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
apiObject:{},
|
||||
shareUrl: "",
|
||||
apiActiveInfoNames: ["info"],
|
||||
batchShareUrl: "",
|
||||
|
@ -102,6 +91,7 @@ export default {
|
|||
apiInfoArray: [],
|
||||
modes: ['text', 'json', 'xml', 'html'],
|
||||
formParamTypes: ['form-data', 'x-www-from-urlencoded', 'BINARY'],
|
||||
methodColorMap: new Map(API_METHOD_COLOUR),
|
||||
mockVariableFuncs: [],
|
||||
apiSearch: {
|
||||
name: "",
|
||||
|
@ -130,7 +120,7 @@ export default {
|
|||
responseBodyStrutureData: "无",
|
||||
responseCode: "无",
|
||||
},
|
||||
methodColorMap: new Map(API_METHOD_COLOUR),
|
||||
|
||||
maxCompnentSize: 5, //浏览器最多渲染的api信息体数量
|
||||
apiShowArray: [],//浏览器要渲染的api信息集合
|
||||
needAsyncSelect: false, //是否需要异步查询api详细数据做展现。只有本次要展示的数据总量大于maxCompnentSize时为true
|
||||
|
@ -140,11 +130,13 @@ export default {
|
|||
},
|
||||
props: {
|
||||
projectId: String,
|
||||
apiInfo: Object
|
||||
apiInfo: Object,
|
||||
api:Object,
|
||||
},
|
||||
activated() {
|
||||
},
|
||||
created: function () {
|
||||
this.apiObject = JSON.parse(JSON.stringify(this.api));
|
||||
if (requireComponent != null && JSON.stringify(apiDocumentBatchShare) != '{}') {
|
||||
this.showXpackCompnent = true;
|
||||
}
|
||||
|
@ -193,33 +185,15 @@ export default {
|
|||
getColor(enable, method) {
|
||||
return this.methodColorMap.get(method);
|
||||
},
|
||||
getName(jsonString) {
|
||||
let returnString = "无";
|
||||
if (jsonString == '无' || jsonString == null) {
|
||||
return returnString;
|
||||
}
|
||||
|
||||
try {
|
||||
let jsonArr = JSON.parse(jsonString);
|
||||
//遍历,把必填项空的数据去掉
|
||||
for (var index = 0; index < jsonArr.length; index++) {
|
||||
var item = jsonArr[index];
|
||||
if (item.name !== "") {
|
||||
returnString = item.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
returnString = jsonString;
|
||||
}
|
||||
|
||||
return returnString;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.apiStatusTag {
|
||||
margin: 10px 10px;
|
||||
}
|
||||
.simpleFontClass {
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
|
@ -233,64 +207,60 @@ export default {
|
|||
.apiInfoRow.el-row {
|
||||
margin: 10px 10px;
|
||||
}
|
||||
|
||||
.apiStatusTag {
|
||||
margin: 10px 10px;
|
||||
}
|
||||
|
||||
/*
|
||||
步骤条中,已经完成后的节点样式和里面a标签的样式
|
||||
*/
|
||||
/deep/ .el-step {
|
||||
flex-basis: 40px !important;
|
||||
}
|
||||
|
||||
/deep/ .el-step__head.is-finish {
|
||||
color: #C0C4CC;
|
||||
border-color: #C0C4CC;
|
||||
}
|
||||
|
||||
/deep/ .el-step__title.is-finish /deep/ .el-link.el-link--default {
|
||||
color: #C0C4CC;
|
||||
}
|
||||
|
||||
/*
|
||||
步骤条中,当前节点样式和当前a标签的样式
|
||||
*/
|
||||
/deep/ .el-step__head {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
/deep/ .el-step__head.is-process {
|
||||
color: #783887;
|
||||
border-color: #783887;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
/deep/ .el-step__title.is-process .el-link.el-link--default.is-underline {
|
||||
color: #783887;
|
||||
}
|
||||
|
||||
/deep/ .el-link--inner {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/deep/ .el-step__icon-inner {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/deep/ .el-step.is-vertical .el-step__line {
|
||||
left: 9px;
|
||||
}
|
||||
|
||||
/deep/ .el-step__icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.attacInfo {
|
||||
font-size: 12px;
|
||||
color: #A0A0A0;
|
||||
margin: 10px;
|
||||
}
|
||||
/*!**/
|
||||
/*步骤条中,已经完成后的节点样式和里面a标签的样式*/
|
||||
/**!*/
|
||||
/*/deep/ .el-step {*/
|
||||
/* flex-basis: 40px !important;*/
|
||||
/*}*/
|
||||
|
||||
/*/deep/ .el-step__head.is-finish {*/
|
||||
/* color: #C0C4CC;*/
|
||||
/* border-color: #C0C4CC;*/
|
||||
/*}*/
|
||||
|
||||
/*/deep/ .el-step__title.is-finish /deep/ .el-link.el-link--default {*/
|
||||
/* color: #C0C4CC;*/
|
||||
/*}*/
|
||||
|
||||
/*!**/
|
||||
/*步骤条中,当前节点样式和当前a标签的样式*/
|
||||
/**!*/
|
||||
/*/deep/ .el-step__head {*/
|
||||
/* width: 20px;*/
|
||||
/*}*/
|
||||
|
||||
/*/deep/ .el-step__head.is-process {*/
|
||||
/* color: #783887;*/
|
||||
/* border-color: #783887;*/
|
||||
/* width: 20px;*/
|
||||
/*}*/
|
||||
|
||||
/*/deep/ .el-step__title.is-process .el-link.el-link--default.is-underline {*/
|
||||
/* color: #783887;*/
|
||||
/*}*/
|
||||
|
||||
/*/deep/ .el-link--inner {*/
|
||||
/* font-size: 12px;*/
|
||||
/*}*/
|
||||
|
||||
/*/deep/ .el-step__icon-inner {*/
|
||||
/* font-size: 12px;*/
|
||||
/*}*/
|
||||
|
||||
/*/deep/ .el-step.is-vertical .el-step__line {*/
|
||||
/* left: 9px;*/
|
||||
/*}*/
|
||||
|
||||
/*/deep/ .el-step__icon {*/
|
||||
/* width: 20px;*/
|
||||
/* height: 20px;*/
|
||||
/*}*/
|
||||
|
||||
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<template>
|
||||
<div>
|
||||
<!-- 请求参数 -->
|
||||
<p class="tip">{{ $t('api_test.definition.request.req_param') }} </p>
|
||||
<ms-basis-parameters :showScript="false" :is-read-only="true" :request="api.request"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsBasisParameters from "@/business/components/api/definition/components/request/dubbo/BasisParameters";
|
||||
export default {
|
||||
name: "DubboInformation",
|
||||
components:{MsBasisParameters},
|
||||
props:{
|
||||
api:{},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,75 @@
|
|||
<template>
|
||||
<div>
|
||||
<!--api请求头-->
|
||||
<api-info-collapse table-coloum-type="nameAndValue" :title="$t('api_test.definition.document.request_head')"
|
||||
:string-data="apiInfo.requestHead"/>
|
||||
<!--QUERY参数-->
|
||||
<api-info-collapse table-coloum-type="simple" :title="'QUERY'+$t('api_test.definition.document.request_param')"
|
||||
:string-data="apiInfo.urlParams"/>
|
||||
<!--REST参数-->
|
||||
<api-info-collapse table-coloum-type="simple" :title="'REST'+$t('api_test.definition.document.request_param')"
|
||||
:string-data="apiInfo.restParams"/>
|
||||
<!--api请求体 以及表格-->
|
||||
<api-info-collapse :is-request="true" :remarks="apiInfo.requestBodyParamType"
|
||||
:title="$t('api_test.definition.document.request_body')">
|
||||
<api-request-info slot="request" :api-info="apiInfo"></api-request-info>
|
||||
</api-info-collapse>
|
||||
|
||||
<!--响应头-->
|
||||
<api-info-collapse table-coloum-type="nameAndValue" :title="$t('api_test.definition.document.response_head')"
|
||||
:string-data="apiInfo.responseHead"/>
|
||||
<!--响应体-->
|
||||
<api-info-collapse :is-response="true" :remarks="apiInfo.responseBodyParamType"
|
||||
:title="$t('api_test.definition.document.response_body')">
|
||||
<api-response-info slot="response" :api-info="apiInfo"></api-response-info>
|
||||
</api-info-collapse>
|
||||
|
||||
<!--响应状态码-->
|
||||
<api-info-collapse :is-text="true" :string-data="getName(apiInfo.responseCode)"
|
||||
:title="$t('api_test.definition.document.response_code')"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {API_METHOD_COLOUR} from "@/business/components/api/definition/model/JsonData";
|
||||
import ApiInfoCollapse from "@/business/components/api/definition/components/document/components/ApiInfoCollapse";
|
||||
import ApiRequestInfo from "@/business/components/api/definition/components/document/components/ApiRequestInfo";
|
||||
import ApiResponseInfo from "@/business/components/api/definition/components/document/components/ApiResponseInfo";
|
||||
export default {
|
||||
name: "HttpInformation",
|
||||
props: {
|
||||
apiInfo: {},
|
||||
},
|
||||
components:{ApiInfoCollapse,ApiResponseInfo,ApiRequestInfo},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getName(jsonString) {
|
||||
let returnString = "无";
|
||||
if (jsonString === '无' || jsonString === null) {
|
||||
return returnString;
|
||||
}
|
||||
try {
|
||||
let jsonArr = JSON.parse(jsonString);
|
||||
//遍历,把必填项空的数据去掉
|
||||
for (var index = 0; index < jsonArr.length; index++) {
|
||||
var item = jsonArr[index];
|
||||
if (item.name !== "") {
|
||||
returnString = item.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
returnString = jsonString;
|
||||
}
|
||||
return returnString;
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -0,0 +1,22 @@
|
|||
<template>
|
||||
<div>
|
||||
<!-- 请求参数 -->
|
||||
<p class="tip">{{ $t('api_test.definition.request.req_param') }} </p>
|
||||
<ms-basis-parameters :showScript="false" :is-read-only="true" :request="api.request"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsBasisParameters from "@/business/components/api/definition/components/request/database/BasisParameters";
|
||||
export default {
|
||||
name: "SqlApiInformation",
|
||||
components:{MsBasisParameters},
|
||||
props:{
|
||||
api:{},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,71 @@
|
|||
<template>
|
||||
<div>
|
||||
<!-- 请求参数 -->
|
||||
<div v-if="apiProtocol=='TCP'">
|
||||
<p class="tip">{{ $t('api_test.definition.request.req_param') }} </p>
|
||||
<ms-tcp-format-parameters :is-read-only="true" :show-pre-script="true" :show-script="false" :request="api.request"
|
||||
ref="tcpFormatParameter"/>
|
||||
</div>
|
||||
<div v-else-if="apiProtocol=='ESB'">
|
||||
<p class="tip">{{ $t('api_test.definition.request.req_param') }} </p>
|
||||
<esb-definition v-xpack :show-pre-script="true" v-if="showXpackCompnent" :show-script="false" :request="api.request"
|
||||
ref="esbDefinition"/>
|
||||
<p class="tip">{{ $t('api_test.definition.request.res_param') }}</p>
|
||||
<esb-definition-response v-xpack v-if="showXpackCompnent" :is-api-component="true" :show-options-button="true"
|
||||
:request="api.request"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {hasLicense} from "@/common/js/utils";
|
||||
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") : {};
|
||||
import MsTcpFormatParameters from "@/business/components/api/definition/components/request/tcp/TcpFormatParameters";
|
||||
|
||||
export default {
|
||||
name: "TcpInformation",
|
||||
components:{
|
||||
MsTcpFormatParameters,
|
||||
"esbDefinition": esbDefinition.default,
|
||||
"esbDefinitionResponse": esbDefinitionResponse.default,
|
||||
},
|
||||
props:{
|
||||
api:{},
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
apiProtocol: "TCP",
|
||||
showXpackCompnent: false,
|
||||
methodTypes: [
|
||||
{
|
||||
'key': "TCP",
|
||||
'value': this.$t('api_test.request.tcp.general_format'),
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.apiProtocol = this.api.method;
|
||||
if (this.apiProtocol === null || this.apiProtocol === "") {
|
||||
this.apiProtocol = "TCP";
|
||||
}
|
||||
if (requireComponent !== null && JSON.stringify(esbDefinition) !== '{}' && JSON.stringify(esbDefinitionResponse) !== '{}') {
|
||||
this.showXpackCompnent = true;
|
||||
if (hasLicense()) {
|
||||
if (this.methodTypes.length === 1) {
|
||||
let esbMethodType = {};
|
||||
esbMethodType.key = "ESB";
|
||||
esbMethodType.value = "ESB";
|
||||
this.methodTypes.push(esbMethodType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -213,7 +213,7 @@
|
|||
:total="total"/>
|
||||
</span>
|
||||
|
||||
<api-case-list @showExecResult="showExecResult" @refreshCase="setRunning" :currentApi="selectCase" ref="caseList"
|
||||
<api-case-list @showExecResult="showExecResult" @refreshCase="setRunning" :currentApi="selectCase" ref="caseList" :test-users="testUsers" :use-external-users="useExternalUsers"
|
||||
@stop="stop" @reLoadCase="initTable"/>
|
||||
<!--批量编辑-->
|
||||
<ms-batch-edit ref="batchEdit" :data-count="$refs.caseTable ? $refs.caseTable.selectDataCounts : 0"
|
||||
|
@ -445,6 +445,8 @@ export default {
|
|||
};
|
||||
},
|
||||
props: {
|
||||
testUsers:Array,
|
||||
useExternalUsers:Boolean,
|
||||
currentProtocol: String,
|
||||
currentVersion: String,
|
||||
apiDefinitionId: String,
|
||||
|
|
|
@ -51,8 +51,8 @@
|
|||
sortable>
|
||||
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip content="编辑">
|
||||
<a style="cursor:pointer" @click="editApi(scope.row)"> {{ scope.row.num }} </a>
|
||||
<el-tooltip :content="$t('commons.view')">
|
||||
<a style="cursor:pointer" @click="showApi(scope.row)"> {{ scope.row.num }} </a>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</ms-table-column>
|
||||
|
@ -63,7 +63,13 @@
|
|||
sortable="custom"
|
||||
:fields-width="fieldsWidth"
|
||||
min-width="120"
|
||||
:field="item"/>
|
||||
:field="item">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip :content="$t('commons.view')">
|
||||
<a style="cursor:pointer" @click="showApi(scope.row)"> {{ scope.row.name }} </a>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</ms-table-column>
|
||||
|
||||
<ms-table-column
|
||||
prop="status"
|
||||
|
@ -677,6 +683,9 @@ export default {
|
|||
editApi(row) {
|
||||
this.$emit('editApi', row);
|
||||
},
|
||||
showApi(row) {
|
||||
this.$emit('showApi', row);
|
||||
},
|
||||
handleCopy(row) {
|
||||
let obj = JSON.parse(JSON.stringify(row));
|
||||
obj.isCopy = true;
|
||||
|
|
|
@ -93,7 +93,7 @@ export default {
|
|||
arguments: [],
|
||||
rest: [],
|
||||
body: {
|
||||
type: 'Form Data',
|
||||
type: 'Raw',
|
||||
binary: [],
|
||||
kvs: [],
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
<ms-table
|
||||
v-loading="result.loading"
|
||||
:data="mockConfigData.mockExpectConfigList.filter(data=>!tableSearch || data.name.toLowerCase().includes(tableSearch.toLowerCase()))"
|
||||
:data="filterMockData()"
|
||||
:operators="operators"
|
||||
:page-size="pageSize"
|
||||
:showSelectAll="false"
|
||||
|
@ -72,9 +72,10 @@
|
|||
</ms-table-column>
|
||||
</ms-table>
|
||||
</div>
|
||||
<mock-edit-drawer :is-tcp="isTcp" :api-id="this.baseMockConfigData.mockConfig.apiId"
|
||||
<mock-edit-drawer :is-tcp="isTcp" :api-id="apiId"
|
||||
:api-params="apiParams"
|
||||
@refreshMockInfo="refreshMockInfo"
|
||||
v-if="mockConfigData && mockConfigData.mockConfig && mockConfigData.mockConfig.id"
|
||||
:mock-config-id="mockConfigData.mockConfig.id" ref="mockEditDrawer"/>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -95,7 +96,8 @@ export default {
|
|||
},
|
||||
props: {
|
||||
baseMockConfigData: {},
|
||||
versionName:String,
|
||||
versionName: String,
|
||||
apiId: String,
|
||||
isTcp: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
|
@ -151,6 +153,14 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
filterMockData() {
|
||||
if (this.mockConfigData && this.mockConfigData.mockExpectConfigList) {
|
||||
return this.mockConfigData.mockExpectConfigList.filter(
|
||||
data => !this.tableSearch || data.name.toLowerCase().includes(this.tableSearch.toLowerCase()))
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
redirectToTest(row) {
|
||||
let requestParam = null;
|
||||
if (row && row.request) {
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
<el-tabs v-model="activeName" class="request-tabs" @tab-click="tabClick">
|
||||
<!-- 请求头-->
|
||||
<el-tab-pane :label="$t('api_test.request.headers')" name="headers">
|
||||
<el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.request.headers')" placement="top-start" slot="label">
|
||||
<el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.request.headers')" placement="top-start"
|
||||
slot="label">
|
||||
<span>{{ $t('api_test.request.headers') }}
|
||||
<div class="el-step__icon is-text ms-api-col ms-header" v-if="headers.length>1">
|
||||
<div class="el-step__icon-inner">{{ headers.length - 1 }}</div>
|
||||
|
@ -13,14 +14,20 @@
|
|||
</span>
|
||||
</el-tooltip>
|
||||
<el-row>
|
||||
<el-link class="ms-el-link" @click="batchAdd" style="color: #783887"> {{ $t("commons.batch_add") }}</el-link>
|
||||
<el-link class="ms-el-link" @click="batchAdd" style="color: #783887"> {{
|
||||
$t("commons.batch_add")
|
||||
}}
|
||||
</el-link>
|
||||
</el-row>
|
||||
<ms-api-key-value @editScenarioAdvance="editScenarioAdvance" :scenario-definition="scenarioDefinition" :show-desc="true" :is-read-only="isReadOnly" :isShowEnable="isShowEnable" :suggestions="headerSuggestions" :items="headers" :need-mock="true"/>
|
||||
<ms-api-key-value @editScenarioAdvance="editScenarioAdvance" :scenario-definition="scenarioDefinition"
|
||||
:show-desc="true" :is-read-only="isReadOnly" :isShowEnable="isShowEnable"
|
||||
:suggestions="headerSuggestions" :items="headers" :need-mock="true"/>
|
||||
</el-tab-pane>
|
||||
|
||||
<!--query 参数-->
|
||||
<el-tab-pane :label="$t('api_test.definition.request.query_param')" name="parameters">
|
||||
<el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.definition.request.query_info')" placement="top-start" slot="label">
|
||||
<el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.definition.request.query_info')"
|
||||
placement="top-start" slot="label">
|
||||
<span>{{ $t('api_test.definition.request.query_param') }}
|
||||
<div class="el-step__icon is-text ms-api-col ms-header" v-if="request.arguments.length>1">
|
||||
<div class="el-step__icon-inner">{{ request.arguments.length - 1 }}</div>
|
||||
|
@ -28,14 +35,20 @@
|
|||
</span>
|
||||
</el-tooltip>
|
||||
<el-row>
|
||||
<el-link class="ms-el-link" @click="batchAdd" style="color: #783887"> {{ $t("commons.batch_add") }}</el-link>
|
||||
<el-link class="ms-el-link" @click="batchAdd" style="color: #783887"> {{
|
||||
$t("commons.batch_add")
|
||||
}}
|
||||
</el-link>
|
||||
</el-row>
|
||||
<ms-api-variable @editScenarioAdvance="editScenarioAdvance" :scenario-definition="scenarioDefinition" :with-mor-setting="true" :is-read-only="isReadOnly" :isShowEnable="isShowEnable" :parameters="request.arguments"/>
|
||||
<ms-api-variable @editScenarioAdvance="editScenarioAdvance" :scenario-definition="scenarioDefinition"
|
||||
:with-mor-setting="true" :is-read-only="isReadOnly" :isShowEnable="isShowEnable"
|
||||
:parameters="request.arguments"/>
|
||||
</el-tab-pane>
|
||||
|
||||
<!--REST 参数-->
|
||||
<el-tab-pane :label="$t('api_test.definition.request.rest_param')" name="rest">
|
||||
<el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.definition.request.rest_info')" placement="top-start" slot="label">
|
||||
<el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.definition.request.rest_info')"
|
||||
placement="top-start" slot="label">
|
||||
<span>
|
||||
{{ $t('api_test.definition.request.rest_param') }}
|
||||
<div class="el-step__icon is-text ms-api-col ms-header" v-if="request.rest.length>1">
|
||||
|
@ -44,9 +57,14 @@
|
|||
</span>
|
||||
</el-tooltip>
|
||||
<el-row>
|
||||
<el-link class="ms-el-link" @click="batchAdd" style="color: #783887"> {{ $t("commons.batch_add") }}</el-link>
|
||||
<el-link class="ms-el-link" @click="batchAdd" style="color: #783887"> {{
|
||||
$t("commons.batch_add")
|
||||
}}
|
||||
</el-link>
|
||||
</el-row>
|
||||
<ms-api-variable @editScenarioAdvance="editScenarioAdvance" :scenario-definition="scenarioDefinition" :with-mor-setting="true" :is-read-only="isReadOnly" :isShowEnable="isShowEnable" :parameters="request.rest"/>
|
||||
<ms-api-variable @editScenarioAdvance="editScenarioAdvance" :scenario-definition="scenarioDefinition"
|
||||
:with-mor-setting="true" :is-read-only="isReadOnly" :isShowEnable="isShowEnable"
|
||||
:parameters="request.rest"/>
|
||||
</el-tab-pane>
|
||||
|
||||
<!--请求体-->
|
||||
|
@ -56,7 +74,8 @@
|
|||
|
||||
<!-- 认证配置 -->
|
||||
<el-tab-pane :label="$t('api_test.definition.request.auth_config')" name="authConfig">
|
||||
<el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.definition.request.auth_config_info')" placement="top-start" slot="label">
|
||||
<el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.definition.request.auth_config_info')"
|
||||
placement="top-start" slot="label">
|
||||
<span>{{ $t('api_test.definition.request.auth_config') }}</span>
|
||||
</el-tooltip>
|
||||
|
||||
|
@ -93,7 +112,8 @@
|
|||
<div class="el-step__icon-inner">{{ request.ruleSize }}</div>
|
||||
</div>
|
||||
</span>
|
||||
<ms-jmx-step :request="request" :apiId="request.id" :response="response" @reload="reloadBody" :tab-type="'assertionsRule'" ref="assertionsRule"/>
|
||||
<ms-jmx-step :request="request" :apiId="request.id" :response="response" @reload="reloadBody"
|
||||
:tab-type="'assertionsRule'" ref="assertionsRule"/>
|
||||
</el-tab-pane>
|
||||
|
||||
</el-tabs>
|
||||
|
|
|
@ -56,7 +56,6 @@
|
|||
this.isActive = !this.isActive;
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (!this.response.headers) {
|
||||
return;
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
<div class="card-container">
|
||||
<div class="ms-opt-btn" v-if="versionEnable">
|
||||
<slot name="msOptBtnLeft"></slot>
|
||||
{{ $t('project.version.name') }}: {{ apiData.versionName }}
|
||||
<slot name="msOptBtnRight"></slot>
|
||||
</div>
|
||||
<el-card class="card-content">
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-card class="table-card" v-loading="result.loading" body-style="padding:16px 5px 16px 16px;" style="height: 350px;margin-top: 5px">
|
||||
<el-card class="table-card" v-loading="result.loading" body-style="padding:16px 5px 16px 16px;" style="height: 360px;margin-top: 5px">
|
||||
<div slot="header">
|
||||
<span class="title">
|
||||
{{ $t('api_test.home_page.api_count_card.title') }}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<el-card class="table-card" v-loading="result.loading" body-style="padding:16px 5px 16px 16px;"
|
||||
style="height: 350px;margin-top: 5px">
|
||||
style="height: 360px;margin-top: 5px">
|
||||
<div slot="header">
|
||||
<span class="title">
|
||||
{{ $t('api_test.home_page.test_scene_count_card.title') }}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<el-card class="table-card" v-loading="result.loading" body-style="padding:16px 5px 16px 16px;"
|
||||
style="height: 350px;margin-top: 5px">
|
||||
style="height: 360px;margin-top: 5px">
|
||||
<div slot="header">
|
||||
<span class="title">
|
||||
{{ $t('api_test.home_page.schedule_task_count_card.title') }}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<el-card class="table-card" v-loading="result.loading" body-style="padding:16px 5px 16px 16px;"
|
||||
style="height: 350px;margin-top: 5px">
|
||||
style="height: 360px;margin-top: 5px">
|
||||
<div slot="header">
|
||||
<span class="title">
|
||||
{{ $t('api_test.home_page.test_case_count_card.title') }}
|
||||
|
|
|
@ -42,6 +42,12 @@ export default {
|
|||
{
|
||||
path: "definition/:redirectID?/:dataType?/:dataSelectRange?/:projectId?/:type?",
|
||||
name: "ApiDefinition",
|
||||
// component: () => import('@/business/components/api/definition/ApiDefinition'),
|
||||
component: () => import('@/business/components/api/definition/ApiDefinitionBaseView'),
|
||||
},
|
||||
{
|
||||
path: "oldDefinition/:redirectID?/:dataType?/:dataSelectRange?/:projectId?/:type?",
|
||||
name: "ApiDefinition",
|
||||
component: () => import('@/business/components/api/definition/ApiDefinition'),
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,20 +1,29 @@
|
|||
<template>
|
||||
<el-main class="ms-main-container">
|
||||
<el-main class="ms-main-container" :style="{
|
||||
'height': calHeight,
|
||||
}">
|
||||
<slot></slot>
|
||||
</el-main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsMainContainer"
|
||||
}
|
||||
export default {
|
||||
name: "MsMainContainer",
|
||||
props: {
|
||||
enableAutoHeight: Boolean
|
||||
},
|
||||
computed: {
|
||||
calHeight() {
|
||||
return this.enableAutoHeight ? null : 'calc(100vh - 80px)';
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.ms-main-container {
|
||||
padding: 5px 10px;
|
||||
height: calc(100vh - 80px);
|
||||
}
|
||||
.ms-main-container {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -118,5 +118,4 @@ export default {
|
|||
padding: 5px 8px;
|
||||
border: solid 1px var(--primary_color);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<div>
|
||||
<ms-container>
|
||||
<ms-aside-container v-show="showAside" :enable-auto-height="true">
|
||||
<slot name="aside"></slot>
|
||||
</ms-aside-container>
|
||||
<ms-main-container :enable-auto-height="true">
|
||||
<slot name="mainContainer"></slot>
|
||||
</ms-main-container>
|
||||
</ms-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsContainer from "@/business/components/common/components/MsContainer";
|
||||
import MsMainContainer from "@/business/components/common/components/MsMainContainer";
|
||||
import MsAsideContainer from "@/business/components/common/components/MsAsideContainer";
|
||||
|
||||
export default {
|
||||
name: "ApiTestBaseContainer",
|
||||
components: {MsMainContainer, MsAsideContainer,MsContainer},
|
||||
props:{
|
||||
showAside:{
|
||||
type:Boolean,
|
||||
default(){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,32 @@
|
|||
<template>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import ApiTestBaseContainer from "@/business/components/common/layout/ApiTestBaseContainer";
|
||||
|
||||
export default {
|
||||
name: "ApiTestBaseLayout",
|
||||
components:{
|
||||
ApiTestBaseContainer
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
trashEnable: false,
|
||||
activeName:"",
|
||||
};
|
||||
},
|
||||
methods:{
|
||||
handleClick(){
|
||||
this.$emit("changeTab")
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -1259,6 +1259,7 @@ export default {
|
|||
extract_param: "Extract parameters",
|
||||
add_module: "Add module",
|
||||
edit_api: "Edit Api",
|
||||
show_api: "Api Info",
|
||||
test_plan_select: "Please select test plan",
|
||||
create_info: 'Create',
|
||||
update_info: 'Update',
|
||||
|
|
|
@ -1265,6 +1265,7 @@ export default {
|
|||
extract_param: "提取参数",
|
||||
add_module: "创建模块",
|
||||
edit_api: "编辑接口",
|
||||
show_api: "查看接口",
|
||||
test_plan_select: "请选择测试计划",
|
||||
create_info: '创建',
|
||||
update_info: '更新',
|
||||
|
|
|
@ -1265,6 +1265,7 @@ export default {
|
|||
extract_param: "提取參數",
|
||||
add_module: "創建模塊",
|
||||
edit_api: "編輯接口",
|
||||
show_api: "查看接口",
|
||||
test_plan_select: "請選擇測試計劃",
|
||||
create_info: '創建',
|
||||
update_info: '更新',
|
||||
|
|
Loading…
Reference in New Issue