From 6ee4ca092143327fd33ceba9735e37bab2c31419 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Tue, 20 Oct 2020 17:41:06 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E6=B5=8B=E8=AF=95=E8=B7=9F=E8=B8=AA):?= =?UTF-8?q?=20=E5=AF=BC=E5=85=A5=E7=94=A8=E4=BE=8B=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=BC=98=E5=8C=96=EF=BC=8C=E6=8C=89=E7=85=A7?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E8=BF=9B=E8=A1=8C=E5=88=92=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../track/service/TestCaseService.java | 22 +++--- .../io/metersphere/xmind/XmindCaseParser.java | 60 +++++++------- .../metersphere/xmind/parser/XmindParser.java | 2 +- .../metersphere/xmind/utils/ProcMessage.java | 78 +++++++++++++++++++ frontend/src/i18n/en-US.js | 2 +- frontend/src/i18n/zh-CN.js | 2 +- frontend/src/i18n/zh-TW.js | 2 +- 7 files changed, 117 insertions(+), 51 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/xmind/utils/ProcMessage.java diff --git a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java index 1503384dc0..726f5f0379 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java @@ -263,25 +263,22 @@ public class TestCaseService { .map(TestCase::getName) .collect(Collectors.toSet()); List> errList = null; - if (multipartFile == null) + if (multipartFile == null) { MSException.throwException(Translator.get("upload_fail")); - + } if (multipartFile.getOriginalFilename().endsWith(".xmind")) { try { - errList = new ArrayList<>(); XmindCaseParser xmindParser = new XmindCaseParser(this, userId, projectId, testCaseNames); - String processLog = xmindParser.parse(multipartFile); - if (!StringUtils.isEmpty(processLog)) { - excelResponse.setSuccess(false); - ExcelErrData excelErrData = new ExcelErrData(null, 1, Translator.get("upload_fail") + ":" + processLog); - errList.add(excelErrData); - excelResponse.setErrList(errList); - } else if (xmindParser.getNodePaths().isEmpty() && xmindParser.getTestCase().isEmpty()) { - excelResponse.setSuccess(false); + errList = xmindParser.parse(multipartFile); + if (xmindParser.getNodePaths().isEmpty() && xmindParser.getTestCase().isEmpty()) { + if (errList == null) { + errList = new ArrayList<>(); + } ExcelErrData excelErrData = new ExcelErrData(null, 1, Translator.get("upload_fail") + ":" + Translator.get("upload_content_is_null")); errList.add(excelErrData); excelResponse.setErrList(errList); - } else { + } + if (errList.isEmpty()) { if (!xmindParser.getNodePaths().isEmpty()) { testCaseNodeService.createNodes(xmindParser.getNodePaths(), projectId); } @@ -290,7 +287,6 @@ public class TestCaseService { this.saveImportData(xmindParser.getTestCase(), projectId); xmindParser.clear(); } - excelResponse.setSuccess(true); } } catch (Exception e) { LogUtil.error(e.getMessage(), e); diff --git a/backend/src/main/java/io/metersphere/xmind/XmindCaseParser.java b/backend/src/main/java/io/metersphere/xmind/XmindCaseParser.java index 9eaaca932f..8137156a8e 100644 --- a/backend/src/main/java/io/metersphere/xmind/XmindCaseParser.java +++ b/backend/src/main/java/io/metersphere/xmind/XmindCaseParser.java @@ -6,12 +6,14 @@ import com.google.common.collect.ImmutableMap; import io.metersphere.base.domain.TestCaseWithBLOBs; import io.metersphere.commons.constants.TestCaseConstants; import io.metersphere.commons.utils.BeanUtils; +import io.metersphere.excel.domain.ExcelErrData; import io.metersphere.excel.domain.TestCaseExcelData; import io.metersphere.i18n.Translator; import io.metersphere.track.service.TestCaseService; import io.metersphere.xmind.parser.XmindParser; import io.metersphere.xmind.parser.pojo.Attached; import io.metersphere.xmind.parser.pojo.JsonRootBean; +import io.metersphere.xmind.utils.ProcMessage; import org.apache.commons.lang3.StringUtils; import org.springframework.web.multipart.MultipartFile; @@ -32,7 +34,7 @@ public class XmindCaseParser { /** * 过程校验记录 */ - private StringBuffer process; + private ProcMessage process; /** * 已存在用例名称 */ @@ -57,7 +59,7 @@ public class XmindCaseParser { this.testCaseNames = testCaseNames; testCases = new LinkedList<>(); compartDatas = new ArrayList<>(); - process = new StringBuffer(); + process = new ProcMessage(); nodePaths = new ArrayList<>(); } @@ -90,15 +92,15 @@ public class XmindCaseParser { nodePaths.forEach(nodePath -> { String[] nodes = nodePath.split("/"); if (nodes.length > TestCaseConstants.MAX_NODE_DEPTH + 1) { - process.append(Translator.get("test_case_node_level_tip") + - TestCaseConstants.MAX_NODE_DEPTH + Translator.get("test_case_node_level") + "; "); + process.add(Translator.get("test_case_node_level_tip") + + TestCaseConstants.MAX_NODE_DEPTH + Translator.get("test_case_node_level"), nodePath); } String path = ""; for (int i = 0; i < nodes.length; i++) { if (i != 0 && StringUtils.equals(nodes[i].trim(), "")) { - process.append(Translator.get("module") + ":【" + path + "】" + Translator.get("module_not_null") + "; "); + process.add(Translator.get("module_not_null"), path); } else if (nodes[i].trim().length() > 30) { - process.append(nodes[i].trim() + ":" + Translator.get("test_track.length_less_than") + "30 ;"); + process.add(Translator.get("module") + Translator.get("test_track.length_less_than") + "30", path + nodes[i].trim()); } else { path += nodes[i].trim() + "/"; } @@ -109,7 +111,7 @@ public class XmindCaseParser { /** * 验证用例的合规性 */ - private boolean validate(TestCaseWithBLOBs data) { + private void validate(TestCaseWithBLOBs data) { String nodePath = data.getNodePath(); if (!nodePath.startsWith("/")) { nodePath = "/" + nodePath; @@ -119,37 +121,36 @@ public class XmindCaseParser { } data.setNodePath(nodePath); - StringBuilder stringBuilder = new StringBuilder(); if (data.getName().length() > 50) { - stringBuilder.append(data.getName() + ":" + Translator.get("test_case") + Translator.get("test_track.length_less_than") + "50 ;"); + process.add(Translator.get("test_case") + Translator.get("test_track.length_less_than") + "50", nodePath + data.getName()); } if (!StringUtils.isEmpty(nodePath)) { String[] nodes = nodePath.split("/"); if (nodes.length > TestCaseConstants.MAX_NODE_DEPTH + 1) { - stringBuilder.append(Translator.get("test_case_node_level_tip") + - TestCaseConstants.MAX_NODE_DEPTH + Translator.get("test_case_node_level") + "; "); + process.add(Translator.get("test_case_node_level_tip") + + TestCaseConstants.MAX_NODE_DEPTH + Translator.get("test_case_node_level"), nodePath); } for (int i = 0; i < nodes.length; i++) { if (i != 0 && StringUtils.equals(nodes[i].trim(), "")) { - stringBuilder.append(Translator.get("test_case") + ":【" + data.getName() + "】" + Translator.get("module_not_null") + "; "); + process.add(Translator.get("test_case") + Translator.get("module_not_null"), nodePath + data.getName()); break; } else if (nodes[i].trim().length() > 30) { - stringBuilder.append(nodes[i].trim() + ":" + Translator.get("module") + Translator.get("test_track.length_less_than") + "30 ;"); + process.add(Translator.get("module") + Translator.get("test_track.length_less_than") + "30 ", nodes[i].trim()); break; } } } if (StringUtils.equals(data.getType(), TestCaseConstants.Type.Functional.getValue()) && StringUtils.equals(data.getMethod(), TestCaseConstants.Method.Auto.getValue())) { - stringBuilder.append(Translator.get("functional_method_tip") + "; "); + process.add(Translator.get("functional_method_tip"), nodePath + data.getName()); } if (testCaseNames.contains(data.getName())) { boolean dbExist = testCaseService.exist(data); if (dbExist) { - stringBuilder.append(Translator.get("test_case_already_exists_excel") + ":" + data.getName() + "; "); + process.add(Translator.get("test_case_already_exists_excel"), nodePath + data.getName()); } } else { testCaseNames.add(data.getName()); @@ -157,26 +158,19 @@ public class XmindCaseParser { // 用例等级和用例性质处理 if (!priorityList.contains(data.getPriority())) { - stringBuilder.append(data.getName() + ":" + Translator.get("test_case_priority") + Translator.get("incorrect_format") + "; "); + process.add(Translator.get("test_case_priority") + Translator.get("incorrect_format"), nodePath + data.getName()); } if (data.getType() == null) { - stringBuilder.append(data.getName() + ":" + Translator.get("test_case_type") + Translator.get("incorrect_format") + "; "); + process.add(Translator.get("test_case_type") + Translator.get("incorrect_format"), nodePath + data.getName()); } - // 重复用例校验 TestCaseExcelData compartData = new TestCaseExcelData(); BeanUtils.copyBean(compartData, data); if (compartDatas.contains(compartData)) { - stringBuilder.append(Translator.get("test_case_already_exists_excel") + ":" + compartData.getName() + "; "); - } - if (!StringUtils.isEmpty(stringBuilder.toString())) { - process.append(stringBuilder.toString()); - return false; + process.add(Translator.get("test_case_already_exists_excel"), nodePath + compartData.getName()); } compartDatas.add(compartData); - - return true; } /** @@ -267,7 +261,7 @@ public class XmindCaseParser { String tc = title.replace(":", ":"); String[] tcArr = tc.split(":"); if (tcArr.length != 2) { - process.append(Translator.get("test_case_name") + "【 " + title + " 】" + Translator.get("incorrect_format")); + process.add(Translator.get("test_case_name") + Translator.get("incorrect_format"), title); return; } // 用例名称 @@ -301,17 +295,15 @@ public class XmindCaseParser { }); } testCase.setSteps(this.getSteps(steps)); - + testCases.add(testCase); // 校验合规性 - if (validate(testCase)) { - testCases.add(testCase); - } + validate(testCase); } /** * 导入思维导图处理 */ - public String parse(MultipartFile multipartFile) { + public List> parse(MultipartFile multipartFile) { try { // 获取思维导图内容 List roots = XmindParser.parseObject(multipartFile); @@ -321,7 +313,7 @@ public class XmindCaseParser { for (Attached item : root.getRootTopic().getChildren().getAttached()) { // 用例 if (isAvailable(item.getTitle(), TC_REGEX)) { - return replace(item.getTitle(), TC_REGEX) + ":" + Translator.get("test_case_create_module_fail"); + return process.parse(replace(item.getTitle(), TC_REGEX) + ":" + Translator.get("test_case_create_module_fail")); } else { String nodePath = item.getTitle(); item.setPath(nodePath); @@ -344,8 +336,8 @@ public class XmindCaseParser { //检查目录合规性 this.validate(); } catch (Exception ex) { - return ex.getMessage(); + return process.parse(ex.getMessage()); } - return process.toString(); + return process.parse(); } } diff --git a/backend/src/main/java/io/metersphere/xmind/parser/XmindParser.java b/backend/src/main/java/io/metersphere/xmind/parser/XmindParser.java index f93356a645..f1e29b585a 100644 --- a/backend/src/main/java/io/metersphere/xmind/parser/XmindParser.java +++ b/backend/src/main/java/io/metersphere/xmind/parser/XmindParser.java @@ -73,7 +73,7 @@ public class XmindParser { JsonRootBean jsonRootBean = JSON.parseObject(content, JsonRootBean.class); jsonRootBeans.add(jsonRootBean); } - if (caseCount > 500) { + if (caseCount > 800) { MSException.throwException(Translator.get("import_xmind_count_error")); } } diff --git a/backend/src/main/java/io/metersphere/xmind/utils/ProcMessage.java b/backend/src/main/java/io/metersphere/xmind/utils/ProcMessage.java new file mode 100644 index 0000000000..271eaf4d13 --- /dev/null +++ b/backend/src/main/java/io/metersphere/xmind/utils/ProcMessage.java @@ -0,0 +1,78 @@ +package io.metersphere.xmind.utils; + +import com.sun.deploy.util.StringUtils; +import io.metersphere.excel.domain.ExcelErrData; +import io.metersphere.excel.domain.TestCaseExcelData; +import io.metersphere.i18n.Translator; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Getter +@Setter +public class ProcMessage implements Serializable { + + private Map process; + + public ProcMessage() { + process = new LinkedHashMap<>(); + } + + public void add(String type, String msContent) { + if (process.containsKey(type)) { + process.get(type).append(msContent + ";"); + } else { + process.put(type, new StringBuilder(msContent+";")); + } + } + + public List> parse(String content) { + List> errList = new ArrayList<>(); + ExcelErrData excelErrData = new ExcelErrData(null, 1, content); + errList.add(excelErrData); + return errList; + } + + public List> parse() { + List> errList = new ArrayList<>(); + List result = new ArrayList<>(); + process.entrySet().parallelStream().reduce(result, (first, second) -> { + first.add(second.getKey() + ":" + second.getValue()); + return first; + }, (first, second) -> { + if (first == second) { + return first; + } + first.addAll(second); + return first; + }); + + for (int i = 0; i < result.size(); i++) { + ExcelErrData excelErrData = new ExcelErrData(null, i, result.get(i)); + errList.add(excelErrData); + } + return errList; + } + + @Override + public String toString() { + List result = new ArrayList<>(); + process.entrySet().parallelStream().reduce(result, (first, second) -> { + first.add(second.getKey() + ":" + second.getValue()); + return first; + }, (first, second) -> { + if (first == second) { + return first; + } + first.addAll(second); + return first; + }); + + return StringUtils.join(result, "\n"); + } +} diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 19f9ed48c5..bc768e3542 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -748,7 +748,7 @@ export default { click_upload: "Upload", upload_limit: "Only XLS/XLSX/XMIND files can be uploaded, and no more than 20M", upload_xmind_format: "Upload files can only be .xmind format", - upload_xmind: "Only xmind files can be uploaded, and no more than 500", + upload_xmind: "Only xmind files can be uploaded, and no more than 800", upload_limit_count: "Only one file can be uploaded at a time", upload_limit_format: "Upload files can only be XLS, XLSX format!", upload_limit_size: "Upload file size cannot exceed 20MB!", diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index 58ff7df239..1aba6660bc 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -751,7 +751,7 @@ export default { download_template: "下载模版", click_upload: "点击上传", upload_limit: "只能上传xls/xlsx文件,且不超过20M", - upload_xmind: "支持文件类型:.xmind;一次至多导入500 条用例", + upload_xmind: "支持文件类型:.xmind;一次至多导入800 条用例", upload_xmind_format: "上传文件只能是 .xmind 格式", upload_limit_other_size: "上传文件大小不能超过", upload_limit_count: "一次只能上传一个文件", diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index 01d7cd0532..2c65d3c31c 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -751,7 +751,7 @@ export default { download_template: "下載模版", click_upload: "點擊上傳", upload_limit: "只能上傳xls/xlsx文件,且不超過20M", - upload_xmind: "支持文件類型:.xmind;壹次至多導入500 條用例", + upload_xmind: "支持文件類型:.xmind;壹次至多導入800 條用例", upload_xmind_format: "上傳文件只能是 .xmind 格式", upload_limit_other_size: "上傳文件大小不能超過", upload_limit_count: "壹次只能上傳壹個文件",