From 8770ed47f9d812ea958ad7fef9a9120259c988a7 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Sun, 27 Sep 2020 20:35:24 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=B5=8B=E8=AF=95=E8=B7=9F=E8=B8=AA):=20?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E5=AF=BC=E5=85=A5=E5=AF=BC=E5=87=BA=E5=9B=BD?= =?UTF-8?q?=E9=99=85=E5=8C=96=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../excel/domain/ExcelDataFactory.java | 5 + .../excel/domain/TestCaseExcelData.java | 66 +++---------- .../excel/domain/TestCaseExcelDataCn.java | 65 ++++++++++++ .../domain/TestCaseExcelDataFactory.java | 18 ++++ .../excel/domain/TestCaseExcelDataTw.java | 65 ++++++++++++ .../excel/domain/TestCaseExcelDataUs.java | 65 ++++++++++++ .../excel/listener/EasyExcelListener.java | 15 +-- .../excel/utils/EasyExcelExporter.java | 15 +-- .../excel/utils/EasyExcelI18nTranslator.java | 98 ------------------- .../track/service/TestCaseService.java | 17 ++-- 10 files changed, 247 insertions(+), 182 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/excel/domain/ExcelDataFactory.java create mode 100644 backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataCn.java create mode 100644 backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataFactory.java create mode 100644 backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataTw.java create mode 100644 backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataUs.java delete mode 100644 backend/src/main/java/io/metersphere/excel/utils/EasyExcelI18nTranslator.java diff --git a/backend/src/main/java/io/metersphere/excel/domain/ExcelDataFactory.java b/backend/src/main/java/io/metersphere/excel/domain/ExcelDataFactory.java new file mode 100644 index 0000000000..5b1fc66513 --- /dev/null +++ b/backend/src/main/java/io/metersphere/excel/domain/ExcelDataFactory.java @@ -0,0 +1,5 @@ +package io.metersphere.excel.domain; + +public interface ExcelDataFactory { + Object getExcelDataByLocal(); +} diff --git a/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelData.java b/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelData.java index f85269958d..af8b17b529 100644 --- a/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelData.java +++ b/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelData.java @@ -1,65 +1,31 @@ package io.metersphere.excel.domain; -import com.alibaba.excel.annotation.ExcelProperty; -import com.alibaba.excel.annotation.write.style.ColumnWidth; -import lombok.Data; -import org.hibernate.validator.constraints.Length; +import com.alibaba.excel.annotation.ExcelIgnore; +import lombok.Getter; +import lombok.Setter; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; - -@Data -@ColumnWidth(15) +@Getter +@Setter public class TestCaseExcelData { - @NotBlank(message = "{cannot_be_null}") - @Length(max = 50) - @ExcelProperty("{test_case_name}") + @ExcelIgnore private String name; - - @NotBlank(message = "{cannot_be_null}") - @Length(max = 1000) - @ExcelProperty("{test_case_module}") - @ColumnWidth(30) - @Pattern(regexp = "^(?!.*//).*$", message = "{incorrect_format}") + @ExcelIgnore private String nodePath; - - @NotBlank(message = "{cannot_be_null}") - @ExcelProperty("{test_case_type}") - @Pattern(regexp = "(^functional$)|(^performance$)|(^api$)", message = "{test_case_type_validate}") + @ExcelIgnore private String type; - - @NotBlank(message = "{cannot_be_null}") - @ExcelProperty("{test_case_maintainer}") + @ExcelIgnore private String maintainer; - - @NotBlank(message = "{cannot_be_null}") - @ExcelProperty("{test_case_priority}") - @Pattern(regexp = "(^P0$)|(^P1$)|(^P2$)|(^P3$)", message = "{test_case_priority_validate}") + @ExcelIgnore private String priority; - - @NotBlank(message = "{cannot_be_null}") - @ExcelProperty("{test_case_method}") - @Pattern(regexp = "(^manual$)|(^auto$)", message = "{test_case_method_validate}") + @ExcelIgnore private String method; - - @ColumnWidth(50) - @ExcelProperty("{test_case_prerequisite}") - @Length(min = 0, max = 1000) + @ExcelIgnore private String prerequisite; - - @ColumnWidth(50) - @ExcelProperty("{test_case_remark}") - @Length(max = 1000) + @ExcelIgnore private String remark; - - @ColumnWidth(50) - @ExcelProperty("{test_case_step_desc}") - @Length(max = 1000) + @ExcelIgnore private String stepDesc; - - @ColumnWidth(50) - @ExcelProperty("{test_case_step_result}") - @Length(max = 1000) + @ExcelIgnore private String stepResult; -} +} \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataCn.java b/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataCn.java new file mode 100644 index 0000000000..1a1757bc7b --- /dev/null +++ b/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataCn.java @@ -0,0 +1,65 @@ +package io.metersphere.excel.domain; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + +@Data +@ColumnWidth(15) +public class TestCaseExcelDataCn extends TestCaseExcelData { + + @NotBlank(message = "{cannot_be_null}") + @Length(max = 50) + @ExcelProperty("用例名称") + private String name; + + @NotBlank(message = "{cannot_be_null}") + @Length(max = 1000) + @ExcelProperty("所属模块") + @ColumnWidth(30) + @Pattern(regexp = "^(?!.*//).*$", message = "{incorrect_format}") + private String nodePath; + + @NotBlank(message = "{cannot_be_null}") + @ExcelProperty("用例类型") + @Pattern(regexp = "(^functional$)|(^performance$)|(^api$)", message = "{test_case_type_validate}") + private String type; + + @NotBlank(message = "{cannot_be_null}") + @ExcelProperty("维护人") + private String maintainer; + + @NotBlank(message = "{cannot_be_null}") + @ExcelProperty("用例等级") + @Pattern(regexp = "(^P0$)|(^P1$)|(^P2$)|(^P3$)", message = "{test_case_priority_validate}") + private String priority; + + @NotBlank(message = "{cannot_be_null}") + @ExcelProperty("测试方式") + @Pattern(regexp = "(^manual$)|(^auto$)", message = "{test_case_method_validate}") + private String method; + + @ColumnWidth(50) + @ExcelProperty("前置条件") + @Length(min = 0, max = 1000) + private String prerequisite; + + @ColumnWidth(50) + @ExcelProperty("备注") + @Length(max = 1000) + private String remark; + + @ColumnWidth(50) + @ExcelProperty("步骤描述") + @Length(max = 1000) + private String stepDesc; + + @ColumnWidth(50) + @ExcelProperty("预期结果") + @Length(max = 1000) + private String stepResult; +} diff --git a/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataFactory.java b/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataFactory.java new file mode 100644 index 0000000000..a26a091975 --- /dev/null +++ b/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataFactory.java @@ -0,0 +1,18 @@ +package io.metersphere.excel.domain; + +import org.springframework.context.i18n.LocaleContextHolder; + +import java.util.Locale; + +public class TestCaseExcelDataFactory implements ExcelDataFactory { + @Override + public Class getExcelDataByLocal() { + Locale locale = LocaleContextHolder.getLocale(); + if (Locale.US.toString().equalsIgnoreCase(locale.toString())) { + return TestCaseExcelDataUs.class; + } else if (Locale.TRADITIONAL_CHINESE.toString().equalsIgnoreCase(locale.toString())) { + return TestCaseExcelDataTw.class; + } + return TestCaseExcelDataCn.class; + } +} diff --git a/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataTw.java b/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataTw.java new file mode 100644 index 0000000000..d016aa4ccd --- /dev/null +++ b/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataTw.java @@ -0,0 +1,65 @@ +package io.metersphere.excel.domain; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + +@Data +@ColumnWidth(15) +public class TestCaseExcelDataTw extends TestCaseExcelData { + + @NotBlank(message = "{cannot_be_null}") + @Length(max = 50) + @ExcelProperty("用例名稱") + private String name; + + @NotBlank(message = "{cannot_be_null}") + @Length(max = 1000) + @ExcelProperty("所屬模塊") + @ColumnWidth(30) + @Pattern(regexp = "^(?!.*//).*$", message = "{incorrect_format}") + private String nodePath; + + @NotBlank(message = "{cannot_be_null}") + @ExcelProperty("用例類型") + @Pattern(regexp = "(^functional$)|(^performance$)|(^api$)", message = "{test_case_type_validate}") + private String type; + + @NotBlank(message = "{cannot_be_null}") + @ExcelProperty("維護人") + private String maintainer; + + @NotBlank(message = "{cannot_be_null}") + @ExcelProperty("用例等級") + @Pattern(regexp = "(^P0$)|(^P1$)|(^P2$)|(^P3$)", message = "{test_case_priority_validate}") + private String priority; + + @NotBlank(message = "{cannot_be_null}") + @ExcelProperty("測試方式") + @Pattern(regexp = "(^manual$)|(^auto$)", message = "{test_case_method_validate}") + private String method; + + @ColumnWidth(50) + @ExcelProperty("前置條件") + @Length(min = 0, max = 1000) + private String prerequisite; + + @ColumnWidth(50) + @ExcelProperty("備註") + @Length(max = 1000) + private String remark; + + @ColumnWidth(50) + @ExcelProperty("步驟描述") + @Length(max = 1000) + private String stepDesc; + + @ColumnWidth(50) + @ExcelProperty("預期結果") + @Length(max = 1000) + private String stepResult; +} diff --git a/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataUs.java b/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataUs.java new file mode 100644 index 0000000000..91b1a11f38 --- /dev/null +++ b/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelDataUs.java @@ -0,0 +1,65 @@ +package io.metersphere.excel.domain; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + +@Data +@ColumnWidth(15) +public class TestCaseExcelDataUs extends TestCaseExcelData { + + @NotBlank(message = "{cannot_be_null}") + @Length(max = 50) + @ExcelProperty("Name") + private String name; + + @NotBlank(message = "{cannot_be_null}") + @Length(max = 1000) + @ExcelProperty("Module") + @ColumnWidth(30) + @Pattern(regexp = "^(?!.*//).*$", message = "{incorrect_format}") + private String nodePath; + + @NotBlank(message = "{cannot_be_null}") + @ExcelProperty("Type") + @Pattern(regexp = "(^functional$)|(^performance$)|(^api$)", message = "{test_case_type_validate}") + private String type; + + @NotBlank(message = "{cannot_be_null}") + @ExcelProperty("Maintainer") + private String maintainer; + + @NotBlank(message = "{cannot_be_null}") + @ExcelProperty("Priority") + @Pattern(regexp = "(^P0$)|(^P1$)|(^P2$)|(^P3$)", message = "{test_case_priority_validate}") + private String priority; + + @NotBlank(message = "{cannot_be_null}") + @ExcelProperty("Method") + @Pattern(regexp = "(^manual$)|(^auto$)", message = "{test_case_method_validate}") + private String method; + + @ColumnWidth(50) + @ExcelProperty("Prerequisite") + @Length(min = 0, max = 1000) + private String prerequisite; + + @ColumnWidth(50) + @ExcelProperty("Remark") + @Length(max = 1000) + private String remark; + + @ColumnWidth(50) + @ExcelProperty("Step description") + @Length(max = 1000) + private String stepDesc; + + @ColumnWidth(50) + @ExcelProperty("Step result") + @Length(max = 1000) + private String stepResult; +} diff --git a/backend/src/main/java/io/metersphere/excel/listener/EasyExcelListener.java b/backend/src/main/java/io/metersphere/excel/listener/EasyExcelListener.java index 9bb8f6e96e..77ce4d66f4 100644 --- a/backend/src/main/java/io/metersphere/excel/listener/EasyExcelListener.java +++ b/backend/src/main/java/io/metersphere/excel/listener/EasyExcelListener.java @@ -8,7 +8,6 @@ import com.alibaba.excel.util.StringUtils; import io.metersphere.commons.utils.LogUtil; import io.metersphere.excel.domain.ExcelErrData; import io.metersphere.excel.domain.TestCaseExcelData; -import io.metersphere.excel.utils.EasyExcelI18nTranslator; import io.metersphere.excel.utils.ExcelValidateHelper; import io.metersphere.i18n.Translator; @@ -17,14 +16,12 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.*; -public abstract class EasyExcelListener extends AnalysisEventListener implements AutoCloseable { +public abstract class EasyExcelListener extends AnalysisEventListener { protected List> errList = new ArrayList<>(); protected List list = new ArrayList<>(); - protected EasyExcelI18nTranslator easyExcelI18nTranslator; - protected List excelDataList = new ArrayList<>(); /** @@ -37,11 +34,6 @@ public abstract class EasyExcelListener extends AnalysisEventListener impl public EasyExcelListener() { Type type = getClass().getGenericSuperclass(); this.clazz = (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; - //防止多线程修改运行时类注解后,saveOriginalExcelProperty保存的是修改后的值 - synchronized (EasyExcelI18nTranslator.class) { - this.easyExcelI18nTranslator = new EasyExcelI18nTranslator(this.clazz); - this.easyExcelI18nTranslator.translateExcelProperty(); - } } /** @@ -153,9 +145,4 @@ public abstract class EasyExcelListener extends AnalysisEventListener impl return errList; } - - @Override - public void close() { - this.easyExcelI18nTranslator.resetExcelProperty(); - } } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/excel/utils/EasyExcelExporter.java b/backend/src/main/java/io/metersphere/excel/utils/EasyExcelExporter.java index b2b4d6fe0d..8183208f0c 100644 --- a/backend/src/main/java/io/metersphere/excel/utils/EasyExcelExporter.java +++ b/backend/src/main/java/io/metersphere/excel/utils/EasyExcelExporter.java @@ -12,20 +12,12 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.List; -public class EasyExcelExporter implements AutoCloseable { - - EasyExcelI18nTranslator easyExcelI18nTranslator; +public class EasyExcelExporter { private Class clazz; public EasyExcelExporter(Class clazz) { this.clazz = clazz; - //防止多线程修改运行时类注解后,saveOriginalExcelProperty保存的是修改后的值 - synchronized (EasyExcelI18nTranslator.class) { - easyExcelI18nTranslator = new EasyExcelI18nTranslator(clazz); - easyExcelI18nTranslator.translateExcelProperty(); - } - } public void export(HttpServletResponse response, List data, String fileName, String sheetName) { @@ -46,9 +38,4 @@ public class EasyExcelExporter implements AutoCloseable { } } - @Override - public void close() { - easyExcelI18nTranslator.resetExcelProperty(); - } - } diff --git a/backend/src/main/java/io/metersphere/excel/utils/EasyExcelI18nTranslator.java b/backend/src/main/java/io/metersphere/excel/utils/EasyExcelI18nTranslator.java deleted file mode 100644 index c85a18fbaa..0000000000 --- a/backend/src/main/java/io/metersphere/excel/utils/EasyExcelI18nTranslator.java +++ /dev/null @@ -1,98 +0,0 @@ -package io.metersphere.excel.utils; - -import com.alibaba.excel.annotation.ExcelProperty; -import io.metersphere.commons.utils.LogUtil; -import io.metersphere.excel.domain.TestCaseExcelData; -import io.metersphere.exception.ExcelException; -import io.metersphere.i18n.Translator; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import java.util.*; -import java.util.function.BiConsumer; -import java.util.regex.Pattern; - -/** - * 表头国际化 - * 先调用 saveOriginalExcelProperty 存储原表头注解值 - * 再调用 translateExcelProperty 获取国际化的值 - * 最后调用 resetExcelProperty 重置为原来值,防止切换语言后无法国际化 - */ -public class EasyExcelI18nTranslator { - - private Map> excelPropertyMap = new HashMap<>(); - - private Class clazz; - - public EasyExcelI18nTranslator(Class clazz) { - this.clazz = clazz; - saveOriginalExcelProperty(); - } - - private void readExcelProperty(Class clazz, BiConsumer> operate) { - Field field; - Field[] fields = clazz.getDeclaredFields(); - for (int i = 0; i < fields.length; i++) { - try { - field = clazz.getDeclaredField(fields[i].getName()); - field.setAccessible(true); - ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); - if (excelProperty != null) { - InvocationHandler invocationHandler = Proxy.getInvocationHandler(excelProperty); - Field fieldValue = invocationHandler.getClass().getDeclaredField("memberValues"); - fieldValue.setAccessible(true); - Map memberValues = null; - try { - memberValues = (Map) fieldValue.get(invocationHandler); - } catch (IllegalAccessException e) { - LogUtil.error(e.getMessage(), e); - throw new ExcelException(e.getMessage()); - } - - operate.accept(field.getName(), memberValues); - - } - } catch (NoSuchFieldException e) { - e.printStackTrace(); - throw new RuntimeException(e.getMessage(), e); - } - } - - - } - - public void saveOriginalExcelProperty() { - readExcelProperty(clazz, (fieldName, memberValues) -> { - List values = Arrays.asList((String[]) memberValues.get("value")); - List copyValues = new ArrayList<>(); - values.forEach(value -> { - copyValues.add(value); - }); - excelPropertyMap.put(fieldName, copyValues); - }); - } - - public void translateExcelProperty() { - readExcelProperty(TestCaseExcelData.class, (fieldName, memberValues) -> { - String[] values = (String[]) memberValues.get("value"); - for (int j = 0; j < values.length; j++) { - if (Pattern.matches("^\\{.+\\}$", values[j])) { - values[j] = Translator.get(values[j].substring(1, values[j].length() - 1)); - } - } - memberValues.put("value", values); - }); - } - - public void resetExcelProperty() { - readExcelProperty(clazz, (fieldName, memberValues) -> { - String[] values = (String[]) memberValues.get("value"); - List list = excelPropertyMap.get(fieldName); - for (int j = 0; j < values.length; j++) { - values[j] = list.get(j); - } - memberValues.put("value", values); - }); - } -} 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 bdf3db6b67..341850c267 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java @@ -20,6 +20,7 @@ import io.metersphere.controller.request.OrderRequest; import io.metersphere.excel.domain.ExcelErrData; import io.metersphere.excel.domain.ExcelResponse; import io.metersphere.excel.domain.TestCaseExcelData; +import io.metersphere.excel.domain.TestCaseExcelDataFactory; import io.metersphere.excel.listener.EasyExcelListener; import io.metersphere.excel.listener.TestCaseDataListener; import io.metersphere.excel.utils.EasyExcelExporter; @@ -302,8 +303,9 @@ public class TestCaseService { Set userIds = userRoleMapper.selectByExample(userRoleExample).stream().map(UserRole::getUserId).collect(Collectors.toSet()); - try (EasyExcelListener easyExcelListener = new TestCaseDataListener(this, projectId, testCaseNames, userIds)) { - EasyExcelFactory.read(multipartFile.getInputStream(), TestCaseExcelData.class, easyExcelListener).sheet().doRead(); + try { + EasyExcelListener easyExcelListener = new TestCaseDataListener(this, projectId, testCaseNames, userIds); + EasyExcelFactory.read(multipartFile.getInputStream(), new TestCaseExcelDataFactory().getExcelDataByLocal(), easyExcelListener).sheet().doRead(); errList = easyExcelListener.getErrList(); } catch (Exception e) { LogUtil.error(e.getMessage(), e); @@ -341,7 +343,8 @@ public class TestCaseService { } public void testCaseTemplateExport(HttpServletResponse response) { - try (EasyExcelExporter easyExcelExporter = new EasyExcelExporter(TestCaseExcelData.class)) { + try { + EasyExcelExporter easyExcelExporter = new EasyExcelExporter(new TestCaseExcelDataFactory().getExcelDataByLocal()); easyExcelExporter.export(response, generateExportTemplate(), Translator.get("test_case_import_template_name"), Translator.get("test_case_import_template_sheet")); } catch (Exception e) { @@ -419,10 +422,12 @@ public class TestCaseService { } public void testCaseExport(HttpServletResponse response, TestCaseBatchRequest request) { - try (EasyExcelExporter easyExcelExporter = new EasyExcelExporter(TestCaseExcelData.class)) { + try { + EasyExcelExporter easyExcelExporter = new EasyExcelExporter(new TestCaseExcelDataFactory().getExcelDataByLocal()); easyExcelExporter.export(response, generateTestCaseExcel(request), Translator.get("test_case_import_template_name"), Translator.get("test_case_import_template_sheet")); } catch (Exception e) { + LogUtil.error(e.getMessage(), e); MSException.throwException(e); } } @@ -470,7 +475,7 @@ public class TestCaseService { } else if (t.getMethod().equals("auto") && t.getType().equals("api")) { data.setStepDesc(""); data.setStepResult(""); - if (t.getTestId().equals("other")) { + if (t.getTestId() != null && t.getTestId().equals("other")) { data.setRemark(t.getOtherTestName()); } else { data.setRemark(t.getApiName()); @@ -479,7 +484,7 @@ public class TestCaseService { } else if (t.getMethod().equals("auto") && t.getType().equals("performance")) { data.setStepDesc(""); data.setStepResult(""); - if (t.getTestId().equals("other")) { + if (t.getTestId() != null && t.getTestId().equals("other")) { data.setRemark(t.getOtherTestName()); } else { data.setRemark(t.getPerformName());