From 70536148e0c3e039fb852e233c05b35b5c1c29a6 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 3 Nov 2021 15:38:26 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E5=85=81=E8=AE=B8=E5=BC=95=E7=94=A8=E7=94=A8?= =?UTF-8?q?=E4=BE=8B=E6=96=B0=E5=A2=9E=E6=AD=A5=E9=AA=A4=20=20--bug=3D1007?= =?UTF-8?q?648=20--user=3D=E8=B5=B5=E5=8B=87=20=E5=BC=95=E7=94=A8=E7=9A=84?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E7=94=A8=E4=BE=8B=E6=97=A0=E6=B3=95=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E7=AD=89=E5=BE=85=E6=97=B6=E9=97=B4=20https://www.tap?= =?UTF-8?q?d.cn/55049933/s/1062875?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/definition/request/ElementUtil.java | 54 ++++++++++++ .../request/sampler/MsDubboSampler.java | 6 +- .../request/sampler/MsHTTPSamplerProxy.java | 6 +- .../request/sampler/MsJDBCSampler.java | 6 +- .../request/sampler/MsTCPSampler.java | 6 +- .../automation/scenario/EditApiScenario.vue | 2 +- .../scenario/common/ApiBaseComponent.vue | 6 +- .../scenario/component/ApiComponent.vue | 82 +++++++++++++++---- .../api/automation/scenario/menu/Menu.js | 16 ++-- .../components/ApiDefinitionStepButton.vue | 5 +- .../api/definition/model/ApiTestModel.js | 1 + 11 files changed, 153 insertions(+), 37 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/ElementUtil.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/ElementUtil.java index dc8299a19c..3c50d81071 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/ElementUtil.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/ElementUtil.java @@ -3,6 +3,9 @@ package io.metersphere.api.dto.definition.request; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; import io.metersphere.api.dto.definition.request.controller.MsLoopController; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.definition.request.variable.ScenarioVariable; @@ -330,6 +333,8 @@ public class ElementUtil { public static void dataSetDomain(JSONArray hashTree, MsParameter msParameter) { try { + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); for (int i = 0; i < hashTree.size(); i++) { JSONObject element = hashTree.getJSONObject(i); boolean isScenarioEnv = false; @@ -357,6 +362,13 @@ public class ElementUtil { MsHTTPSamplerProxy httpSamplerProxy = JSON.toJavaObject(element, MsHTTPSamplerProxy.class); if (httpSamplerProxy != null && (!httpSamplerProxy.isCustomizeReq() || (httpSamplerProxy.isCustomizeReq() && httpSamplerProxy.getIsRefEnvironment()))) { + // 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取 + if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) { + LinkedList elements = mapper.readValue(element.getString("hashTree"), + new TypeReference>() { + }); + httpSamplerProxy.setHashTree(elements); + } HashTree tmpHashTree = new HashTree(); httpSamplerProxy.toHashTree(tmpHashTree, null, msParameter); if (tmpHashTree != null && tmpHashTree.getArray().length > 0) { @@ -380,4 +392,46 @@ public class ElementUtil { LogUtil.error(e.getMessage()); } } + + public static void mergeHashTree(List sourceHashTree, List targetHashTree) { + List sourceIds = new ArrayList<>(); + List delIds = new ArrayList<>(); + Map updateMap = new HashMap<>(); + if (CollectionUtils.isEmpty(sourceHashTree)) { + sourceHashTree.addAll(targetHashTree); + return; + } + if (CollectionUtils.isNotEmpty(targetHashTree)) { + for (MsTestElement item : targetHashTree) { + updateMap.put(item.getId(), item); + } + } + // 找出待更新内容和源已经被删除的内容 + if (CollectionUtils.isNotEmpty(sourceHashTree)) { + for (int i = 0; i < sourceHashTree.size(); i++) { + MsTestElement source = sourceHashTree.get(i); + if (source != null) { + sourceIds.add(source.getId()); + if (!StringUtils.equals(source.getLabel(), "SCENARIO-REF-STEP")) { + if (StringUtils.isNotEmpty(source.getId()) && updateMap.containsKey(source.getId())) { + sourceHashTree.set(i, updateMap.get(source.getId())); + } else { + delIds.add(source.getId()); + } + } + } + } + } + + // 删除多余的步骤 + sourceHashTree.removeIf(item -> item != null && delIds.contains(item.getId())); + // 补充新增的源引用步骤 + if (CollectionUtils.isNotEmpty(targetHashTree)) { + for (MsTestElement item : targetHashTree) { + if (!sourceIds.contains(item.getId())) { + sourceHashTree.add(item); + } + } + } + } } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java index 15c7842f41..c326e5af59 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java @@ -128,7 +128,11 @@ public class MsDubboSampler extends MsTestElement { } } if (proxy != null) { - this.setHashTree(proxy.getHashTree()); + if (StringUtils.equals(this.getRefType(), "CASE")) { + ElementUtil.mergeHashTree(this.getHashTree(), proxy.getHashTree()); + } else { + this.setHashTree(proxy.getHashTree()); + } this.setMethod(proxy.getMethod()); this.set_interface(proxy.get_interface()); this.setAttachmentArgs(proxy.getAttachmentArgs()); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java index 7585c17f0d..a893ed39c4 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java @@ -154,7 +154,11 @@ public class MsHTTPSamplerProxy extends MsTestElement { } } if (proxy != null) { - this.setHashTree(proxy.getHashTree()); + if (StringUtils.equals(this.getRefType(), "CASE")) { + ElementUtil.mergeHashTree(this.getHashTree(), proxy.getHashTree()); + }else { + this.setHashTree(proxy.getHashTree()); + } this.setMethod(proxy.getMethod()); this.setBody(proxy.getBody()); this.setRest(proxy.getRest()); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java index 6dcd3edb34..393681bd28 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java @@ -230,7 +230,11 @@ public class MsJDBCSampler extends MsTestElement { } } if (proxy != null) { - this.setHashTree(proxy.getHashTree()); + if (StringUtils.equals(this.getRefType(), "CASE")) { + ElementUtil.mergeHashTree(this.getHashTree(), proxy.getHashTree()); + } else { + this.setHashTree(proxy.getHashTree()); + } this.setDataSource(proxy.getDataSource()); this.setDataSourceId(proxy.getDataSourceId()); this.setQuery(proxy.getQuery()); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java index 0c8cdf1a68..846d1e1e84 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java @@ -182,7 +182,11 @@ public class MsTCPSampler extends MsTestElement { } } if (proxy != null) { - this.setHashTree(proxy.getHashTree()); + if (StringUtils.equals(this.getRefType(), "CASE")) { + ElementUtil.mergeHashTree(this.getHashTree(), proxy.getHashTree()); + }else { + this.setHashTree(proxy.getHashTree()); + } this.setClassname(proxy.getClassname()); this.setServer(proxy.getServer()); this.setPort(proxy.getPort()); diff --git a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue index a1baabf167..739988faf8 100644 --- a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue @@ -948,7 +948,7 @@ export default { setComponent(type, this, plugin); }, nodeClick(data, node) { - if (data.referenced != 'REF' && data.referenced != 'Deleted' && !data.disabled && this.stepFilter) { + if ((data.referenced != 'REF' && data.referenced != 'Deleted' && !data.disabled && this.stepFilter) || data.refType === 'CASE') { this.operatingElements = this.stepFilter.get(data.type); } else { this.operatingElements = []; diff --git a/frontend/src/business/components/api/automation/scenario/common/ApiBaseComponent.vue b/frontend/src/business/components/api/automation/scenario/common/ApiBaseComponent.vue index cc7f6f1384..bd05dc5924 100644 --- a/frontend/src/business/components/api/automation/scenario/common/ApiBaseComponent.vue +++ b/frontend/src/business/components/api/automation/scenario/common/ApiBaseComponent.vue @@ -2,18 +2,16 @@
-
+
{{ data.index }}
{{ title }} {{ getMethod() }} - - + diff --git a/frontend/src/business/components/api/automation/scenario/component/ApiComponent.vue b/frontend/src/business/components/api/automation/scenario/component/ApiComponent.vue index 0d82ce1002..10aa4a21ca 100644 --- a/frontend/src/business/components/api/automation/scenario/component/ApiComponent.vue +++ b/frontend/src/business/components/api/automation/scenario/component/ApiComponent.vue @@ -32,10 +32,10 @@