From 23d76b335d125505563a25d2be51ec98c5d7aeb6 Mon Sep 17 00:00:00 2001
From: guoyuqi <xiaomeinvG@126.com>
Date: Tue, 21 Jun 2022 17:23:45 +0800
Subject: [PATCH] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):=20?=
 =?UTF-8?q?=E5=9C=BA=E6=99=AF=E6=8E=A5=E5=8F=A3=E6=A8=A1=E5=9D=97=E5=AF=BC?=
 =?UTF-8?q?=E5=85=A5=E9=80=BB=E8=BE=91=E9=87=8D=E6=9E=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

--user=郭雨琦
---
 .../api/controller/ApiModuleController.java   |   6 -
 .../dto/automation/ApiScenarioModuleDTO.java  |   4 +-
 .../automation/UpdateScenarioModuleDTO.java   |  16 +
 .../parse/ApiScenarioImportUtil.java          |   6 +
 .../dto/automation/parse/EsbDataParser.java   |   5 +-
 .../automation/parse/HarScenarioParser.java   |  93 +--
 .../dto/automation/parse/MsJmeterParser.java  |  26 +-
 .../automation/parse/MsScenarioParser.java    |  73 +-
 .../parse/PostmanScenarioParser.java          |  20 +-
 .../api/dto/definition/ApiModuleDTO.java      |   2 +
 .../dto/definition/UpdateApiModuleDTO.java    |  17 +
 .../api/dto/definition/parse/ESBParser.java   |  95 +--
 .../api/dto/definition/parse/HarParser.java   |  22 -
 .../parse/JmeterDefinitionParser.java         |  31 +-
 .../definition/parse/MsDefinitionParser.java  |  79 +-
 .../parse/PostmanDefinitionParser.java        |  40 +-
 .../dto/definition/parse/Swagger2Parser.java  |  35 +-
 .../dto/definition/parse/Swagger3Parser.java  |  57 +-
 .../api/parse/ApiImportAbstractParser.java    |   1 +
 .../api/service/ApiAutomationService.java     |  81 ++-
 .../api/service/ApiDefinitionService.java     | 257 ++++---
 .../api/service/ApiModuleService.java         | 686 +++++++++++++++++-
 .../api/service/ApiScenarioModuleService.java | 446 +++++++++++-
 .../mapper/ext/ExtApiDefinitionMapper.java    |  12 +-
 .../mapper/ext/ExtApiDefinitionMapper.xml     | 236 ++++--
 .../base/mapper/ext/ExtApiScenarioMapper.java |   6 +
 .../base/mapper/ext/ExtApiScenarioMapper.xml  |  42 ++
 .../base/mapper/ext/ExtLoadTestMapper.xml     | 102 +--
 .../ext/ExtSwaggerUrlScheduleMapper.xml       |   2 +-
 .../components/import/ApiImport.vue           |   6 -
 30 files changed, 1792 insertions(+), 712 deletions(-)
 create mode 100644 backend/src/main/java/io/metersphere/api/dto/automation/UpdateScenarioModuleDTO.java
 create mode 100644 backend/src/main/java/io/metersphere/api/dto/definition/UpdateApiModuleDTO.java

diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiModuleController.java b/backend/src/main/java/io/metersphere/api/controller/ApiModuleController.java
index 36585ceedc..d42b24d650 100644
--- a/backend/src/main/java/io/metersphere/api/controller/ApiModuleController.java
+++ b/backend/src/main/java/io/metersphere/api/controller/ApiModuleController.java
@@ -46,12 +46,6 @@ public class ApiModuleController {
         return apiModuleService.countTrashApiData(projectId, protocol);
     }
 
-    @GetMapping("/getModuleByName/{projectId}/{protocol}")
-    public ApiModule getModuleByName(@PathVariable String projectId, @PathVariable String protocol) {
-//        checkPermissionService.checkProjectOwner(projectId);
-        return apiModuleService.getModuleByName(projectId, protocol);
-    }
-
     @GetMapping("/getUserDefaultApiType")
     public String getUserDefaultApiType() {
         String returnStr = ApiDefinitionDefaultApiTypeUtil.HTTP;
diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/ApiScenarioModuleDTO.java b/backend/src/main/java/io/metersphere/api/dto/automation/ApiScenarioModuleDTO.java
index c4e9200298..154aaccfd4 100644
--- a/backend/src/main/java/io/metersphere/api/dto/automation/ApiScenarioModuleDTO.java
+++ b/backend/src/main/java/io/metersphere/api/dto/automation/ApiScenarioModuleDTO.java
@@ -1,13 +1,11 @@
 package io.metersphere.api.dto.automation;
 
-import io.metersphere.base.domain.ApiScenarioModule;
 import io.metersphere.track.dto.TreeNodeDTO;
 import lombok.Getter;
 import lombok.Setter;
 
-import java.util.List;
-
 @Getter
 @Setter
 public class ApiScenarioModuleDTO extends TreeNodeDTO<ApiScenarioModuleDTO> {
+    private String path;
 }
diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/UpdateScenarioModuleDTO.java b/backend/src/main/java/io/metersphere/api/dto/automation/UpdateScenarioModuleDTO.java
new file mode 100644
index 0000000000..534d963ba8
--- /dev/null
+++ b/backend/src/main/java/io/metersphere/api/dto/automation/UpdateScenarioModuleDTO.java
@@ -0,0 +1,16 @@
+package io.metersphere.api.dto.automation;
+
+import io.metersphere.base.domain.ApiScenarioModule;
+import io.metersphere.base.domain.ApiScenarioWithBLOBs;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+public class UpdateScenarioModuleDTO {
+    private List<ApiScenarioModule> moduleList;
+    private List<ApiScenarioWithBLOBs> needUpdateList;
+    private List<ApiScenarioWithBLOBs> apiScenarioWithBLOBsList;
+}
diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/ApiScenarioImportUtil.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/ApiScenarioImportUtil.java
index 584173a95a..2fe45151ce 100644
--- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/ApiScenarioImportUtil.java
+++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/ApiScenarioImportUtil.java
@@ -247,6 +247,9 @@ public class ApiScenarioImportUtil {
         test.setUserId(SessionUtils.getUserId());
         test.setLatest(true);
         test.setOrder(apiDefinitionService.getImportNextOrder(projectId));
+        if (test.getName().length() > 255) {
+            test.setName(test.getName().substring(0, 255));
+        }
         apiDefinitionMapper.insert(test);
         definitionMap.put(object.getString("path") + object.getString("method") + object.getString("protocol"), test);
         return test;
@@ -279,6 +282,9 @@ public class ApiScenarioImportUtil {
         objectNew.remove("referenced");
         apiTestCase.setRequest(objectNew.toJSONString());
         apiTestCase.setOrder(apiDefinitionService.getImportNextCaseOrder(projectId));
+        if (apiTestCase.getName().length() > 255) {
+            apiTestCase.setName(apiTestCase.getName().substring(0, 255));
+        }
         apiTestCaseMapper.insert(apiTestCase);
     }
 
diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/EsbDataParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/EsbDataParser.java
index 577aea787e..f270bdb47f 100644
--- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/EsbDataParser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/EsbDataParser.java
@@ -1,6 +1,5 @@
 package io.metersphere.api.dto.automation.parse;
 
-import com.alibaba.fastjson.JSONArray;
 import io.metersphere.api.dto.automation.EsbDataStruct;
 import io.metersphere.commons.utils.LogUtil;
 import io.metersphere.commons.utils.XMLUtils;
@@ -89,11 +88,11 @@ public class EsbDataParser {
                     } else {
                         returnData = dataStuct.copy(true);
                     }
-                }else if(index == 0){
+                } else if (index == 0) {
                     //如果是第一个节点不符合,则遍历子节点是否有符合的。
                     int newIndex = index;
                     EsbDataStruct itemData = selectEsbDataStructByNameStruct(dataStuct.getChildren(), paramArr, newIndex);
-                    if(itemData != null ){
+                    if (itemData != null) {
                         returnData = itemData;
                     }
                 }
diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/HarScenarioParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/HarScenarioParser.java
index da2543a827..20fd2959ff 100644
--- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/HarScenarioParser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/HarScenarioParser.java
@@ -8,7 +8,6 @@ import io.metersphere.api.dto.definition.request.MsScenario;
 import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
 import io.metersphere.api.dto.scenario.KeyValue;
 import io.metersphere.api.parse.HarScenarioAbstractParser;
-import io.metersphere.base.domain.ApiScenarioModule;
 import io.metersphere.base.domain.ApiScenarioWithBLOBs;
 import io.metersphere.commons.exception.MSException;
 import io.metersphere.commons.utils.LogUtil;
@@ -16,7 +15,6 @@ import io.metersphere.dto.RequestResult;
 import io.metersphere.dto.ResponseResult;
 import io.metersphere.plugin.core.MsTestElement;
 import org.apache.commons.lang3.ObjectUtils;
-import org.apache.commons.lang3.StringUtils;
 
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -49,33 +47,20 @@ public class HarScenarioParser extends HarScenarioAbstractParser<ScenarioImport>
         MsScenario msScenario = new MsScenario();
         msScenario.setName(harName);
         this.projectId = request.getProjectId();
-        if (!ObjectUtils.isEmpty(har.log)&&!ObjectUtils.isEmpty(har.log.entries)) {
+        if (!ObjectUtils.isEmpty(har.log) && !ObjectUtils.isEmpty(har.log.entries)) {
             parseItem(har.log.entries, msScenario, apiScenarioWithBLOBs);
         }
 
         // 生成场景对象
         List<ApiScenarioWithBLOBs> scenarioWithBLOBs = new LinkedList<>();
-        parseScenarioWithBLOBs(scenarioWithBLOBs, msScenario, request);
+        parseScenarioWithBLOBs(scenarioWithBLOBs, msScenario);
         scenarioImport.setData(scenarioWithBLOBs);
         return scenarioImport;
     }
 
-    private void parseScenarioWithBLOBs(List<ApiScenarioWithBLOBs> scenarioWithBLOBsList, MsScenario msScenario, ApiTestImportRequest request) {
-        ApiScenarioModule selectModule = null;
-        if (StringUtils.isNotBlank(request.getModuleId())) {
-            selectModule = ApiScenarioImportUtil.getSelectModule(request.getModuleId());
-        }
-        ApiScenarioModule module = ApiScenarioImportUtil.buildModule(selectModule, msScenario.getName(), this.projectId);
+    private void parseScenarioWithBLOBs(List<ApiScenarioWithBLOBs> scenarioWithBLOBsList, MsScenario msScenario) {
         ApiScenarioWithBLOBs scenarioWithBLOBs = parseScenario(msScenario);
-        if (module != null) {
-            scenarioWithBLOBs.setApiScenarioModuleId(module.getId());
-            if (selectModule != null) {
-                String selectModulePath = ApiScenarioImportUtil.getSelectModulePath(selectModule.getName(), selectModule.getParentId());
-                scenarioWithBLOBs.setModulePath(selectModulePath + "/" + module.getName());
-            } else {
-                scenarioWithBLOBs.setModulePath("/" + module.getName());
-            }
-        }
+        scenarioWithBLOBs.setModulePath("/" + msScenario.getName());
         scenarioWithBLOBsList.add(scenarioWithBLOBs);
     }
 
@@ -89,47 +74,47 @@ public class HarScenarioParser extends HarScenarioAbstractParser<ScenarioImport>
         scenario.setHashTree(results);
     }
 
-private RequestResult getRequestResult(MsHTTPSamplerProxy samplerProxy, HarEntry harEntry) {
-    HarRequest request = harEntry.request;
-    HarResponse response = harEntry.response;
+    private RequestResult getRequestResult(MsHTTPSamplerProxy samplerProxy, HarEntry harEntry) {
+        HarRequest request = harEntry.request;
+        HarResponse response = harEntry.response;
 
-    RequestResult requestResult = new RequestResult();
-    requestResult.setName("Response");
-    requestResult.setUrl(request.url);
-    requestResult.setMethod(request.method);
-    if(samplerProxy.getBody()!= null){
-        List<KeyValue> keyValueList = new ArrayList<>();
-        if(!ObjectUtils.isEmpty(request.queryString)){
-            for (HarQueryParm model : request.queryString) {
-                KeyValue keyValue = new KeyValue(model.name,model.value);
-                keyValueList.add(keyValue);
+        RequestResult requestResult = new RequestResult();
+        requestResult.setName("Response");
+        requestResult.setUrl(request.url);
+        requestResult.setMethod(request.method);
+        if (samplerProxy.getBody() != null) {
+            List<KeyValue> keyValueList = new ArrayList<>();
+            if (!ObjectUtils.isEmpty(request.queryString)) {
+                for (HarQueryParm model : request.queryString) {
+                    KeyValue keyValue = new KeyValue(model.name, model.value);
+                    keyValueList.add(keyValue);
+                }
             }
-        }
-        if(!ObjectUtils.isEmpty(request.postData)&&!ObjectUtils.isEmpty(request.postData.params)){
-            for (HarPostParam model : request.postData.params) {
-                KeyValue keyValue = new KeyValue(model.name,model.value);
-                keyValueList.add(keyValue);
+            if (!ObjectUtils.isEmpty(request.postData) && !ObjectUtils.isEmpty(request.postData.params)) {
+                for (HarPostParam model : request.postData.params) {
+                    KeyValue keyValue = new KeyValue(model.name, model.value);
+                    keyValueList.add(keyValue);
+                }
             }
+
+            requestResult.setBody(JSONArray.toJSONString(keyValueList));
         }
 
-        requestResult.setBody(JSONArray.toJSONString(keyValueList));
-    }
+        requestResult.setHeaders(JSONArray.toJSONString(request.headers));
+        requestResult.setRequestSize(request.bodySize);
+        if (!ObjectUtils.isEmpty(request.cookies)) {
+            requestResult.setCookies(JSONArray.toJSONString(request.cookies));
+        }
 
-    requestResult.setHeaders(JSONArray.toJSONString(request.headers));
-    requestResult.setRequestSize(request.bodySize);
-    if(!ObjectUtils.isEmpty(request.cookies)){
-        requestResult.setCookies(JSONArray.toJSONString(request.cookies));
-    }
+        ResponseResult responseResult = requestResult.getResponseResult();
+        responseResult.setHeaders(JSONArray.toJSONString(response.headers));
+        responseResult.setResponseCode(String.valueOf(response.status));
+        responseResult.setResponseSize(response.bodySize);
+        if (response.content != null && response.content.text != null) {
+            responseResult.setBody(response.content.text);
+            responseResult.setResponseMessage(response.content.text);
+        }
 
-    ResponseResult responseResult = requestResult.getResponseResult();
-    responseResult.setHeaders(JSONArray.toJSONString(response.headers));
-    responseResult.setResponseCode(String.valueOf(response.status));
-    responseResult.setResponseSize(response.bodySize);
-    if(response.content != null && response.content.text != null){
-        responseResult.setBody(response.content.text);
-        responseResult.setResponseMessage(response.content.text);
+        return requestResult;
     }
-
-    return requestResult;
-}
 }
diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsJmeterParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsJmeterParser.java
index c3cae551de..526a3ff12a 100644
--- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsJmeterParser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsJmeterParser.java
@@ -8,7 +8,6 @@ import io.github.ningyu.jmeter.plugin.util.Constants;
 import io.metersphere.api.dto.ApiTestImportRequest;
 import io.metersphere.api.dto.automation.ImportPoolsDTO;
 import io.metersphere.api.dto.definition.request.MsScenario;
-import io.metersphere.plugin.core.MsTestElement;
 import io.metersphere.api.dto.definition.request.assertions.*;
 import io.metersphere.api.dto.definition.request.controller.MsLoopController;
 import io.metersphere.api.dto.definition.request.controller.MsTransactionController;
@@ -39,7 +38,6 @@ import io.metersphere.api.dto.scenario.request.BodyFile;
 import io.metersphere.api.dto.scenario.request.RequestType;
 import io.metersphere.api.parse.ApiImportAbstractParser;
 import io.metersphere.api.service.ApiTestEnvironmentService;
-import io.metersphere.base.domain.ApiScenarioModule;
 import io.metersphere.base.domain.ApiScenarioWithBLOBs;
 import io.metersphere.base.domain.ApiTestEnvironmentExample;
 import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
@@ -48,6 +46,7 @@ import io.metersphere.commons.exception.MSException;
 import io.metersphere.commons.utils.BeanUtils;
 import io.metersphere.commons.utils.CommonBeanFactory;
 import io.metersphere.commons.utils.LogUtil;
+import io.metersphere.plugin.core.MsTestElement;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.jmeter.assertions.*;
@@ -115,27 +114,11 @@ public class MsJmeterParser extends ApiImportAbstractParser<ScenarioImport> {
     private List<ApiScenarioWithBLOBs> parseObj(MsScenario msScenario, ApiTestImportRequest request) {
         List<ApiScenarioWithBLOBs> scenarioWithBLOBsList = new ArrayList<>();
         ApiScenarioWithBLOBs scenarioWithBLOBs = new ApiScenarioWithBLOBs();
-        ApiScenarioModule selectModule = null;
-        String selectModulePath = null;
-        if (StringUtils.isNotBlank(request.getModuleId())) {
-            selectModule = ApiScenarioImportUtil.getSelectModule(request.getModuleId());
-            if (selectModule != null) {
-                selectModulePath = ApiScenarioImportUtil.getSelectModulePath(selectModule.getName(), selectModule.getParentId());
-            }
-        }
-        ApiScenarioModule module = ApiScenarioImportUtil.buildModule(selectModule, msScenario.getName(), this.projectId);
         scenarioWithBLOBs.setName(request.getFileName());
         scenarioWithBLOBs.setProjectId(request.getProjectId());
         if (msScenario != null && CollectionUtils.isNotEmpty(msScenario.getHashTree())) {
             scenarioWithBLOBs.setStepTotal(msScenario.getHashTree().size());
-        }
-        if (module != null) {
-            scenarioWithBLOBs.setApiScenarioModuleId(module.getId());
-            if (StringUtils.isNotBlank(selectModulePath)) {
-                scenarioWithBLOBs.setModulePath(selectModulePath + "/" + module.getName());
-            } else {
-                scenarioWithBLOBs.setModulePath("/" + module.getName());
-            }
+            scenarioWithBLOBs.setModulePath("/" + msScenario.getName());
         }
         scenarioWithBLOBs.setId(UUID.randomUUID().toString());
         scenarioWithBLOBs.setScenarioDefinition(JSON.toJSONString(msScenario));
@@ -780,11 +763,6 @@ public class MsJmeterParser extends ApiImportAbstractParser<ScenarioImport> {
                 elementNode.setType("ConstantTimer");
             }
             // IF条件控制器,这里平台方式和jmeter 不同,暂时不处理
-//            else if (key instanceof IfController) {
-//                elementNode = new MsIfController();
-//                BeanUtils.copyBean(elementNode, key);
-//                elementNode.setType("IfController");
-//            }
             // 次数循环控制器
             else if (key instanceof LoopController) {
                 elementNode = new MsLoopController();
diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsScenarioParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsScenarioParser.java
index 792d124af9..b836033407 100644
--- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsScenarioParser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsScenarioParser.java
@@ -5,37 +5,27 @@ import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.parser.Feature;
 import io.metersphere.api.dto.ApiTestImportRequest;
 import io.metersphere.api.dto.EnvironmentType;
-import io.metersphere.api.dto.definition.parse.ms.NodeTree;
 import io.metersphere.api.dto.definition.request.MsScenario;
-import io.metersphere.base.domain.*;
-import io.metersphere.plugin.core.MsTestElement;
 import io.metersphere.api.parse.MsAbstractParser;
+import io.metersphere.base.domain.ApiScenarioWithBLOBs;
+import io.metersphere.plugin.core.MsTestElement;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 
 import java.io.InputStream;
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
 
 public class MsScenarioParser extends MsAbstractParser<ScenarioImport> {
 
-    private ApiScenarioModule selectModule;
-
-    private String selectModulePath;
-
     @Override
     public ScenarioImport parse(InputStream source, ApiTestImportRequest request) {
         String testStr = getApiTestStr(source);
         this.projectId = request.getProjectId();
         JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField);
 
-        if (StringUtils.isNotBlank(request.getModuleId())) {
-            this.selectModule = ApiScenarioImportUtil.getSelectModule(request.getModuleId());
-            if (this.selectModule != null) {
-                this.selectModulePath = ApiScenarioImportUtil.getSelectModulePath(this.selectModule.getName(), this.selectModule.getParentId());
-            }
-        }
-
         if (testObject.get("projectName") != null || testObject.get("projectId") != null) {
             return parseMsFormat(testStr, request);
         } else {
@@ -64,19 +54,7 @@ public class MsScenarioParser extends MsAbstractParser<ScenarioImport> {
         ScenarioImport scenarioImport = JSON.parseObject(testStr, ScenarioImport.class, Feature.DisableSpecialKeyDetect);
         List<ApiScenarioWithBLOBs> data = scenarioImport.getData();
 
-        Set<String> moduleIdSet = scenarioImport.getData().stream()
-                .map(ApiScenarioWithBLOBs::getApiScenarioModuleId).collect(Collectors.toSet());
-
-        Map<String, NodeTree> nodeMap = null;
-        List<NodeTree> nodeTree = scenarioImport.getNodeTree();
-        if (CollectionUtils.isNotEmpty(nodeTree)) {
-            cutDownTree(nodeTree, moduleIdSet);
-            ApiScenarioImportUtil.createNodeTree(nodeTree, projectId, importRequest.getModuleId());
-            nodeMap = getNodeMap(nodeTree);
-        }
-
         if (CollectionUtils.isNotEmpty(data)) {
-            Map<String, NodeTree> finalNodeMap = nodeMap;
             data.forEach(item -> {
                 String scenarioDefinitionStr = item.getScenarioDefinition();
                 if (StringUtils.isNotBlank(scenarioDefinitionStr)) {
@@ -94,48 +72,9 @@ public class MsScenarioParser extends MsAbstractParser<ScenarioImport> {
                     }
                 }
 
-                if (finalNodeMap != null && finalNodeMap.get(item.getApiScenarioModuleId()) != null) {
-                    NodeTree node = finalNodeMap.get(item.getApiScenarioModuleId());
-                    item.setApiScenarioModuleId(node.getNewId());
-                    item.setModulePath(node.getPath());
-                } else {
-                    if (StringUtils.isBlank(item.getModulePath())) {
-                        item.setApiScenarioModuleId(null);
-                    }
-                    // 旧版本未导出模块
-                    parseModule(item.getModulePath(), importRequest, item);
-                }
                 item.setProjectId(this.projectId);
             });
         }
         return scenarioImport;
     }
-
-    protected void parseModule(String modulePath, ApiTestImportRequest importRequest, ApiScenarioWithBLOBs apiScenarioWithBLOBs) {
-        if (StringUtils.isEmpty(modulePath)) {
-            return;
-        }
-        if (modulePath.startsWith("/")) {
-            modulePath = modulePath.substring(1);
-        }
-        if (modulePath.endsWith("/")) {
-            modulePath = modulePath.substring(0, modulePath.length() - 1);
-        }
-        List<String> modules = Arrays.asList(modulePath.split("/"));
-        ApiScenarioModule parent = this.selectModule;
-        Iterator<String> iterator = modules.iterator();
-        while (iterator.hasNext()) {
-            String item = iterator.next();
-            parent = ApiScenarioImportUtil.buildModule(parent, item, this.projectId);
-            if (!iterator.hasNext()) {
-                apiScenarioWithBLOBs.setApiScenarioModuleId(parent.getId());
-                String path = apiScenarioWithBLOBs.getModulePath() == null ? "" : apiScenarioWithBLOBs.getModulePath();
-                if (StringUtils.isNotBlank(this.selectModulePath)) {
-                    apiScenarioWithBLOBs.setModulePath(this.selectModulePath + path);
-                } else if (StringUtils.isBlank(importRequest.getModuleId())) {
-                    apiScenarioWithBLOBs.setModulePath("/未规划场景" + path);
-                }
-            }
-        }
-    }
 }
diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/PostmanScenarioParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/PostmanScenarioParser.java
index 2b14cb5ff6..f1e620c6c0 100644
--- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/PostmanScenarioParser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/PostmanScenarioParser.java
@@ -3,7 +3,6 @@ package io.metersphere.api.dto.automation.parse;
 import com.alibaba.fastjson.JSON;
 import io.metersphere.api.dto.ApiTestImportRequest;
 import io.metersphere.api.dto.definition.request.MsScenario;
-import io.metersphere.plugin.core.MsTestElement;
 import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
 import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
 import io.metersphere.api.dto.parse.postman.PostmanCollection;
@@ -11,9 +10,9 @@ import io.metersphere.api.dto.parse.postman.PostmanCollectionInfo;
 import io.metersphere.api.dto.parse.postman.PostmanItem;
 import io.metersphere.api.dto.parse.postman.PostmanKeyValue;
 import io.metersphere.api.parse.PostmanAbstractParserParser;
-import io.metersphere.base.domain.ApiScenarioModule;
 import io.metersphere.base.domain.ApiScenarioWithBLOBs;
 import io.metersphere.commons.constants.VariableTypeConstants;
+import io.metersphere.plugin.core.MsTestElement;
 
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -40,25 +39,14 @@ public class PostmanScenarioParser extends PostmanAbstractParserParser<ScenarioI
         parseItem(postmanCollection.getItem(), variables, msScenario, apiScenarioWithBLOBs);
         // 生成场景对象
         List<ApiScenarioWithBLOBs> scenarioWithBLOBs = new LinkedList<>();
-        parseScenarioWithBLOBs(scenarioWithBLOBs, msScenario, request);
+        parseScenarioWithBLOBs(scenarioWithBLOBs, msScenario);
         scenarioImport.setData(scenarioWithBLOBs);
         return scenarioImport;
     }
 
-    private void parseScenarioWithBLOBs(List<ApiScenarioWithBLOBs> scenarioWithBLOBsList, MsScenario msScenario, ApiTestImportRequest request) {
-        ApiScenarioModule selectModule = ApiScenarioImportUtil.getSelectModule(request.getModuleId());
-
-        ApiScenarioModule module = ApiScenarioImportUtil.buildModule(selectModule, msScenario.getName(), this.projectId);
+    private void parseScenarioWithBLOBs(List<ApiScenarioWithBLOBs> scenarioWithBLOBsList, MsScenario msScenario) {
         ApiScenarioWithBLOBs scenarioWithBLOBs = parseScenario(msScenario);
-        if (module != null) {
-            scenarioWithBLOBs.setApiScenarioModuleId(module.getId());
-            if (selectModule != null) {
-                String selectModulePath = ApiScenarioImportUtil.getSelectModulePath(selectModule.getName(), selectModule.getParentId());
-                scenarioWithBLOBs.setModulePath(selectModulePath + "/" + module.getName());
-            } else {
-                scenarioWithBLOBs.setModulePath("/" + module.getName());
-            }
-        }
+        scenarioWithBLOBs.setModulePath("/" + msScenario.getName());
         scenarioWithBLOBsList.add(scenarioWithBLOBs);
     }
 
diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/ApiModuleDTO.java b/backend/src/main/java/io/metersphere/api/dto/definition/ApiModuleDTO.java
index d76ac995fc..30eb8f8f3e 100644
--- a/backend/src/main/java/io/metersphere/api/dto/definition/ApiModuleDTO.java
+++ b/backend/src/main/java/io/metersphere/api/dto/definition/ApiModuleDTO.java
@@ -8,4 +8,6 @@ import lombok.Setter;
 @Setter
 public class ApiModuleDTO extends TreeNodeDTO<ApiModuleDTO> {
     private String protocol;
+
+    private String path;
 }
diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/UpdateApiModuleDTO.java b/backend/src/main/java/io/metersphere/api/dto/definition/UpdateApiModuleDTO.java
new file mode 100644
index 0000000000..de4b644e26
--- /dev/null
+++ b/backend/src/main/java/io/metersphere/api/dto/definition/UpdateApiModuleDTO.java
@@ -0,0 +1,17 @@
+package io.metersphere.api.dto.definition;
+
+import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
+import io.metersphere.base.domain.ApiModule;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+public class UpdateApiModuleDTO {
+    private List<ApiModule> moduleList;
+    private List<ApiDefinitionWithBLOBs> needUpdateList;
+    private List<ApiDefinitionWithBLOBs> definitionWithBLOBs;
+
+}
diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/ESBParser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ESBParser.java
index 2df437ff73..4bc959b9b9 100644
--- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/ESBParser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ESBParser.java
@@ -13,7 +13,6 @@ import io.metersphere.api.dto.scenario.KeyValue;
 import io.metersphere.api.dto.scenario.request.RequestType;
 import io.metersphere.api.service.EsbApiParamService;
 import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
-import io.metersphere.base.domain.ApiModule;
 import io.metersphere.base.domain.EsbApiParamsWithBLOBs;
 import io.metersphere.commons.utils.CommonBeanFactory;
 import io.metersphere.commons.utils.LogUtil;
@@ -165,17 +164,6 @@ public class ESBParser extends EsbAbstractParser {
         setCellValue("", row1.createCell(8), font, cellStyleMap.get("default"));
         setCellValue("", row1.createCell(9), font, cellStyleMap.get("default"));
 
-//        } else {
-//            setCellValue("", row1.createCell(4), font, cellStyleMap.get("default"));
-//            setCellValue("", row1.createCell(5), font, cellStyleMap.get("pop"));
-//            setCellValue("服务名称", row1.createCell(6), font, cellStyleMap.get("default"));
-//            setCellValue("服务场景", row1.createCell(7), font, cellStyleMap.get("default"));
-//            setCellValue("", row1.createCell(8), font, cellStyleMap.get("default"));
-//            setCellValue("", row1.createCell(9), font, cellStyleMap.get("default"));
-//            setCellValue("", row1.createCell(10), font, cellStyleMap.get("default"));
-//        }
-
-
         XSSFRow row2 = sheet.createRow(1);
         setCellValue("请输入交易码(必填)", row2.createCell(0), font, cellStyleMap.get("default"));
         setCellValue("请输入交易名称(必填)", row2.createCell(1), font, cellStyleMap.get("default"));
@@ -188,15 +176,6 @@ public class ESBParser extends EsbAbstractParser {
         setCellValue("", row2.createCell(7), font, cellStyleMap.get("default"));
         setCellValue("", row2.createCell(8), font, cellStyleMap.get("default"));
         setCellValue("", row2.createCell(9), font, cellStyleMap.get("default"));
-//        } else {
-//            setCellValue("", row2.createCell(4), font, cellStyleMap.get("default"));
-//            setCellValue("", row2.createCell(5), font, cellStyleMap.get("pop"));
-//            setCellValue("请输入服务名称(如果不填,则以交易名称为主)", row2.createCell(6), font, null);
-//            setCellValue("请输入服务场景(选填)", row2.createCell(7), font, cellStyleMap.get("default"));
-//            setCellValue("", row2.createCell(8), font, cellStyleMap.get("default"));
-//            setCellValue("", row2.createCell(9), font, cellStyleMap.get("default"));
-//            setCellValue("", row2.createCell(10), font, cellStyleMap.get("default"));
-//        }
 
         XSSFRow row3 = sheet.createRow(2);
         setCellValue("", row3.createCell(0), font, cellStyleMap.get("yellow"));
@@ -214,19 +193,6 @@ public class ESBParser extends EsbAbstractParser {
         sheet.addMergedRegion(region1);
         CellRangeAddress region2 = new CellRangeAddress(2, 2, 5, 9);
         sheet.addMergedRegion(region2);
-//        } else {
-//            setCellValue("", row3.createCell(4), font, cellStyleMap.get("yellow"));
-//            setCellValue("", row3.createCell(5), font, cellStyleMap.get("yellow"));
-//            setCellValue("请输入系统名称", row3.createCell(6), font, cellStyleMap.get("yellow"));
-//            setCellValue("", row3.createCell(7), font, cellStyleMap.get("yellow"));
-//            setCellValue("", row3.createCell(8), font, cellStyleMap.get("yellow"));
-//            setCellValue("", row3.createCell(9), font, cellStyleMap.get("yellow"));
-//            setCellValue("", row3.createCell(10), font, cellStyleMap.get("yellow"));
-//            CellRangeAddress region1 = new CellRangeAddress(2, 2, 0, 4);
-//            sheet.addMergedRegion(region1);
-//            CellRangeAddress region2 = new CellRangeAddress(2, 2, 6, 10);
-//            sheet.addMergedRegion(region2);
-//        }
 
         XSSFRow row4 = sheet.createRow(3);
         setCellValue("英文名称", row4.createCell(0), font, cellStyleMap.get("yellow"));
@@ -240,16 +206,6 @@ public class ESBParser extends EsbAbstractParser {
         setCellValue("中文名称", row4.createCell(7), font, cellStyleMap.get("yellow"));
         setCellValue("备注", row4.createCell(8), font, cellStyleMap.get("yellow"));
         setCellValue("所在报文位置", row4.createCell(9), font, cellStyleMap.get("yellow"));
-//        } else {
-//            setCellValue("是否必输", row4.createCell(3), font, cellStyleMap.get("yellow"));
-//            setCellValue("备注", row4.createCell(4), font, cellStyleMap.get("yellow"));
-//            setCellValue("", row4.createCell(5), font, cellStyleMap.get("pop"));
-//            setCellValue("英文名称", row4.createCell(6), font, cellStyleMap.get("yellow"));
-//            setCellValue("数据类型/长度", row4.createCell(7), font, cellStyleMap.get("yellow"));
-//            setCellValue("中文名称", row4.createCell(8), font, cellStyleMap.get("yellow"));
-//            setCellValue("备注", row4.createCell(9), font, cellStyleMap.get("yellow"));
-//            setCellValue("所在报文位置", row4.createCell(10), font, cellStyleMap.get("yellow"));
-//        }
 
         XSSFRow row5 = sheet.createRow(4);
         setCellValue("输入", row5.createCell(0), font, cellStyleMap.get("green"));
@@ -262,54 +218,31 @@ public class ESBParser extends EsbAbstractParser {
         setCellValue("", row5.createCell(7), font, cellStyleMap.get("green"));
         setCellValue("", row5.createCell(8), font, cellStyleMap.get("green"));
         setCellValue("", row5.createCell(9), font, cellStyleMap.get("green"));
-//        if (!isHead) {
-//            setCellValue("", row5.createCell(10), font, cellStyleMap.get("green"));
-//        }
 
         XSSFRow row6 = sheet.createRow(5);
         setCellValue("", row6.createCell(0), font, cellStyleMap.get("default"));
         setCellValue("", row6.createCell(1), font, cellStyleMap.get("default"));
         setCellValue("请输入STRING(具体长度) 或 ARRAY", row6.createCell(2), font, cellStyleMap.get("default"));
         setCellValue("", row6.createCell(3), font, cellStyleMap.get("default"));
-//        if (isHead) {
+
         setCellValue("", row6.createCell(4), font, cellStyleMap.get("pop"));
         setCellValue("", row6.createCell(5), font, cellStyleMap.get("default"));
         setCellValue("请输入STRING(具体长度) 或 ARRAY", row6.createCell(6), font, cellStyleMap.get("default"));
         setCellValue("", row6.createCell(7), font, cellStyleMap.get("default"));
         setCellValue("", row6.createCell(8), font, cellStyleMap.get("default"));
         setCellValue("", row6.createCell(9), font, cellStyleMap.get("default"));
-//        } else {
-//            setCellValue("", row6.createCell(4), font, cellStyleMap.get("default"));
-//            setCellValue("", row6.createCell(5), font, cellStyleMap.get("pop"));
-//            setCellValue("", row6.createCell(6), font, cellStyleMap.get("default"));
-//            setCellValue("请输入STRING(具体长度) 或 ARRAY", row6.createCell(7), font, cellStyleMap.get("default"));
-//            setCellValue("", row6.createCell(8), font, cellStyleMap.get("default"));
-//            setCellValue("", row6.createCell(9), font, cellStyleMap.get("default"));
-//            setCellValue("", row6.createCell(10), font, cellStyleMap.get("default"));
-//        }
-
 
         XSSFRow row7 = sheet.createRow(6);
         setCellValue("", row7.createCell(1), font, cellStyleMap.get("default"));
         setCellValue("", row7.createCell(2), font, cellStyleMap.get("default"));
         setCellValue("", row7.createCell(3), font, cellStyleMap.get("default"));
-//        if (isHead) {
+
         setCellValue("", row7.createCell(4), font, cellStyleMap.get("pop"));
         setCellValue("", row7.createCell(5), font, cellStyleMap.get("default"));
         setCellValue("", row7.createCell(6), font, cellStyleMap.get("default"));
         setCellValue("", row7.createCell(7), font, cellStyleMap.get("default"));
         setCellValue("", row7.createCell(8), font, cellStyleMap.get("default"));
         setCellValue("", row7.createCell(9), font, cellStyleMap.get("default"));
-//        } else {
-//            setCellValue("", row7.createCell(4), font, cellStyleMap.get("default"));
-//            setCellValue("", row7.createCell(5), font, cellStyleMap.get("pop"));
-//            setCellValue("", row7.createCell(6), font, cellStyleMap.get("default"));
-//            setCellValue("", row7.createCell(7), font, cellStyleMap.get("default"));
-//            setCellValue("", row7.createCell(8), font, cellStyleMap.get("default"));
-//            setCellValue("", row7.createCell(9), font, cellStyleMap.get("default"));
-//            setCellValue("", row7.createCell(10), font, cellStyleMap.get("default"));
-//        }
-
 
         XSSFRow row8 = sheet.createRow(7);
         setCellValue("输出", row8.createCell(0), font, cellStyleMap.get("green"));
@@ -322,33 +255,19 @@ public class ESBParser extends EsbAbstractParser {
         setCellValue("", row8.createCell(7), font, cellStyleMap.get("green"));
         setCellValue("", row8.createCell(8), font, cellStyleMap.get("green"));
         setCellValue("", row8.createCell(9), font, cellStyleMap.get("green"));
-//        if (!isHead) {
-//            setCellValue("", row8.createCell(10), font, cellStyleMap.get("green"));
-//        }
-
 
         XSSFRow row9 = sheet.createRow(8);
         setCellValue("", row9.createCell(0), font, cellStyleMap.get("default"));
         setCellValue("", row9.createCell(1), font, cellStyleMap.get("default"));
         setCellValue("请输入STRING(具体长度) 或 ARRAY", row9.createCell(2), font, cellStyleMap.get("default"));
         setCellValue("", row9.createCell(3), font, cellStyleMap.get("default"));
-//        if (isHead) {
+
         setCellValue("", row9.createCell(4), font, cellStyleMap.get("pop"));
         setCellValue("", row9.createCell(5), font, cellStyleMap.get("default"));
         setCellValue("请输入STRING(具体长度) 或 ARRAY", row9.createCell(6), font, cellStyleMap.get("default"));
         setCellValue("", row9.createCell(7), font, cellStyleMap.get("default"));
         setCellValue("", row9.createCell(8), font, cellStyleMap.get("default"));
         setCellValue("", row9.createCell(9), font, cellStyleMap.get("default"));
-//        } else {
-//            setCellValue("", row9.createCell(4), font, cellStyleMap.get("default"));
-//            setCellValue("", row9.createCell(5), font, cellStyleMap.get("pop"));
-//            setCellValue("", row9.createCell(6), font, cellStyleMap.get("default"));
-//            setCellValue("请输入STRING(具体长度) 或 ARRAY", row9.createCell(7), font, cellStyleMap.get("default"));
-//            setCellValue("", row9.createCell(7), font, cellStyleMap.get("default"));
-//            setCellValue("", row9.createCell(8), font, cellStyleMap.get("default"));
-//            setCellValue("", row9.createCell(9), font, cellStyleMap.get("default"));
-//            setCellValue("", row9.createCell(10), font, cellStyleMap.get("default"));
-//        }
 
     }
 
@@ -580,7 +499,9 @@ public class ESBParser extends EsbAbstractParser {
         ApiDefinitionImport resultModel = new ApiDefinitionImport();
         List<ApiDefinitionWithBLOBs> apiDataList = new ArrayList<>();
 
+/*
         ApiModule parentNode = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId());
+*/
         EsbSheetDataStruct headSheetData = esbExcelDataStruct.getHeadData();
         List<EsbSheetDataStruct> interfaceDataList = esbExcelDataStruct.getInterfaceList();
         List<String> savedNames = new ArrayList<>();
@@ -603,8 +524,8 @@ public class ESBParser extends EsbAbstractParser {
             apiDefinition.setMethod("ESB");
             apiDefinition.setId(apiId);
             apiDefinition.setProjectId(this.projectId);
-            apiDefinition.setModuleId(importRequest.getModuleId());
-            apiDefinition.setModulePath(importRequest.getModulePath());
+           /* apiDefinition.setModuleId(importRequest.getModuleId());
+            apiDefinition.setModulePath(importRequest.getModulePath());*/
             apiDefinition.setRequest(genTCPSampler(esbSendRequest, reqDataStructStr));
             if (StringUtils.equalsIgnoreCase("schedule", importRequest.getType())) {
                 apiDefinition.setUserId(importRequest.getUserId());
@@ -612,7 +533,7 @@ public class ESBParser extends EsbAbstractParser {
                 apiDefinition.setUserId(SessionUtils.getUserId());
             }
             apiDefinition.setProtocol(RequestType.TCP);
-            buildModule(parentNode, apiDefinition, null);
+            /*  buildModule(parentNode, apiDefinition, null);*/
             apiDataList.add(apiDefinition);
 
             EsbApiParamsWithBLOBs apiParams = new EsbApiParamsWithBLOBs();
diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/HarParser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/HarParser.java
index 74893208bd..d91768c26e 100644
--- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/HarParser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/HarParser.java
@@ -11,7 +11,6 @@ import io.metersphere.api.dto.scenario.Body;
 import io.metersphere.api.dto.scenario.KeyValue;
 import io.metersphere.api.dto.scenario.request.RequestType;
 import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
-import io.metersphere.base.domain.ApiModule;
 import io.metersphere.commons.exception.MSException;
 import io.metersphere.commons.utils.LogUtil;
 import io.metersphere.commons.utils.XMLUtils;
@@ -60,16 +59,6 @@ public class HarParser extends HarAbstractParser {
     private List<ApiDefinitionWithBLOBs> parseRequests(Har har, ApiTestImportRequest importRequest) {
         List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
 
-        ApiModule selectModule = null;
-        String selectModulePath = null;
-        if (StringUtils.isNotBlank(importRequest.getModuleId())) {
-            selectModule = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId());
-            if (selectModule != null) {
-                selectModulePath = ApiDefinitionImportUtil.getSelectModulePath(selectModule.getName(), selectModule.getParentId());
-            }
-        }
-
-
         List<HarEntry> harEntryList = new ArrayList<>();
         if (har.log != null && har.log.entries != null) {
             harEntryList = har.log.entries;
@@ -113,17 +102,6 @@ public class HarParser extends HarAbstractParser {
                 addBodyHeader(request);
                 apiDefinition.setRequest(JSON.toJSONString(request));
                 apiDefinition.setResponse(JSON.toJSONString(parseResponse(entry.response)));
-                if (selectModule == null) {
-                    apiDefinition.setModuleId("default-module");
-
-                } else {
-                    apiDefinition.setModuleId(selectModule.getId());
-                }
-                if (StringUtils.isNotBlank(selectModulePath)) {
-                    apiDefinition.setModulePath(selectModulePath);
-                } else {
-                    apiDefinition.setModulePath("/未规划接口");
-                }
                 results.add(apiDefinition);
             }
         }
diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/JmeterDefinitionParser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/JmeterDefinitionParser.java
index 0e95b07fd0..e3c9eba31a 100644
--- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/JmeterDefinitionParser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/JmeterDefinitionParser.java
@@ -16,8 +16,6 @@ import io.metersphere.api.dto.definition.request.extract.MsExtractRegex;
 import io.metersphere.api.dto.definition.request.extract.MsExtractXPath;
 import io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor;
 import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor;
-import io.metersphere.commons.utils.LogUtil;
-import io.metersphere.plugin.core.MsTestElement;
 import io.metersphere.api.dto.definition.request.sampler.MsDubboSampler;
 import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
 import io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler;
@@ -35,11 +33,16 @@ import io.metersphere.api.dto.scenario.request.BodyFile;
 import io.metersphere.api.dto.scenario.request.RequestType;
 import io.metersphere.api.parse.ApiImportAbstractParser;
 import io.metersphere.api.service.ApiTestEnvironmentService;
-import io.metersphere.base.domain.*;
+import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
+import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
+import io.metersphere.base.domain.ApiTestEnvironmentExample;
+import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
 import io.metersphere.commons.exception.MSException;
 import io.metersphere.commons.utils.BeanUtils;
 import io.metersphere.commons.utils.CommonBeanFactory;
+import io.metersphere.commons.utils.LogUtil;
 import io.metersphere.commons.utils.SessionUtils;
+import io.metersphere.plugin.core.MsTestElement;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.jmeter.assertions.*;
@@ -72,9 +75,7 @@ public class JmeterDefinitionParser extends ApiImportAbstractParser<ApiDefinitio
     private ImportPoolsDTO dataPools;
     private final String ENV_NAME = "导入数据环境";
 
-    private ApiModule selectModule;
-    private ApiModule apiModule;
-    private String selectModulePath;
+
     private String planName = "default";
     private static final Integer GROUP_GLOBAL = 1;
 
@@ -93,12 +94,6 @@ public class JmeterDefinitionParser extends ApiImportAbstractParser<ApiDefinitio
 
             jmeterHashTree(testPlan, scenario);
 
-            this.selectModule = ApiDefinitionImportUtil.getSelectModule(request.getModuleId());
-            if (this.selectModule != null) {
-                this.selectModulePath = ApiDefinitionImportUtil.getSelectModulePath(this.selectModule.getName(), this.selectModule.getParentId());
-            }
-            this.apiModule = ApiDefinitionImportUtil.buildModule(this.selectModule, this.planName, this.projectId);
-
             LinkedList<MsTestElement> elements = scenario.getHashTree();
             LinkedList<MsTestElement> results = new LinkedList<>();
             getAllApiCase(elements, results);
@@ -279,14 +274,8 @@ public class JmeterDefinitionParser extends ApiImportAbstractParser<ApiDefinitio
         apiDefinition.setName(element.getName());
         apiDefinition.setProjectId(this.projectId);
         apiDefinition.setRequest(JSON.toJSONString(element));
-        if (this.apiModule != null) {
-            apiDefinition.setModuleId(this.apiModule.getId());
-            if (StringUtils.isNotBlank(this.selectModulePath)) {
-                apiDefinition.setModulePath(this.selectModulePath + "/" + this.apiModule.getName());
-            } else {
-                apiDefinition.setModulePath("/" + this.apiModule.getName());
-            }
-        }
+       
+        apiDefinition.setModulePath("/" + this.planName);
         // todo 除HTTP协议外,其它协议设置默认模块
         apiDefinition.setStatus("Prepare");
         apiDefinition.setProtocol(protocol);
@@ -638,7 +627,7 @@ public class JmeterDefinitionParser extends ApiImportAbstractParser<ApiDefinitio
             });
         }
         elementNode.setAttachmentArgs(attachmentArgs);
-        if(StringUtils.isEmpty(elementNode.getMethod())){
+        if (StringUtils.isEmpty(elementNode.getMethod())) {
             elementNode.setMethod(elementNode.getProtocol());
         }
     }
diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/MsDefinitionParser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/MsDefinitionParser.java
index a7130c4a15..3896f9bb35 100644
--- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/MsDefinitionParser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/MsDefinitionParser.java
@@ -4,13 +4,11 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.parser.Feature;
 import io.metersphere.api.dto.ApiTestImportRequest;
-import io.metersphere.api.dto.definition.parse.ms.NodeTree;
 import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
 import io.metersphere.api.dto.scenario.request.RequestType;
 import io.metersphere.api.parse.ApiImportAbstractParser;
 import io.metersphere.api.parse.MsAbstractParser;
 import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
-import io.metersphere.base.domain.ApiModule;
 import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
 import io.metersphere.commons.constants.ApiImportPlatform;
 import io.metersphere.commons.utils.CommonBeanFactory;
@@ -21,26 +19,19 @@ import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 
 import java.io.InputStream;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 public class MsDefinitionParser extends MsAbstractParser<ApiDefinitionImport> {
 
-    private ApiModule selectModule;
-
-    private String selectModulePath;
-
     @Override
     public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
         String testStr = getApiTestStr(source);
         JSONObject testObject = JSONObject.parseObject(testStr, Feature.DisableSpecialKeyDetect);
         this.projectId = request.getProjectId();
-        if (StringUtils.isNotBlank(request.getModuleId())) {
-            this.selectModule = ApiDefinitionImportUtil.getSelectModule(request.getModuleId());
-            if (this.selectModule != null) {
-                this.selectModulePath = ApiDefinitionImportUtil.getSelectModulePath(this.selectModule.getName(), this.selectModule.getParentId());
-            }
-        }
 
         if (testObject.get("projectName") != null || testObject.get("projectId") != null) {//  metersphere 格式导入
             return parseMsFormat(testStr, request);
@@ -56,14 +47,10 @@ public class MsDefinitionParser extends MsAbstractParser<ApiDefinitionImport> {
     protected List<ApiDefinitionWithBLOBs> parsePluginFormat(JSONObject testObject, ApiTestImportRequest importRequest, Boolean isCreateModule) {
         List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
         testObject.keySet().forEach(tag -> {
-            String moduleId = null;
-            if (isCreateModule) {
-                moduleId = ApiDefinitionImportUtil.buildModule(this.selectModule, tag, this.projectId).getId();
-            }
+
             List<MsHTTPSamplerProxy> msHTTPSamplerProxies = parseMsHTTPSamplerProxy(testObject, tag, false);
             for (MsHTTPSamplerProxy msHTTPSamplerProxy : msHTTPSamplerProxies) {
                 ApiDefinitionWithBLOBs apiDefinition = buildApiDefinition(msHTTPSamplerProxy.getId(), msHTTPSamplerProxy.getName(), msHTTPSamplerProxy.getPath(), msHTTPSamplerProxy.getMethod(), importRequest);
-                apiDefinition.setModuleId(moduleId);
                 apiDefinition.setProjectId(this.projectId);
                 apiDefinition.setRequest(JSONObject.toJSONString(msHTTPSamplerProxy));
                 apiDefinition.setName(apiDefinition.getPath() + " [" + apiDefinition.getMethod() + "]");
@@ -90,20 +77,8 @@ public class MsDefinitionParser extends MsAbstractParser<ApiDefinitionImport> {
             });
         }
 
-        Set<String> moduleIdSet = apiDefinitionImport.getData().stream()
-                .map(ApiDefinitionWithBLOBs::getModuleId).collect(Collectors.toSet());
-
-        Map<String, NodeTree> nodeMap = null;
-        List<NodeTree> nodeTree = apiDefinitionImport.getNodeTree();
-        if (CollectionUtils.isNotEmpty(nodeTree)) {
-            cutDownTree(nodeTree, moduleIdSet);
-            ApiDefinitionImportUtil.createNodeTree(nodeTree, projectId, importRequest.getModuleId());
-            nodeMap = getNodeMap(nodeTree);
-        }
-
-        Map<String, NodeTree> finalNodeMap = nodeMap;
         apiDefinitionImport.getData().forEach(apiDefinition -> {
-            parseApiDefinition(apiDefinition, importRequest, caseMap, finalNodeMap);
+            parseApiDefinition(apiDefinition, importRequest, caseMap);
         });
         if (MapUtils.isNotEmpty(caseMap)) {
             List<ApiTestCaseWithBLOBs> list = new ArrayList<>();
@@ -116,19 +91,8 @@ public class MsDefinitionParser extends MsAbstractParser<ApiDefinitionImport> {
     }
 
     private void parseApiDefinition(ApiDefinitionWithBLOBs apiDefinition, ApiTestImportRequest importRequest,
-                                    Map<String, List<ApiTestCaseWithBLOBs>> caseMap, Map<String, NodeTree> nodeMap) {
+                                    Map<String, List<ApiTestCaseWithBLOBs>> caseMap) {
         String originId = apiDefinition.getId();
-        if (nodeMap != null && nodeMap.get(apiDefinition.getModuleId()) != null) {
-            NodeTree nodeTree = nodeMap.get(apiDefinition.getModuleId());
-            apiDefinition.setModuleId(nodeTree.getNewId());
-            apiDefinition.setModulePath(nodeTree.getPath());
-        } else {
-            if (StringUtils.isBlank(apiDefinition.getModulePath())) {
-                apiDefinition.setModuleId(null);
-            }
-            // 旧版本未导出模块
-            parseModule(apiDefinition.getModulePath(), importRequest, apiDefinition);
-        }
 
         apiDefinition.setProjectId(this.projectId);
         JSONObject requestObj = this.parseObject(apiDefinition.getRequest(), apiDefinition.getProjectId());
@@ -190,32 +154,5 @@ public class MsDefinitionParser extends MsAbstractParser<ApiDefinitionImport> {
             return null;
         }
     }
-
-    private void parseModule(String modulePath, ApiTestImportRequest importRequest, ApiDefinitionWithBLOBs apiDefinition) {
-        if (StringUtils.isEmpty(modulePath)) {
-            return;
-        }
-        if (modulePath.startsWith("/")) {
-            modulePath = modulePath.substring(1, modulePath.length());
-        }
-        if (modulePath.endsWith("/")) {
-            modulePath = modulePath.substring(0, modulePath.length() - 1);
-        }
-        List<String> modules = Arrays.asList(modulePath.split("/"));
-        ApiModule parent = this.selectModule;
-        Iterator<String> iterator = modules.iterator();
-        while (iterator.hasNext()) {
-            String item = iterator.next();
-            parent = ApiDefinitionImportUtil.buildModule(parent, item, this.projectId, importRequest.getUserId());
-            if (!iterator.hasNext()) {
-                apiDefinition.setModuleId(parent.getId());
-                String path = apiDefinition.getModulePath() == null ? "" : apiDefinition.getModulePath();
-                if (StringUtils.isNotBlank(this.selectModulePath)) {
-                    apiDefinition.setModulePath(this.selectModulePath + path);
-                } else if (StringUtils.isBlank(importRequest.getModuleId())) {
-                    apiDefinition.setModulePath("/未规划接口" + path);
-                }
-            }
-        }
-    }
+    
 }
diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/PostmanDefinitionParser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/PostmanDefinitionParser.java
index 7ed3c8ec2e..e617b05360 100644
--- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/PostmanDefinitionParser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/PostmanDefinitionParser.java
@@ -10,7 +10,6 @@ import io.metersphere.api.dto.parse.postman.PostmanItem;
 import io.metersphere.api.dto.parse.postman.PostmanKeyValue;
 import io.metersphere.api.parse.PostmanAbstractParserParser;
 import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
-import io.metersphere.base.domain.ApiModule;
 import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
 import io.metersphere.base.domain.Project;
 import io.metersphere.base.mapper.ProjectMapper;
@@ -26,10 +25,6 @@ import java.util.*;
 
 public class PostmanDefinitionParser extends PostmanAbstractParserParser<ApiDefinitionImport> {
 
-    private ApiModule selectModule;
-
-    private String selectModulePath;
-
     @Override
     public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
         String testStr = getApiTestStr(source);
@@ -38,12 +33,11 @@ public class PostmanDefinitionParser extends PostmanAbstractParserParser<ApiDefi
         List<PostmanKeyValue> variables = postmanCollection.getVariable();
         ApiDefinitionImport apiImport = new ApiDefinitionImport();
         List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
-        this.selectModule = ApiDefinitionImportUtil.getSelectModule(request.getModuleId());
-        if (this.selectModule != null) {
-            this.selectModulePath = ApiDefinitionImportUtil.getSelectModulePath(this.selectModule.getName(), this.selectModule.getParentId());
-        }
 
-        ApiModule apiModule = ApiDefinitionImportUtil.buildModule(this.selectModule, postmanCollection.getInfo().getName(), this.projectId);
+        String modulePath = null;
+        if (StringUtils.isNotBlank(postmanCollection.getInfo().getName())) {
+            modulePath = "/" + postmanCollection.getInfo().getName();
+        }
         List<ApiTestCaseWithBLOBs> cases = new ArrayList<>();
         Map<String, String> repeatMap = new HashMap();
         ProjectMapper projectMapper = CommonBeanFactory.getBean(ProjectMapper.class);
@@ -51,8 +45,8 @@ public class PostmanDefinitionParser extends PostmanAbstractParserParser<ApiDefi
         ProjectApplicationService projectApplicationService = CommonBeanFactory.getBean(ProjectApplicationService.class);
         ProjectConfig config = projectApplicationService.getSpecificTypeValue(project.getId(), ProjectApplicationType.URL_REPEATABLE.name());
         boolean urlRepeat = config.getUrlRepeatable();
-        parseItem(postmanCollection.getItem(), variables, results,
-                apiModule, apiModule.getName(), cases, repeatMap, urlRepeat);
+        parseItem(postmanCollection.getItem(), modulePath, variables, results,
+                cases, repeatMap, urlRepeat);
         Collections.reverse(results); // 调整顺序
         Collections.reverse(cases);
         apiImport.setData(results);
@@ -60,14 +54,16 @@ public class PostmanDefinitionParser extends PostmanAbstractParserParser<ApiDefi
         return apiImport;
     }
 
-    protected void parseItem(List<PostmanItem> items, List<PostmanKeyValue> variables, List<ApiDefinitionWithBLOBs> results,
-                             ApiModule parentModule, String path, List<ApiTestCaseWithBLOBs> cases, Map<String, String> repeatMap, Boolean repeatable) {
+    protected void parseItem(List<PostmanItem> items, String modulePath, List<PostmanKeyValue> variables, List<ApiDefinitionWithBLOBs> results,
+                             List<ApiTestCaseWithBLOBs> cases, Map<String, String> repeatMap, Boolean repeatable) {
         for (PostmanItem item : items) {
             List<PostmanItem> childItems = item.getItem();
             if (childItems != null) {
-                ApiModule module = null;
-                module = ApiDefinitionImportUtil.buildModule(parentModule, item.getName(), this.projectId);
-                parseItem(childItems, variables, results, module, path + "/" + module.getName(), cases, repeatMap, repeatable);
+
+                if (StringUtils.isNotBlank(modulePath) && StringUtils.isNotBlank(item.getName())) {
+                    modulePath = modulePath + "/" + item.getName();
+                }
+                parseItem(childItems, modulePath, variables, results, cases, repeatMap, repeatable);
             } else {
                 MsHTTPSamplerProxy msHTTPSamplerProxy = parsePostman(item);
                 HttpResponse response = parsePostmanResponse(item);
@@ -76,13 +72,9 @@ public class PostmanDefinitionParser extends PostmanAbstractParserParser<ApiDefi
                 request.setPath(msHTTPSamplerProxy.getPath());
                 request.setRequest(JSON.toJSONString(msHTTPSamplerProxy));
                 request.setResponse(JSON.toJSONString(response));
-                if (parentModule != null) {
-                    request.setModuleId(parentModule.getId());
-                    if (StringUtils.isNotBlank(this.selectModulePath)) {
-                        request.setModulePath(this.selectModulePath + "/" + path);
-                    } else {
-                        request.setModulePath("/" + path);
-                    }
+              
+                if (StringUtils.isNotBlank(modulePath)) {
+                    request.setModulePath(modulePath);
                 }
                 if (request != null) {
                     if (repeatMap.keySet().contains(request.getMethod() + request.getPath())
diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java
index 442ebd97be..af08d272f0 100644
--- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java
@@ -11,7 +11,6 @@ import io.metersphere.api.dto.scenario.Body;
 import io.metersphere.api.dto.scenario.KeyValue;
 import io.metersphere.api.dto.scenario.request.RequestType;
 import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
-import io.metersphere.base.domain.ApiModule;
 import io.metersphere.commons.constants.SwaggerParameterType;
 import io.metersphere.commons.exception.MSException;
 import io.metersphere.utils.LoggerUtil;
@@ -115,15 +114,6 @@ public class Swagger2Parser extends SwaggerAbstractParser {
 
         List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
 
-        ApiModule selectModule = null;
-        String selectModulePath = null;
-        if (StringUtils.isNotBlank(importRequest.getModuleId())) {
-            selectModule = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId());
-            if (selectModule != null) {
-                selectModulePath = ApiDefinitionImportUtil.getSelectModulePath(selectModule.getName(), selectModule.getParentId());
-            }
-        }
-
         String basePath = swagger.getBasePath();
         for (String pathName : pathNames) {
             Path path = paths.get(pathName);
@@ -142,7 +132,8 @@ public class Swagger2Parser extends SwaggerAbstractParser {
                 }
                 apiDefinition.setRequest(JSON.toJSONString(request));
                 apiDefinition.setResponse(JSON.toJSONString(parseResponse(operation, operation.getResponses())));
-                buildModule(selectModule, apiDefinition, operation.getTags(), selectModulePath);
+                
+                buildModulePath(apiDefinition, operation.getTags());
                 if (operation.isDeprecated() != null && operation.isDeprecated()) {
                     apiDefinition.setTags("[\"Deleted\"]");
                 }
@@ -154,6 +145,28 @@ public class Swagger2Parser extends SwaggerAbstractParser {
         return results;
     }
 
+    private void buildModulePath(ApiDefinitionWithBLOBs apiDefinition, List<String> tags) {
+        StringBuilder modulePathBuilder = new StringBuilder();
+        String modulePath = getModulePath(tags, modulePathBuilder);
+        apiDefinition.setModulePath(modulePath);
+    }
+
+    private String getModulePath(List<String> tagTree, StringBuilder modulePath) {
+        for (String s : tagTree) {
+            if (s.contains("/")) {
+                String[] split = s.split("/");
+                if (split.length > 0) {
+                    getModulePath(List.of(split), modulePath);
+                }
+            } else {
+                if (StringUtils.isNotBlank(s)) {
+                    modulePath.append("/").append(s);
+                }
+            }
+        }
+        return modulePath.toString();
+    }
+
     private ApiDefinitionWithBLOBs buildApiDefinition(String id, Operation operation, String path, String method, ApiTestImportRequest importRequest) {
         String name = "";
         if (StringUtils.isNotBlank(operation.getSummary())) {
diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger3Parser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger3Parser.java
index f015ad47e8..3fb887a057 100644
--- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger3Parser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger3Parser.java
@@ -5,7 +5,6 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.parser.Feature;
 import io.metersphere.api.dto.ApiTestImportRequest;
-import io.metersphere.api.dto.definition.ApiModuleDTO;
 import io.metersphere.api.dto.definition.SwaggerApiExportResult;
 import io.metersphere.api.dto.definition.parse.swagger.SwaggerApiInfo;
 import io.metersphere.api.dto.definition.parse.swagger.SwaggerInfo;
@@ -16,11 +15,8 @@ import io.metersphere.api.dto.definition.response.HttpResponse;
 import io.metersphere.api.dto.scenario.Body;
 import io.metersphere.api.dto.scenario.KeyValue;
 import io.metersphere.api.dto.scenario.request.RequestType;
-import io.metersphere.api.service.ApiModuleService;
 import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
-import io.metersphere.base.domain.ApiModule;
 import io.metersphere.commons.exception.MSException;
-import io.metersphere.commons.utils.CommonBeanFactory;
 import io.metersphere.commons.utils.LogUtil;
 import io.metersphere.commons.utils.XMLUtils;
 import io.swagger.parser.OpenAPIParser;
@@ -131,15 +127,6 @@ public class Swagger3Parser extends SwaggerAbstractParser {
 
         List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
 
-        ApiModule selectModule = null;
-        String selectModulePath = null;
-        if (StringUtils.isNotBlank(importRequest.getModuleId())) {
-            selectModule = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId());
-            if (selectModule != null) {
-                selectModulePath = ApiDefinitionImportUtil.getSelectModulePath(selectModule.getName(), selectModule.getParentId());
-            }
-        }
-
         for (String pathName : pathNames) {
             PathItem pathItem = paths.get(pathName);
 
@@ -167,7 +154,7 @@ public class Swagger3Parser extends SwaggerAbstractParser {
                     }   //  有数据的话,去掉 Kvs 里初始化的第一个全 null 的数据,否则有空行
                     apiDefinition.setRequest(JSON.toJSONString(request));
                     apiDefinition.setResponse(JSON.toJSONString(parseResponse(operation.getResponses())));
-                    buildModule(selectModule, apiDefinition, operation.getTags(), selectModulePath);
+                    buildModulePath(apiDefinition, operation.getTags());
                     if (operation.getDeprecated() != null && operation.getDeprecated()) {
                         apiDefinition.setTags("[\"Deleted\"]");
                     }
@@ -179,6 +166,12 @@ public class Swagger3Parser extends SwaggerAbstractParser {
         return results;
     }
 
+    private void buildModulePath(ApiDefinitionWithBLOBs apiDefinition, List<String> tags) {
+        StringBuilder modulePathBuilder = new StringBuilder();
+        String modulePath = getModulePath(tags, modulePathBuilder);
+        apiDefinition.setModulePath(modulePath);
+    }
+
     private ApiDefinitionWithBLOBs buildApiDefinition(String id, Operation operation, String path, String method, ApiTestImportRequest importRequest) {
         String name;
         if (StringUtils.isNotBlank(operation.getSummary())) {
@@ -588,15 +581,20 @@ public class Swagger3Parser extends SwaggerAbstractParser {
             SwaggerApiInfo swaggerApiInfo = new SwaggerApiInfo();   //  {tags:, summary:, description:, parameters:}
             swaggerApiInfo.setSummary(apiDefinition.getName());
             //  设置导入后的模块名 (根据 api 的 moduleID 查库获得所属模块,作为导出的模块名)
-            ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
-            String moduleName = "";
-            if (apiDefinition.getModuleId() != null) {   //  module_id 可能为空
-                ApiModuleDTO node = apiModuleService.getNode(apiDefinition.getModuleId());
-                if (node != null) {
-                    moduleName = node.getName();
+            //直接导出完整路径
+            if (apiDefinition.getModulePath() != null) {
+                String[] split = new String[0];
+                String modulePath = apiDefinition.getModulePath();
+                String substring = modulePath.substring(0, 1);
+                if (substring.equals("/")) {
+                    modulePath = modulePath.substring(1);
                 }
+                if (modulePath.contains("/")) {
+                    split = modulePath.split("/");
+                }
+                swaggerApiInfo.setTags(Arrays.asList(split));
             }
-            swaggerApiInfo.setTags(Arrays.asList(moduleName));
+
             //  设置请求体
             JSONObject requestObject = JSON.parseObject(apiDefinition.getRequest(), Feature.DisableSpecialKeyDetect);    //  将api的request属性转换成JSON对象以便获得参数
             JSONObject requestBody = buildRequestBody(requestObject);
@@ -990,4 +988,21 @@ public class Swagger3Parser extends SwaggerAbstractParser {
         }
         return content;
     }
+
+    private String getModulePath(List<String> tagTree, StringBuilder modulePath) {
+        for (String s : tagTree) {
+            if (s.contains("/")) {
+                String[] split = s.split("/");
+                if (split.length > 0) {
+                    getModulePath(List.of(split), modulePath);
+                }
+            } else {
+                if (StringUtils.isNotBlank(s)) {
+                    modulePath.append("/").append(s);
+                }
+            }
+        }
+        return modulePath.toString();
+    }
+
 }
diff --git a/backend/src/main/java/io/metersphere/api/parse/ApiImportAbstractParser.java b/backend/src/main/java/io/metersphere/api/parse/ApiImportAbstractParser.java
index 3ac7f6cf4f..957303a401 100644
--- a/backend/src/main/java/io/metersphere/api/parse/ApiImportAbstractParser.java
+++ b/backend/src/main/java/io/metersphere/api/parse/ApiImportAbstractParser.java
@@ -161,6 +161,7 @@ public abstract class ApiImportAbstractParser<T> implements ApiImportParser<T> {
         request.setHeaders(new ArrayList<>());
         request.setArguments(new ArrayList<>());
         request.setRest(new ArrayList<>());
+        request.setFollowRedirects(true);
         Body body = new Body();
         body.initKvs();
         body.initBinary();
diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
index c6e33cb2e1..7557e01167 100644
--- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
+++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.parser.Feature;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import io.metersphere.api.dto.*;
 import io.metersphere.api.dto.automation.*;
 import io.metersphere.api.dto.automation.parse.ApiScenarioImportUtil;
@@ -75,6 +77,8 @@ import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.stream.Collectors;
 
+import static java.util.stream.Collectors.toList;
+
 @Service
 @Transactional(rollbackFor = Exception.class)
 public class ApiAutomationService {
@@ -1216,7 +1220,7 @@ public class ApiAutomationService {
     }
 
     private ApiScenarioWithBLOBs importCreate(ApiScenarioWithBLOBs request, ApiScenarioMapper batchMapper, ExtApiScenarioMapper extApiScenarioMapper,
-                                              ApiTestImportRequest apiTestImportRequest, ApiTestCaseMapper apiTestCaseMapper, ApiDefinitionMapper apiDefinitionMapper) {
+                                              ApiTestImportRequest apiTestImportRequest, List<ApiScenarioWithBLOBs> sameList, ApiTestCaseMapper apiTestCaseMapper, ApiDefinitionMapper apiDefinitionMapper) {
         final ApiScenarioWithBLOBs scenarioWithBLOBs = new ApiScenarioWithBLOBs();
         BeanUtils.copyBean(scenarioWithBLOBs, request);
         scenarioWithBLOBs.setCreateTime(System.currentTimeMillis());
@@ -1235,14 +1239,12 @@ public class ApiAutomationService {
         }
         scenarioWithBLOBs.setDescription(request.getDescription());
 
-        List<ApiScenarioWithBLOBs> sameRequest = getSameScenario(scenarioWithBLOBs);
-
         Boolean openCustomNum = apiTestImportRequest.getOpenCustomNum();
         List<ApiScenario> list = new ArrayList<>();
         if (BooleanUtils.isTrue(openCustomNum)) {
             ApiScenarioExample example = new ApiScenarioExample();
             ApiScenarioExample.Criteria criteria = example.createCriteria();
-            if (CollectionUtils.isEmpty(sameRequest)) {
+            if (CollectionUtils.isEmpty(sameList)) {
                 criteria.andCustomNumEqualTo(scenarioWithBLOBs.getCustomNum())
                         .andProjectIdEqualTo(scenarioWithBLOBs.getProjectId());
             } else {
@@ -1250,7 +1252,7 @@ public class ApiAutomationService {
                     criteria.andNameEqualTo(scenarioWithBLOBs.getName())
                             .andCustomNumEqualTo(scenarioWithBLOBs.getCustomNum())
                             .andProjectIdEqualTo(scenarioWithBLOBs.getProjectId())
-                            .andIdNotEqualTo(sameRequest.get(0).getId());
+                            .andIdNotEqualTo(sameList.get(0).getId());
                 }
 
             }
@@ -1265,9 +1267,9 @@ public class ApiAutomationService {
         }
 
         if (StringUtils.equals("fullCoverage", apiTestImportRequest.getModeId())) {
-            _importCreate(sameRequest, batchMapper, extApiScenarioMapper, scenarioWithBLOBs, apiTestImportRequest, apiTestCaseMapper, apiDefinitionMapper);
+            _importCreate(sameList, batchMapper, extApiScenarioMapper, scenarioWithBLOBs, apiTestImportRequest, apiTestCaseMapper, apiDefinitionMapper);
         } else if (StringUtils.equals("incrementalMerge", apiTestImportRequest.getModeId())) {
-            if (CollectionUtils.isEmpty(sameRequest)) {
+            if (CollectionUtils.isEmpty(sameList)) {
                 scenarioWithBLOBs.setOrder(getImportNextOrder(request.getProjectId()));
                 scenarioWithBLOBs.setId(UUID.randomUUID().toString());
                 scenarioWithBLOBs.setRefId(scenarioWithBLOBs.getId());
@@ -1288,21 +1290,36 @@ public class ApiAutomationService {
             }
 
         } else {
-            _importCreate(sameRequest, batchMapper, extApiScenarioMapper, scenarioWithBLOBs, apiTestImportRequest, apiTestCaseMapper, apiDefinitionMapper);
+            _importCreate(sameList, batchMapper, extApiScenarioMapper, scenarioWithBLOBs, apiTestImportRequest, apiTestCaseMapper, apiDefinitionMapper);
         }
         return scenarioWithBLOBs;
     }
 
     private void editScenario(ApiTestImportRequest request, ScenarioImport apiImport) {
+        ApiScenarioModuleService apiScenarioModuleService = CommonBeanFactory.getBean(ApiScenarioModuleService.class);
+
         SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
         ApiScenarioMapper batchMapper = sqlSession.getMapper(ApiScenarioMapper.class);
         ExtApiScenarioMapper extApiScenarioMapper = sqlSession.getMapper(ExtApiScenarioMapper.class);
         ApiTestCaseMapper apiTestCaseMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
         ApiDefinitionMapper apiDefinitionMapper = sqlSession.getMapper(ApiDefinitionMapper.class);
-        List<ApiScenarioWithBLOBs> data = apiImport.getData();
+        ApiScenarioModuleMapper apiScenarioModuleMapper = sqlSession.getMapper(ApiScenarioModuleMapper.class);
+
+        List<ApiScenarioWithBLOBs> initData = apiImport.getData();
         currentScenarioOrder.remove();
+
+        UpdateScenarioModuleDTO updateScenarioModuleDTO = apiScenarioModuleService.checkScenarioModule(request, initData, StringUtils.equals("fullCoverage", request.getModeId()), request.getCoverModule());
+        List<ApiScenarioModule> moduleList = updateScenarioModuleDTO.getModuleList();
+        List<ApiScenarioWithBLOBs> data = updateScenarioModuleDTO.getApiScenarioWithBLOBsList();
+        List<ApiScenarioWithBLOBs> needUpdateList = updateScenarioModuleDTO.getNeedUpdateList();
+
+        if (moduleList != null) {
+            for (ApiScenarioModule apiScenarioModule : moduleList) {
+                apiScenarioModuleMapper.insert(apiScenarioModule);
+            }
+        }
         int num = 0;
-        Project project = new Project();
+        Project project;
         if (!CollectionUtils.isEmpty(data) && data.get(0) != null && data.get(0).getProjectId() != null) {
             project = projectMapper.selectByPrimaryKey(data.get(0).getProjectId());
             ProjectConfig config = projectApplicationService.getSpecificTypeValue(project.getId(), ProjectApplicationType.SCENARIO_CUSTOM_NUM.name());
@@ -1312,11 +1329,9 @@ public class ApiAutomationService {
         String defaultVersion = extProjectVersionMapper.getDefaultVersion(request.getProjectId());
         request.setDefaultVersion(defaultVersion);
         for (int i = 0; i < data.size(); i++) {
-            ApiScenarioWithBLOBs item = data.get(i);
-            if (StringUtils.isBlank(item.getApiScenarioModuleId()) || "default-module".equals(item.getApiScenarioModuleId())) {
-                replenishScenarioModuleIdPath(request.getProjectId(), apiScenarioModuleMapper, item);
-            }
 
+            ApiScenarioWithBLOBs item = data.get(i);
+            List<ApiScenarioWithBLOBs> sameList = needUpdateList.stream().filter(t -> t.getId().equals(item.getId())).collect(toList());
             if (StringUtils.isBlank(item.getCreateUser())) {
                 item.setCreateUser(SessionUtils.getUserId());
             }
@@ -1340,11 +1355,12 @@ public class ApiAutomationService {
             item.setUserId(SessionUtils.getUserId());
             item.setPrincipal(SessionUtils.getUserId());
             // 导入之后刷新latest
-            importCreate(item, batchMapper, extApiScenarioMapper, request, apiTestCaseMapper, apiDefinitionMapper);
+            importCreate(item, batchMapper, extApiScenarioMapper, request, sameList, apiTestCaseMapper, apiDefinitionMapper);
             if (i % 300 == 0) {
                 sqlSession.flushStatements();
             }
         }
+
         sqlSession.flushStatements();
         if (sqlSession != null && sqlSessionFactory != null) {
             SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
@@ -2111,4 +2127,39 @@ public class ApiAutomationService {
         }
         return returnMap;
     }
+
+    public Boolean checkIsSynchronize(ApiScenarioWithBLOBs existApiScenario, ApiScenarioWithBLOBs apiScenario) {
+
+        ApiScenario exScenario;
+        ApiScenario scenario;
+        exScenario = existApiScenario;
+        scenario = apiScenario;
+        ObjectMapper objectMapper = new ObjectMapper();
+        String exScenarioString = null;
+        String scenarioString = null;
+        try {
+            exScenarioString = objectMapper.writeValueAsString(exScenario);
+            scenarioString = objectMapper.writeValueAsString(scenario);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+
+        //Compare the basic information of the APIScenario. 
+
+        if (!StringUtils.equals(exScenario.getName(), scenario.getName())) {
+            return true;
+        }
+        if (!StringUtils.equals(exScenarioString, scenarioString)) {
+            return true;
+        }
+        if (!StringUtils.equals(existApiScenario.getEnvironmentJson(), apiScenario.getEnvironmentJson())) {
+            return true;
+        }
+
+        if (!StringUtils.equals(existApiScenario.getDescription(), apiScenario.getDescription())) {
+            return true;
+        }
+
+        return !StringUtils.equals(existApiScenario.getScenarioDefinition(), apiScenario.getScenarioDefinition());
+    }
 }
diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java
index 558f75965e..ea306a2261 100644
--- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java
+++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java
@@ -3,6 +3,9 @@ package io.metersphere.api.service;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.parser.Feature;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.github.pagehelper.Page;
 import com.github.pagehelper.PageHelper;
 import io.metersphere.api.dto.APIReportResult;
@@ -544,51 +547,6 @@ public class ApiDefinitionService {
         }
     }
 
-    private List<ApiDefinition> getSameRequest(SaveApiDefinitionRequest request) {
-        ApiDefinitionExample example = new ApiDefinitionExample();
-        if (request.getProtocol().equals(RequestType.HTTP)) {
-            example.createCriteria().andMethodEqualTo(request.getMethod()).andStatusNotEqualTo("Trash")
-                    .andPathEqualTo(request.getPath())
-                    .andProjectIdEqualTo(request.getProjectId()).andIdNotEqualTo(request.getId());
-            return apiDefinitionMapper.selectByExample(example);
-        } else {
-            example.createCriteria().andProtocolEqualTo(request.getProtocol()).andStatusNotEqualTo("Trash")
-                    .andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId())
-                    .andIdNotEqualTo(request.getId());
-            return apiDefinitionMapper.selectByExample(example);
-        }
-    }
-
-    private List<ApiDefinition> getSameRequestById(String id, String projectId) {
-        ApiDefinitionExample example = new ApiDefinitionExample();
-        example.createCriteria().andStatusNotEqualTo("Trash")
-                .andProjectIdEqualTo(projectId)
-                .andIdEqualTo(id);
-        return apiDefinitionMapper.selectByExample(example);
-    }
-
-    private List<ApiDefinition> getSameRequestWithName(SaveApiDefinitionRequest request) {
-        ApiDefinitionExample example = new ApiDefinitionExample();
-        if (request.getProtocol().equals(RequestType.HTTP)) {
-            example.createCriteria()
-                    .andMethodEqualTo(request.getMethod())
-                    .andStatusNotEqualTo("Trash")
-                    .andPathEqualTo(request.getPath())
-                    .andNameEqualTo(request.getName())
-                    .andProjectIdEqualTo(request.getProjectId())
-                    .andIdNotEqualTo(request.getId());
-        } else {
-            example.createCriteria()
-                    .andStatusNotEqualTo("Trash")
-                    .andNameEqualTo(request.getName())
-                    .andProjectIdEqualTo(request.getProjectId())
-                    .andIdNotEqualTo(request.getId());
-        }
-
-        return apiDefinitionMapper.selectByExample(example);
-
-    }
-
     private ApiDefinitionWithBLOBs updateTest(SaveApiDefinitionRequest request) {
         checkNameExist(request);
         if (StringUtils.equals(request.getMethod(), "ESB")) {
@@ -787,10 +745,10 @@ public class ApiDefinitionService {
         }
     }
 
-    private ApiDefinition importCreate(ApiDefinitionWithBLOBs apiDefinition, ApiDefinitionMapper batchMapper,
-                                       ApiTestCaseMapper apiTestCaseMapper, ExtApiDefinitionMapper extApiDefinitionMapper,
+    private ApiDefinition importCreate(ApiDefinitionWithBLOBs apiDefinition, ApiDefinitionMapper batchMapper, ApiTestCaseMapper apiTestCaseMapper,
+                                       ExtApiDefinitionMapper extApiDefinitionMapper,
                                        ApiTestImportRequest apiTestImportRequest, List<ApiTestCaseWithBLOBs> cases, List<MockConfigImportDTO> mocks,
-                                       Boolean repeatable) {
+                                       List<ApiDefinitionWithBLOBs> updateList) {
         SaveApiDefinitionRequest saveReq = new SaveApiDefinitionRequest();
         BeanUtils.copyBean(saveReq, apiDefinition);
         apiDefinition.setCreateTime(System.currentTimeMillis());
@@ -803,27 +761,13 @@ public class ApiDefinitionService {
         } else {
             apiDefinition.setUserId(apiDefinition.getUserId());
         }
-        if (apiDefinition.getModuleId() == null) {
-            if (StringUtils.isEmpty(apiDefinition.getModuleId()) || "default-module".equals(apiDefinition.getModuleId())) {
-                initModulePathAndId(apiDefinition.getProjectId(), apiDefinition);
-            }
-        }
         apiDefinition.setDescription(apiDefinition.getDescription());
+        List<ApiDefinitionWithBLOBs> collect = updateList.stream().filter(t -> t.getId().equals(apiDefinition.getId())).collect(Collectors.toList());
 
-        List<ApiDefinition> sameRequest;
-        if (repeatable == null || !repeatable) {
-            sameRequest = getSameRequest(saveReq);
-        } else {
-            // 如果勾选了允许重复,则判断更新要加上name字段
-            sameRequest = getSameRequestWithName(saveReq);
-        }
-        if (CollectionUtils.isEmpty(sameRequest)) {
-            sameRequest = getSameRequestById(apiDefinition.getId(), apiTestImportRequest.getProjectId());
-        }
         if (StringUtils.equals("fullCoverage", apiTestImportRequest.getModeId())) {
-            _importCreate(sameRequest, batchMapper, apiDefinition, apiTestCaseMapper, extApiDefinitionMapper, apiTestImportRequest, cases, mocks);
+            _importCreate(collect, batchMapper, apiTestCaseMapper, apiDefinition, extApiDefinitionMapper, apiTestImportRequest, cases, mocks);
         } else if (StringUtils.equals("incrementalMerge", apiTestImportRequest.getModeId())) {
-            if (CollectionUtils.isEmpty(sameRequest)) {
+            if (CollectionUtils.isEmpty(collect)) {
                 //postman 可能含有前置脚本,接口定义去掉脚本
                 apiDefinition.setOrder(getImportNextOrder(apiTestImportRequest.getProjectId()));
                 String originId = apiDefinition.getId();
@@ -845,13 +789,13 @@ public class ApiDefinitionService {
                 reSetImportCasesApiId(cases, originId, apiDefinition.getId());
                 reSetImportMocksApiId(mocks, originId, apiDefinition.getId(), apiDefinition.getNum());
                 apiDefinition.setRequest(requestStr);
-                importApiCase(apiDefinition, apiTestImportRequest);
+                importApiCase(apiDefinition, apiTestImportRequest, apiTestCaseMapper);
             } else {
                 //不覆盖的接口,如果没有sameRequest则不导入。此时清空mock信息
                 mocks.clear();
             }
         } else {
-            _importCreate(sameRequest, batchMapper, apiDefinition, apiTestCaseMapper, extApiDefinitionMapper, apiTestImportRequest, cases, mocks);
+            _importCreate(collect, batchMapper, apiTestCaseMapper, apiDefinition, extApiDefinitionMapper, apiTestImportRequest, cases, mocks);
         }
 
         return apiDefinition;
@@ -877,8 +821,8 @@ public class ApiDefinitionService {
         return order;
     }
 
-    private void _importCreate(List<ApiDefinition> sameRequest, ApiDefinitionMapper batchMapper, ApiDefinitionWithBLOBs apiDefinition,
-                               ApiTestCaseMapper apiTestCaseMapper, ExtApiDefinitionMapper extApiDefinitionMapper,
+    private void _importCreate(List<ApiDefinitionWithBLOBs> sameRequest, ApiDefinitionMapper batchMapper, ApiTestCaseMapper apiTestCaseMapper, ApiDefinitionWithBLOBs apiDefinition,
+                               ExtApiDefinitionMapper extApiDefinitionMapper,
                                ApiTestImportRequest apiTestImportRequest, List<ApiTestCaseWithBLOBs> cases, List<MockConfigImportDTO> mocks) {
         String originId = apiDefinition.getId();
 
@@ -902,7 +846,7 @@ public class ApiDefinitionService {
                 batchMapper.insert(apiDefinition);
                 String request = setImportHashTree(apiDefinition);
                 apiDefinition.setRequest(request);
-                importApiCase(apiDefinition, apiTestImportRequest);
+                importApiCase(apiDefinition, apiTestImportRequest, apiTestCaseMapper);
             } else {
                 if (StringUtils.equalsAnyIgnoreCase(apiDefinition.getProtocol(), RequestType.TCP)) {
                     setImportTCPHashTree(apiDefinition);
@@ -914,13 +858,17 @@ public class ApiDefinitionService {
             if (StringUtils.isEmpty(apiTestImportRequest.getUpdateVersionId())) {
                 apiTestImportRequest.setUpdateVersionId(apiTestImportRequest.getDefaultVersion());
             }
-            Optional<ApiDefinition> apiOp = sameRequest.stream()
+            Optional<ApiDefinitionWithBLOBs> apiOp = sameRequest.stream()
                     .filter(api -> StringUtils.equals(api.getVersionId(), apiTestImportRequest.getUpdateVersionId()))
                     .findFirst();
 
             if (!apiOp.isPresent()) {
                 apiDefinition.setId(UUID.randomUUID().toString());
-                apiDefinition.setRefId(sameRequest.get(0).getRefId());
+                if (sameRequest.get(0).getRefId() != null) {
+                    apiDefinition.setRefId(sameRequest.get(0).getRefId());
+                } else {
+                    apiDefinition.setRefId(apiDefinition.getId());
+                }
                 apiDefinition.setVersionId(apiTestImportRequest.getUpdateVersionId());
                 apiDefinition.setNum(sameRequest.get(0).getNum()); // 使用第一个num当作本次的num
                 apiDefinition.setOrder(sameRequest.get(0).getOrder());
@@ -929,16 +877,26 @@ public class ApiDefinitionService {
                 }
                 batchMapper.insert(apiDefinition);
             } else {
-                ApiDefinition existApi = apiOp.get();
+                ApiDefinitionWithBLOBs existApi = apiOp.get();
                 apiDefinition.setStatus(existApi.getStatus());
                 apiDefinition.setOriginalState(existApi.getOriginalState());
                 apiDefinition.setCaseStatus(existApi.getCaseStatus());
                 apiDefinition.setNum(existApi.getNum()); //id 不变
                 apiDefinition.setRefId(existApi.getRefId());
+                if (existApi.getRefId() != null) {
+                    apiDefinition.setRefId(existApi.getRefId());
+                } else {
+                    apiDefinition.setRefId(apiDefinition.getId());
+                }
                 apiDefinition.setVersionId(apiTestImportRequest.getUpdateVersionId());
                 if (existApi.getUserId() != null) {
                     apiDefinition.setUserId(existApi.getUserId());
                 }
+                //Check whether the content has changed, if not, do not change the creation time
+                Boolean toChangeTime = checkIsSynchronize(existApi, apiDefinition);
+                if (!toChangeTime) {
+                    apiDefinition.setUpdateTime(existApi.getUpdateTime());
+                }
                 // case 设置版本
                 cases.forEach(c -> {
                     c.setVersionId(apiDefinition.getVersionId());
@@ -950,14 +908,12 @@ public class ApiDefinitionService {
                     //如果存在则修改
                     apiDefinition.setId(existApi.getId());
                     String request = setImportHashTree(apiDefinition);
-                    apiDefinition.setModuleId(existApi.getModuleId());
-                    apiDefinition.setModulePath(existApi.getModulePath());
                     apiDefinition.setOrder(existApi.getOrder());
-                    apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition);
+                    batchMapper.updateByPrimaryKeyWithBLOBs(apiDefinition);
                     apiDefinition.setRequest(request);
                     reSetImportCasesApiId(cases, originId, apiDefinition.getId());
                     reSetImportMocksApiId(mocks, originId, apiDefinition.getId(), apiDefinition.getNum());
-                    importApiCase(apiDefinition, apiTestImportRequest);
+                    importApiCase(apiDefinition, apiTestImportRequest, apiTestCaseMapper);
                 } else {
                     apiDefinition.setId(existApi.getId());
                     if (StringUtils.equalsAnyIgnoreCase(apiDefinition.getProtocol(), RequestType.TCP)) {
@@ -966,7 +922,7 @@ public class ApiDefinitionService {
                     apiDefinition.setOrder(existApi.getOrder());
                     reSetImportCasesApiId(cases, originId, apiDefinition.getId());
                     reSetImportMocksApiId(mocks, originId, apiDefinition.getId(), apiDefinition.getNum());
-                    apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition);
+                    batchMapper.updateByPrimaryKeyWithBLOBs(apiDefinition);
                 }
             }
             extApiDefinitionMapper.clearLatestVersion(apiDefinition.getRefId());
@@ -974,6 +930,82 @@ public class ApiDefinitionService {
         }
     }
 
+    public Boolean checkIsSynchronize(ApiDefinitionWithBLOBs existApi, ApiDefinitionWithBLOBs apiDefinition) {
+
+        ApiDefinition exApi;
+        ApiDefinition api;
+        exApi = existApi;
+        api = apiDefinition;
+        ObjectMapper objectMapper = new ObjectMapper();
+        String exApiString = null;
+        String apiString = null;
+        try {
+            exApiString = objectMapper.writeValueAsString(exApi);
+            apiString = objectMapper.writeValueAsString(api);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+
+        //Compare the basic information of the API. If it contains the comparison that needs to be done for the synchronization information,
+        // put the data into the to-be-synchronized
+        if (!StringUtils.equals(exApiString, apiString)) {
+            if (!StringUtils.equals(apiDefinition.getMethod(), existApi.getMethod())) {
+                return true;
+            }
+            if (!StringUtils.equals(apiDefinition.getProtocol(), existApi.getProtocol())) {
+                return true;
+            }
+
+            if (!StringUtils.equals(apiDefinition.getPath(), existApi.getPath())) {
+                return true;
+            }
+
+            return true;
+        }
+
+        if (!StringUtils.equals(existApi.getRemark(), apiDefinition.getRemark())) {
+            return true;
+        }
+
+        if (!StringUtils.equals(existApi.getDescription(), apiDefinition.getDescription())) {
+            return true;
+        }
+
+        if (!StringUtils.equals(existApi.getResponse(), apiDefinition.getResponse())) {
+            return true;
+        }
+
+        JsonNode exApiRequest = null;
+        JsonNode apiRequest = null;
+        try {
+            exApiRequest = objectMapper.readTree(existApi.getRequest());
+            apiRequest = objectMapper.readTree(apiDefinition.getRequest());
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+
+        if (exApiRequest == null || apiRequest == null) {
+            return false;
+        }
+        if (!StringUtils.equals(exApiRequest.get("headers").toString(), apiRequest.get("headers").toString())) {
+            return true;
+        }
+
+        if (!StringUtils.equals(exApiRequest.get("arguments").toString(), apiRequest.get("arguments").toString())) {
+            return true;
+        }
+
+        if (!StringUtils.equals(exApiRequest.get("rest").toString(), apiRequest.get("rest").toString())) {
+            return true;
+        }
+
+        if (!StringUtils.equals(exApiRequest.get("body").toString(), apiRequest.get("body").toString())) {
+            return true;
+        }
+
+        return false;
+    }
+
     /**
      * 如果是MS格式,带用例导出,最后创建用例,重新设置接口id
      *
@@ -1023,17 +1055,18 @@ public class ApiDefinitionService {
     }
 
     private void importMsCase(ApiDefinitionImport apiImport, SqlSession sqlSession,
-                              ApiTestImportRequest request) {
+                              ApiTestImportRequest request, ApiTestCaseMapper apiTestCaseMapper) {
         List<ApiTestCaseWithBLOBs> cases = apiImport.getCases();
         if (CollectionUtils.isNotEmpty(cases)) {
             int batchCount = 0;
             for (int i = 0; i < cases.size(); i++) {
                 ApiTestCaseWithBLOBs item = cases.get(i);
-                ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(item.getApiDefinitionId());
-                if (apiDefinitionWithBLOBs == null) {
+                List<ApiDefinitionWithBLOBs> data = apiImport.getData();
+                List<ApiDefinitionWithBLOBs> collect = data.stream().filter(t -> t.getId().equals(item.getApiDefinitionId())).collect(Collectors.toList());
+                if (collect.isEmpty()) {
                     continue;
                 }
-                insertOrUpdateImportCase(item, request, apiDefinitionWithBLOBs);
+                insertOrUpdateImportCase(item, request, collect.get(0), apiTestCaseMapper);
             }
             if (batchCount % 300 == 0) {
                 sqlSession.flushStatements();
@@ -1045,7 +1078,7 @@ public class ApiDefinitionService {
      * 导入是插件或者postman时创建用例
      * postman考虑是否有前置脚本
      */
-    private void importApiCase(ApiDefinitionWithBLOBs apiDefinition, ApiTestImportRequest apiTestImportRequest) {
+    private void importApiCase(ApiDefinitionWithBLOBs apiDefinition, ApiTestImportRequest apiTestImportRequest, ApiTestCaseMapper apiTestCaseMapper) {
         try {
             if (StringUtils.equalsAnyIgnoreCase(apiTestImportRequest.getPlatform(), ApiImportPlatform.Plugin.name(), ApiImportPlatform.Postman.name())) {
                 ApiTestCaseWithBLOBs apiTestCase = new ApiTestCaseWithBLOBs();
@@ -1055,16 +1088,21 @@ public class ApiDefinitionService {
                 if (apiTestCase.getName().length() > 255) {
                     apiTestCase.setName(apiTestCase.getName().substring(0, 255));
                 }
-                insertOrUpdateImportCase(apiTestCase, apiTestImportRequest, apiDefinition);
+                insertOrUpdateImportCase(apiTestCase, apiTestImportRequest, apiDefinition, apiTestCaseMapper);
             }
         } catch (Exception e) {
             LogUtil.error("导入创建用例异常", e);
         }
     }
 
-    private void insertOrUpdateImportCase(ApiTestCaseWithBLOBs apiTestCase, ApiTestImportRequest apiTestImportRequest, ApiDefinitionWithBLOBs apiDefinition) {
+    private void insertOrUpdateImportCase(ApiTestCaseWithBLOBs apiTestCase, ApiTestImportRequest apiTestImportRequest, ApiDefinitionWithBLOBs apiDefinition, ApiTestCaseMapper apiTestCaseMapper) {
         SaveApiTestCaseRequest checkRequest = new SaveApiTestCaseRequest();
-        checkRequest.setName(apiTestCase.getName());
+        if (apiTestCase.getName().length() > 255) {
+            apiTestCase.setName(apiTestCase.getName().substring(0, 255));
+            checkRequest.setName(apiTestCase.getName().substring(0, 255));
+        } else {
+            checkRequest.setName(apiTestCase.getName());
+        }
         checkRequest.setApiDefinitionId(apiTestCase.getApiDefinitionId());
         checkRequest.setId(apiTestCase.getId());
         ApiTestCase sameCase = apiTestCaseService.getSameCase(checkRequest);
@@ -1221,6 +1259,10 @@ public class ApiDefinitionService {
                 MSException.throwException(Translator.get("connection_timeout"));
             }
         }
+        Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
+        if (StringUtils.equals(request.getType(), "schedule")) {
+            request.setProtocol("HTTP");
+        }
         try {
             apiImport = (ApiDefinitionImport) Objects.requireNonNull(runService).parse(file == null ? null : file.getInputStream(), request);
             if (apiImport.getMocks() == null) {
@@ -1242,7 +1284,7 @@ public class ApiDefinitionService {
                 paramMap.put("url", request.getSwaggerUrl());
                 paramMap.put("projectId", request.getProjectId());
                 NoticeModel noticeModel = NoticeModel.builder()
-                        .operator(SessionUtils.getUserId())
+                        .operator(project.getCreateUser())
                         .context(context)
                         .testId(scheduleId)
                         .subject(Translator.get("swagger_url_scheduled_import_notification"))
@@ -1267,7 +1309,7 @@ public class ApiDefinitionService {
                 Map<String, Object> paramMap = new HashMap<>();
                 paramMap.put("url", request.getSwaggerUrl());
                 NoticeModel noticeModel = NoticeModel.builder()
-                        .operator(SessionUtils.getUserId())
+                        .operator(project.getCreateUser())
                         .context(context)
                         .testId(scheduleId)
                         .subject(Translator.get("swagger_url_scheduled_import_notification"))
@@ -1287,21 +1329,39 @@ public class ApiDefinitionService {
         SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
         currentApiCaseOrder.remove();
         currentApiOrder.remove();
-        List<ApiDefinitionWithBLOBs> data = apiImport.getData();
-        data = this.initApiModuleId(data);
-        ApiDefinitionMapper batchMapper = sqlSession.getMapper(ApiDefinitionMapper.class);
-        ApiTestCaseMapper apiTestCaseMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
-        ExtApiDefinitionMapper extApiDefinitionMapper = sqlSession.getMapper(ExtApiDefinitionMapper.class);
+        String defaultVersion = extProjectVersionMapper.getDefaultVersion(request.getProjectId());
+        request.setDefaultVersion(defaultVersion);
+        List<ApiDefinitionWithBLOBs> initData = apiImport.getData();
 
         Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
         ProjectConfig config = projectApplicationService.getSpecificTypeValue(project.getId(), ProjectApplicationType.URL_REPEATABLE.name());
         boolean urlRepeat = config.getUrlRepeatable();
+        //过滤(一次只导入一个协议)
+        List<ApiDefinitionWithBLOBs> filterData = initData.stream().filter(t -> t.getProtocol().equals(request.getProtocol())).collect(Collectors.toList());
+        if (filterData.isEmpty()) {
+            return;
+        }
+        UpdateApiModuleDTO updateApiModuleDTO = apiModuleService.checkApiModule(request, apiImport, filterData, StringUtils.equals("fullCoverage", request.getModeId()), urlRepeat);
+        List<ApiDefinitionWithBLOBs> updateList = updateApiModuleDTO.getNeedUpdateList();
+        List<ApiDefinitionWithBLOBs> data = updateApiModuleDTO.getDefinitionWithBLOBs();
+        List<ApiModule> moduleList = updateApiModuleDTO.getModuleList();
+
+        ApiDefinitionMapper batchMapper = sqlSession.getMapper(ApiDefinitionMapper.class);
+        ApiTestCaseMapper apiTestCaseMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
+        ExtApiDefinitionMapper extApiDefinitionMapper = sqlSession.getMapper(ExtApiDefinitionMapper.class);
+        ApiModuleMapper apiModuleMapper = sqlSession.getMapper(ApiModuleMapper.class);
+
         int num = 0;
         if (!CollectionUtils.isEmpty(data) && data.get(0) != null && data.get(0).getProjectId() != null) {
             num = getNextNum(data.get(0).getProjectId());
         }
-        String defaultVersion = extProjectVersionMapper.getDefaultVersion(request.getProjectId());
-        request.setDefaultVersion(defaultVersion);
+
+        if (moduleList != null) {
+            for (ApiModule apiModule : moduleList) {
+                apiModuleMapper.insert(apiModule);
+            }
+        }
+
         for (int i = 0; i < data.size(); i++) {
             ApiDefinitionWithBLOBs item = data.get(i);
             this.setModule(item);
@@ -1314,14 +1374,14 @@ public class ApiDefinitionService {
                 String apiId = item.getId();
                 EsbApiParamsWithBLOBs model = apiImport.getEsbApiParamsMap().get(apiId);
                 request.setModeId("fullCoverage");//标准版ESB数据导入不区分是否覆盖,默认都为覆盖
-                importCreate(item, batchMapper, apiTestCaseMapper, extApiDefinitionMapper, request, apiImport.getCases(), apiImport.getMocks(), urlRepeat);
+                importCreate(item, batchMapper, apiTestCaseMapper, extApiDefinitionMapper, request, apiImport.getCases(), apiImport.getMocks(), updateList);
                 if (model != null) {
                     apiImport.getEsbApiParamsMap().remove(apiId);
                     model.setResourceId(item.getId());
                     apiImport.getEsbApiParamsMap().put(item.getId(), model);
                 }
             } else {
-                importCreate(item, batchMapper, apiTestCaseMapper, extApiDefinitionMapper, request, apiImport.getCases(), apiImport.getMocks(), urlRepeat);
+                importCreate(item, batchMapper, apiTestCaseMapper, extApiDefinitionMapper, request, apiImport.getCases(), apiImport.getMocks(), updateList);
             }
             if (i % 300 == 0) {
                 sqlSession.flushStatements();
@@ -1341,7 +1401,6 @@ public class ApiDefinitionService {
                     model.setId(exiteModelList.get(0).getId());
                     esbApiParamsMapper.updateByPrimaryKeyWithBLOBs(model);
                 }
-
             }
         }
 
@@ -1351,7 +1410,7 @@ public class ApiDefinitionService {
         }
 
         if (!CollectionUtils.isEmpty(apiImport.getCases())) {
-            importMsCase(apiImport, sqlSession, request);
+            importMsCase(apiImport, sqlSession, request, apiTestCaseMapper);
         }
         if (sqlSession != null && sqlSessionFactory != null) {
             SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
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 b87a1d19bb..b63e786803 100644
--- a/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java
+++ b/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java
@@ -2,10 +2,9 @@ package io.metersphere.api.service;
 
 
 import com.alibaba.fastjson.JSON;
-import io.metersphere.api.dto.definition.ApiDefinitionRequest;
-import io.metersphere.api.dto.definition.ApiDefinitionResult;
-import io.metersphere.api.dto.definition.ApiModuleDTO;
-import io.metersphere.api.dto.definition.DragModuleRequest;
+import io.metersphere.api.dto.ApiTestImportRequest;
+import io.metersphere.api.dto.definition.*;
+import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
 import io.metersphere.base.domain.*;
 import io.metersphere.base.mapper.ApiDefinitionMapper;
 import io.metersphere.base.mapper.ApiModuleMapper;
@@ -13,6 +12,7 @@ import io.metersphere.base.mapper.ext.ExtApiDefinitionMapper;
 import io.metersphere.base.mapper.ext.ExtApiModuleMapper;
 import io.metersphere.commons.constants.TestCaseConstants;
 import io.metersphere.commons.exception.MSException;
+import io.metersphere.commons.utils.BeanUtils;
 import io.metersphere.commons.utils.LogUtil;
 import io.metersphere.commons.utils.SessionUtils;
 import io.metersphere.i18n.Translator;
@@ -49,8 +49,6 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
     @Resource
     private ExtApiDefinitionMapper extApiDefinitionMapper;
     @Resource
-    private ApiDefinitionMapper apiDefinitionMapper;
-    @Resource
     private TestPlanProjectService testPlanProjectService;
     @Resource
     private ProjectService projectService;
@@ -72,11 +70,16 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
         return apiModuleMapper.selectByPrimaryKey(id);
     }
 
+
+    public List<ApiModuleDTO> getApiModulesByProjectAndPro(String projectId, String protocol) {
+        return extApiModuleMapper.getNodeTreeByProjectId(projectId, protocol);
+    }
+
     public List<ApiModuleDTO> getNodeTreeByProjectId(String projectId, String protocol, String versionId) {
         // 判断当前项目下是否有默认模块,没有添加默认模块
         this.getDefaultNode(projectId, protocol);
-        List<ApiModuleDTO> apiModules = extApiModuleMapper.getNodeTreeByProjectId(projectId, protocol);
         ApiDefinitionRequest request = new ApiDefinitionRequest();
+        List<ApiModuleDTO> apiModules = getApiModulesByProjectAndPro(projectId, protocol);
         request.setProjectId(projectId);
         request.setProtocol(protocol);
         List<String> list = new ArrayList<>();
@@ -162,7 +165,7 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
         return addNodeWithoutValidate(node);
     }
 
-    private double getNextLevelPos(String projectId, int level, String parentId) {
+    public double getNextLevelPos(String projectId, int level, String parentId) {
         List<ApiModule> list = getPos(projectId, level, parentId, "pos desc");
         if (!CollectionUtils.isEmpty(list) && list.get(0) != null && list.get(0).getPos() != null) {
             return list.get(0).getPos() + DEFAULT_POS;
@@ -219,7 +222,7 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
         if (apiCases.isEmpty()) {
             return null;
         }
-        List<ApiModuleDTO> testCaseNodes = extApiModuleMapper.getNodeTreeByProjectId(projectId, protocol);
+        List<ApiModuleDTO> testCaseNodes = getApiModulesByProjectAndPro(projectId, protocol);
 
         List<String> caseIds = apiCases.stream()
                 .map(TestPlanApiCase::getApiCaseId)
@@ -453,31 +456,23 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
         }
     }
 
-    public ApiModule getModuleByName(String projectId, String protocol) {
+    public ApiModule getModuleByNameAndLevel(String projectId, String protocol, String name, Integer level) {
         ApiModuleExample example = new ApiModuleExample();
-        ApiModuleExample.Criteria criteria = example.createCriteria();
-        criteria.andNameEqualTo("bug")
-                .andProjectIdEqualTo(projectId).andProtocolEqualTo(protocol);
+        example.createCriteria().andProjectIdEqualTo(projectId).andProtocolEqualTo(protocol).andNameEqualTo(name).andLevelEqualTo(level);
         List<ApiModule> modules = apiModuleMapper.selectByExample(example);
         if (CollectionUtils.isNotEmpty(modules)) {
             return modules.get(0);
         } else {
-            ApiModule node = new ApiModule();
-            node.setName("bug");
-            node.setLevel(1);
-            node.setPos(0.0);
-            node.setParentId(null);
-            node.setProjectId(projectId);
-            node.setProtocol(protocol);
-            node.setCreateTime(System.currentTimeMillis());
-            node.setUpdateTime(System.currentTimeMillis());
-            node.setId(UUID.randomUUID().toString());
-            node.setCreateUser(SessionUtils.getUserId());
-            apiModuleMapper.insertSelective(node);
-            return node;
+            return null;
         }
     }
 
+    public List<ApiModule> getMListByProAndProtocol(String projectId, String protocol) {
+        ApiModuleExample example = new ApiModuleExample();
+        example.createCriteria().andProjectIdEqualTo(projectId).andProtocolEqualTo(protocol);
+        return apiModuleMapper.selectByExample(example);
+    }
+
     public String getLogDetails(List<String> ids) {
         ApiModuleExample example = new ApiModuleExample();
         ApiModuleExample.Criteria criteria = example.createCriteria();
@@ -597,10 +592,647 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
                         });
                         returnMap.put(protocol, idLIst);
                     }
-
                 }
             }
         }
         return returnMap;
     }
+
+    /**
+     * 上传文件时对文件的模块进行检测
+     *
+     * @param data
+     * @param fullCoverage 是否覆盖接口
+     * @return Return to the newly added module list and api list
+     */
+    public UpdateApiModuleDTO checkApiModule(ApiTestImportRequest request, ApiDefinitionImport apiImport, List<ApiDefinitionWithBLOBs> data, Boolean fullCoverage, boolean urlRepeat) {
+        Boolean fullCoverageApi = request.getCoverModule();
+        String projectId = request.getProjectId();
+        String protocol = request.getProtocol();
+        //上传文件时选的模块ID
+        String chooseModuleId = request.getModuleId();
+
+        if (fullCoverage == null) {
+            fullCoverage = false;
+        }
+
+        if (fullCoverageApi == null) {
+            fullCoverageApi = false;
+        }
+
+        //标准版ESB数据导入不区分是否覆盖,默认都为覆盖
+        if (apiImport.getEsbApiParamsMap() != null) {
+            fullCoverage = true;
+        }
+        Set<String> versionSet = new HashSet<>();
+
+        if (fullCoverage) {
+            setFullVersionSet(request, versionSet);
+        } else {
+            String updateVersionId = getUpdateVersionId(request);
+            versionSet.add(updateVersionId);
+        }
+
+        //需要新增的模块,key 为模块路径
+        Map<String, ApiModule> moduleMap = new HashMap<>();
+        //系统原有的需要更新的list,
+        List<ApiDefinitionWithBLOBs> toUpdateList = new ArrayList<>();
+        //获取当前项目的当前协议下的所有模块的Tree
+        List<ApiModuleDTO> apiModules = this.getApiModulesByProjectAndPro(projectId, protocol);
+        List<ApiModuleDTO> nodeTreeByProjectId = this.getNodeTrees(apiModules);
+
+        //所有模块的ID 及其自身 的map
+        Map<String, ApiModuleDTO> idModuleMap = apiModules.stream().collect(Collectors.toMap(ApiModuleDTO::getId, apiModuleDTO -> apiModuleDTO));
+
+        //父级ID与其子模块集合的map
+        Map<String, List<ApiModule>> pidChildrenMap = new HashMap<>();
+        //所有模块的ID 及其全路径的map
+        Map<String, String> idPathMap = new HashMap<>();
+
+        String initParentModulePath = "/root";
+        Map<String, String> initParentModulePathMap = new HashMap<>();
+        initParentModulePathMap.put("root", initParentModulePath);
+        buildProcessData(nodeTreeByProjectId, pidChildrenMap, idPathMap, initParentModulePathMap);
+
+        //获取选中的模块
+        ApiModuleDTO chooseModule = null;
+        if (chooseModuleId != null) {
+            chooseModule = idModuleMap.get(chooseModuleId);
+        }
+
+        List<ApiDefinitionWithBLOBs> optionData = new ArrayList<>();
+
+        if (protocol.equals("HTTP")) {
+            //去重 如果url可重复 则模块+名称+请求方式+路径 唯一,否则 请求方式+路径唯一,
+            //覆盖模式留重复的最后一个,不覆盖留第一个
+            removeHTTPRepeat(data, fullCoverage, urlRepeat, optionData);
+
+            //处理模块
+            setModule(moduleMap, pidChildrenMap, idPathMap, idModuleMap, optionData, chooseModule);
+            //系统内重复的数据
+            List<ApiDefinitionWithBLOBs> repeatApiDefinitionWithBLOBs = getRepeatBLOBsList(projectId, versionSet, chooseModule, optionData);
+            //处理数据
+            if (urlRepeat) {
+                moduleMap = getRepeatApiModuleMap(fullCoverage, fullCoverageApi, moduleMap, toUpdateList, idPathMap, chooseModule, optionData, repeatApiDefinitionWithBLOBs);
+            } else {
+                moduleMap = getOnlyApiModuleMap(fullCoverage, fullCoverageApi, moduleMap, toUpdateList, idPathMap, chooseModule, optionData, repeatApiDefinitionWithBLOBs);
+            }
+        } else {
+            //去重,TCP,SQL,DUBBO 模块下名称唯一
+            removeRepeat(data, fullCoverage, optionData);
+
+            //处理模块
+            setModule(moduleMap, pidChildrenMap, idPathMap, idModuleMap, optionData, chooseModule);
+
+            //处理数据
+            List<String> nameList = optionData.stream().map(ApiDefinitionWithBLOBs::getName).collect(Collectors.toList());
+
+            //获取系统内重复数据
+            List<ApiDefinitionWithBLOBs> repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByProtocol(nameList, protocol, versionSet);
+            
+            Map<String, ApiDefinitionWithBLOBs> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), api -> api));
+            Map<String, ApiDefinitionWithBLOBs> nameModuleMap = getNameApiMap(idPathMap, chooseModule, optionData, repeatApiDefinitionWithBLOBs);
+
+            //处理数据
+            if (fullCoverage) {
+                if (fullCoverageApi) {
+                    coverModule(toUpdateList, nameModuleMap, repeatDataMap);
+                } else {
+                    moduleMap = cover(moduleMap, toUpdateList, nameModuleMap, repeatDataMap);
+                }
+            } else {
+                //不覆盖
+                removeRepeat(optionData, nameModuleMap, repeatDataMap);
+            }
+        }
+        return getUpdateApiModuleDTO(moduleMap, toUpdateList, optionData);
+    }
+
+
+    private UpdateApiModuleDTO getUpdateApiModuleDTO(Map<String, ApiModule> moduleMap, List<ApiDefinitionWithBLOBs> toUpdateList, List<ApiDefinitionWithBLOBs> optionData) {
+        UpdateApiModuleDTO updateApiModuleDTO = new UpdateApiModuleDTO();
+        updateApiModuleDTO.setModuleList(new ArrayList<>(moduleMap.values()));
+        updateApiModuleDTO.setNeedUpdateList(toUpdateList);
+        updateApiModuleDTO.setDefinitionWithBLOBs(optionData);
+        return updateApiModuleDTO;
+    }
+
+    private Map<String, ApiDefinitionWithBLOBs> getNameApiMap(Map<String, String> idPathMap, ApiModuleDTO chooseModule, List<ApiDefinitionWithBLOBs> optionData, List<ApiDefinitionWithBLOBs> repeatApiDefinitionWithBLOBs) {
+        Map<String, ApiDefinitionWithBLOBs> nameModuleMap = null;
+        if (chooseModule != null) {
+            if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
+                String chooseModuleParentId = getChooseModuleParentId(chooseModule);
+                String chooseModulePath = getChooseModulePath(idPathMap, chooseModule, chooseModuleParentId);
+                nameModuleMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + chooseModulePath, api -> api));
+            }
+        } else {
+            nameModuleMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + (t.getModulePath() == null ? "" : t.getModulePath()), api -> api));
+        }
+        return nameModuleMap;
+    }
+
+    private List<ApiDefinitionWithBLOBs> getRepeatBLOBsList(String projectId, Set<String> versionSet, ApiModuleDTO chooseModule, List<ApiDefinitionWithBLOBs> optionData) {
+        List<ApiDefinitionWithBLOBs> repeatApiDefinitionWithBLOBs;
+        if (chooseModule != null) {
+            repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByBLOBsSameUrl(optionData, projectId, chooseModule.getId(), versionSet);
+        } else {
+            repeatApiDefinitionWithBLOBs = extApiDefinitionMapper.selectRepeatByBLOBs(optionData, projectId, versionSet);
+        }
+        return repeatApiDefinitionWithBLOBs;
+    }
+
+    private void removeRepeat(List<ApiDefinitionWithBLOBs> optionData, Map<String, ApiDefinitionWithBLOBs> nameModuleMap, Map<String, ApiDefinitionWithBLOBs> repeatDataMap) {
+        if (nameModuleMap != null) {
+            Map<String, ApiDefinitionWithBLOBs> finalNameModuleMap = nameModuleMap;
+            repeatDataMap.forEach((k, v) -> {
+                ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = finalNameModuleMap.get(k);
+                if (apiDefinitionWithBLOBs != null) {
+                    optionData.remove(apiDefinitionWithBLOBs);
+                }
+            });
+        }
+    }
+
+    private Map<String, ApiModule> cover(Map<String, ApiModule> moduleMap, List<ApiDefinitionWithBLOBs> toUpdateList, Map<String, ApiDefinitionWithBLOBs> nameModuleMap, Map<String, ApiDefinitionWithBLOBs> repeatDataMap) {
+        //覆盖但不覆盖模块
+        if (nameModuleMap != null) {
+            //导入文件没有新增场景无需创建接口模块
+            if (repeatDataMap.size() >= nameModuleMap.size()) {
+                moduleMap = new HashMap<>();
+            }
+            Map<String, ApiDefinitionWithBLOBs> finalNameModuleMap = nameModuleMap;
+            repeatDataMap.forEach((k, v) -> {
+                ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = finalNameModuleMap.get(k);
+                if (apiDefinitionWithBLOBs != null) {
+                    apiDefinitionWithBLOBs.setId(v.getId());
+                    apiDefinitionWithBLOBs.setVersionId(v.getVersionId());
+                    apiDefinitionWithBLOBs.setModuleId(v.getModuleId());
+                    apiDefinitionWithBLOBs.setModulePath(v.getModulePath());
+                    toUpdateList.add(apiDefinitionWithBLOBs);
+                }
+            });
+        }
+        return moduleMap;
+    }
+
+    private void coverModule(List<ApiDefinitionWithBLOBs> toUpdateList, Map<String, ApiDefinitionWithBLOBs> nameModuleMap, Map<String, ApiDefinitionWithBLOBs> repeatDataMap) {
+        if (nameModuleMap != null) {
+            Map<String, ApiDefinitionWithBLOBs> finalNameModuleMap = nameModuleMap;
+            repeatDataMap.forEach((k, v) -> {
+                ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = finalNameModuleMap.get(k);
+                if (apiDefinitionWithBLOBs != null) {
+                    apiDefinitionWithBLOBs.setId(v.getId());
+                    apiDefinitionWithBLOBs.setVersionId(v.getVersionId());
+                    toUpdateList.add(apiDefinitionWithBLOBs);
+                }
+            });
+        }
+    }
+
+    private void removeRepeat(List<ApiDefinitionWithBLOBs> data, Boolean fullCoverage, List<ApiDefinitionWithBLOBs> optionData) {
+        LinkedHashMap<String, List<ApiDefinitionWithBLOBs>> methodPathMap = data.stream().collect(Collectors.groupingBy(t -> t.getName() + (t.getModulePath() == null ? "" : t.getModulePath()), LinkedHashMap::new, Collectors.toList()));
+        if (fullCoverage) {
+            methodPathMap.forEach((k, v) -> {
+                optionData.add(v.get(v.size() - 1));
+            });
+        } else {
+            methodPathMap.forEach((k, v) -> {
+                optionData.add(v.get(0));
+            });
+        }
+    }
+
+    private Map<String, ApiModule> getOnlyApiModuleMap(Boolean fullCoverage, Boolean fullCoverageApi, Map<String, ApiModule> moduleMap, List<ApiDefinitionWithBLOBs> toUpdateList, Map<String, String> idPathMap, ApiModuleDTO chooseModule, List<ApiDefinitionWithBLOBs> optionData, List<ApiDefinitionWithBLOBs> repeatApiDefinitionWithBLOBs) {
+        Map<String, ApiDefinitionWithBLOBs> methodPathMap;
+        Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getMethod() + t.getPath()));
+
+        //按照原来的顺序
+        if (chooseModule != null) {
+            String chooseModuleParentId = getChooseModuleParentId(chooseModule);
+            String chooseModulePath = getChooseModulePath(idPathMap, chooseModule, chooseModuleParentId);
+            methodPathMap = optionData.stream().collect(Collectors.toMap(t -> t.getMethod() + chooseModulePath, api -> api));
+        } else {
+            methodPathMap = optionData.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), api -> api));
+        }
+
+        if (fullCoverage) {
+            if (fullCoverageApi) {
+                if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
+                    startCoverModule(toUpdateList, optionData, methodPathMap, repeatDataMap);
+                }
+            } else {
+                //不覆盖模块
+                if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
+                    if (repeatDataMap.size() >= methodPathMap.size()) {
+                        //导入文件没有新增接口无需创建接口模块
+                        moduleMap = new HashMap<>();
+                    }
+                    startCover(toUpdateList, optionData, methodPathMap, repeatDataMap);
+                }
+            }
+        } else {
+            //不覆盖,同一接口不做更新
+            if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
+                removeSameData(repeatDataMap, methodPathMap, optionData);
+            }
+        }
+        return moduleMap;
+    }
+
+    private Map<String, ApiModule> getRepeatApiModuleMap(Boolean fullCoverage, Boolean fullCoverageApi, Map<String, ApiModule> moduleMap, List<ApiDefinitionWithBLOBs> toUpdateList, Map<String, String> idPathMap, ApiModuleDTO chooseModule, List<ApiDefinitionWithBLOBs> optionData, List<ApiDefinitionWithBLOBs> repeatApiDefinitionWithBLOBs) {
+        Map<String, ApiDefinitionWithBLOBs> methodPathMap;
+        //按照原来的顺序
+        if (chooseModule != null) {
+            String chooseModuleParentId = getChooseModuleParentId(chooseModule);
+            String chooseModulePath = getChooseModulePath(idPathMap, chooseModule, chooseModuleParentId);
+            methodPathMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + t.getMethod() + t.getPath() + chooseModulePath, api -> api));
+        } else {
+            methodPathMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + t.getMethod() + t.getPath() + (t.getModulePath() == null ? "" : t.getModulePath()), api -> api));
+        }
+
+        Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap = repeatApiDefinitionWithBLOBs.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + t.getModulePath()));
+
+        //覆盖接口
+        if (fullCoverage) {
+            //允许覆盖模块,用导入的重复数据的最后一条覆盖查询的所有重复数据 
+            if (fullCoverageApi) {
+                if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
+                    startCoverModule(toUpdateList, optionData, methodPathMap, repeatDataMap);
+                }
+            } else {
+                //覆盖但不覆盖模块
+                if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
+                    moduleMap = judgeModuleMap(moduleMap, methodPathMap, repeatDataMap);
+                    startCover(toUpdateList, optionData, methodPathMap, repeatDataMap);
+                }
+            }
+        } else {
+            //不覆盖,同一接口不做更新
+            if (!repeatApiDefinitionWithBLOBs.isEmpty()) {
+                removeSameData(repeatDataMap, methodPathMap, optionData);
+            }
+
+        }
+        return moduleMap;
+    }
+
+    private void removeHTTPRepeat(List<ApiDefinitionWithBLOBs> data, Boolean fullCoverage, boolean urlRepeat, List<ApiDefinitionWithBLOBs> optionData) {
+        if (urlRepeat) {
+            LinkedHashMap<String, List<ApiDefinitionWithBLOBs>> methodPathMap = data.stream().collect(Collectors.groupingBy(t -> t.getName() + t.getMethod() + t.getPath() + (t.getModulePath() == null ? "" : t.getModulePath()), LinkedHashMap::new, Collectors.toList()));
+            if (fullCoverage) {
+                methodPathMap.forEach((k, v) -> {
+                    optionData.add(v.get(v.size() - 1));
+                });
+            } else {
+                methodPathMap.forEach((k, v) -> {
+                    optionData.add(v.get(0));
+                });
+            }
+        } else {
+            LinkedHashMap<String, List<ApiDefinitionWithBLOBs>> methodPathMap = data.stream().collect(Collectors.groupingBy(t -> t.getMethod() + t.getPath(), LinkedHashMap::new, Collectors.toList()));
+            if (fullCoverage) {
+                methodPathMap.forEach((k, v) -> {
+                    optionData.add(v.get(v.size() - 1));
+                });
+            } else {
+                methodPathMap.forEach((k, v) -> {
+                    optionData.add(v.get(0));
+                });
+            }
+        }
+    }
+
+    private void setFullVersionSet(ApiTestImportRequest request, Set<String> versionSet) {
+        String creatVersionId;
+        if (request.getVersionId() != null) {
+            creatVersionId = request.getVersionId();
+        } else {
+            creatVersionId = request.getDefaultVersion();
+        }
+        versionSet.add(creatVersionId);
+        String updateVersionId;
+        if (request.getUpdateVersionId() != null) {
+            updateVersionId = request.getUpdateVersionId();
+        } else {
+            updateVersionId = request.getDefaultVersion();
+        }
+        versionSet.add(updateVersionId);
+    }
+
+    private String getUpdateVersionId(ApiTestImportRequest request) {
+        String updateVersionId;
+        if (request.getVersionId() == null) {
+            updateVersionId = request.getDefaultVersion();
+        } else {
+            updateVersionId = request.getVersionId();
+        }
+        return updateVersionId;
+    }
+
+    private void removeSameData(Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap, Map<String, ApiDefinitionWithBLOBs> methodPathMap, List<ApiDefinitionWithBLOBs> optionData) {
+        repeatDataMap.forEach((k, v) -> {
+            ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k);
+            if (apiDefinitionWithBLOBs != null) {
+                optionData.remove(apiDefinitionWithBLOBs);
+            }
+        });
+    }
+
+    private void startCoverModule(List<ApiDefinitionWithBLOBs> toUpdateList, List<ApiDefinitionWithBLOBs> optionData, Map<String, ApiDefinitionWithBLOBs> methodPathMap, Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap) {
+        List<ApiDefinitionWithBLOBs> coverApiList = new ArrayList<>();
+        repeatDataMap.forEach((k, v) -> {
+            ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k);
+            if (apiDefinitionWithBLOBs != null) {
+                for (ApiDefinitionWithBLOBs definitionWithBLOBs : v) {
+                    ApiDefinitionWithBLOBs api = new ApiDefinitionWithBLOBs();
+                    BeanUtils.copyBean(api, apiDefinitionWithBLOBs);
+                    api.setId(definitionWithBLOBs.getId());
+                    api.setVersionId(definitionWithBLOBs.getVersionId());
+                    api.setOrder(definitionWithBLOBs.getOrder());
+                    api.setRefId(apiDefinitionWithBLOBs.getRefId());
+                    api.setLatest(apiDefinitionWithBLOBs.getLatest());
+                    coverApiList.add(api);
+                }
+                optionData.remove(apiDefinitionWithBLOBs);
+            }
+        });
+        buildOtherParam(toUpdateList, optionData, coverApiList);
+    }
+
+    private void startCover(List<ApiDefinitionWithBLOBs> toUpdateList, List<ApiDefinitionWithBLOBs> optionData, Map<String, ApiDefinitionWithBLOBs> methodPathMap, Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap) {
+        List<ApiDefinitionWithBLOBs> coverApiList = new ArrayList<>();
+        repeatDataMap.forEach((k, v) -> {
+            ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = methodPathMap.get(k);
+            if (apiDefinitionWithBLOBs != null) {
+                for (ApiDefinitionWithBLOBs definitionWithBLOBs : v) {
+                    ApiDefinitionWithBLOBs api = new ApiDefinitionWithBLOBs();
+                    BeanUtils.copyBean(api, apiDefinitionWithBLOBs);
+                    api.setId(definitionWithBLOBs.getId());
+                    api.setVersionId(definitionWithBLOBs.getVersionId());
+                    api.setModuleId(definitionWithBLOBs.getModuleId());
+                    api.setModulePath(definitionWithBLOBs.getModulePath());
+                    api.setOrder(definitionWithBLOBs.getOrder());
+                    api.setRefId(apiDefinitionWithBLOBs.getRefId());
+                    api.setLatest(apiDefinitionWithBLOBs.getLatest());
+                    coverApiList.add(api);
+                }
+                optionData.remove(apiDefinitionWithBLOBs);
+            }
+        });
+        buildOtherParam(toUpdateList, optionData, coverApiList);
+    }
+
+    private Map<String, ApiModule> judgeModuleMap(Map<String, ApiModule> moduleMap, Map<String, ApiDefinitionWithBLOBs> methodPathMap, Map<String, List<ApiDefinitionWithBLOBs>> repeatDataMap) {
+        Set<String> repeatKeys = repeatDataMap.keySet();
+        Set<String> importKeys = methodPathMap.keySet();
+        List<String> repeatKeyList = new ArrayList<>(repeatKeys);
+        List<String> importKeysList = new ArrayList<>(importKeys);
+        List<String> intersection = repeatKeyList.stream().filter(item -> importKeysList.contains(item)).collect(Collectors.toList());
+        if (intersection.size() == importKeysList.size()) {
+            //导入文件没有新增接口无需创建接口模块
+            moduleMap = new HashMap<>();
+        }
+        return moduleMap;
+    }
+
+    private void buildOtherParam(List<ApiDefinitionWithBLOBs> toUpdateList, List<ApiDefinitionWithBLOBs> optionData, List<ApiDefinitionWithBLOBs> coverApiList) {
+        optionData.addAll(coverApiList);
+        toUpdateList.addAll(coverApiList);
+    }
+
+    private List<ApiDefinitionWithBLOBs> setModule(Map<String, ApiModule> moduleMap, Map<String, List<ApiModule>> pidChildrenMap,
+                                                   Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, List<ApiDefinitionWithBLOBs> data, ApiModuleDTO chooseModule) {
+        for (ApiDefinitionWithBLOBs datum : data) {
+            String modulePath = datum.getModulePath();
+            ApiModule apiModule = moduleMap.get(modulePath);
+            if (chooseModule != null) {
+                dealChooseModuleData(moduleMap, pidChildrenMap, idPathMap, idModuleMap, chooseModule, datum, modulePath);
+            } else {
+                dealNoModuleData(moduleMap, pidChildrenMap, idPathMap, idModuleMap, datum, modulePath, apiModule);
+            }
+        }
+        return data;
+    }
+
+    private void dealNoModuleData(Map<String, ApiModule> moduleMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, ApiDefinitionWithBLOBs datum, String modulePath, ApiModule apiModule) {
+        String[] pathTree;
+        if (StringUtils.isNotBlank(modulePath)) {
+            //导入时没选模块但接口有模块的,根据modulePath,和当前协议查询当前项目里是否有同名称模块,如果有,就在该模块下建立接口,否则新建模块
+            pathTree = getPathTree(modulePath);
+            if (apiModule != null) {
+                datum.setModuleId(apiModule.getId());
+                datum.setModulePath(modulePath);
+            } else {
+                List<ApiModule> moduleList = pidChildrenMap.get("root");
+                ApiModule minModule = getMinModule(pathTree, moduleList, null, pidChildrenMap, moduleMap, idPathMap, idModuleMap);
+                String id = minModule.getId();
+                datum.setModuleId(id);
+                datum.setModulePath(idPathMap.get(id));
+            }
+        } else {
+            //导入时即没选中模块,接口自身也没模块的,直接返会当前项目,当前协议下的默认模块
+            List<ApiModule> moduleList = pidChildrenMap.get("root");
+            for (ApiModule module : moduleList) {
+                if (module.getName().equals("未规划接口")) {
+                    datum.setModuleId(module.getId());
+                    datum.setModulePath("/" + module.getName());
+                }
+            }
+        }
+    }
+
+    private void dealChooseModuleData(Map<String, ApiModule> moduleMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap, ApiModuleDTO chooseModule, ApiDefinitionWithBLOBs datum, String modulePath) {
+        String[] pathTree;
+        String chooseModuleParentId = getChooseModuleParentId(chooseModule);
+        String chooseModulePath = getChooseModulePath(idPathMap, chooseModule, chooseModuleParentId);
+        //导入时选了模块,且接口有模块的
+        if (StringUtils.isNotBlank(modulePath)) {
+            List<ApiModule> moduleList = pidChildrenMap.get(chooseModuleParentId);
+            pathTree = getPathTree(chooseModulePath + modulePath);
+
+            ApiModule chooseModuleOne = JSON.parseObject(JSON.toJSONString(chooseModule), ApiModule.class);
+            ApiModule minModule = getMinModule(pathTree, moduleList, chooseModuleOne, pidChildrenMap, moduleMap, idPathMap, idModuleMap);
+            String id = minModule.getId();
+            datum.setModuleId(id);
+            datum.setModulePath(idPathMap.get(id));
+        } else {
+            //导入时选了模块,且接口没有模块的
+            datum.setModuleId(chooseModule.getId());
+            datum.setModulePath(idPathMap.get(chooseModule.getId()));
+        }
+    }
+
+    private String getChooseModulePath(Map<String, String> idPathMap, ApiModuleDTO chooseModule, String chooseModuleParentId) {
+        String s;
+        if (chooseModuleParentId.equals("root")) {
+            s = "/" + chooseModule.getName();
+        } else {
+            s = idPathMap.get(chooseModuleParentId);
+        }
+        return s;
+    }
+
+    private String getChooseModuleParentId(ApiModuleDTO chooseModule) {
+        if (chooseModule.getParentId() == null) {
+            chooseModule.setParentId("root");
+        }
+        String chooseModuleParentId = chooseModule.getParentId();
+        return chooseModuleParentId;
+    }
+
+    private String[] getPathTree(String modulePath) {
+        String substring = modulePath.substring(0, 1);
+        if (substring.equals("/")) {
+            modulePath = modulePath.substring(1);
+        }
+        if (modulePath.contains("/")) {
+            //如果模块有层级,逐级查找,如果某一级不在当前项目了,则新建该层级的模块及其子集
+            return modulePath.split("/");
+        } else {
+            return new String[]{modulePath};
+        }
+    }
+
+    private ApiModule getMinModule(String[] tagTree, List<ApiModule> parentModuleList, ApiModule parentModule, Map<String, List<ApiModule>> pidChildrenMap, Map<String, ApiModule> moduleMap
+            , Map<String, String> idPathMap, Map<String, ApiModuleDTO> idModuleMap) {
+        //如果parentModule==null 则证明需要创建根目录同级的模块
+        ApiModule returnModule = null;
+        for (int i = 0; i < tagTree.length; i++) {
+            int finalI = i;
+            List<ApiModule> collect = parentModuleList.stream().filter(t -> t.getName().equals(tagTree[finalI])).collect(Collectors.toList());
+            if (collect.isEmpty()) {
+                if (i == 0) {
+                    //证明需要在根目录创建,
+                    parentModule = new ApiModule();
+                    parentModule.setProjectId(pidChildrenMap.get("root").get(0).getProjectId());
+                    parentModule.setId("root");
+                    parentModule.setLevel(0);
+                    parentModule.setProtocol(pidChildrenMap.get("root").get(0).getProtocol());
+                } else {
+                    if (!parentModuleList.isEmpty() && parentModule == null) {
+                        String parentId = parentModuleList.get(0).getParentId();
+                        ApiModuleDTO apiModuleDTO = idModuleMap.get(parentId);
+                        parentModule = JSON.parseObject(JSON.toJSONString(apiModuleDTO), ApiModule.class);
+                    }
+                }
+                return createModule(tagTree, i, parentModule, moduleMap, pidChildrenMap, idPathMap);
+            } else {
+                returnModule = collect.get(0);
+                parentModule = collect.get(0);
+                parentModuleList = pidChildrenMap.get(collect.get(0).getId());
+            }
+        }
+        return returnModule;
+    }
+
+    private ApiModule createModule(String[] tagTree, int i, ApiModule parentModule, Map<String, ApiModule> moduleMap, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap) {
+        ApiModule returnModule = null;
+        for (int i1 = i; i1 < tagTree.length; i1++) {
+            String pathName = tagTree[i1];
+            ApiModule newModule = this.getNewModule(pathName, parentModule.getProjectId(), parentModule.getLevel() + 1);
+            String parentId;
+            if (parentModule.getId().equals("root")) {
+                parentId = null;
+            } else {
+                parentId = parentModule.getId();
+            }
+            double pos = this.getNextLevelPos(parentModule.getProjectId(), parentModule.getLevel() + 1, parentId);
+            newModule.setPos(pos);
+            newModule.setProtocol(parentModule.getProtocol());
+            newModule.setParentId(parentId);
+            List<ApiModule> moduleList = pidChildrenMap.get(parentModule.getId());
+            if (moduleList != null) {
+                moduleList.add(newModule);
+            } else {
+                moduleList = new ArrayList<>();
+                moduleList.add(newModule);
+                pidChildrenMap.put(parentModule.getId(), moduleList);
+            }
+
+            String parentPath = idPathMap.get(parentModule.getId());
+            String path;
+            if (StringUtils.isNotBlank(parentPath)) {
+                path = parentPath + "/" + pathName;
+            } else {
+                path = "/" + pathName;
+            }
+            idPathMap.put(newModule.getId(), path);
+            moduleMap.putIfAbsent(path, newModule);
+            parentModule = newModule;
+            returnModule = newModule;
+        }
+        return returnModule;
+    }
+
+    private void buildProcessData(List<ApiModuleDTO> nodeTreeByProjectId, Map<String, List<ApiModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, String> parentModulePathMap) {
+        //当前层级的模块的所有子模块的集合
+        Map<String, List<ApiModuleDTO>> idChildrenMap = new HashMap<>();
+        int i = 0;
+        Map<String, List<ApiModule>> idModuleMap = new HashMap<>();
+        for (ApiModuleDTO apiModuleDTO : nodeTreeByProjectId) {
+            if (StringUtils.isBlank(apiModuleDTO.getParentId())) {
+                apiModuleDTO.setParentId("root");
+            }
+            String parentModulePath = parentModulePathMap.get(apiModuleDTO.getParentId());
+            if (parentModulePath != null) {
+                if (parentModulePath.equals("/root")) {
+                    apiModuleDTO.setPath("/" + apiModuleDTO.getName());
+                } else {
+                    apiModuleDTO.setPath(parentModulePath + "/" + apiModuleDTO.getName());
+                }
+            } else {
+                apiModuleDTO.setPath("/" + apiModuleDTO.getName());
+            }
+            idPathMap.put(apiModuleDTO.getId(), apiModuleDTO.getPath());
+
+            ApiModule apiModule = buildModule(idModuleMap, apiModuleDTO);
+            if (pidChildrenMap.get(apiModuleDTO.getParentId()) != null) {
+                pidChildrenMap.get(apiModuleDTO.getParentId()).add(apiModule);
+            } else {
+                pidChildrenMap.put(apiModuleDTO.getParentId(), idModuleMap.get(apiModuleDTO.getId()));
+            }
+            i = i + 1;
+            List<ApiModuleDTO> childrenList = idChildrenMap.get(apiModuleDTO.getId());
+            if (apiModuleDTO.getChildren() != null) {
+                if (childrenList != null) {
+                    childrenList.addAll(apiModuleDTO.getChildren());
+                } else {
+                    idChildrenMap.put(apiModuleDTO.getId(), apiModuleDTO.getChildren());
+                }
+            } else {
+                if (childrenList == null) {
+                    pidChildrenMap.put(apiModuleDTO.getId(), new ArrayList<>());
+                }
+            }
+            parentModulePathMap.put(apiModuleDTO.getId(), apiModuleDTO.getPath());
+        }
+        if (i == nodeTreeByProjectId.size() && nodeTreeByProjectId.size() > 0) {
+            Collection<List<ApiModuleDTO>> values = idChildrenMap.values();
+            List<ApiModuleDTO> childrenList = new ArrayList<>();
+            for (List<ApiModuleDTO> value : values) {
+                childrenList.addAll(value);
+            }
+            buildProcessData(childrenList, pidChildrenMap, idPathMap, parentModulePathMap);
+        }
+    }
+
+    private ApiModule buildModule(Map<String, List<ApiModule>> idModuleMap, ApiModuleDTO apiModuleDTO) {
+        ApiModule apiModule = new ApiModule();
+        apiModule.setId(apiModuleDTO.getId());
+        apiModule.setName(apiModuleDTO.getName());
+        apiModule.setParentId(apiModuleDTO.getParentId());
+        apiModule.setProjectId(apiModuleDTO.getProjectId());
+        apiModule.setProtocol(apiModuleDTO.getProtocol());
+        apiModule.setLevel(apiModuleDTO.getLevel());
+        List<ApiModule> moduleList = idModuleMap.get(apiModuleDTO.getId());
+        if (moduleList != null) {
+            moduleList.add(apiModule);
+        } else {
+            moduleList = new ArrayList<>();
+            moduleList.add(apiModule);
+            idModuleMap.put(apiModuleDTO.getId(), moduleList);
+        }
+        return apiModule;
+    }
+
 }
diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java
index 475448c326..25c0dcdd86 100644
--- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java
+++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java
@@ -2,10 +2,8 @@ package io.metersphere.api.service;
 
 
 import com.alibaba.fastjson.JSON;
-import io.metersphere.api.dto.automation.ApiScenarioDTO;
-import io.metersphere.api.dto.automation.ApiScenarioModuleDTO;
-import io.metersphere.api.dto.automation.ApiScenarioRequest;
-import io.metersphere.api.dto.automation.DragApiScenarioModuleRequest;
+import io.metersphere.api.dto.ApiTestImportRequest;
+import io.metersphere.api.dto.automation.*;
 import io.metersphere.base.domain.*;
 import io.metersphere.base.mapper.ApiScenarioMapper;
 import io.metersphere.base.mapper.ApiScenarioModuleMapper;
@@ -88,21 +86,21 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
             moduleIds = this.nodeList(nodes, node.getId(), moduleIds);
             moduleIds.add(node.getId());
             for (String moduleId : moduleIds) {
-                if(!allModuleIdList.contains(moduleId)){
+                if (!allModuleIdList.contains(moduleId)) {
                     allModuleIdList.add(moduleId);
                 }
             }
         }
         request.setModuleIds(allModuleIdList);
-        List<Map<String,Object>> moduleCountList = extApiScenarioMapper.listModuleByCollection(request);
-        Map<String,Integer> moduleCountMap = this.parseModuleCountList(moduleCountList);
+        List<Map<String, Object>> moduleCountList = extApiScenarioMapper.listModuleByCollection(request);
+        Map<String, Integer> moduleCountMap = this.parseModuleCountList(moduleCountList);
         nodes.forEach(node -> {
             List<String> moduleIds = new ArrayList<>();
             moduleIds = this.nodeList(nodes, node.getId(), moduleIds);
             moduleIds.add(node.getId());
             int countNum = 0;
             for (String moduleId : moduleIds) {
-                if(moduleCountMap.containsKey(moduleId)){
+                if (moduleCountMap.containsKey(moduleId)) {
                     countNum += moduleCountMap.get(moduleId).intValue();
                 }
             }
@@ -110,17 +108,18 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
         });
         return getNodeTrees(nodes);
     }
+
     private Map<String, Integer> parseModuleCountList(List<Map<String, Object>> moduleCountList) {
-        Map<String,Integer> returnMap = new HashMap<>();
-        for (Map<String, Object> map: moduleCountList){
+        Map<String, Integer> returnMap = new HashMap<>();
+        for (Map<String, Object> map : moduleCountList) {
             Object moduleIdObj = map.get("moduleId");
             Object countNumObj = map.get("countNum");
-            if(moduleIdObj!= null && countNumObj != null){
+            if (moduleIdObj != null && countNumObj != null) {
                 String moduleId = String.valueOf(moduleIdObj);
                 try {
                     Integer countNumInteger = new Integer(String.valueOf(countNumObj));
-                    returnMap.put(moduleId,countNumInteger);
-                }catch (Exception e){
+                    returnMap.put(moduleId, countNumInteger);
+                } catch (Exception e) {
                 }
             }
         }
@@ -140,7 +139,7 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
         return list;
     }
 
-    private double getNextLevelPos(String projectId, int level, String parentId) {
+    public double getNextLevelPos(String projectId, int level, String parentId) {
         List<ApiScenarioModule> list = getPos(projectId, level, parentId, "pos desc");
         if (!CollectionUtils.isEmpty(list) && list.get(0) != null && list.get(0).getPos() != null) {
             return list.get(0).getPos() + DEFAULT_POS;
@@ -465,9 +464,424 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
             record.setProjectId(projectId);
             record.setCreateUser(SessionUtils.getUserId());
             apiScenarioModuleMapper.insert(record);
-            return  record;
-        }else {
+            return record;
+        } else {
             return list.get(0);
         }
     }
+
+    /**
+     * 上传文件时对文件的模块进行检测
+     *
+     * @param data
+     * @param fullCoverage         是否覆盖接口
+     * @param fullCoverageScenario 是否更新当前接口所在模块
+     * @return Return to the newly added module map
+     */
+    public UpdateScenarioModuleDTO checkScenarioModule(ApiTestImportRequest request, List<ApiScenarioWithBLOBs> data, Boolean fullCoverage, Boolean fullCoverageScenario) {
+        //需要新增的模块,key 为模块路径
+        Map<String, ApiScenarioModule> moduleMap = new HashMap<>();
+        List<ApiScenarioWithBLOBs> toUpdateList = new ArrayList<>();
+
+        //上传文件时选的模块ID
+        String chooseModuleId = request.getModuleId();
+        String projectId = request.getProjectId();
+
+        if (fullCoverageScenario == null) {
+            fullCoverageScenario = false;
+        }
+
+        //获取当前项目的当前协议下的所有模块的Tree
+        List<ApiScenarioModuleDTO> scenarioModules = extApiScenarioModuleMapper.getNodeTreeByProjectId(projectId);
+        List<ApiScenarioModuleDTO> nodeTreeByProjectId = this.getNodeTrees(scenarioModules);
+
+        Map<String, ApiScenarioModuleDTO> idModuleMap = scenarioModules.stream().collect(Collectors.toMap(ApiScenarioModuleDTO::getId, scenarioModuleDTO -> scenarioModuleDTO));
+
+        Map<String, List<ApiScenarioModule>> pidChildrenMap = new HashMap<>();
+        Map<String, String> idPathMap = new HashMap<>();
+        //构建以上两种数据
+        String initParentModulePath = "/root";
+        Map<String, String> initParentModulePathMap = new HashMap<>();
+        initParentModulePathMap.put("root", initParentModulePath);
+        buildProcessData(nodeTreeByProjectId, pidChildrenMap, idPathMap, initParentModulePathMap);
+
+        ApiScenarioModuleDTO chooseModule = null;
+        if (chooseModuleId != null) {
+            chooseModule = idModuleMap.get(chooseModuleId);
+        }
+
+        Set<String> versionSet = new HashSet<>();
+
+        if (fullCoverage) {
+            setFullVersionSet(request, versionSet);
+        } else {
+            String updateVersionId = getUpdateVersionId(request);
+            versionSet.add(updateVersionId);
+        }
+
+
+        List<ApiScenarioWithBLOBs> optionData = new ArrayList<>();
+
+        //覆盖模式留重复的最后一个,不覆盖留第一个
+        LinkedHashMap<String, List<ApiScenarioWithBLOBs>> nameModuleMapList = data.stream().collect(Collectors.groupingBy(t -> t.getName() + (t.getModulePath() == null ? "" : t.getModulePath()), LinkedHashMap::new, Collectors.toList()));
+        removeRepeat(fullCoverage, optionData, nameModuleMapList);
+
+        //处理模块
+        setModule(optionData, moduleMap, pidChildrenMap, idPathMap, idModuleMap, chooseModule);
+
+        //系统内重复的数据
+        List<ApiScenarioWithBLOBs> repeatApiScenarioWithBLOBs;
+        if (chooseModule != null) {
+            repeatApiScenarioWithBLOBs = extApiScenarioMapper.selectRepeatByBLOBsSameUrl(optionData, projectId, chooseModule.getId(), versionSet);
+        } else {
+            repeatApiScenarioWithBLOBs = extApiScenarioMapper.selectRepeatByBLOBs(optionData, projectId, versionSet);
+        }
+
+        Map<String, ApiScenarioWithBLOBs> nameModuleMap = null;
+        Map<String, ApiScenarioWithBLOBs> repeatDataMap = repeatApiScenarioWithBLOBs.stream().collect(Collectors.toMap(t -> t.getName() + t.getModulePath(), scenario -> scenario));
+        if (chooseModule != null) {
+            if (!repeatApiScenarioWithBLOBs.isEmpty()) {
+                String chooseModuleParentId = getChooseModuleParentId(chooseModule);
+                String chooseModulePath = getChooseModulePath(idPathMap, chooseModule, chooseModuleParentId);
+                nameModuleMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + chooseModulePath, scenario -> scenario));
+            }
+        } else {
+            nameModuleMap = optionData.stream().collect(Collectors.toMap(t -> t.getName() + (t.getModulePath() == null ? "" : t.getModulePath()), scenario -> scenario));
+        }
+        //处理数据
+        if (fullCoverage) {
+            if (fullCoverageScenario) {
+                startCoverModule(toUpdateList, nameModuleMap, repeatDataMap);
+            } else {
+                //覆盖但不覆盖模块
+                if (nameModuleMap != null) {
+                    //导入文件没有新增场景无需创建接口模块
+                    moduleMap = judgeModuleMap(moduleMap, nameModuleMap, repeatDataMap);
+                    startCover(toUpdateList, nameModuleMap, repeatDataMap);
+                }
+            }
+        } else {
+            //不覆盖
+            removeRepeat(optionData, nameModuleMap, repeatDataMap);
+        }
+
+        UpdateScenarioModuleDTO updateScenarioModuleDTO = new UpdateScenarioModuleDTO();
+        updateScenarioModuleDTO.setModuleList(new ArrayList<>(moduleMap.values()));
+        updateScenarioModuleDTO.setNeedUpdateList(toUpdateList);
+        updateScenarioModuleDTO.setApiScenarioWithBLOBsList(optionData);
+        return updateScenarioModuleDTO;
+    }
+
+    private void setFullVersionSet(ApiTestImportRequest request, Set<String> versionSet) {
+        String creatVersionId;
+        if (request.getVersionId() != null) {
+            creatVersionId = request.getVersionId();
+        } else {
+            creatVersionId = request.getDefaultVersion();
+        }
+        versionSet.add(creatVersionId);
+        String updateVersionId;
+        if (request.getUpdateVersionId() != null) {
+            updateVersionId = request.getUpdateVersionId();
+        } else {
+            updateVersionId = request.getDefaultVersion();
+        }
+        versionSet.add(updateVersionId);
+    }
+
+    private void removeRepeat(List<ApiScenarioWithBLOBs> optionData, Map<String, ApiScenarioWithBLOBs> nameModuleMap, Map<String, ApiScenarioWithBLOBs> repeatDataMap) {
+        if (repeatDataMap != null) {
+            repeatDataMap.forEach((k, v) -> {
+                ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameModuleMap.get(k);
+                if (apiScenarioWithBLOBs != null) {
+                    optionData.remove(apiScenarioWithBLOBs);
+                }
+            });
+        }
+    }
+
+    private void startCover(List<ApiScenarioWithBLOBs> toUpdateList, Map<String, ApiScenarioWithBLOBs> nameModuleMap, Map<String, ApiScenarioWithBLOBs> repeatDataMap) {
+        repeatDataMap.forEach((k, v) -> {
+            ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameModuleMap.get(k);
+            if (apiScenarioWithBLOBs != null) {
+                apiScenarioWithBLOBs.setId(v.getId());
+                apiScenarioWithBLOBs.setVersionId(v.getVersionId());
+                apiScenarioWithBLOBs.setApiScenarioModuleId(v.getApiScenarioModuleId());
+                apiScenarioWithBLOBs.setModulePath(v.getModulePath());
+                toUpdateList.add(apiScenarioWithBLOBs);
+            }
+        });
+    }
+
+    private Map<String, ApiScenarioModule> judgeModuleMap(Map<String, ApiScenarioModule> moduleMap, Map<String, ApiScenarioWithBLOBs> nameModuleMap, Map<String, ApiScenarioWithBLOBs> repeatDataMap) {
+        if (repeatDataMap.size() >= nameModuleMap.size()) {
+            moduleMap = new HashMap<>();
+        }
+        return moduleMap;
+    }
+
+    private void startCoverModule(List<ApiScenarioWithBLOBs> toUpdateList, Map<String, ApiScenarioWithBLOBs> nameModuleMap, Map<String, ApiScenarioWithBLOBs> repeatDataMap) {
+        if (repeatDataMap != null) {
+            repeatDataMap.forEach((k, v) -> {
+                ApiScenarioWithBLOBs apiScenarioWithBLOBs = nameModuleMap.get(k);
+                if (apiScenarioWithBLOBs != null) {
+                    apiScenarioWithBLOBs.setId(v.getId());
+                    apiScenarioWithBLOBs.setVersionId(v.getVersionId());
+                    toUpdateList.add(apiScenarioWithBLOBs);
+                }
+            });
+        }
+    }
+
+    private void removeRepeat(Boolean fullCoverage, List<ApiScenarioWithBLOBs> optionData, LinkedHashMap<String, List<ApiScenarioWithBLOBs>> nameModuleMapList) {
+        if (fullCoverage) {
+            nameModuleMapList.forEach((k, v) -> {
+                optionData.add(v.get(v.size() - 1));
+            });
+        } else {
+            nameModuleMapList.forEach((k, v) -> {
+                optionData.add(v.get(0));
+            });
+        }
+    }
+
+    private String getUpdateVersionId(ApiTestImportRequest request) {
+        String updateVersionId;
+        if (request.getVersionId() == null) {
+            updateVersionId = request.getDefaultVersion();
+        } else {
+            updateVersionId = request.getVersionId();
+        }
+        return updateVersionId;
+    }
+
+    private void setModule(List<ApiScenarioWithBLOBs> data, Map<String, ApiScenarioModule> map, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, ApiScenarioModuleDTO> idModuleMap, ApiScenarioModuleDTO chooseModule) {
+        for (ApiScenarioWithBLOBs datum : data) {
+            StringBuilder path = new StringBuilder();
+            path.append("/");
+            String[] tagTree;
+            String modulePath = datum.getModulePath();
+            ApiScenarioModule scenarioModule = map.get(modulePath);
+            if (chooseModule != null) {
+                String chooseModuleParentId = getChooseModuleParentId(chooseModule);
+                String chooseModulePath = getChooseModulePath(idPathMap, chooseModule, chooseModuleParentId);
+                //导入时选了模块,且接口有模块的
+                if (StringUtils.isNotBlank(modulePath)) {
+                    //选中模块的同级模块集合,用于和场景的全路径做对比
+                    List<ApiScenarioModule> parentModuleList = pidChildrenMap.get(chooseModuleParentId);
+                    //场景的全部路径的集合
+                    tagTree = getTagTree(chooseModulePath + modulePath);
+
+                    ApiScenarioModule chooseModuleOne = JSON.parseObject(JSON.toJSONString(chooseModule), ApiScenarioModule.class);
+                    ApiScenarioModule minModule = getMinModule(tagTree, parentModuleList, chooseModuleOne, pidChildrenMap, map, idPathMap, idModuleMap);
+                    String id = minModule.getId();
+                    datum.setApiScenarioModuleId(id);
+                    datum.setModulePath(idPathMap.get(id));
+                } else {
+                    //导入时选了模块,且接口没有模块的
+                    datum.setApiScenarioModuleId(chooseModule.getId());
+                    datum.setModulePath(idPathMap.get(chooseModule.getId()));
+                }
+            } else {
+                if (StringUtils.isNotBlank(modulePath)) {
+                    //导入时没选模块但接口有模块的,根据modulePath,和当前协议查询当前项目里是否有同名称模块,如果有,就在该模块下建立接口,否则新建模块
+                    tagTree = getTagTree(modulePath);
+                    if (scenarioModule != null) {
+                        datum.setApiScenarioModuleId(scenarioModule.getId());
+                        datum.setModulePath(modulePath);
+                    } else {
+                        //父级同级的模块list
+                        ApiScenarioModule minModule = getMinModule(tagTree, pidChildrenMap.get("root"), null, pidChildrenMap, map, idPathMap, idModuleMap);
+                        String id = minModule.getId();
+                        datum.setApiScenarioModuleId(id);
+                        datum.setModulePath(idPathMap.get(id));
+                    }
+                } else {
+                    //导入时即没选中模块,接口自身也没模块的,直接返会当前项目,当前协议下的默认模块
+                    List<ApiScenarioModule> moduleList = pidChildrenMap.get("root");
+                    for (ApiScenarioModule module : moduleList) {
+                        if (module.getName().equals("未规划场景")) {
+                            datum.setApiScenarioModuleId(module.getId());
+                            datum.setModulePath("/" + module.getName());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private String getChooseModuleParentId(ApiScenarioModuleDTO chooseModule) {
+        if (chooseModule.getParentId() == null) {
+            chooseModule.setParentId("root");
+        }
+        String chooseModuleParentId = chooseModule.getParentId();
+        return chooseModuleParentId;
+    }
+
+    private String getChooseModulePath(Map<String, String> idPathMap, ApiScenarioModuleDTO chooseModule, String chooseModuleParentId) {
+        String s;
+        if (chooseModuleParentId.equals("root")) {
+            s = "/" + chooseModule.getName();
+        } else {
+            s = idPathMap.get(chooseModuleParentId);
+        }
+        return s;
+    }
+
+    private String[] getTagTree(String modulePath) {
+        String substring = modulePath.substring(0, 1);
+        if (substring.equals("/")) {
+            modulePath = modulePath.substring(1);
+        }
+        if (modulePath.contains("/")) {
+            //如果模块有层级,逐级查找,如果某一级不在当前项目了,则新建该层级的模块及其子集
+            return modulePath.split("/");
+        } else {
+            return new String[]{modulePath};
+        }
+    }
+
+    private ApiScenarioModule getMinModule(String[] tagTree, List<ApiScenarioModule> parentModuleList, ApiScenarioModule parentModule, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, ApiScenarioModule> map, Map<String, String> idPathMap, Map<String, ApiScenarioModuleDTO> idModuleMap) {
+        //如果parentModule==null 则证明需要创建根目录同级的模块
+        ApiScenarioModule returnModule = null;
+
+        for (int i = 0; i < tagTree.length; i++) {
+            int finalI = i;
+            //查找上一级里面是否有当前全路径的第一级,没有则需要创建
+            List<ApiScenarioModule> collect = parentModuleList.stream().filter(t -> t.getName().equals(tagTree[finalI])).collect(Collectors.toList());
+
+            if (collect.isEmpty()) {
+                if (i == 0) {
+                    //证明需要在根目录创建,
+                    parentModule = new ApiScenarioModule();
+                    parentModule.setProjectId(pidChildrenMap.get("root").get(0).getProjectId());
+                    parentModule.setId("root");
+                    parentModule.setLevel(0);
+                } else {
+                    if (!parentModuleList.isEmpty() && parentModule == null) {
+                        String parentId = parentModuleList.get(0).getParentId();
+                        ApiScenarioModuleDTO apiScenarioModuleDTO = idModuleMap.get(parentId);
+                        parentModule = JSON.parseObject(JSON.toJSONString(apiScenarioModuleDTO), ApiScenarioModule.class);
+                    }
+                }
+                return createModule(tagTree, i, parentModule, map, pidChildrenMap, idPathMap);
+            } else {
+                returnModule = collect.get(0);
+                parentModule = collect.get(0);
+                parentModuleList = pidChildrenMap.get(collect.get(0).getId());
+            }
+        }
+        return returnModule;
+    }
+
+
+    private ApiScenarioModule createModule(String[] tagTree, int i, ApiScenarioModule parentModule, Map<String, ApiScenarioModule> map, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, String> idPathMap) {
+
+        ApiScenarioModule returnModule = null;
+        for (int i1 = i; i1 < tagTree.length; i1++) {
+            String pathName = tagTree[i1];
+
+            //创建模块
+            ApiScenarioModule newModule = this.getNewModule(pathName, parentModule.getProjectId(), parentModule.getLevel() + 1);
+            String parentId;
+            if (parentModule.getId().equals("root")) {
+                parentId = null;
+            } else {
+                parentId = parentModule.getId();
+            }
+            double pos = this.getNextLevelPos(parentModule.getProjectId(), parentModule.getLevel() + 1, parentId);
+            newModule.setPos(pos);
+            newModule.setParentId(parentId);
+            List<ApiScenarioModule> moduleList = pidChildrenMap.get(parentModule.getId());
+            if (moduleList != null) {
+                moduleList.add(newModule);
+            } else {
+                moduleList = new ArrayList<>();
+                moduleList.add(newModule);
+                pidChildrenMap.put(parentModule.getId(), moduleList);
+            }
+
+            String parentPath = idPathMap.get(parentModule.getId());
+            String path;
+            if (StringUtils.isNotBlank(parentPath)) {
+                path = parentPath + "/" + pathName;
+            } else {
+                path = "/" + pathName;
+            }
+            idPathMap.put(newModule.getId(), path);
+            map.putIfAbsent(path, newModule);
+            parentModule = newModule;
+            returnModule = newModule;
+        }
+        return returnModule;
+    }
+
+    private void buildProcessData(List<ApiScenarioModuleDTO> nodeTreeByProjectId, Map<String, List<ApiScenarioModule>> pidChildrenMap, Map<String, String> idPathMap, Map<String, String> parentModulePathMap) {
+        Map<String, List<ApiScenarioModuleDTO>> idChildrenMap = new HashMap<>();
+        int i = 0;
+        Map<String, List<ApiScenarioModule>> idModuleMap = new HashMap<>();
+        for (ApiScenarioModuleDTO scenarioModuleDTO : nodeTreeByProjectId) {
+            if (StringUtils.isBlank(scenarioModuleDTO.getParentId())) {
+                scenarioModuleDTO.setParentId("root");
+            }
+            String parentModulePath = parentModulePathMap.get(scenarioModuleDTO.getParentId());
+            if (parentModulePath != null) {
+                if (parentModulePath.equals("/root")) {
+                    scenarioModuleDTO.setPath("/" + scenarioModuleDTO.getName());
+                } else {
+                    scenarioModuleDTO.setPath(parentModulePath + "/" + scenarioModuleDTO.getName());
+                }
+            } else {
+                scenarioModuleDTO.setPath("/" + scenarioModuleDTO.getName());
+            }
+            idPathMap.put(scenarioModuleDTO.getId(), scenarioModuleDTO.getPath());
+
+            ApiScenarioModule scenarioModule = buildModule(idModuleMap, scenarioModuleDTO);
+            if (pidChildrenMap.get(scenarioModuleDTO.getParentId()) != null) {
+                pidChildrenMap.get(scenarioModuleDTO.getParentId()).add(scenarioModule);
+            } else {
+                pidChildrenMap.put(scenarioModuleDTO.getParentId(), idModuleMap.get(scenarioModuleDTO.getId()));
+            }
+            i = i + 1;
+            List<ApiScenarioModuleDTO> childrenList = idChildrenMap.get(scenarioModuleDTO.getId());
+            if (scenarioModuleDTO.getChildren() != null) {
+                if (childrenList != null) {
+                    childrenList.addAll(scenarioModuleDTO.getChildren());
+                } else {
+                    idChildrenMap.put(scenarioModuleDTO.getId(), scenarioModuleDTO.getChildren());
+                }
+            } else {
+                if (childrenList == null) {
+                    pidChildrenMap.put(scenarioModuleDTO.getId(), new ArrayList<>());
+                }
+            }
+            parentModulePathMap.put(scenarioModuleDTO.getId(), scenarioModuleDTO.getPath());
+        }
+        if (i == nodeTreeByProjectId.size() && nodeTreeByProjectId.size() > 0) {
+            Collection<List<ApiScenarioModuleDTO>> values = idChildrenMap.values();
+            List<ApiScenarioModuleDTO> childrenList = new ArrayList<>();
+            for (List<ApiScenarioModuleDTO> value : values) {
+                childrenList.addAll(value);
+            }
+            buildProcessData(childrenList, pidChildrenMap, idPathMap, parentModulePathMap);
+        }
+    }
+
+    private ApiScenarioModule buildModule(Map<String, List<ApiScenarioModule>> IdModuleMap, ApiScenarioModuleDTO scenarioModuleDTO) {
+        ApiScenarioModule scenarioModule = new ApiScenarioModule();
+        scenarioModule.setId(scenarioModuleDTO.getId());
+        scenarioModule.setName(scenarioModuleDTO.getName());
+        scenarioModule.setParentId(scenarioModuleDTO.getParentId());
+        scenarioModule.setProjectId(scenarioModuleDTO.getProjectId());
+        scenarioModule.setLevel(scenarioModuleDTO.getLevel());
+        List<ApiScenarioModule> moduleList = IdModuleMap.get(scenarioModuleDTO.getId());
+        if (moduleList != null) {
+            moduleList.add(scenarioModule);
+        } else {
+            moduleList = new ArrayList<>();
+            moduleList.add(scenarioModule);
+            IdModuleMap.put(scenarioModuleDTO.getId(), moduleList);
+        }
+        return scenarioModule;
+    }
 }
diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java
index b088e3b601..395da1207f 100644
--- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java
+++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java
@@ -9,6 +9,7 @@ import io.metersphere.api.dto.scenario.Scenario;
 import io.metersphere.base.domain.ApiDefinition;
 import io.metersphere.base.domain.ApiDefinitionExample;
 import io.metersphere.base.domain.ApiDefinitionExampleWithOperation;
+import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
 import io.metersphere.controller.request.BaseQueryRequest;
 import io.metersphere.dto.RelationshipGraphData;
 import org.apache.ibatis.annotations.Param;
@@ -64,13 +65,13 @@ public interface ExtApiDefinitionMapper {
 
     ApiDefinition selectUrlAndMethodById(String id);
 
-    int checkOriginalStatusByIds(@Param("ids")List<String> ids);
+    int checkOriginalStatusByIds(@Param("ids") List<String> ids);
 
     List<String> selectProjectIds();
 
     List<String> getIdsOrderByUpdateTime(@Param("projectId") String projectId);
 
-    Long getPreOrder(@Param("projectId")String projectId, @Param("baseOrder") Long baseOrder);
+    Long getPreOrder(@Param("projectId") String projectId, @Param("baseOrder") Long baseOrder);
 
     Long getLastOrder(@Param("projectId") String projectId, @Param("baseOrder") Long baseOrder);
 
@@ -89,4 +90,11 @@ public interface ExtApiDefinitionMapper {
     List<String> selectRefIdsForVersionChange(@Param("versionId") String versionId, @Param("projectId") String projectId);
 
     String selectNameById(String testId);
+
+    List<ApiDefinitionWithBLOBs> selectRepeatByBLOBs(@Param("blobs") List<ApiDefinitionWithBLOBs> blobs, @Param("projectId") String projectId, @Param("versionIds") Set<String> versionIds);
+
+    List<ApiDefinitionWithBLOBs> selectRepeatByBLOBsSameUrl(@Param("blobs") List<ApiDefinitionWithBLOBs> blobs, @Param("projectId") String projectId, @Param("moduleId") String moduleId, @Param("versionIds") Set<String> versionIds);
+
+    List<ApiDefinitionWithBLOBs> selectRepeatByProtocol(@Param("names") List<String> names, @Param("protocol") String protocol, @Param("versionIds") Set<String> versionIds);
+
 }
diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml
index 17a4fe94eb..14a73ce78e 100644
--- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml
+++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml
@@ -81,15 +81,17 @@
         </where>
     </sql>
     <sql id="Base_Column_List">
-    id, project_id, name,module_id,module_path,protocol ,path,method ,description, status, user_id, create_time, update_time
-      </sql>
+        id
+        , project_id, name,module_id,module_path,protocol ,path,method ,description, status, user_id, create_time, update_time
+    </sql>
     <sql id="Blob_Column_List">
         request
     </sql>
 
     <select id="selectByIds" resultType="io.metersphere.api.dto.definition.ApiComputeResult">
         SELECT t1.api_definition_id apiDefinitionId,count(t1.id) caseTotal,
-        SUM(case when t2.status ='success' then 1 else 0 end) as success ,SUM(case when t2.status ='error' then 1 else 0 end) as error,
+        SUM(case when t2.status ='success' then 1 else 0 end) as success ,SUM(case when t2.status ='error' then 1 else 0
+        end) as error,
         CONCAT(FORMAT(SUM(IF (t2.`status`='success',1,0))/COUNT(t1.id)*100,2),'%') passRate
         FROM api_test_case t1
         LEFT JOIN api_definition_exec_result t2 ON t1.last_result_id=t2.id
@@ -102,7 +104,8 @@
 
     <select id="selectByIdsAndStatusIsNotTrash" resultType="io.metersphere.api.dto.definition.ApiComputeResult">
         SELECT t1.api_definition_id apiDefinitionId,count(t1.id) caseTotal,
-        SUM(case when t2.status ='success' then 1 else 0 end) as success ,SUM(case when t2.status ='error' then 1 else 0 end) as error,
+        SUM(case when t2.status ='success' then 1 else 0 end) as success ,SUM(case when t2.status ='error' then 1 else 0
+        end) as error,
         CONCAT(FORMAT(SUM(IF (t2.`status`='success',1,0))/COUNT(t1.id)*100,2),'%') passRate
         FROM api_test_case t1
         LEFT JOIN api_definition_exec_result t2 ON t1.last_result_id=t2.id
@@ -193,7 +196,18 @@
                 <property name="object" value="${condition}.tags"/>
             </include>
         </if>
-
+        <if test="${condition}.module != null">
+            and api_definition.module_path
+            <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
+                <property name="object" value="${condition}.module"/>
+            </include>
+        </if>
+        <if test="${condition}.caseCount != null">
+            and api_definition.case_total
+            <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
+                <property name="object" value="${condition}.caseCount"/>
+            </include>
+        </if>
 
     </sql>
 
@@ -242,10 +256,13 @@
     </sql>
 
     <select id="list" resultType="io.metersphere.api.dto.definition.ApiDefinitionResult">
-        select api_definition.id, api_definition.project_id, api_definition.num, api_definition.tags,api_definition.original_state,
+        select api_definition.id, api_definition.project_id, api_definition.num,
+        api_definition.tags,api_definition.original_state,
         api_definition.name,api_definition.protocol,api_definition.path,api_definition.module_id,api_definition.module_path,api_definition.method,
         api_definition.description,api_definition.request,api_definition.response,api_definition.environment_id,
-        api_definition.status, api_definition.user_id, api_definition.create_time, api_definition.update_time, api_definition.delete_user_id, api_definition.create_user,api_definition.delete_time, api_definition.remark, api_definition.version_id,
+        api_definition.status, api_definition.user_id, api_definition.create_time, api_definition.update_time,
+        api_definition.delete_user_id, api_definition.create_user,api_definition.delete_time, api_definition.remark,
+        api_definition.version_id,
         project_version.name as version_name, api_definition.ref_id, user.name as user_name
         from api_definition
         left join user on api_definition.user_id = user.id
@@ -268,12 +285,16 @@
     </select>
 
     <select id="weekList" resultType="io.metersphere.api.dto.definition.ApiDefinitionResult">
-        select api_definition.id, api_definition.project_id, api_definition.num, api_definition.tags,api_definition.original_state,
+        select api_definition.id, api_definition.project_id, api_definition.num,
+        api_definition.tags,api_definition.original_state,
         api_definition.name,api_definition.protocol,api_definition.path,api_definition.module_id,api_definition.module_path,api_definition.method,
         api_definition.description,api_definition.environment_id,
-        api_definition.status, api_definition.user_id, api_definition.create_time, api_definition.update_time, project.name as
-        project_name, user.name as user_name,deleteUser.name AS delete_user,api_definition.delete_time, api_definition.remark
-        from (select * from api_definition where update_time >= #{startTimestamp} order by update_time desc)api_definition
+        api_definition.status, api_definition.user_id, api_definition.create_time, api_definition.update_time,
+        project.name as
+        project_name, user.name as user_name,deleteUser.name AS delete_user,api_definition.delete_time,
+        api_definition.remark
+        from (select * from api_definition where update_time >= #{startTimestamp} order by update_time
+        desc)api_definition
         left join project on api_definition.project_id = project.id
         left join user on api_definition.user_id = user.id
         left join user deleteUser on api_definition.delete_user_id = deleteUser.id
@@ -303,7 +324,8 @@
         from api_definition
         left join project on api_definition.project_id = project.id
         left join user on api_definition.user_id = user.id
-        left join project_version on api_definition.project_id = project_version.project_id and api_definition.version_id = project_version.id
+        left join project_version on api_definition.project_id = project_version.project_id and
+        api_definition.version_id = project_version.id
         WHERE api_definition.id IN
         <foreach collection="ids" item="v" separator="," open="(" close=")">
             #{v}
@@ -347,33 +369,48 @@
     </update>
 
     <select id="countProtocolByProjectID" resultType="io.metersphere.api.dto.datacount.ApiDataCountResult">
-        SELECT protocol AS groupField,count(DISTINCT ref_id) AS countNumber
+        SELECT protocol AS groupField, count(DISTINCT ref_id) AS countNumber
         FROM api_definition
         WHERE project_id = #{0}
-            AND `status` != 'Trash'
+          AND `status` != 'Trash'
             AND latest = 1
         GROUP BY protocol
     </select>
     <select id="countStateByProjectID" resultType="io.metersphere.api.dto.datacount.ApiDataCountResult">
-        SELECT status AS groupField,count(id) AS countNumber FROM api_definition  WHERE project_id = #{0} AND `status` != 'Trash' AND latest = 1 GROUP BY status
+        SELECT status AS groupField, count(id) AS countNumber
+        FROM api_definition
+        WHERE project_id = #{0}
+          AND `status` != 'Trash' AND latest = 1
+        GROUP BY status
     </select>
     <select id="countByProjectIDAndCreateInThisWeek" resultType="java.lang.Long">
-        SELECT count(id) AS countNumber FROM api_definition
+        SELECT count(id) AS countNumber
+        FROM api_definition
         WHERE project_id = #{projectId}
-        AND create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp} AND `status` != 'Trash' AND latest = 1
+          AND create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp}
+          AND `status` != 'Trash' AND latest = 1
     </select>
     <select id="countApiCoverageByProjectID" resultType="io.metersphere.api.dto.datacount.ApiDataCountResult">
-        SELECT count(api.id) AS countNumber, if(test_case_api.api_definition_id is null,"uncoverage","coverage") AS groupField  FROM api_definition api left Join (
+        SELECT count(api.id)                                                         AS countNumber,
+               if(test_case_api.api_definition_id is null, "uncoverage", "coverage") AS groupField
+        FROM api_definition api
+                 left Join (
             SELECT DISTINCT api_definition_id FROM api_test_case WHERE status is null or status != 'Trash'
         ) test_case_api ON api.id = test_case_api.api_definition_id
-        WHERE api.project_id = #{0} and  api.`status` != 'Trash' and api.latest = 1
+        WHERE api.project_id = #{0}
+          and api.`status` != 'Trash' and api.latest = 1
         GROUP BY groupField
     </select>
     <select id="getNextNum" resultType="io.metersphere.base.domain.ApiDefinition">
-        SELECT * FROM api_definition WHERE api_definition.project_id = #{projectId} ORDER BY num DESC LIMIT 1;
+        SELECT *
+        FROM api_definition
+        WHERE api_definition.project_id = #{projectId}
+        ORDER BY num DESC LIMIT 1;
     </select>
     <select id="selectUrlAndMethodById" resultType="io.metersphere.base.domain.ApiDefinition">
-        SELECT method,path FROM api_definition WHERE id = #{0}
+        SELECT method, path
+        FROM api_definition
+        WHERE id = #{0}
     </select>
     <select id="listRelevance" resultType="io.metersphere.api.dto.definition.ApiDefinitionResult">
         select
@@ -405,7 +442,8 @@
         api_definition.`order`,
         api_definition.ref_id
         from api_definition
-        left join project_version on api_definition.project_id = project_version.project_id and api_definition.version_id = project_version.id
+        left join project_version on api_definition.project_id = project_version.project_id and
+        api_definition.version_id = project_version.id
         <where>
             <if test="request.combine != null">
                 <include refid="combine">
@@ -600,9 +638,10 @@
     </select>
 
     <select id="selectEffectiveIdByProjectId" resultType="io.metersphere.base.domain.ApiDefinition">
-        select id,path,method
+        select id, path, method
         from api_definition
-        WHERE project_id = #{0} AND status != 'Trash' AND protocol = 'HTTP' AND latest = 1
+        WHERE project_id = #{0}
+          AND status != 'Trash' AND protocol = 'HTTP' AND latest = 1
     </select>
 
     <select id="moduleCount" resultType="java.lang.Integer">
@@ -801,10 +840,14 @@
     </sql>
 
     <select id="selectProjectIds" resultType="java.lang.String">
-        select DISTINCT project_id from api_definition;
+        select DISTINCT project_id
+        from api_definition;
     </select>
     <select id="getIdsOrderByUpdateTime" resultType="java.lang.String">
-        select id from api_definition where project_id = #{projectId} order by update_time ASC;
+        select id
+        from api_definition
+        where project_id = #{projectId}
+        order by update_time ASC;
     </select>
 
     <select id="getLastOrder" resultType="java.lang.Long">
@@ -824,8 +867,10 @@
     </select>
 
     <select id="countQuotedApiByProjectId" resultType="java.lang.Long">
-        SELECT COUNT(id) FROM api_definition
-        WHERE project_id = #{0} AND `status` != 'Trash'
+        SELECT COUNT(id)
+        FROM api_definition
+        WHERE project_id = #{0}
+          AND `status` != 'Trash'
           AND (
                     id IN (
                     SELECT reference_id FROM api_scenario_reference_id WHERE api_scenario_id in (
@@ -866,7 +911,8 @@
         and api_definition.status != 'Trash';
     </select>
 
-    <select id="countByExample" parameterType="io.metersphere.base.domain.ApiDefinitionExample" resultType="java.lang.Long">
+    <select id="countByExample" parameterType="io.metersphere.base.domain.ApiDefinitionExample"
+            resultType="java.lang.Long">
         select count(DISTINCT ref_id) from api_definition
         <if test="_parameter != null">
             <include refid="io.metersphere.base.mapper.ApiDefinitionMapper.Example_Where_Clause"/>
@@ -888,44 +934,41 @@
     <update id="clearLatestVersion">
         UPDATE api_definition
         SET latest = 0
-        <where>
-            <if test="refId != null">
-                and ref_id = #{refId}
-            </if>
-        </where>
+        where ref_id = #{refId}
     </update>
 
     <update id="addLatestVersion">
         UPDATE api_definition
-        INNER JOIN ((
-        SELECT tmp.id
-        FROM api_definition tmp
-        JOIN project_version
-        ON tmp.project_id = project_version.project_id AND
-        tmp.version_id = project_version.id AND project_version.latest = TRUE
-        WHERE ref_id = #{refId,jdbcType=VARCHAR}
-        LIMIT 1
-        )
-        UNION ALL
-        (
-        SELECT tmp.id
-        FROM api_definition tmp
-        JOIN project_version
-        ON tmp.project_id = project_version.project_id AND
-        tmp.version_id = project_version.id
-        AND NOT EXISTS(SELECT ref_id
-        FROM api_definition tmp2
-        JOIN project_version
-        ON tmp2.project_id =
-        project_version.project_id AND
-        version_id =
-        project_version.id AND
-        project_version.latest = TRUE
-        WHERE tmp.ref_id = tmp2.ref_id)
-        WHERE tmp.ref_id = #{refId,jdbcType=VARCHAR}
-        ORDER BY tmp.update_time DESC
-        LIMIT 1)) AS t ON api_definition.id = t.id
-        SET api_definition.latest = TRUE
+            INNER JOIN ((
+            SELECT tmp.id
+            FROM api_definition tmp
+            JOIN project_version
+            ON tmp.project_id = project_version.project_id AND
+            tmp.version_id = project_version.id AND project_version.latest = TRUE
+            WHERE ref_id = #{refId,jdbcType=VARCHAR}
+            LIMIT 1
+            )
+            UNION ALL
+            (
+            SELECT tmp.id
+            FROM api_definition tmp
+            JOIN project_version
+            ON tmp.project_id = project_version.project_id AND
+            tmp.version_id = project_version.id
+            AND NOT EXISTS (SELECT ref_id
+            FROM api_definition tmp2
+            JOIN project_version
+            ON tmp2.project_id =
+            project_version.project_id AND
+            version_id =
+            project_version.id AND
+            project_version.latest = TRUE
+            WHERE tmp.ref_id = tmp2.ref_id)
+            WHERE tmp.ref_id = #{refId,jdbcType=VARCHAR}
+            ORDER BY tmp.update_time DESC
+            LIMIT 1)) AS t
+        ON api_definition.id = t.id
+            SET api_definition.latest = TRUE
         WHERE ref_id = #{refId,jdbcType=VARCHAR}
     </update>
 
@@ -933,13 +976,70 @@
         SELECT DISTINCT ref_id
         FROM api_definition
         WHERE ref_id NOT IN (
-                SELECT DISTINCT ref_id
-                FROM api_definition
-                WHERE version_id = #{versionId} AND project_id = #{projectId}
-        ) AND project_id = #{projectId}
+            SELECT DISTINCT ref_id
+            FROM api_definition
+            WHERE version_id = #{versionId}
+              AND project_id = #{projectId}
+        )
+          AND project_id = #{projectId}
     </select>
 
     <select id="selectNameById" resultType="java.lang.String">
-        SELECT name FROM api_definition WHERE id = #{0}
+        SELECT name
+        FROM api_definition
+        WHERE id = #{0}
     </select>
+
+    <select id="selectRepeatByBLOBs" resultType="io.metersphere.base.domain.ApiDefinitionWithBLOBs">
+        SELECT * from api_definition
+        <include refid="Same_Where_Clause"/>
+        and status != 'Trash'
+        and project_id = #{projectId}
+        and version_id in
+        <foreach collection="versionIds" item="versionId" separator="," open="(" close=")">
+            #{versionId}
+        </foreach>
+    </select>
+    <select id="selectRepeatByBLOBsSameUrl" resultType="io.metersphere.base.domain.ApiDefinitionWithBLOBs">
+        SELECT * from api_definition
+        <include refid="Same_Where_Clause"/>
+        and status != 'TRASH'
+        and project_id = #{projectId}
+        and module_id = #{moduleId}
+        and version_id in
+        <foreach collection="versionIds" item="versionId" separator="," open="(" close=")">
+            #{versionId}
+        </foreach>
+    </select>
+    <select id="selectRepeatByProtocol" resultType="io.metersphere.base.domain.ApiDefinitionWithBLOBs">
+        SELECT * from api_definition
+        where name in
+        <foreach collection="names" item="name" separator="," open="(" close=")">
+            #{name}
+        </foreach>
+        and version_id in
+        <foreach collection="versionIds" item="versionId" separator="," open="(" close=")">
+            #{versionId}
+        </foreach>
+        and protocol = #{protocol}
+    </select>
+    <sql id="Same_Where_Clause">
+        <where>
+            <if test="blobs">
+                <trim prefix="(" prefixOverrides="and" suffix=")">
+                    <foreach collection="blobs" item="blob" separator="or">
+                        <trim prefix="(" prefixOverrides="and" suffix=")">
+                            <if test="blob.method">
+                                and api_definition.method = #{blob.method}
+                            </if>
+                            <if test="blob.path">
+                                and api_definition.path = #{blob.path}
+                            </if>
+                        </trim>
+                    </foreach>
+                </trim>
+            </if>
+        </where>
+    </sql>
+
 </mapper>
diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java
index 568e9010a9..66d880ca87 100644
--- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java
+++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java
@@ -90,4 +90,10 @@ public interface ExtApiScenarioMapper {
     List<String> selectRefIdsForVersionChange(@Param("versionId") String versionId, @Param("projectId") String projectId);
 
     List<ApiScenarioWithBLOBs> selectByStatusIsNotTrash();
+
+    List<ApiScenarioWithBLOBs> selectRepeatByBLOBs(@Param("blobs") List<ApiScenarioWithBLOBs> blobs, @Param("projectId") String projectId, @Param("versionIds") Set<String> versionIds);
+
+    List<ApiScenarioWithBLOBs> selectRepeatByBLOBsSameUrl(@Param("blobs") List<ApiScenarioWithBLOBs> blobs, @Param("projectId") String projectId, @Param("moduleId") String moduleId, @Param("versionIds") Set<String> versionIds);
+
+
 }
diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml
index 0ffcdd12b6..5df55a31a4 100644
--- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml
+++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml
@@ -754,4 +754,46 @@
         FROM api_scenario
         WHERE `status` != 'Trash' AND project_id IN (SELECT id FROM project);
     </select>
+    <select id="selectRepeatByBLOBs" resultType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
+        SELECT * from api_scenario
+        <include refid="Same_Where_Clause"/>
+        and status != 'Trash'
+        and project_id = #{projectId}
+        and version_id in
+        <foreach collection="versionIds" item="versionId" separator="," open="(" close=")">
+            #{versionId}
+        </foreach>
+    </select>
+
+    <select id="selectRepeatByBLOBsSameUrl" resultType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
+        SELECT * from api_scenario
+        <include refid="Same_Where_Clause"/>
+        and status != 'TRASH'
+        and api_scenario_module_id = #{moduleId}
+        and project_id = #{projectId}
+        and version_id in
+        <foreach collection="versionIds" item="versionId" separator="," open="(" close=")">
+            #{versionId}
+        </foreach>
+    </select>
+
+    <sql id="Same_Where_Clause">
+        <where>
+            <if test="blobs">
+                <trim prefix="(" prefixOverrides="and" suffix=")">
+                    <foreach collection="blobs" item="blob" separator="or">
+                        <trim prefix="(" prefixOverrides="and" suffix=")">
+                            <if test="blob.name">
+                                and api_scenario.name = #{blob.name}
+                            </if>
+                        </trim>
+
+                    </foreach>
+                </trim>
+            </if>
+
+        </where>
+    </sql>
+
 </mapper>
+
diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.xml
index 6d52431ea6..ced38fd300 100644
--- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.xml
+++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.xml
@@ -103,9 +103,10 @@
             parameterType="io.metersphere.performance.request.QueryTestPlanRequest">
         SELECT load_test.*, project.name AS project_name, user.name AS user_name, project_version.name as version_name
         FROM load_test
-                     LEFT JOIN project ON load_test.project_id = project.id
-                     LEFT JOIN user ON load_test.user_id = user.id
-        LEFT JOIN project_version on project.id = project_version.project_id AND project_version.id = load_test.version_id
+        LEFT JOIN project ON load_test.project_id = project.id
+        LEFT JOIN user ON load_test.user_id = user.id
+        LEFT JOIN project_version on project.id = project_version.project_id AND project_version.id =
+        load_test.version_id
         <where>
             <if test="request.combine != null">
                 <include refid="combine">
@@ -191,7 +192,7 @@
     <select id="checkLoadTestOwner" resultType="int">
         SELECT COUNT(1)
         FROM load_test
-                     LEFT JOIN project ON load_test.project_id = project.id
+        LEFT JOIN project ON load_test.project_id = project.id
         <where>
             <if test="testId != null">
                 and load_test.id = #{testId}
@@ -205,7 +206,10 @@
         </where>
     </select>
     <select id="getNextNum" resultType="io.metersphere.base.domain.LoadTest">
-        select * from load_test lt where lt.project_id = #{projectId} ORDER BY num DESC LIMIT 1;
+        select *
+        from load_test lt
+        where lt.project_id = #{projectId}
+        ORDER BY num DESC LIMIT 1;
     </select>
 
     <select id="moduleCount" resultType="java.lang.Integer">
@@ -271,7 +275,7 @@
             </foreach>
         </if>
     </sql>
-    
+
     <sql id="queryWhereCondition">
         <where>
             <if test="request.combine != null">
@@ -316,7 +320,6 @@
     </sql>
 
 
-
     <select id="getProjectFiles" resultType="io.metersphere.base.domain.FileMetadata">
         SELECT file_metadata.*
         FROM file_metadata
@@ -332,10 +335,14 @@
     </select>
 
     <select id="selectProjectIds" resultType="java.lang.String">
-        select DISTINCT project_id from load_test;
+        select DISTINCT project_id
+        from load_test;
     </select>
     <select id="getIdsOrderByUpdateTime" resultType="java.lang.String">
-        select id from load_test where project_id = #{projectId} order by update_time ASC;
+        select id
+        from load_test
+        where project_id = #{projectId}
+        order by update_time ASC;
     </select>
 
     <select id="getLastOrder" resultType="java.lang.Long">
@@ -368,62 +375,61 @@
 
     <update id="addLatestVersion">
         UPDATE load_test
-                INNER JOIN ((
-                                    SELECT tmp.id
-                                    FROM load_test tmp
-                                                 JOIN project_version
-                                            ON tmp.project_id = project_version.project_id AND
-                                               tmp.version_id = project_version.id AND project_version.latest = TRUE
-                                    WHERE ref_id = #{refId,jdbcType=VARCHAR}
-                                    LIMIT 1
-                                    )
-                            UNION ALL
-                            (
-                                    SELECT tmp.id
-                                    FROM load_test tmp
-                                                 JOIN project_version
-                                            ON tmp.project_id = project_version.project_id AND
-                                               tmp.version_id = project_version.id
-                                                    AND NOT EXISTS(SELECT ref_id
-                                                                   FROM load_test tmp2
-                                                                                JOIN project_version
-                                                                           ON tmp2.project_id =
-                                                                              project_version.project_id AND
-                                                                              version_id =
-                                                                              project_version.id AND
-                                                                              project_version.latest = TRUE
-                                                                   WHERE tmp.ref_id = tmp2.ref_id)
-                                    WHERE tmp.ref_id = #{refId,jdbcType=VARCHAR}
-                                    ORDER BY tmp.update_time DESC
-                                    LIMIT 1)) AS t ON load_test.id = t.id
-        SET load_test.latest = TRUE
+            INNER JOIN ((
+            SELECT tmp.id
+            FROM load_test tmp
+            JOIN project_version
+            ON tmp.project_id = project_version.project_id AND
+            tmp.version_id = project_version.id AND project_version.latest = TRUE
+            WHERE ref_id = #{refId,jdbcType=VARCHAR}
+            LIMIT 1
+            )
+            UNION ALL
+            (
+            SELECT tmp.id
+            FROM load_test tmp
+            JOIN project_version
+            ON tmp.project_id = project_version.project_id AND
+            tmp.version_id = project_version.id
+            AND NOT EXISTS (SELECT ref_id
+            FROM load_test tmp2
+            JOIN project_version
+            ON tmp2.project_id =
+            project_version.project_id AND
+            version_id =
+            project_version.id AND
+            project_version.latest = TRUE
+            WHERE tmp.ref_id = tmp2.ref_id)
+            WHERE tmp.ref_id = #{refId,jdbcType=VARCHAR}
+            ORDER BY tmp.update_time DESC
+            LIMIT 1)) AS t
+        ON load_test.id = t.id
+            SET load_test.latest = TRUE
         WHERE ref_id = #{refId,jdbcType=VARCHAR}
     </update>
 
     <update id="clearLatestVersion">
         UPDATE load_test
         SET latest = 0
-        <where>
-            <if test="refId != null">
-                and ref_id = #{refId}
-            </if>
-        </where>
+        where ref_id = #{refId}
     </update>
 
     <select id="selectRefIdsForVersionChange" resultType="java.lang.String">
         SELECT DISTINCT ref_id
         FROM load_test
         WHERE ref_id NOT IN (
-        SELECT DISTINCT ref_id
-        FROM load_test
-        WHERE version_id = #{versionId} AND project_id = #{projectId}
-        ) AND project_id = #{projectId}
+            SELECT DISTINCT ref_id
+            FROM load_test
+            WHERE version_id = #{versionId}
+              AND project_id = #{projectId}
+        )
+          AND project_id = #{projectId}
     </select>
 
     <select id="getFileMetadataByIds" resultType="io.metersphere.base.domain.FileMetadata">
         SELECT file_metadata.*
         FROM load_test_file
-                     JOIN file_metadata ON file_id = file_metadata.id
+                 JOIN file_metadata ON file_id = file_metadata.id
         WHERE test_id = #{testId}
         ORDER BY sort
     </select>
diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtSwaggerUrlScheduleMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtSwaggerUrlScheduleMapper.xml
index e803a7256b..60b6707435 100644
--- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtSwaggerUrlScheduleMapper.xml
+++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtSwaggerUrlScheduleMapper.xml
@@ -12,7 +12,7 @@
                sup.config,
                sch.value as rule,
                sch.enable,
-               sch.id as taskId
+               sch.id    as taskId
         FROM swagger_url_project sup
                  INNER JOIN schedule sch ON sup.id = sch.resource_id
         WHERE sup.project_id = #{projectId}
diff --git a/frontend/src/business/components/api/definition/components/import/ApiImport.vue b/frontend/src/business/components/api/definition/components/import/ApiImport.vue
index 7f7914c083..77ca545ae0 100644
--- a/frontend/src/business/components/api/definition/components/import/ApiImport.vue
+++ b/frontend/src/business/components/api/definition/components/import/ApiImport.vue
@@ -438,11 +438,6 @@ export default {
       param.saved = this.saved;
       param.model = this.model;
       if (this.currentModule) {
-        if (!this.formData.moduleId || this.formData.moduleId.length === 0) {
-          param.moduleId = this.currentModule[0].id;
-        } else {
-          param.moduleId = this.formData.moduleId
-        }
         param.modeId = this.formData.modeId
       }
       param.projectId = this.projectId;
@@ -572,5 +567,4 @@ export default {
   height: 200px;
 }
 
-
 </style>