From e1a3c7c4c4602903a49e5cc05f8c0380255444ee Mon Sep 17 00:00:00 2001 From: song-tianyang Date: Thu, 11 Aug 2022 15:05:32 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):?= =?UTF-8?q?=20=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 接口测试文档重构,包括但不限于交互优化、展示内容优化 --- .../api/controller/ShareInfoController.java | 56 +- .../dto/share/ApiDocumentShareRequest.java | 5 +- .../api/service/ApiModuleService.java | 12 + .../api/service/ShareInfoService.java | 675 ++++++++++-------- .../base/mapper/ext/ExtApiModuleMapper.java | 2 + .../base/mapper/ext/ExtApiModuleMapper.xml | 9 + .../base/mapper/ext/ExtShareInfoMapper.java | 7 +- .../base/mapper/ext/ExtShareInfoMapper.xml | 13 +- .../components/document/ApiDocumentAnchor.vue | 648 ++++++----------- .../document/components/ApiInformation.vue | 124 +++- 10 files changed, 743 insertions(+), 808 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/controller/ShareInfoController.java b/backend/src/main/java/io/metersphere/api/controller/ShareInfoController.java index 8b297a0207..9e46cc2abb 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ShareInfoController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ShareInfoController.java @@ -4,24 +4,17 @@ import io.metersphere.api.dto.share.ApiDocumentInfoDTO; import io.metersphere.api.dto.share.ApiDocumentRequest; import io.metersphere.api.dto.share.ApiDocumentShareRequest; import io.metersphere.api.dto.share.ShareInfoDTO; -import io.metersphere.api.service.ApiDefinitionService; import io.metersphere.api.service.ShareInfoService; -import io.metersphere.base.domain.ApiDefinitionWithBLOBs; import io.metersphere.base.domain.ReportStatisticsWithBLOBs; import io.metersphere.base.domain.ShareInfo; -import io.metersphere.base.domain.User; -import io.metersphere.commons.utils.LogUtil; +import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.SessionUtils; import io.metersphere.reportstatistics.dto.ReportStatisticsSaveRequest; import io.metersphere.reportstatistics.service.ReportStatisticsService; -import io.metersphere.service.UserService; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; -import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; /** * @author song.tianyang @@ -34,16 +27,11 @@ public class ShareInfoController { @Resource ShareInfoService shareInfoService; @Resource - ApiDefinitionService apiDefinitionService; - @Resource ReportStatisticsService reportStatisticsService; - @Resource - UserService userService; - @PostMapping("/selectApiSimpleInfo") - public List list(@RequestBody ApiDocumentRequest request) { - List returnList = shareInfoService.findApiDocumentSimpleInfoByRequest(request); - return returnList; + @PostMapping("/selectApiInfoByParam/{goPage}/{pageSize}") + public Pager> list(@RequestBody ApiDocumentRequest apiDocumentRequest, @PathVariable int goPage, @PathVariable int pageSize) { + return shareInfoService.selectApiInfoByParam(apiDocumentRequest, goPage, pageSize); } @GetMapping("/get/{id}") @@ -51,42 +39,6 @@ public class ShareInfoController { return shareInfoService.get(id); } - @PostMapping("/selectApiInfoByParam") - public List selectApiInfoByParam(@RequestBody ApiDocumentRequest request) { - List returnList = new ArrayList<>(); - if (request.getApiIdList() != null) { - //要根据ids的顺序进行返回排序 - List apiModels = apiDefinitionService.getBLOBs(request.getApiIdList()); - Map apiModelMaps = apiModels.stream().collect(Collectors.toMap(ApiDefinitionWithBLOBs::getId, a -> a, (k1, k2) -> k1)); - Map userIdMap = userService.queryName(); - for (String id : request.getApiIdList()) { - ApiDefinitionWithBLOBs model = apiModelMaps.get(id); - if (model == null) { - model = new ApiDefinitionWithBLOBs(); - model.setId(id); - model.setName(id); - } - ApiDocumentInfoDTO returnDTO = shareInfoService.conversionModelToDTO(model,userIdMap); - returnList.add(returnDTO); - } - } - return returnList; - } - - @GetMapping("/selectApiInfoById/{id}") - public ApiDocumentInfoDTO selectApiInfoById(@PathVariable String id) { - ApiDefinitionWithBLOBs apiModel = apiDefinitionService.getBLOBs(id); - ApiDocumentInfoDTO returnDTO = new ApiDocumentInfoDTO(); - try { - Map userIdMap = userService.queryName(); - returnDTO = shareInfoService.conversionModelToDTO(apiModel,userIdMap); - } catch (Exception e) { - LogUtil.error(e); - } - returnDTO.setSelectedFlag(true); - return returnDTO; - } - @PostMapping("/generateApiDocumentShareInfo") public ShareInfoDTO generateApiDocumentShareInfo(@RequestBody ApiDocumentShareRequest request) { request.setCreateUserId(SessionUtils.getUserId()); diff --git a/backend/src/main/java/io/metersphere/api/dto/share/ApiDocumentShareRequest.java b/backend/src/main/java/io/metersphere/api/dto/share/ApiDocumentShareRequest.java index 4016a73331..0553c29320 100644 --- a/backend/src/main/java/io/metersphere/api/dto/share/ApiDocumentShareRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/share/ApiDocumentShareRequest.java @@ -4,8 +4,6 @@ import io.metersphere.base.domain.ShareInfo; import lombok.Getter; import lombok.Setter; -import java.util.List; - /** * @author song.tianyang * @Date 2021/2/23 5:04 下午 @@ -14,5 +12,6 @@ import java.util.List; @Getter @Setter public class ApiDocumentShareRequest extends ShareInfo { - private List shareApiIdList; + private String shareId; + private ApiDocumentRequest selectRequest; } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java b/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java index ae44a1f850..c9d68a8e32 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java @@ -617,6 +617,18 @@ public class ApiModuleService extends NodeTreeService { return extApiModuleMapper.getNameById(moduleId); } + public Map getApiModuleNameDicByIds(List ids) { + if (CollectionUtils.isEmpty(ids)) { + return new LinkedHashMap<>(0); + } + Map returnMap = new LinkedHashMap<>(ids.size()); + List apiModuleList = extApiModuleMapper.selectNameByIds(ids); + apiModuleList.forEach(item -> { + returnMap.put(item.getId(), item.getName()); + }); + return returnMap; + } + /** * 上传文件时对文件的模块进行检测 * diff --git a/backend/src/main/java/io/metersphere/api/service/ShareInfoService.java b/backend/src/main/java/io/metersphere/api/service/ShareInfoService.java index f1564befb6..d6f6e04223 100644 --- a/backend/src/main/java/io/metersphere/api/service/ShareInfoService.java +++ b/backend/src/main/java/io/metersphere/api/service/ShareInfoService.java @@ -3,6 +3,8 @@ package io.metersphere.api.service; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.Feature; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; import io.metersphere.api.dto.automation.APIScenarioReportResult; import io.metersphere.api.dto.share.*; import io.metersphere.base.domain.*; @@ -13,14 +15,14 @@ import io.metersphere.commons.constants.ProjectApplicationType; import io.metersphere.commons.constants.ShareType; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.json.JSONSchemaGenerator; -import io.metersphere.commons.utils.BeanUtils; -import io.metersphere.commons.utils.CommonBeanFactory; -import io.metersphere.commons.utils.LogUtil; +import io.metersphere.commons.utils.*; import io.metersphere.i18n.Translator; import io.metersphere.service.ProjectApplicationService; +import io.metersphere.service.UserService; import io.metersphere.track.service.TestPlanApiCaseService; import io.metersphere.track.service.TestPlanScenarioCaseService; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.util.Strings; import org.springframework.context.annotation.Lazy; @@ -30,6 +32,7 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.*; +import java.util.stream.Collectors; import static io.metersphere.api.service.utils.ShareUtil.getTimeMills; @@ -65,22 +68,69 @@ public class ShareInfoService { @Resource private ExtApiScenarioReportMapper extApiScenarioReportMapper; + @Resource + ApiDefinitionService apiDefinitionService; + @Resource + ApiModuleService apiModuleService; + @Resource + UserService userService; - public List findApiDocumentSimpleInfoByRequest(ApiDocumentRequest request) { - if (this.isParamLegitimacy(request)) { - if (request.getProjectId() == null) { - List shareIdList = this.selectShareIdByShareInfoId(request.getShareId()); - request.setApiIdList(shareIdList); - if (shareIdList.isEmpty()) { - return new ArrayList<>(); - } else { - return extShareInfoMapper.findApiDocumentSimpleInfoByRequest(request); - } - } else { - return extShareInfoMapper.findApiDocumentSimpleInfoByRequest(request); + public Pager> selectApiInfoByParam(ApiDocumentRequest apiDocumentRequest, int goPage, int pageSize) { + this.iniApiDocumentRequest(apiDocumentRequest); + Map userIdMap = userService.queryName(); + + Page page = PageHelper.startPage(goPage, pageSize, true); + List apiDocumentInfoDTOS = new ArrayList<>(); + if (this.isParamLegitimacy(apiDocumentRequest)) { + apiDocumentInfoDTOS = this.findApiDocumentSimpleInfoByRequest(apiDocumentRequest, goPage, pageSize); + } + PageHelper.clearPage(); + + List apiModuleIdList = new ArrayList<>(); + LogUtil.info("查找模块相关信息"); + apiDocumentInfoDTOS.forEach(item -> { + if (StringUtils.isNotBlank(item.getModuleId()) && !apiModuleIdList.contains(item.getModuleId())) { + apiModuleIdList.add(item.getModuleId()); } + }); + Map moduleNameMap = apiModuleService.getApiModuleNameDicByIds(apiModuleIdList); + LogUtil.info("开始遍历组装数据"); + List returnList = this.conversionModelListToDTO(apiDocumentInfoDTOS, userIdMap, moduleNameMap); + + return PageUtils.setPageInfo(page, returnList); + } + + public List findApiDocumentSimpleInfoByRequest(ApiDocumentRequest request, int goPage, int pageSize) { + List apiList = this.selectByRequest(request); + return this.sortApiListByRequest(apiList, request); + } + + private List sortApiListByRequest(List apiList, ApiDocumentRequest request) { + if (CollectionUtils.isNotEmpty(request.getApiIdList()) && CollectionUtils.isNotEmpty(apiList)) { + List returnList = new ArrayList<>(apiList.size()); + Map apiDefinitionWithBLOBsMap = apiList.stream().collect(Collectors.toMap(ApiDefinitionWithBLOBs::getId, (k1 -> k1))); + for (String id : request.getApiIdList()) { + ApiDefinitionWithBLOBs api = apiDefinitionWithBLOBsMap.get(id); + if (api != null) { + returnList.add(api); + } + } + return returnList; } else { - return new ArrayList<>(); + return apiList; + } + } + + private void iniApiDocumentRequest(ApiDocumentRequest request) { + List shareIdList = this.selectShareIdByShareInfoId(request.getShareId()); + request.setApiIdList(shareIdList); + } + + public List selectByRequest(ApiDocumentRequest request) { + if (StringUtils.isNotBlank(request.getProjectId()) || CollectionUtils.isNotEmpty(request.getApiIdList())) { + return extShareInfoMapper.findApiDocumentSimpleInfoByRequest(request); + } else { + return new ArrayList<>(0); } } @@ -109,307 +159,322 @@ public class ShareInfoService { return true; } - public ApiDocumentInfoDTO conversionModelToDTO(ApiDefinitionWithBLOBs apiModel, Map 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 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 (this.isObjectHasKey(headObj, "name")) { - requestHeadDataArr.add(headObj); - } + public List conversionModelListToDTO(List apiModelList, Map userIdMap, Map moduleMap) { + if (CollectionUtils.isEmpty(apiModelList)) { + return new ArrayList<>(0); + } else { + List returnList = new ArrayList<>(apiModelList.size()); + for (ApiDefinitionWithBLOBs apiModel : apiModelList) { + ApiDocumentInfoDTO apiInfoDTO = new ApiDocumentInfoDTO(); + JSONArray previewJsonArray = new JSONArray(); + if (apiModel != null) { + LogUtil.info(apiModel.getName() + ": start"); + apiInfoDTO.setId(apiModel.getId()); + apiInfoDTO.setName(apiModel.getName()); + apiInfoDTO.setMethod(apiModel.getMethod()); + apiInfoDTO.setUri(apiModel.getPath()); + apiInfoDTO.setStatus(apiModel.getStatus()); + LogUtil.info(apiModel.getName() + ":tag"); + if (StringUtils.isNotEmpty(apiModel.getTags())) { + JSONArray tagsArr = JSONArray.parseArray(apiModel.getTags()); + List tagList = new ArrayList<>(); + for (int i = 0; i < tagsArr.size(); i++) { + tagList.add(tagsArr.getString(i)); } - 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 (this.isObjectHasKey(headObj, "name")) { - urlParamArr.add(headObj); - } - } - } catch (Exception e) { - LogUtil.error(e.getMessage()); + if (!tagList.isEmpty()) { + apiInfoDTO.setTags(StringUtils.join(tagList, ",")); } } - //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 (this.isObjectHasKey(headObj, "name")) { - restParamArr.add(headObj); - } - } - } catch (Exception e) { - LogUtil.error(e.getMessage()); - } + LogUtil.info(apiModel.getName() + ":baseInfo"); + 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()); + if (MapUtils.isNotEmpty(moduleMap)) { + apiInfoDTO.setModules(moduleMap.containsKey(apiModel.getModuleId()) ? moduleMap.get(apiModel.getModuleId()) : ""); + } else { + ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class); + apiInfoDTO.setModules(apiModuleService.getModuleNameById(apiModel.getModuleId())); } - apiInfoDTO.setUrlParams(urlParamArr.toJSONString()); - apiInfoDTO.setRestParams(restParamArr.toJSONString()); - //请求体参数类型 - if (requestObj.containsKey("body")) { - try { - JSONObject bodyObj = requestObj.getJSONObject("body"); - if (this.isObjectHasKey(bodyObj, "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); + LogUtil.info(apiModel.getName() + ":request"); + 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 (this.isObjectHasKey(headObj, "name")) { + requestHeadDataArr.add(headObj); + } } - - 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; + 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 (this.isObjectHasKey(headObj, "name")) { + urlParamArr.add(headObj); } } - JSONSchemaBodyDTO jsonSchemaBodyDTO = new JSONSchemaBodyDTO(); - if (isJsonSchema) { - jsonSchemaBodyDTO.setJsonSchema(bodyObj.get("jsonSchema")); - apiInfoDTO.setJsonSchemaBody(jsonSchemaBodyDTO); - String raw = JSONSchemaGenerator.getJson(JSONObject.toJSONString(bodyObj.get("jsonSchema"))); - this.setPreviewData(previewJsonArray, raw); - } else { - if (bodyObj.containsKey("raw")) { - String raw = bodyObj.getString("raw"); - jsonSchemaBodyDTO.setRaw(raw); - apiInfoDTO.setJsonSchemaBody(jsonSchemaBodyDTO); - apiInfoDTO.setRequestBodyStrutureData(raw); - //转化jsonObje 或者 jsonArray - this.setPreviewData(previewJsonArray, raw); + } catch (Exception e) { + LogUtil.error(e.getMessage()); + } + } + //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 (this.isObjectHasKey(headObj, "name")) { + restParamArr.add(headObj); } } - } 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 previewObjMap = new LinkedHashMap<>(); - for (int i = 0; i < kvsArr.size(); i++) { - JSONObject kv = kvsArr.getJSONObject(i); - if (this.isObjectHasKey(kv, "name")) { - String value = ""; - if (kv.containsKey("value")) { - value = String.valueOf(kv.get("value")); + } catch (Exception e) { + LogUtil.error(e.getMessage()); + } + } + apiInfoDTO.setUrlParams(urlParamArr.toJSONString()); + apiInfoDTO.setRestParams(restParamArr.toJSONString()); + //请求体参数类型 + if (requestObj.containsKey("body")) { + try { + JSONObject bodyObj = requestObj.getJSONObject("body"); + if (this.isObjectHasKey(bodyObj, "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; } - 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> bodyParamList = new ArrayList<>(); - JSONArray kvsArr = bodyObj.getJSONArray("binary"); - - Map previewObjMap = new LinkedHashMap<>(); - for (int i = 0; i < kvsArr.size(); i++) { - JSONObject kv = kvsArr.getJSONObject(i); - if (this.isObjectHasKey(kv, "description") && this.isObjectHasKey(kv, "files")) { - Map 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 (this.isObjectHasKey(fileObj, "name")) { - value += fileObj.getString("name") + " ;"; + JSONSchemaBodyDTO jsonSchemaBodyDTO = new JSONSchemaBodyDTO(); + if (isJsonSchema) { + jsonSchemaBodyDTO.setJsonSchema(bodyObj.get("jsonSchema")); + apiInfoDTO.setJsonSchemaBody(jsonSchemaBodyDTO); + String raw = JSONSchemaGenerator.getJson(JSONObject.toJSONString(bodyObj.get("jsonSchema"))); + this.setPreviewData(previewJsonArray, raw); + } else { + if (bodyObj.containsKey("raw")) { + String raw = bodyObj.getString("raw"); + jsonSchemaBodyDTO.setRaw(raw); + apiInfoDTO.setJsonSchemaBody(jsonSchemaBodyDTO); + 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 previewObjMap = new LinkedHashMap<>(); + for (int i = 0; i < kvsArr.size(); i++) { + JSONObject kv = kvsArr.getJSONObject(i); + if (this.isObjectHasKey(kv, "name")) { + String value = ""; + if (kv.containsKey("value")) { + value = String.valueOf(kv.get("value")); + } + bodyParamArr.add(kv); + previewObjMap.put(String.valueOf(kv.get("name")), value); } } - bodyMap.put("name", name); - bodyMap.put("value", value); - bodyMap.put("contentType", "File"); - bodyParamList.add(bodyMap); + this.setPreviewData(previewJsonArray, JSONObject.toJSONString(previewObjMap)); + apiInfoDTO.setRequestBodyFormData(bodyParamArr.toJSONString()); + } + } else if (StringUtils.equals(type, "BINARY")) { + if (bodyObj.containsKey("binary")) { + List> bodyParamList = new ArrayList<>(); + JSONArray kvsArr = bodyObj.getJSONArray("binary"); - previewObjMap.put(String.valueOf(name), String.valueOf(value)); + Map previewObjMap = new LinkedHashMap<>(); + for (int i = 0; i < kvsArr.size(); i++) { + JSONObject kv = kvsArr.getJSONObject(i); + if (this.isObjectHasKey(kv, "description") && this.isObjectHasKey(kv, "files")) { + Map 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 (this.isObjectHasKey(fileObj, "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)); } } - this.setPreviewData(previewJsonArray, JSONObject.toJSONString(previewObjMap)); - apiInfoDTO.setRequestBodyFormData(JSONArray.toJSONString(bodyParamList)); } + } catch (Exception e) { + LogUtil.error(e.getMessage()); } } - } catch (Exception e) { - LogUtil.error(e.getMessage()); } } - } - } - - //赋值响应头 - if (apiModel.getResponse() != null) { - JSONObject responseJsonObj = this.genJSONObject(apiModel.getResponse()); - if (this.isObjectHasKey(responseJsonObj, "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 (this.isObjectHasKey(headObj, "name")) { - responseHeadDataArr.add(headObj); + LogUtil.info(apiModel.getName() + ":response"); + //赋值响应头 + if (apiModel.getResponse() != null) { + JSONObject responseJsonObj = this.genJSONObject(apiModel.getResponse()); + if (this.isObjectHasKey(responseJsonObj, "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 (this.isObjectHasKey(headObj, "name")) { + responseHeadDataArr.add(headObj); + } + } + apiInfoDTO.setResponseHead(responseHeadDataArr.toJSONString()); + } catch (Exception e) { + LogUtil.error(e.getMessage()); } } - apiInfoDTO.setResponseHead(responseHeadDataArr.toJSONString()); - } catch (Exception e) { - LogUtil.error(e.getMessage()); - } - } - // 赋值响应体 - if (this.isObjectHasKey(responseJsonObj, "body")) { - try { - JSONObject bodyObj = responseJsonObj.getJSONObject("body"); - if (this.isObjectHasKey(bodyObj, "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")) { + // 赋值响应体 + if (this.isObjectHasKey(responseJsonObj, "body")) { + try { + JSONObject bodyObj = responseJsonObj.getJSONObject("body"); + if (this.isObjectHasKey(bodyObj, "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.setResponseBodyParamType("JSON-SCHEMA"); - apiInfoDTO.setJsonSchemaResponseBody(bodyObj); - } else { - 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 (this.isObjectHasKey(kv, "name")) { - bodyParamArr.add(kv); + //判断是否是JsonSchema + boolean isJsonSchema = false; + if (bodyObj.containsKey("format")) { + String foramtValue = String.valueOf(bodyObj.get("format")); + if (StringUtils.equals("JSON-SCHEMA", foramtValue)) { + isJsonSchema = true; + } } - } - apiInfoDTO.setResponseBodyFormData(bodyParamArr.toJSONString()); - } - } else if (StringUtils.equals(type, "BINARY")) { - if (bodyObj.containsKey("binary")) { - List> 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 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 (this.isObjectHasKey(fileObj, "name")) { - value += fileObj.getString("name") + " ;"; + if (isJsonSchema) { + apiInfoDTO.setResponseBodyParamType("JSON-SCHEMA"); + apiInfoDTO.setJsonSchemaResponseBody(bodyObj); + } else { + 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 (this.isObjectHasKey(kv, "name")) { + bodyParamArr.add(kv); } } - bodyMap.put("name", name); - bodyMap.put("value", value); - bodyParamList.add(bodyMap); + apiInfoDTO.setResponseBodyFormData(bodyParamArr.toJSONString()); + } + } else if (StringUtils.equals(type, "BINARY")) { + if (bodyObj.containsKey("binary")) { + List> 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 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 (this.isObjectHasKey(fileObj, "name")) { + value += fileObj.getString("name") + " ;"; + } + } + bodyMap.put("name", name); + bodyMap.put("value", value); + bodyParamList.add(bodyMap); + } + } + apiInfoDTO.setResponseBodyFormData(JSONArray.toJSONString(bodyParamList)); } } - apiInfoDTO.setResponseBodyFormData(JSONArray.toJSONString(bodyParamList)); } + } catch (Exception e) { + LogUtil.error(e.getMessage()); } - } - } catch (Exception e) { - LogUtil.error(e.getMessage()); - } - } - // 赋值响应码 - if (this.isObjectHasKey(responseJsonObj, "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 (this.isObjectHasKey(statusObj, "name")) { - responseStatusDataArr.add(statusObj); + } + // 赋值响应码 + if (this.isObjectHasKey(responseJsonObj, "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 (this.isObjectHasKey(statusObj, "name")) { + responseStatusDataArr.add(statusObj); + } + } + apiInfoDTO.setResponseCode(responseStatusDataArr.toJSONString()); + } catch (Exception e) { + LogUtil.error(e.getMessage()); } } - apiInfoDTO.setResponseCode(responseStatusDataArr.toJSONString()); - } catch (Exception e) { - LogUtil.error(e.getMessage()); + } + apiInfoDTO.setRemark(apiModel.getRemark()); + } + LogUtil.info(apiModel.getName() + ":end and preview"); + if (!previewJsonArray.isEmpty()) { + if (previewJsonArray.size() == 1) { + apiInfoDTO.setRequestPreviewData(previewJsonArray.get(0)); + } else { + apiInfoDTO.setRequestPreviewData(previewJsonArray); } } + apiInfoDTO.setSelectedFlag(true); + LogUtil.info(apiModel.getName() + ":over"); + returnList.add(apiInfoDTO); } - apiInfoDTO.setRemark(apiModel.getRemark()); + return returnList; } - if (!previewJsonArray.isEmpty()) { - if (previewJsonArray.size() == 1) { - apiInfoDTO.setRequestPreviewData(previewJsonArray.get(0)); - } else { - apiInfoDTO.setRequestPreviewData(previewJsonArray); - } - } - apiInfoDTO.setSelectedFlag(true); - return apiInfoDTO; } private JSONObject genJSONObject(String request) { @@ -422,18 +487,20 @@ public class ShareInfoService { return returnObj; } - private void setPreviewData(JSONArray previewArray, String data) { + private JSONArray setPreviewData(JSONArray previewArray, String data) { + try { - JSONObject previewObj = JSONObject.parseObject(data, Feature.DisableCircularReferenceDetect); - previewArray.add(previewObj); - } catch (Exception e) { - LogUtil.error(e.getMessage()); - } - try { - previewArray = JSONArray.parseArray(data); + if (StringUtils.startsWith(data, "{") && StringUtils.endsWith(data, "}")) { + JSONObject previewObj = JSONObject.parseObject(data, Feature.DisableCircularReferenceDetect); + previewArray.add(previewObj); + } else { + previewArray = JSONArray.parseArray(data); + } + } catch (Exception e) { LogUtil.error(e.getMessage()); } + return previewArray; } /** @@ -445,13 +512,23 @@ public class ShareInfoService { * @return ShareInfo数据对象 */ public ShareInfo generateApiDocumentShareInfo(ApiDocumentShareRequest request) { - if (request.getShareApiIdList() != null && !request.getShareApiIdList().isEmpty() - && StringUtils.equalsAny(request.getShareType(), ShareInfoType.Single.name(), ShareInfoType.Batch.name())) { - //将ID进行排序 - ShareInfo shareInfoRequest = new ShareInfo(); - BeanUtils.copyBean(shareInfoRequest, request); - shareInfoRequest.setCustomData(genShareIdJsonString(request.getShareApiIdList())); - return generateShareInfo(shareInfoRequest); + if (StringUtils.equalsAny(request.getShareType(), ShareInfoType.Single.name(), ShareInfoType.Batch.name())) { + String customData = null; + if (request.getSelectRequest() != null) { + List shareIdList = extShareInfoMapper.findIdByRequest(request.getSelectRequest()); + customData = genShareIdJsonString(shareIdList); + } else if (StringUtils.isNotBlank(request.getShareId())) { + customData = genShareIdJsonString(new ArrayList<>(1) {{ + this.add(request.getShareId()); + }}); + } + + if (StringUtils.isNotBlank(customData)) { + ShareInfo shareInfoRequest = new ShareInfo(); + BeanUtils.copyBean(shareInfoRequest, request); + shareInfoRequest.setCustomData(customData); + return generateShareInfo(shareInfoRequest); + } } return new ShareInfo(); } @@ -481,11 +558,6 @@ public class ShareInfoService { return shareInfo; } - private List findByShareTypeAndShareApiIdWithBLOBs(String shareType, List shareApiIdList) { - String shareApiIdString = this.genShareIdJsonString(shareApiIdList); - return extShareInfoMapper.selectByShareTypeAndShareApiIdWithBLOBs(shareType, shareApiIdString); - } - /** * 根据treeSet排序生成apiId的Jsonarray字符串 * @@ -614,13 +686,6 @@ public class ShareInfoService { } } - public void apiReportValidate(String shareId, String testId) { - TestPlanApiCase testPlanApiCase = testPlanApiCaseService.getById(testId); - if (!StringUtils.equals(getPlanId(shareId), testPlanApiCase.getTestPlanId())) { - MSException.throwException("validate failure!"); - } - } - public String getPlanId(String shareId) { ShareInfo shareInfo = shareInfoMapper.selectByPrimaryKey(shareId); String planId = shareInfo.getCustomData(); diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiModuleMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiModuleMapper.java index dcc74121f1..79ada37288 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiModuleMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiModuleMapper.java @@ -17,4 +17,6 @@ public interface ExtApiModuleMapper { void updatePos(String id, Double pos); String getNameById(String moduleId); + + List selectNameByIds(List ids); } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiModuleMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiModuleMapper.xml index a22d4f72cf..4a672f8772 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiModuleMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiModuleMapper.xml @@ -33,6 +33,15 @@ order by api_module.pos asc + + - SELECT api.id,api.name FROM api_definition api WHERE api.protocol = 'HTTP' + + AND api.status = 'Trash' @@ -42,6 +42,15 @@ ORDER BY api.update_time DESC + + + + diff --git a/frontend/src/business/components/api/definition/components/document/ApiDocumentAnchor.vue b/frontend/src/business/components/api/definition/components/document/ApiDocumentAnchor.vue index 1f970afa68..95c27339d9 100644 --- a/frontend/src/business/components/api/definition/components/document/ApiDocumentAnchor.vue +++ b/frontend/src/business/components/api/definition/components/document/ApiDocumentAnchor.vue @@ -1,99 +1,117 @@ @@ -122,7 +140,6 @@ export default { isLoading: false, shareUrl: "", batchShareUrl: "", - apiStepIndex: 0, showXpackCompnent: false, apiInfoArray: [], modes: ['text', 'json', 'xml', 'html'], @@ -156,11 +173,13 @@ export default { }, methodColorMap: new Map(API_METHOD_COLOUR), clientHeight: '',//浏览器高度, - maxCompnentSize: 5, //浏览器最多渲染的api信息体数量 - apiShowArray: [],//浏览器要渲染的api信息集合 + maxCompnentSize: 10, //浏览器最多渲染的api信息体数量 needAsyncSelect: false, //是否需要异步查询api详细数据做展现。只有本次要展示的数据总量大于maxCompnentSize时为true currentApiIndexInApiShowArray: 0,//当前主要展示的api信息在apiShowArray的索引 clickStepFlag: false, + pageSize: 10, + currentPage: 1, + total: 0, }; }, props: { @@ -189,12 +208,12 @@ export default { } this.initApiDocSimpleList(); this.clientHeight = `${document.documentElement.clientHeight}`;//获取浏览器可视区域高度 - let that = this; + // let that = this; window.onresize = function () { this.clientHeight = `${document.documentElement.clientHeight}`; this.changeFixed(this.clientHeight); }; - window.addEventListener('scroll', that.handleScroll); + window.addEventListener('scroll', this.handleScroll); }, mounted() { let that = this; @@ -218,27 +237,63 @@ export default { }, }, methods: { - - + handleSizeChange(val) { + this.pageSize = val; + this.initApiDocSimpleList(); + }, + handleCurrentChange(val) { + this.currentPage = val; + this.initApiDocSimpleList(); + }, changeFixed(clientHeight) { if (this.$refs.apiDocInfoDiv) { let countPageHeight = 210; if (this.pageHeaderHeight != 0 && this.pageHeaderHeight != null) { countPageHeight = this.pageHeaderHeight; } - this.$refs.apiDocInfoDiv.style.height = clientHeight - countPageHeight + 'px'; this.$refs.apiDocInfoDiv.style.overflow = 'auto'; this.$refs.apiDocList.style.height = clientHeight - countPageHeight + 'px'; } }, initApiDocSimpleList() { - //首先跳转到第一个节点(为了让滚动条变为0,防止重新加载后滚动条位置出现动乱导致页面混乱) - if (this.apiInfoArray.length > 0) { - this.clickStep(this.apiInfoArray[0].id); - } this.apiInfoArray = []; - this.apiShowArray = []; + let simpleRequest = this.apiSearch; + if (this.projectId != null && this.projectId != "") { + simpleRequest.projectId = this.projectId; + } + if (this.documentId != null && this.documentId != "") { + simpleRequest.shareId = this.documentId; + } + if (this.moduleIds.length > 0) { + simpleRequest.moduleIds = this.moduleIds; + } else { + simpleRequest.moduleIds = []; + } + simpleRequest.trashEnable = this.trashEnable; + let simpleInfoUrl = "/share/info/selectApiInfoByParam/" + this.currentPage + "/" + this.pageSize; + this.$post(simpleInfoUrl, simpleRequest, response => { + this.apiInfoArray = response.data.listObject; + this.total = response.data.itemCount; + if (response.data.length > this.maxCompnentSize) { + this.needAsyncSelect = true; + } else { + this.needAsyncSelect = false; + } + //每次查询完成之后定位右侧的步骤 + this.$nextTick(() => { + this.handleScroll(); + }); + }); + }, + shareApiDocument() { + this.shareUrl = ""; + this.batchShareUrl = ""; + let shareIdArr = []; + let genShareInfoParam = {}; + genShareInfoParam.shareApiIdList = shareIdArr; + genShareInfoParam.shareType = "Batch"; + let simpleRequest = this.apiSearch; if (this.projectId != null && this.projectId != "") { simpleRequest.projectId = this.projectId; @@ -253,295 +308,82 @@ export default { } simpleRequest.trashEnable = this.trashEnable; - let simpleInfoUrl = "/share/info/selectApiSimpleInfo"; - - - this.$post(simpleInfoUrl, simpleRequest, response => { - this.apiInfoArray = response.data; - this.apiStepIndex = 0; - if (this.apiInfoArray.length > 0) { - this.checkApiInfoNode(this.apiStepIndex, true); - } - if (response.data.length > this.maxCompnentSize) { - this.needAsyncSelect = true; - } else { - this.needAsyncSelect = false; - } - }); - }, - shareApiDocument(isBatchShare) { - this.shareUrl = ""; - this.batchShareUrl = ""; - let shareIdArr = []; - let shareType = "Single"; - if (isBatchShare == 'true') { - this.apiInfoArray.forEach(f => { - if (!f.id) { - return; - } - shareIdArr.push(f.id); - }); - shareType = "Batch"; - } else { - shareIdArr.push(this.apiInfoArray[this.apiStepIndex].id); - } - let genShareInfoParam = {}; - genShareInfoParam.shareApiIdList = shareIdArr; - genShareInfoParam.shareType = shareType; + genShareInfoParam.selectRequest = simpleRequest; generateApiDocumentShareInfo(genShareInfoParam, (data) => { let thisHost = window.location.host; - if (shareType == "Batch") { - this.batchShareUrl = thisHost + "/document" + data.shareUrl; - } else { - this.shareUrl = thisHost + "/document" + data.shareUrl; - } + this.batchShareUrl = thisHost + "/document" + data.shareUrl; }); }, - selectApiInfo(index, apiId, needUpdateShowArray) { - let simpleInfoUrl = "/share/info/selectApiInfoById/" + apiId; - this.$get(simpleInfoUrl, response => { - let returnData = response.data; - this.$set(this.apiInfoArray, index, returnData); - if (needUpdateShowArray) { - let showApiIndex = -1; - for (let i = 0; i < this.apiShowArray.length; i++) { - if (this.apiShowArray[i].id === apiId) { - showApiIndex = i; - } - } - if (showApiIndex > -1) { - this.$set(this.apiShowArray, showApiIndex, returnData); - } - } - }); - }, - //itemIndex,afterNodeIndex,beforeNodeIndex 三个是回调参数,用于重新构建showArray的数据 isRedirectScroll:是否调用跳转函数 - selectApiInfoBatch(indexArr, apiIdArr, itemIndex, afterNodeIndex, beforeNodeIndex, isRedirectScroll) { - if (indexArr.length != apiIdArr.length) { - this.isLoading = false; - this.clickStepFlag = false; - return; - } else { - let params = {}; - params.apiIdList = apiIdArr; - this.$post("/share/info/selectApiInfoByParam", params, response => { - let returnDatas = response.data; - for (let dataIndex = 0; dataIndex < returnDatas.length; dataIndex++) { - let index = indexArr[dataIndex]; - let data = returnDatas[dataIndex]; - this.$set(this.apiInfoArray, index, data); - } - this.updateShowArray(itemIndex, afterNodeIndex, beforeNodeIndex); - if (isRedirectScroll) { - this.redirectScroll(); - } - }); - } - }, clickStep(apiId) { - this.isLoading = true; this.clickStepFlag = true; + let apiStepIndex = 0; for (let index = 0; index < this.apiInfoArray.length; index++) { if (apiId == this.apiInfoArray[index].id) { - this.apiStepIndex = index; + apiStepIndex = index; break; } } - //检查数据 - this.checkApiInfoNode(this.apiStepIndex, true); + //节点跳转 + this.checkApiInfoNode(apiStepIndex); + }, + changeApiStepNodeClass(apiStep, isApiShow) { + if (isApiShow) { + if (apiStep.className.indexOf("apiShowStep") < 0) { + apiStep.className = apiStep.className + " apiShowStep"; + } + } else { + if (apiStep.className.indexOf("apiShowStep") > 0) { + apiStep.className = apiStep.className.substring(0, apiStep.className.length - 12); + } + } }, handleScroll() { if (!this.clickStepFlag && this.$refs.apiDocInfoDiv) { - //apiDocInfoDiv的总高度,是(每个item的高度+20)数量 - let apiDocDivScrollTop = 0; + //apiNodeDom:设置右侧节点的样式 + let apiNodeDoms = document.getElementsByName("apiInfoStepNode"); + if (!apiNodeDoms) { + return; + } + + let scrollTopCount = 0; if (this.$refs.apiDocInfoDiv && this.$refs.apiDocInfoDiv.scrollTop) { - apiDocDivScrollTop = this.$refs.apiDocInfoDiv.scrollTop; - } - let apiDocDivClientTop = this.$refs.apiDocInfoDiv.clientHeight; - let scrolledHeigh = apiDocDivScrollTop + apiDocDivClientTop; - let lastIndex = 0; - for (let index = 0; index < this.apiShowArray.length; index++) { - //判断移动到了第几个元素. 公式: 移动过的高度+页面显示高度-第index子元素的高度(含20px)>0 的 index最大值 - if (scrolledHeigh > 0) { - lastIndex = index; - let itemHeight = this.$refs.apiDocInfoDivItem[index].getHeight() + 10; - scrolledHeigh = scrolledHeigh - itemHeight; - } else { - break; - } + scrollTopCount = this.$refs.apiDocInfoDiv.scrollTop; } + let mainDivHeight = this.$refs.apiDocInfoDiv.clientHeight; - if (lastIndex < this.currentApiIndexInApiShowArray) { - //上移 - //进行判断:是否还需要为apiShowArray(已经查出来的api数据集) 增加数据。 由于在当前数据前后最多展现2条数据, - //若 apiStepIndex-1- 2 < apiInfoArray(已经查出来的api数据集),需要添加数据 - let dataIndex = this.apiStepIndex - 3; - if (dataIndex >= 0) { - let apiInfo = this.apiInfoArray[dataIndex]; - let haveData = false; - //检查showArray是否存在这条数据。不存在才加入 - this.apiShowArray.forEach(api => { - if (api.id === apiInfo.id) { - haveData = true; - } - }); - if (!haveData) { - this.apiShowArray.unshift(apiInfo); - if (!apiInfo.selectedFlag) { - this.selectApiInfo(dataIndex, this.apiInfoArray[dataIndex].id, true); - } + let apiDocDivScrollTop = scrollTopCount; + let screenHight = mainDivHeight; + for (let index = 0; index < this.apiInfoArray.length; index++) { + let itemHeight = this.$refs.apiDocInfoDivItem[index].getHeight() + 3; + if (apiDocDivScrollTop > itemHeight) { + this.changeApiStepNodeClass(apiNodeDoms[index], false); + } else { + if (screenHight + apiDocDivScrollTop > 0) { + this.changeApiStepNodeClass(apiNodeDoms[index], true); } else { - this.currentApiIndexInApiShowArray--; - } - } else { - this.currentApiIndexInApiShowArray--; - } - - if (this.apiShowArray.length > (this.currentApiIndexInApiShowArray + 3)) { - this.apiShowArray.pop(); - } - // } - this.apiStepIndex--; - } else if (lastIndex > this.currentApiIndexInApiShowArray) { - //下滚 - //进行判断:是否还需要为apiShowArray 增加数据。 由于在当前数据前后最多展现2条数据, - //可得: apiStepIndex+1+ 2 < apiInfoArray,需要添加数据 - let dataIndex = this.apiStepIndex + 3; - if (dataIndex < this.apiInfoArray.length) { - let apiInfo = this.apiInfoArray[dataIndex]; - - let haveData = false; - //检查showArray是否存在这条数据。不存在才加入 - this.apiShowArray.forEach(api => { - if (api.id === apiInfo.id) { - haveData = true; - } - }); - if (!haveData) { - this.apiShowArray.push(apiInfo); - if (!apiInfo.selectedFlag) { - this.selectApiInfo(dataIndex, this.apiInfoArray[dataIndex].id, true); - } - } - - } - - if (this.apiShowArray.length <= this.maxCompnentSize) { - //判断currentApiIndexInApiShowArray 是否需要添加,以及是否需要删除第一个元素 - this.currentApiIndexInApiShowArray++; - } else { - this.apiShowArray.shift(); - let itemHeight = this.$refs.apiDocInfoDivItem[0].getHeight() + 10; - if (this.$refs.apiDocInfoDiv && this.$refs.apiDocInfoDiv.scrollTop) { - this.$refs.apiDocInfoDiv.scrollTop = (apiDocDivScrollTop - itemHeight); + this.changeApiStepNodeClass(apiNodeDoms[index], false); } } - this.apiStepIndex++; + apiDocDivScrollTop = apiDocDivScrollTop - itemHeight; } } - this.clickStepFlag = false; }, - redirectScroll() { - if (!this.$refs.apiDocInfoDiv) { - return; - } - //滚动条跳转:将滚动条下拉到显示对应对api接口的位置 - let apiDocDivClientTop = 0; - let itemHeightCount = 0; - if (this.currentApiIndexInApiShowArray > 0) { - for (let i = 0; i <= this.currentApiIndexInApiShowArray - 1; i++) { - let itemHeight = this.$refs.apiDocInfoDivItem[i].getHeight() + 10; - itemHeightCount += itemHeight; + + checkApiInfoNode(itemIndex) { + let scrollTopCount = 0; + for (let index = 0; index < this.apiInfoArray.length; index++) { + if (index < itemIndex) { + scrollTopCount += this.$refs.apiDocInfoDivItem[index].getHeight() + 5; } } - this.clickStepFlag = true; - let scrollTopIndex = this.$refs.apiDocInfoDiv.scrollTop; - if (this.$refs.apiDocInfoDiv && this.$refs.apiDocInfoDiv.scrollTop) { - this.$refs.apiDocInfoDiv.scrollTop = (apiDocDivClientTop + itemHeightCount); - } else if (scrollTopIndex === 0) { - this.$refs.apiDocInfoDiv.scrollTop = (apiDocDivClientTop + itemHeightCount); - } - this.isLoading = false; + this.$refs.apiDocInfoDiv.scrollTop = scrollTopCount; + this.$nextTick(() => { + this.handleScroll(); + }); }, - - //检查要展示的api信息节点,和上下个2个及以内的范围内数据有没有查询过。并赋值为showArray - //isRedirectScroll 最后是否调用跳转函数 - checkApiInfoNode(itemIndex, isRedirectScroll) { - let beforeNodeIndex = itemIndex < 2 ? 0 : (itemIndex - 2); - let afterNodeIndex = (itemIndex + 2) < this.apiInfoArray.length ? (itemIndex + 2) : this.apiInfoArray.length; - this.apiShowArray = []; - - let selectIndexArr = []; - let selectApiId = []; - - //查当前节点前两个 - for (let afterIndex = beforeNodeIndex; afterIndex < itemIndex; afterIndex++) { - let apiInfo = this.apiInfoArray[afterIndex]; - if (apiInfo == null) { - continue; - } - if (apiInfo == null || !apiInfo.selectedFlag) { - let apiId = apiInfo.id; - if (!apiInfo.isSearching) { - apiInfo.isSearching = true; - selectIndexArr.push(afterIndex); - selectApiId.push(apiId); - } - } - this.apiShowArray.push(apiInfo); - } - this.currentApiIndexInApiShowArray = this.apiShowArray.length; - //查当前节点以及后三个 - for (let beforeIndex = itemIndex; beforeIndex <= afterNodeIndex; beforeIndex++) { - let apiInfo = this.apiInfoArray[beforeIndex]; - if (apiInfo == null) { - continue; - } - if (apiInfo == null || !apiInfo.selectedFlag) { - let apiId = apiInfo.id; - if (!apiInfo.isSearching) { - apiInfo.isSearching = true; - selectIndexArr.push(beforeIndex); - selectApiId.push(apiId); - } - } - this.apiShowArray.push(apiInfo); - } - if (selectIndexArr.length > 0) { - this.selectApiInfoBatch(selectIndexArr, selectApiId, itemIndex, afterNodeIndex, beforeNodeIndex, isRedirectScroll); - } else { - if (isRedirectScroll) { - //进行跳转 - this.$nextTick(() => { - this.redirectScroll(); - }); - } - } - }, - //该方法只用于批量查询后的函数处理。 因为查询完成,数据更新,重新为apiShowArray赋值 - updateShowArray(itemIndex, afterNodeIndex, beforeNodeIndex) { - this.apiShowArray = []; - //查当前节点前两个 - for (let afterIndex = beforeNodeIndex; afterIndex < itemIndex; afterIndex++) { - let apiInfo = this.apiInfoArray[afterIndex]; - if (apiInfo == null) { - continue; - } - this.apiShowArray.push(apiInfo); - } - this.currentApiIndexInApiShowArray = this.apiShowArray.length; - //查当前节点以及后三个 - for (let beforeIndex = itemIndex; beforeIndex <= afterNodeIndex; beforeIndex++) { - let apiInfo = this.apiInfoArray[beforeIndex]; - if (apiInfo == null) { - continue; - } - this.apiShowArray.push(apiInfo); - } - } }, }; @@ -580,6 +422,24 @@ export default { /* 步骤条中,已经完成后的节点样式和里面a标签的样式 */ +/deep/ .el-step__head { + width: 20px; +} + +.apiShowStep /deep/ .el-step__head.is-wait { + color: #783887; + border-color: #783887; + width: 20px; +} + +.apiShowStep /deep/ .el-step__title.is-wait .el-link.el-link--default.is-underline { + color: #783887; +} + +/deep/ .el-step__icon-inner { + font-size: 12px; + border-top-color: #783887; +} /deep/ .el-step { flex-basis: 40px !important; @@ -594,66 +454,10 @@ export 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; - border-top-color: var(--primary_color); -} - -/deep/ .el-step.is-vertical .el-step__line { - left: 9px; -} - - -/deep/ .el-step__icon { - width: 20px; - height: 20px; -} - -.document-table { - margin: 10px 10px; - width: auto; -} - -.document-table /deep/ .el-table__row { - font-size: 12px; - font-weight: initial; -} - -.document-table /deep/ .has-gutter { - font-size: 12px; - color: #404040; -} - -.document-table /deep/ td { - border-right: 0px solid #EBEEF5 -} - -.document-table /deep/ th { - background-color: #FAFAFA; - border-right: 0px solid #EBEEF5 -} - .el-divider--horizontal { margin: 12px 0; } diff --git a/frontend/src/business/components/api/definition/components/document/components/ApiInformation.vue b/frontend/src/business/components/api/definition/components/document/components/ApiInformation.vue index 9f0a06fd55..e5d0e27d82 100644 --- a/frontend/src/business/components/api/definition/components/document/components/ApiInformation.vue +++ b/frontend/src/business/components/api/definition/components/document/components/ApiInformation.vue @@ -1,5 +1,5 @@