From b0e81fcc26035e60c8a31593177aae9e9205b644 Mon Sep 17 00:00:00 2001 From: song-tianyang Date: Wed, 9 Jun 2021 17:17:26 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dmock=E8=BF=94=E5=9B=9E?= =?UTF-8?q?JSON-Schema=E5=8F=82=E6=95=B0=E4=B8=8D=E5=85=A8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E3=80=81=E4=BF=AE=E5=A4=8DJSON-Schema?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E5=8F=82=E6=95=B0=E5=9C=A8=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E9=87=8C=E4=B8=8D=E6=98=BE=E7=A4=BA=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复mock返回JSON-Schema参数不全的问题、修复JSON-Schema响应参数在文档里不显示的问题 --- .../api/dto/document/ApiDocumentInfoDTO.java | 1 + .../response/JsonSchemaReturnObj.java | 3 + .../api/service/ApiDocumentService.java | 28 +++++- .../api/service/MockConfigService.java | 92 +++++++++++++++---- .../components/document/ApiDocumentAnchor.vue | 31 +++++-- 5 files changed, 124 insertions(+), 31 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/dto/document/ApiDocumentInfoDTO.java b/backend/src/main/java/io/metersphere/api/dto/document/ApiDocumentInfoDTO.java index 81b8cadd82..2499c086e0 100644 --- a/backend/src/main/java/io/metersphere/api/dto/document/ApiDocumentInfoDTO.java +++ b/backend/src/main/java/io/metersphere/api/dto/document/ApiDocumentInfoDTO.java @@ -28,6 +28,7 @@ public class ApiDocumentInfoDTO { private String responseHead; private String responseBody; + private Object jsonSchemaResponseBody; private String responseBodyParamType; private String responseBodyFormData; private String responseBodyStrutureData; diff --git a/backend/src/main/java/io/metersphere/api/dto/mockconfig/response/JsonSchemaReturnObj.java b/backend/src/main/java/io/metersphere/api/dto/mockconfig/response/JsonSchemaReturnObj.java index 7f68d8215b..0a2d3c1316 100644 --- a/backend/src/main/java/io/metersphere/api/dto/mockconfig/response/JsonSchemaReturnObj.java +++ b/backend/src/main/java/io/metersphere/api/dto/mockconfig/response/JsonSchemaReturnObj.java @@ -1,5 +1,6 @@ package io.metersphere.api.dto.mockconfig.response; +import com.alibaba.fastjson.JSONObject; import lombok.Getter; import lombok.Setter; @@ -19,6 +20,8 @@ public class JsonSchemaReturnObj { private String title; private String type; private int maxLength = -1; + private JSONObject properties; + private JSONObject items; public String getMockValue() { if (mock == null) { diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDocumentService.java b/backend/src/main/java/io/metersphere/api/service/ApiDocumentService.java index 5a161efdc6..e015f3ca5e 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDocumentService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDocumentService.java @@ -257,10 +257,32 @@ public class ApiDocumentService { apiInfoDTO.setResponseBodyParamType(type); } if (StringUtils.equalsAny(type, "JSON", "XML", "Raw")) { - if (bodyObj.containsKey("raw")) { - String raw = bodyObj.getString("raw"); - apiInfoDTO.setResponseBodyStrutureData(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(); diff --git a/backend/src/main/java/io/metersphere/api/service/MockConfigService.java b/backend/src/main/java/io/metersphere/api/service/MockConfigService.java index 89408645c0..a5848fe8c8 100644 --- a/backend/src/main/java/io/metersphere/api/service/MockConfigService.java +++ b/backend/src/main/java/io/metersphere/api/service/MockConfigService.java @@ -328,24 +328,7 @@ public class MockConfigService { if (bodyObj.containsKey("jsonSchema") && bodyObj.getJSONObject("jsonSchema").containsKey("properties")) { String bodyRetunStr = bodyObj.getJSONObject("jsonSchema").getJSONObject("properties").toJSONString(); JSONObject bodyReturnObj = JSONObject.parseObject(bodyRetunStr); - Set keySet = bodyReturnObj.keySet(); - JSONObject returnObj = new JSONObject(); - for (String key : keySet) { - try { - JsonSchemaReturnObj obj = bodyReturnObj.getObject(key, JsonSchemaReturnObj.class); - String values = obj.getMockValue(); - if (StringUtils.isEmpty(values)) { - values = ""; - } else { - try { - values = values.startsWith("@") ? ScriptEngineUtils.calculate(values) : values; - } catch (Exception e) { - } - } - returnObj.put(key, values); - } catch (Exception e) { - } - } + JSONObject returnObj = this.parseJsonSchema(bodyReturnObj); returnStr = returnObj.toJSONString(); } } else { @@ -422,6 +405,79 @@ public class MockConfigService { return returnStr; } + private JSONObject parseJsonSchema(JSONObject bodyReturnObj) { + JSONObject returnObj = new JSONObject(); + if(bodyReturnObj == null){ + return returnObj; + } + + Set keySet = bodyReturnObj.keySet(); + for (String key : keySet) { + try { + JsonSchemaReturnObj obj = bodyReturnObj.getObject(key, JsonSchemaReturnObj.class); + if(StringUtils.equals("object",obj.getType())) { + JSONObject itemObj = this.parseJsonSchema(obj.getProperties()); + if (!itemObj.isEmpty()) { + returnObj.put(key, itemObj); + } + }else if(StringUtils.equals("array",obj.getType())){ + if(obj.getItems() != null){ + JSONObject itemObj = obj.getItems(); + if(itemObj.containsKey("type")){ + if(StringUtils.equals("object",itemObj.getString("type"))&& itemObj.containsKey("properties")){ + JSONObject arrayObj = itemObj.getJSONObject("properties"); +// Set arrayKeys = arrayObj.keySet(); +// +// JSONObject parseObj = new JSONObject(); +// for (String arrayKey : arrayKeys) { +// JsonSchemaReturnObj arrayItemObj = arrayObj.getObject(arrayKey, JsonSchemaReturnObj.class); +// String value = this.getMockValues(arrayItemObj.getMockValue()); +// parseObj.put(arrayKey,value); +// } + JSONObject parseObj = this.parseJsonSchema(arrayObj); + JSONArray array = new JSONArray(); + array.add(parseObj); + returnObj.put(key, array); + }else if(StringUtils.equals("string",itemObj.getString("type"))&& itemObj.containsKey("mock")){ + JsonSchemaReturnObj arrayObj = JSONObject.toJavaObject(itemObj,JsonSchemaReturnObj.class); + String value = this.getMockValues(arrayObj.getMockValue()); + JSONArray array = new JSONArray(); + array.add(value); + returnObj.put(key, array); + } + } + } + }else { + String values = obj.getMockValue(); + if (StringUtils.isEmpty(values)) { + values = ""; + } else { + try { + values = values.startsWith("@") ? ScriptEngineUtils.calculate(values) : values; + } catch (Exception e) { + } + } + returnObj.put(key, values); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return returnObj; + } + + private String getMockValues(String values) { + if (StringUtils.isEmpty(values)) { + values = ""; + } else { + try { + values = values.startsWith("@") ? ScriptEngineUtils.calculate(values) : values; + } catch (Exception e) { + } + } + return values; + } + public MockExpectConfigWithBLOBs findMockExpectConfigById(String id) { return mockExpectConfigMapper.selectByPrimaryKey(id); } 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 a91d3b66d9..71e68024d1 100644 --- a/frontend/src/business/components/api/definition/components/document/ApiDocumentAnchor.vue +++ b/frontend/src/business/components/api/definition/components/document/ApiDocumentAnchor.vue @@ -104,7 +104,7 @@
+ :data="getJsonArr(apiInfo.requestHead)" class="test-content document-table"> @@ -126,7 +126,7 @@
+ :data="getJsonArr(apiInfo.urlParams)" class="test-content document-table">
{{ $t('api_test.definition.document.response_head') }}: + :data="getJsonArr(apiInfo.responseHead)" class="test-content document-table"> @@ -244,7 +244,7 @@
+
+ +

{{ $t('api_test.definition.document.response_code') }}: + :data="getJsonArr(apiInfo.responseCode)" class="test-content document-table"> @@ -358,6 +361,7 @@ export default { requestBodyStrutureData: "", sharePopoverVisible:false, jsonSchemaBody: {}, + JsonSchemaResponseBody:{}, responseHead: "无", responseBody: "", responseBodyParamType: "无", @@ -427,7 +431,7 @@ export default { }, trashEnable() { this.initApiDocSimpleList(); - } + }, }, methods: { formatRowData(dataType, data) { @@ -660,7 +664,10 @@ export default { handleScroll(){ if(!this.clickStepFlag){ //apiDocInfoDiv的总高度,是(每个item的高度+20)数量 - let apiDocDivScrollTop = this.$refs.apiDocInfoDiv.scrollTop; + let apiDocDivScrollTop = 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; @@ -737,7 +744,9 @@ export default { }else{ this.apiShowArray.shift(); let itemHeight = this.$refs.apiDocInfoDivItem[0].offsetHeight+10; - this.$refs.apiDocInfoDiv.scrollTop = (apiDocDivScrollTop-itemHeight); + if(this.$refs.apiDocInfoDiv&&this.$refs.apiDocInfoDiv.scrollTop){ + this.$refs.apiDocInfoDiv.scrollTop = (apiDocDivScrollTop-itemHeight); + } } this.apiStepIndex ++; } @@ -756,7 +765,9 @@ export default { } } this.clickStepFlag = true; - this.$refs.apiDocInfoDiv.scrollTop = (apiDocDivClientTop+itemHeightCount); + if(this.$refs.apiDocInfoDiv&&this.$refs.apiDocInfoDiv.scrollTop){ + this.$refs.apiDocInfoDiv.scrollTop = (apiDocDivClientTop+itemHeightCount); + } }, //检查要展示的api信息节点,和上下个2个及以内的范围内数据有没有查询过。并赋值为showArray