feat(测试跟踪): 导入功能用例支持合并单元格
This commit is contained in:
parent
491c5276c5
commit
5a3fb68149
|
@ -0,0 +1,28 @@
|
|||
package io.metersphere.excel.constants;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public enum TestCaseImportFiled {
|
||||
|
||||
ID("ID", "ID", "ID"), NAME("用例名称", "用例名稱", "Name"), MODULE("所属模块", "所屬模塊", "Module"),
|
||||
TAG("标签", "標簽", "Tag"), PREREQUISITE("前置条件", "前置條件", "Prerequisite"), REMARK("备注", "備註", "Remark"),
|
||||
STEP_DESC("步骤描述", "步驟描述", "Step description"), STEP_RESULT("预期结果", "預期結果", "Step result"), STEP_MODEL("编辑模式", "編輯模式", "Edit Model"),
|
||||
STATUS("用例状态", "用例狀態", "Case status"), MAINTAINER("责任人", "責任人", "Maintainer"), PRIORITY("用例等级", "用例等級", "Priority");
|
||||
|
||||
private Map<Locale, String> filedLangMap;
|
||||
|
||||
public Map<Locale, String> getFiledLangMap() {
|
||||
return this.filedLangMap;
|
||||
}
|
||||
|
||||
TestCaseImportFiled(String zn, String chineseTw, String us) {
|
||||
this.filedLangMap = new HashMap<>() {{
|
||||
put(Locale.SIMPLIFIED_CHINESE, zn);
|
||||
put(Locale.TRADITIONAL_CHINESE, chineseTw);
|
||||
put(Locale.US, us);
|
||||
}};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package io.metersphere.excel.domain;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class ExcelMergeInfo implements Comparable<ExcelMergeInfo> {
|
||||
|
||||
/**
|
||||
* 合并单元格的第一行
|
||||
*/
|
||||
private Integer firstRowIndex;
|
||||
/**
|
||||
* 合并单元格的最后一行
|
||||
*/
|
||||
private Integer lastRowIndex;
|
||||
/**
|
||||
* 合并单元格的第一列,不考虑同一行合并单元格的情况
|
||||
*/
|
||||
private Integer firstColumnIndex;
|
||||
|
||||
/**
|
||||
* 根据 firstRowIndex, firstColumnIndex 重写 compareTo
|
||||
* 使用 TreeSet 按 Excel 表格顺序查找时,可以优化效率
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(@NotNull ExcelMergeInfo o) {
|
||||
int compare = Integer.compare(this.getFirstRowIndex(), o.getFirstRowIndex());
|
||||
if (compare == 0) {
|
||||
return Integer.compare(this.getFirstColumnIndex(), o.getFirstColumnIndex());
|
||||
}
|
||||
return compare;
|
||||
}
|
||||
}
|
|
@ -2,8 +2,11 @@ package io.metersphere.excel.domain;
|
|||
|
||||
import com.alibaba.excel.annotation.ExcelIgnore;
|
||||
import io.metersphere.dto.CustomFieldDao;
|
||||
import io.metersphere.excel.constants.TestCaseImportFiled;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -47,7 +50,45 @@ public class TestCaseExcelData {
|
|||
@ExcelIgnore
|
||||
Map<String, String> customDatas = new LinkedHashMap<>();
|
||||
|
||||
@ExcelIgnore
|
||||
List<String> mergeStepDesc;
|
||||
@ExcelIgnore
|
||||
List<String> mergeStepResult;
|
||||
|
||||
public List<List<String>> getHead(boolean needNum, List<CustomFieldDao> customFields) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<List<String>> getHead(boolean needNum, List<CustomFieldDao> customFields, Locale lang) {
|
||||
List<List<String>> heads = new ArrayList<>();
|
||||
TestCaseImportFiled[] fields = TestCaseImportFiled.values();
|
||||
for (TestCaseImportFiled field : fields) {
|
||||
heads.add(Arrays.asList(field.getFiledLangMap().get(lang)));
|
||||
}
|
||||
|
||||
Iterator<List<String>> iterator = heads.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
List<String> head = iterator.next();
|
||||
if (StringUtils.equals(head.get(0), TestCaseImportFiled.ID.getFiledLangMap().get(lang)) && !needNum) {
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(customFields)) {
|
||||
for (CustomFieldDao dto : customFields) {
|
||||
if (StringUtils.equalsAny(dto.getName(),
|
||||
TestCaseImportFiled.PRIORITY.getFiledLangMap().get(Locale.SIMPLIFIED_CHINESE),
|
||||
TestCaseImportFiled.STATUS.getFiledLangMap().get(Locale.SIMPLIFIED_CHINESE),
|
||||
TestCaseImportFiled.MAINTAINER.getFiledLangMap().get(Locale.SIMPLIFIED_CHINESE).concat("(ID)"))) {
|
||||
continue;
|
||||
}
|
||||
heads.add(new ArrayList<>() {{
|
||||
add(dto.getName());
|
||||
}});
|
||||
}
|
||||
}
|
||||
return heads;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,23 +5,17 @@ import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
|||
import io.metersphere.dto.CustomFieldDao;
|
||||
import io.metersphere.excel.annotation.NotRequired;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
@Data
|
||||
@ColumnWidth(15)
|
||||
public class TestCaseExcelDataCn extends TestCaseExcelData {
|
||||
|
||||
// @ExcelProperty("ID")
|
||||
// @NotRequired
|
||||
// private Integer num;
|
||||
|
||||
@ColumnWidth(50)
|
||||
@ExcelProperty("ID")
|
||||
@NotRequired
|
||||
|
@ -45,11 +39,6 @@ public class TestCaseExcelDataCn extends TestCaseExcelData {
|
|||
@Length(min = 0, max = 1000)
|
||||
private String tags;
|
||||
|
||||
// @NotBlank(message = "{cannot_be_null}")
|
||||
// @ExcelProperty("测试方式")
|
||||
// @Pattern(regexp = "(^manual$)|(^auto$)", message = "{test_case_method_validate}")
|
||||
// private String method;
|
||||
|
||||
@ColumnWidth(50)
|
||||
@ExcelProperty("前置条件")
|
||||
private String prerequisite;
|
||||
|
@ -86,63 +75,6 @@ public class TestCaseExcelDataCn extends TestCaseExcelData {
|
|||
|
||||
@Override
|
||||
public List<List<String>> getHead(boolean needNum, List<CustomFieldDao> customFields) {
|
||||
List<List<String>> returnList = new ArrayList<>();
|
||||
if (needNum) {
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add("ID");
|
||||
returnList.add(list);
|
||||
}
|
||||
|
||||
List<String> list1 = new ArrayList<>();
|
||||
list1.add("用例名称");
|
||||
returnList.add(list1);
|
||||
|
||||
List<String> list2 = new ArrayList<>();
|
||||
list2.add("所属模块");
|
||||
returnList.add(list2);
|
||||
|
||||
List<String> list3 = new ArrayList<>();
|
||||
list3.add("标签");
|
||||
returnList.add(list3);
|
||||
|
||||
List<String> list4 = new ArrayList<>();
|
||||
list4.add("前置条件");
|
||||
returnList.add(list4);
|
||||
|
||||
List<String> list5 = new ArrayList<>();
|
||||
list5.add("备注");
|
||||
returnList.add(list5);
|
||||
|
||||
List<String> list6 = new ArrayList<>();
|
||||
list6.add("步骤描述");
|
||||
returnList.add(list6);
|
||||
|
||||
List<String> list7 = new ArrayList<>();
|
||||
list7.add("预期结果");
|
||||
returnList.add(list7);
|
||||
|
||||
List<String> list8 = new ArrayList<>();
|
||||
list8.add("编辑模式");
|
||||
returnList.add(list8);
|
||||
|
||||
List<String> list9 = new ArrayList<>();
|
||||
list9.add("用例等级");
|
||||
returnList.add(list9);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(customFields)) {
|
||||
for (CustomFieldDao dto : customFields) {
|
||||
if (StringUtils.equals(dto.getName(), "用例等级")) {
|
||||
continue;
|
||||
}
|
||||
List<String> list = new ArrayList<>();
|
||||
if (StringUtils.equals(dto.getName(), "责任人")) {
|
||||
list.add("责任人(ID)");
|
||||
} else {
|
||||
list.add(dto.getName());
|
||||
}
|
||||
returnList.add(list);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
return super.getHead(needNum, customFields, Locale.SIMPLIFIED_CHINESE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,23 +5,17 @@ import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
|||
import io.metersphere.dto.CustomFieldDao;
|
||||
import io.metersphere.excel.annotation.NotRequired;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
@Data
|
||||
@ColumnWidth(15)
|
||||
public class TestCaseExcelDataTw extends TestCaseExcelData {
|
||||
|
||||
// @ExcelProperty("ID")
|
||||
// @NotRequired
|
||||
// private Integer num;
|
||||
|
||||
@ColumnWidth(50)
|
||||
@ExcelProperty("ID")
|
||||
@NotRequired
|
||||
|
@ -45,11 +39,6 @@ public class TestCaseExcelDataTw extends TestCaseExcelData {
|
|||
@Length(min = 0, max = 1000)
|
||||
private String tags;
|
||||
|
||||
// @NotBlank(message = "{cannot_be_null}")
|
||||
// @ExcelProperty("測試方式")
|
||||
// @Pattern(regexp = "(^manual$)|(^auto$)", message = "{test_case_method_validate}")
|
||||
// private String method;
|
||||
|
||||
@ColumnWidth(50)
|
||||
@ExcelProperty("前置條件")
|
||||
private String prerequisite;
|
||||
|
@ -81,75 +70,11 @@ public class TestCaseExcelDataTw extends TestCaseExcelData {
|
|||
@Pattern(regexp = "(^P0$)|(^P1$)|(^P2$)|(^P3$)", message = "{test_case_priority_validate}")
|
||||
private String priority;
|
||||
|
||||
@ExcelProperty("維護人(ID)")
|
||||
@ExcelProperty("責任人(ID)")
|
||||
private String maintainer;
|
||||
|
||||
@Override
|
||||
public List<List<String>> getHead(boolean needNum, List<CustomFieldDao> customFields) {
|
||||
List<List<String>> returnList = new ArrayList<>();
|
||||
if (needNum) {
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add("ID");
|
||||
returnList.add(list);
|
||||
}
|
||||
|
||||
List<String> list1 = new ArrayList<>();
|
||||
list1.add("用例名稱");
|
||||
returnList.add(list1);
|
||||
|
||||
List<String> list2 = new ArrayList<>();
|
||||
list2.add("所屬模塊");
|
||||
returnList.add(list2);
|
||||
|
||||
List<String> list3 = new ArrayList<>();
|
||||
list3.add("標簽");
|
||||
returnList.add(list3);
|
||||
|
||||
List<String> list4 = new ArrayList<>();
|
||||
list4.add("前置條件");
|
||||
returnList.add(list4);
|
||||
|
||||
List<String> list5 = new ArrayList<>();
|
||||
list5.add("備註");
|
||||
returnList.add(list5);
|
||||
|
||||
List<String> list6 = new ArrayList<>();
|
||||
list6.add("步驟描述");
|
||||
returnList.add(list6);
|
||||
|
||||
List<String> list7 = new ArrayList<>();
|
||||
list7.add("預期結果");
|
||||
returnList.add(list7);
|
||||
|
||||
List<String> list8 = new ArrayList<>();
|
||||
list8.add("編輯模式");
|
||||
returnList.add(list8);
|
||||
|
||||
List<String> list9 = new ArrayList<>();
|
||||
list9.add("用例等級");
|
||||
returnList.add(list9);
|
||||
|
||||
List<String> list10 = new ArrayList<>();
|
||||
list10.add("用例狀態");
|
||||
returnList.add(list10);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(customFields)) {
|
||||
for (CustomFieldDao dto : customFields) {
|
||||
if (StringUtils.equals(dto.getName(), "用例等級")) {
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.equals(dto.getName(), "用例状态")) {
|
||||
continue;
|
||||
}
|
||||
List<String> list = new ArrayList<>();
|
||||
if (StringUtils.equals(dto.getName(), "责任人")) {
|
||||
list.add("維護人(ID)");
|
||||
} else {
|
||||
list.add(dto.getName());
|
||||
}
|
||||
returnList.add(list);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
return super.getHead(needNum, customFields, Locale.TRADITIONAL_CHINESE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,24 +5,18 @@ import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
|||
import io.metersphere.dto.CustomFieldDao;
|
||||
import io.metersphere.excel.annotation.NotRequired;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
@Data
|
||||
@ColumnWidth(15)
|
||||
public class TestCaseExcelDataUs extends TestCaseExcelData {
|
||||
|
||||
// @ExcelProperty("ID")
|
||||
// @NotRequired
|
||||
// private Integer num;
|
||||
|
||||
@ColumnWidth(50)
|
||||
@ExcelProperty("ID")
|
||||
@NotRequired
|
||||
|
@ -46,11 +40,6 @@ public class TestCaseExcelDataUs extends TestCaseExcelData {
|
|||
@Length(min = 0, max = 1000)
|
||||
private String tags;
|
||||
|
||||
// @NotBlank(message = "{cannot_be_null}")
|
||||
// @ExcelProperty("Method")
|
||||
// @Pattern(regexp = "(^manual$)|(^auto$)", message = "{test_case_method_validate}")
|
||||
// private String method;
|
||||
|
||||
@ColumnWidth(50)
|
||||
@ExcelProperty("Prerequisite")
|
||||
private String prerequisite;
|
||||
|
@ -86,70 +75,6 @@ public class TestCaseExcelDataUs extends TestCaseExcelData {
|
|||
|
||||
@Override
|
||||
public List<List<String>> getHead(boolean needNum, List<CustomFieldDao> customFields) {
|
||||
List<List<String>> returnList = new ArrayList<>();
|
||||
if (needNum) {
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add("ID");
|
||||
returnList.add(list);
|
||||
}
|
||||
|
||||
List<String> list1 = new ArrayList<>();
|
||||
list1.add("Name");
|
||||
returnList.add(list1);
|
||||
|
||||
List<String> list2 = new ArrayList<>();
|
||||
list2.add("Module");
|
||||
returnList.add(list2);
|
||||
|
||||
List<String> list3 = new ArrayList<>();
|
||||
list3.add("Tag");
|
||||
returnList.add(list3);
|
||||
|
||||
List<String> list4 = new ArrayList<>();
|
||||
list4.add("Prerequisite");
|
||||
returnList.add(list4);
|
||||
|
||||
List<String> list5 = new ArrayList<>();
|
||||
list5.add("Remark");
|
||||
returnList.add(list5);
|
||||
|
||||
List<String> list6 = new ArrayList<>();
|
||||
list6.add("Step description");
|
||||
returnList.add(list6);
|
||||
|
||||
List<String> list7 = new ArrayList<>();
|
||||
list7.add("Step result");
|
||||
returnList.add(list7);
|
||||
|
||||
List<String> list8 = new ArrayList<>();
|
||||
list8.add("Edit Model");
|
||||
returnList.add(list8);
|
||||
|
||||
List<String> list9 = new ArrayList<>();
|
||||
list9.add("Priority");
|
||||
returnList.add(list9);
|
||||
|
||||
List<String> list10 = new ArrayList<>();
|
||||
list10.add("Case status");
|
||||
returnList.add(list10);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(customFields)) {
|
||||
for (CustomFieldDao dto : customFields) {
|
||||
if (StringUtils.equals(dto.getName(), "用例等级")) {
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.equals(dto.getName(), "用例状态")) {
|
||||
continue;
|
||||
}
|
||||
List<String> list = new ArrayList<>();
|
||||
if (StringUtils.equals(dto.getName(), "责任人")) {
|
||||
list.add("Maintainer(ID)");
|
||||
} else {
|
||||
list.add(dto.getName());
|
||||
}
|
||||
returnList.add(list);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
return super.getHead(needNum, customFields, Locale.US);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package io.metersphere.excel.handler;
|
||||
|
||||
import com.alibaba.excel.write.handler.RowWriteHandler;
|
||||
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
|
||||
import io.metersphere.excel.constants.TestCaseImportFiled;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class FunctionCaseMergeWriteHandler implements RowWriteHandler {
|
||||
|
||||
/**
|
||||
* 存储需要合并单元格的信息,key 是需要合并的第一条的行号,值是需要合并多少行
|
||||
*/
|
||||
Map<Integer, Integer> rowMergeInfo;
|
||||
List<List<String>> headList;
|
||||
int stepDescRowIndex;
|
||||
int stepResultRowIndex;
|
||||
|
||||
public FunctionCaseMergeWriteHandler(Map<Integer, Integer> rowMergeInfo, List<List<String>> headList) {
|
||||
this.rowMergeInfo = rowMergeInfo;
|
||||
this.headList = headList;
|
||||
for (int i = 0; i < headList.size(); i++) {
|
||||
List<String> list = headList.get(i);
|
||||
for (String head : list) {
|
||||
if (TestCaseImportFiled.STEP_DESC.getFiledLangMap().values().contains(head)) {
|
||||
stepDescRowIndex = i;
|
||||
} else if (TestCaseImportFiled.STEP_RESULT.getFiledLangMap().values().contains(head)) {
|
||||
stepResultRowIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterRowDispose(RowWriteHandlerContext context) {
|
||||
if (context.getHead() || context.getRelativeRowIndex() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Integer mergeCount = rowMergeInfo.get(context.getRowIndex());
|
||||
|
||||
if (mergeCount == null || mergeCount <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < headList.size(); i++) {
|
||||
// 除了描述其他数据合并多行
|
||||
if (i != stepDescRowIndex && i != stepResultRowIndex) {
|
||||
CellRangeAddress cellRangeAddress =
|
||||
new CellRangeAddress(context.getRowIndex(), context.getRowIndex() + mergeCount - 1, i, i);
|
||||
context.getWriteSheetHolder().getSheet().addMergedRegionUnsafe(cellRangeAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,11 +9,16 @@ import io.metersphere.base.domain.TestCase;
|
|||
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||
import io.metersphere.commons.constants.TestCaseConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
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.dto.CustomFieldDao;
|
||||
import io.metersphere.dto.CustomFieldOption;
|
||||
import io.metersphere.excel.annotation.NotRequired;
|
||||
import io.metersphere.excel.constants.TestCaseImportFiled;
|
||||
import io.metersphere.excel.domain.ExcelErrData;
|
||||
import io.metersphere.excel.domain.ExcelMergeInfo;
|
||||
import io.metersphere.excel.domain.TestCaseExcelData;
|
||||
import io.metersphere.excel.domain.TestCaseExcelDataFactory;
|
||||
import io.metersphere.excel.utils.ExcelValidateHelper;
|
||||
|
@ -23,11 +28,11 @@ import io.metersphere.track.request.testcase.TestCaseImportRequest;
|
|||
import io.metersphere.track.service.TestCaseService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
@ -48,7 +53,6 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
private Map<Integer, String> headMap;
|
||||
private Map<String, String> excelHeadToFieldNameDic = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* 每隔2000条存储数据库,然后清理list ,方便内存回收
|
||||
*/
|
||||
|
@ -71,13 +75,36 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
|
||||
private TestCaseImportRequest request;
|
||||
|
||||
private Set<ExcelMergeInfo> mergeInfoSet;
|
||||
|
||||
// 存储当前合并的一条完整数据,其中步骤没有合并是多行
|
||||
private TestCaseExcelData currentMergeData;
|
||||
|
||||
private static final String ERROR_MSG_SEPARATOR = ";";
|
||||
|
||||
/**
|
||||
* 标记下当前遍历的行是不是有合并单元格
|
||||
*/
|
||||
private Boolean isMergeRow;
|
||||
|
||||
/**
|
||||
* 标记下当前遍历的行是不是合并单元格的最后一行
|
||||
*/
|
||||
private Boolean isMergeLastRow;
|
||||
|
||||
/**
|
||||
* 存储合并单元格对应的数据,key 为重写了 compareTo 的 ExcelMergeInfo
|
||||
*/
|
||||
private HashMap<ExcelMergeInfo, String> mergeCellDataMap = new HashMap<>();
|
||||
|
||||
public boolean isUpdated() {
|
||||
return isUpdated;
|
||||
}
|
||||
|
||||
public TestCaseNoModelDataListener(TestCaseImportRequest request, Class c) {
|
||||
public TestCaseNoModelDataListener(TestCaseImportRequest request, Class c, Set<ExcelMergeInfo> mergeInfoSet) {
|
||||
this.mergeInfoSet = mergeInfoSet;
|
||||
this.excelDataClass = c;
|
||||
this.testCaseService = (TestCaseService) CommonBeanFactory.getBean("testCaseService");
|
||||
this.testCaseService = CommonBeanFactory.getBean(TestCaseService.class);
|
||||
customIds = new HashSet<>();
|
||||
|
||||
this.request = request;
|
||||
|
@ -89,11 +116,11 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
if (StringUtils.isNotEmpty(name)) {
|
||||
name = name.trim();
|
||||
}
|
||||
if (StringUtils.equalsAny(name, "责任人", "維護人", "Maintainer")) {
|
||||
if (TestCaseImportFiled.MAINTAINER.getFiledLangMap().values().contains(name)) {
|
||||
customFieldsMap.put("maintainer", dto);
|
||||
} else if (StringUtils.equalsAny(name, "用例等级", "用例等級", "Priority")) {
|
||||
} else if (TestCaseImportFiled.PRIORITY.getFiledLangMap().values().contains(name)) {
|
||||
customFieldsMap.put("priority", dto);
|
||||
} else if (StringUtils.equalsAny(name, "用例状态", "用例狀態", "Case status")) {
|
||||
} else if (TestCaseImportFiled.STATUS.getFiledLangMap().values().contains(name)) {
|
||||
customFieldsMap.put("status", dto);
|
||||
} else {
|
||||
customFieldsMap.put(name, dto);
|
||||
|
@ -115,98 +142,249 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
}
|
||||
|
||||
public void invoke(Map<Integer, String> data, AnalysisContext analysisContext) {
|
||||
String errMsg;
|
||||
|
||||
Integer rowIndex = analysisContext.readRowHolder().getRowIndex();
|
||||
String updateMsg = "update_testcase";
|
||||
TestCaseExcelData testCaseExcelData = this.parseDataToModel(data);
|
||||
|
||||
handleMergeData(data, rowIndex);
|
||||
|
||||
TestCaseExcelData testCaseExcelData;
|
||||
// 读取名称列,如果该列是合并单元格,则读取多行数据后合并步骤
|
||||
if (this.isMergeRow) {
|
||||
if (currentMergeData == null) {
|
||||
// 如果是合并单元格的首行
|
||||
testCaseExcelData = this.parseDataToModel(data);
|
||||
testCaseExcelData.setMergeStepDesc(new ArrayList<>() {{
|
||||
add(testCaseExcelData.getStepDesc());
|
||||
}});
|
||||
testCaseExcelData.setMergeStepResult(new ArrayList<>() {{
|
||||
add(testCaseExcelData.getStepResult());
|
||||
}});
|
||||
// 记录下数据并返回
|
||||
this.currentMergeData = testCaseExcelData;
|
||||
return;
|
||||
} else {
|
||||
// 获取存储的数据,并添加多个步骤
|
||||
this.currentMergeData.getMergeStepDesc()
|
||||
.add(data.get(getStepDescColIndex()));
|
||||
this.currentMergeData.getMergeStepResult()
|
||||
.add(data.get(getStepResultColIndex()));
|
||||
// 是最后一行的合并单元格,保存并清空 currentMergeData,走之后的逻辑
|
||||
if (this.isMergeLastRow) {
|
||||
testCaseExcelData = this.currentMergeData;
|
||||
this.currentMergeData = null;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
testCaseExcelData = this.parseDataToModel(data);
|
||||
}
|
||||
|
||||
StringBuilder errMsg;
|
||||
try {
|
||||
//根据excel数据实体中的javax.validation + 正则表达式来校验excel数据
|
||||
errMsg = ExcelValidateHelper.validateEntity(testCaseExcelData);
|
||||
errMsg = new StringBuilder(ExcelValidateHelper.validateEntity(testCaseExcelData));
|
||||
//自定义校验规则
|
||||
if (StringUtils.isEmpty(errMsg)) {
|
||||
errMsg = validate(testCaseExcelData, errMsg);
|
||||
validate(testCaseExcelData, errMsg);
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
errMsg = Translator.get("parse_data_error");
|
||||
errMsg = new StringBuilder(Translator.get("parse_data_error"));
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(errMsg)) {
|
||||
|
||||
//如果errMsg只有"update testcase",说明用例待更新
|
||||
if (!errMsg.equals(updateMsg)) {
|
||||
ExcelErrData excelErrData = new ExcelErrData(testCaseExcelData, rowIndex,
|
||||
Translator.get("number") + " " + rowIndex + " " + Translator.get("row") + Translator.get("error")
|
||||
+ ":" + errMsg);
|
||||
errList.add(excelErrData);
|
||||
}
|
||||
ExcelErrData excelErrData = new ExcelErrData(testCaseExcelData, rowIndex,
|
||||
Translator.get("number")
|
||||
.concat(" ")
|
||||
.concat(rowIndex.toString()).concat(" ")
|
||||
.concat(Translator.get("row"))
|
||||
.concat(Translator.get("error"))
|
||||
.concat(":")
|
||||
.concat(errMsg.toString()));
|
||||
errList.add(excelErrData);
|
||||
} else {
|
||||
list.add(testCaseExcelData);
|
||||
if (isCreateModel()) {
|
||||
list.add(testCaseExcelData);
|
||||
}
|
||||
}
|
||||
if (list.size() > BATCH_COUNT) {
|
||||
if (list.size() > BATCH_COUNT || updateList.size() > BATCH_COUNT) {
|
||||
saveData();
|
||||
list.clear();
|
||||
updateList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public String validate(TestCaseExcelData data, String errMsg) {
|
||||
Set<String> savedCustomIds = request.getSavedCustomIds();
|
||||
String importType = request.getImportType();
|
||||
StringBuilder stringBuilder = new StringBuilder(errMsg);
|
||||
if (request.isUseCustomId() || StringUtils.equals(importType, FunctionCaseImportEnum.Update.name())) {
|
||||
if (data.getCustomNum() == null) {
|
||||
stringBuilder.append(Translator.get("id_required") + ";");
|
||||
} else {
|
||||
String customId = data.getCustomNum();
|
||||
if (StringUtils.isEmpty(customId)) {
|
||||
stringBuilder.append(Translator.get("id_required") + ";");
|
||||
} else if (customIds.contains(customId.toLowerCase())) {
|
||||
stringBuilder.append(Translator.get("id_repeat_in_table") + ";");
|
||||
} else if (StringUtils.equals(FunctionCaseImportEnum.Create.name(), importType) && savedCustomIds.contains(customId)) {
|
||||
stringBuilder.append(Translator.get("custom_num_is_exist") + ";");
|
||||
} else if (StringUtils.equals(FunctionCaseImportEnum.Update.name(), importType) && !savedCustomIds.contains(customId)) {
|
||||
stringBuilder.append(Translator.get("custom_num_is_not_exist") + ";");
|
||||
} else {
|
||||
customIds.add(customId.toLowerCase());
|
||||
/**
|
||||
* 处理合并单元格
|
||||
*
|
||||
* @param data
|
||||
* @param rowIndex
|
||||
*/
|
||||
private void handleMergeData(Map<Integer, String> data, Integer rowIndex) {
|
||||
this.isMergeRow = false;
|
||||
this.isMergeLastRow = false;
|
||||
data.keySet().forEach(col -> {
|
||||
Iterator<ExcelMergeInfo> iterator = mergeInfoSet.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ExcelMergeInfo mergeInfo = iterator.next();
|
||||
// 如果单元格的行号在合并单元格的范围之间,并且列号相等,说明该单元格是合并单元格中的一部分
|
||||
if (mergeInfo.getFirstRowIndex() <= rowIndex && rowIndex <= mergeInfo.getLastRowIndex()
|
||||
&& col.equals(mergeInfo.getFirstColumnIndex())) {
|
||||
// 根据名称列是否是合并单元格判断是不是同一条用例
|
||||
if (getNameColIndex().equals(col)) {
|
||||
this.isMergeRow = true;
|
||||
}
|
||||
// 如果是合并单元格的第一个cell,则把这个单元格的数据存起来
|
||||
if (rowIndex.equals(mergeInfo.getFirstRowIndex())) {
|
||||
if (StringUtils.isNotBlank(data.get(col))) {
|
||||
mergeCellDataMap.put(mergeInfo, data.get(col));
|
||||
}
|
||||
} else {
|
||||
// 非第一个,获取存储的数据填充
|
||||
String cellData = mergeCellDataMap.get(mergeInfo);
|
||||
if (StringUtils.isNotBlank(cellData)) {
|
||||
data.put(col, cellData);
|
||||
}
|
||||
// 如果合并单元格的最后一个单元格,标记下
|
||||
if (rowIndex == mergeInfo.getLastRowIndex()) {
|
||||
// 根据名称列是否是合并单元格判断是不是同一条用例
|
||||
if (getNameColIndex().equals(col)) {
|
||||
this.isMergeLastRow = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (rowIndex > mergeInfo.getLastRowIndex()) {
|
||||
// TreeSet 按照行号排序了
|
||||
// 清除掉上一次已经遍历完成的数据,提高查询效率
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
String nodePath = data.getNodePath();
|
||||
//校验”所属模块"
|
||||
if (nodePath != null) {
|
||||
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") + "; ");
|
||||
public void validate(TestCaseExcelData data, StringBuilder errMsg) {
|
||||
|
||||
validateCustomNum(data, errMsg);
|
||||
|
||||
validateModule(data, errMsg);
|
||||
|
||||
validateCustomField(data, errMsg);
|
||||
|
||||
validateIdExist(data, errMsg);
|
||||
|
||||
validateDbExist(data, errMsg);
|
||||
}
|
||||
|
||||
private void validateDbExist(TestCaseExcelData data, StringBuilder stringBuilder) {
|
||||
if (request.getTestCaseNames().contains(data.getName())) {
|
||||
TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(testCase, data);
|
||||
testCase.setProjectId(request.getProjectId());
|
||||
String steps = getSteps(data);
|
||||
testCase.setSteps(steps);
|
||||
testCase.setType(TestCaseConstants.Type.Functional.getValue());
|
||||
|
||||
boolean dbExist = testCaseService.exist(testCase);
|
||||
boolean excelExist = false;
|
||||
|
||||
if (dbExist) {
|
||||
// db exist
|
||||
stringBuilder.append(
|
||||
Translator.get("test_case_already_exists")
|
||||
.concat(":")
|
||||
.concat(data.getName())
|
||||
.concat(ERROR_MSG_SEPARATOR));
|
||||
} else {
|
||||
// @Data 重写了 equals 和 hashCode 方法
|
||||
excelExist = excelDataList.contains(data);
|
||||
}
|
||||
//模块名不能为空
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
if (i != 0 && StringUtils.equals(nodes[i].trim(), "")) {
|
||||
stringBuilder.append(Translator.get("module_not_null") + "; ");
|
||||
break;
|
||||
|
||||
if (excelExist) {
|
||||
// excel exist
|
||||
stringBuilder.append(
|
||||
Translator.get("test_case_already_exists_excel")
|
||||
.concat(":")
|
||||
.concat(data.getName())
|
||||
.concat(ERROR_MSG_SEPARATOR));
|
||||
} else {
|
||||
if (!dbExist) {
|
||||
excelDataList.add(data);
|
||||
}
|
||||
}
|
||||
//增加字数校验,每一层不能超过100字
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
String nodeStr = nodes[i];
|
||||
if (StringUtils.isNotEmpty(nodeStr)) {
|
||||
if (nodeStr.trim().length() > 100) {
|
||||
stringBuilder.append(Translator.get("module") + Translator.get("test_track.length_less_than") + "100:" + nodeStr);
|
||||
break;
|
||||
|
||||
} else {
|
||||
request.getTestCaseNames().add(data.getName());
|
||||
excelDataList.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验Excel中是否有ID
|
||||
* 有的话校验ID是否已在当前项目中存在,存在则更新用例,
|
||||
* 不存在则继续校验看是否重复,不重复则新建用例
|
||||
*
|
||||
* @param data
|
||||
* @param stringBuilder
|
||||
*/
|
||||
@Nullable
|
||||
private void validateIdExist(TestCaseExcelData data, StringBuilder stringBuilder) {
|
||||
|
||||
//当前读取的数据有ID
|
||||
if (null != data.getCustomNum()) {
|
||||
if (isUpdateModel()) {
|
||||
String checkResult = null;
|
||||
if (request.isUseCustomId()) {
|
||||
checkResult = testCaseService.checkCustomIdExist(data.getCustomNum(), request.getProjectId());
|
||||
} else {
|
||||
int customNumId = -1;
|
||||
try {
|
||||
customNumId = Integer.parseInt(data.getCustomNum());
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
if (customNumId < 0) {
|
||||
stringBuilder.append(Translator.get("id_not_rightful"))
|
||||
.append("[")
|
||||
.append(data.getCustomNum())
|
||||
.append("]; ");
|
||||
} else {
|
||||
checkResult = testCaseService.checkIdExist(customNumId, request.getProjectId());
|
||||
}
|
||||
}
|
||||
//该ID在当前项目中存在
|
||||
if (null != checkResult) {
|
||||
//如果前面所经过的校验都没报错
|
||||
if (StringUtils.isEmpty(stringBuilder)) {
|
||||
data.setId(checkResult);
|
||||
//将当前数据存入更新列表
|
||||
updateList.add(data);
|
||||
}
|
||||
} else {
|
||||
// 该ID在当前数据库中不存在,应当继续校验用例是否重复,
|
||||
// 在下面的校验过程中,num的值会被用于判断是否重复,所以应当先设置为null
|
||||
data.setNum(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isUpdateModel() {
|
||||
return StringUtils.equals(request.getImportType(), FunctionCaseImportEnum.Update.name());
|
||||
}
|
||||
|
||||
private boolean isCreateModel() {
|
||||
return StringUtils.equals(request.getImportType(), FunctionCaseImportEnum.Create.name());
|
||||
}
|
||||
|
||||
private void validateCustomField(TestCaseExcelData data, StringBuilder stringBuilder) {
|
||||
//校验自定义必填字段
|
||||
for (Map.Entry<String, CustomFieldDao> customEntry : customFieldsMap.entrySet()) {
|
||||
String customName = customEntry.getKey();
|
||||
CustomFieldDao field = customEntry.getValue();
|
||||
|
||||
if (field.getRequired()) {
|
||||
String value = null;
|
||||
String value;
|
||||
if (StringUtils.equals(customName, "status")) {
|
||||
Map<String, String> valueMap = new HashMap<>() {{
|
||||
put("Prepare", Translator.get("test_case_status_prepare"));
|
||||
|
@ -221,11 +399,14 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
} else if (StringUtils.equals(customName, "maintainer")) {
|
||||
value = data.getMaintainer();
|
||||
//校验维护人
|
||||
if (StringUtils.isBlank(data.getMaintainer())) {
|
||||
if (StringUtils.isBlank(value)) {
|
||||
data.setMaintainer(SessionUtils.getUserId());
|
||||
} else {
|
||||
if (!request.getUserIds().contains(data.getMaintainer())) {
|
||||
stringBuilder.append(Translator.get("user_not_exists") + ":" + data.getMaintainer() + "; ");
|
||||
if (!request.getUserIds().contains(value)) {
|
||||
stringBuilder.append(Translator.get("user_not_exists"))
|
||||
.append( ":")
|
||||
.append(value)
|
||||
.append(ERROR_MSG_SEPARATOR);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
@ -233,93 +414,80 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
value = data.getCustomDatas().get(customName);
|
||||
}
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
stringBuilder.append(field.getName() + " " + Translator.get("required") + "; ");
|
||||
stringBuilder.append(field.getName())
|
||||
.append(" ")
|
||||
.append(Translator.get("required"))
|
||||
.append(ERROR_MSG_SEPARATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
校验Excel中是否有ID
|
||||
有的话校验ID是否已在当前项目中存在,存在则更新用例,
|
||||
不存在则继续校验看是否重复,不重复则新建用例。
|
||||
*/
|
||||
if (null != data.getCustomNum()) { //当前读取的数据有ID
|
||||
|
||||
if (StringUtils.equals(request.getImportType(), FunctionCaseImportEnum.Update.name())) {
|
||||
String checkResult = null;
|
||||
if (request.isUseCustomId()) {
|
||||
checkResult = testCaseService.checkCustomIdExist(data.getCustomNum(), request.getProjectId());
|
||||
} else {
|
||||
int customNumId = -1;
|
||||
try {
|
||||
customNumId = Integer.parseInt(data.getCustomNum());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
if (customNumId < 0) {
|
||||
stringBuilder.append(Translator.get("id_not_rightful") + "[" + data.getCustomNum() + "]; ");
|
||||
} else {
|
||||
checkResult = testCaseService.checkIdExist(customNumId, request.getProjectId());
|
||||
}
|
||||
}
|
||||
if (null != checkResult) { //该ID在当前项目中存在
|
||||
//如果前面所经过的校验都没报错
|
||||
if (StringUtils.isEmpty(stringBuilder)) {
|
||||
data.setId(checkResult);
|
||||
updateList.add(data); //将当前数据存入更新列表
|
||||
stringBuilder.append("update_testcase"); //该信息用于在invoke方法中判断是否该更新用例
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
} else {
|
||||
/*
|
||||
该ID在当前数据库中不存在,应当继续校验用例是否重复,
|
||||
在下面的校验过程中,num的值会被用于判断是否重复,所以应当先设置为null
|
||||
*/
|
||||
data.setNum(null);
|
||||
private void validateModule(TestCaseExcelData data, StringBuilder stringBuilder) {
|
||||
String nodePath = data.getNodePath();
|
||||
//校验”所属模块"
|
||||
if (nodePath != null) {
|
||||
String[] nodes = nodePath.split("/");
|
||||
//校验模块深度
|
||||
if (nodes.length > TestCaseConstants.MAX_NODE_DEPTH + 1) {
|
||||
stringBuilder.append(Translator.get("test_case_node_level_tip"))
|
||||
.append(TestCaseConstants.MAX_NODE_DEPTH)
|
||||
.append(Translator.get("test_case_node_level"))
|
||||
.append("; ");
|
||||
}
|
||||
//模块名不能为空
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
if (i != 0 && StringUtils.equals(nodes[i].trim(), "")) {
|
||||
stringBuilder.append(Translator.get("module_not_null"))
|
||||
.append(ERROR_MSG_SEPARATOR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//增加字数校验,每一层不能超过100字
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
String nodeStr = nodes[i];
|
||||
if (StringUtils.isNotEmpty(nodeStr)) {
|
||||
if (nodeStr.trim().length() > 100) {
|
||||
stringBuilder.append(Translator.get("module"))
|
||||
.append(Translator.get("test_track.length_less_than"))
|
||||
.append("100:")
|
||||
.append(nodeStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
校验用例
|
||||
*/
|
||||
if (request.getTestCaseNames().contains(data.getName())) {
|
||||
TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(testCase, data);
|
||||
testCase.setProjectId(request.getProjectId());
|
||||
String steps = getSteps(data);
|
||||
testCase.setSteps(steps);
|
||||
testCase.setType("functional");
|
||||
|
||||
boolean dbExist = testCaseService.exist(testCase);
|
||||
boolean excelExist = false;
|
||||
|
||||
if (dbExist) {
|
||||
// db exist
|
||||
stringBuilder.append(Translator.get("test_case_already_exists") + ":" + data.getName() + "; ");
|
||||
private void validateCustomNum(TestCaseExcelData data, StringBuilder stringBuilder) {
|
||||
if (request.isUseCustomId() || isUpdateModel()) {
|
||||
if (data.getCustomNum() == null) {
|
||||
stringBuilder.append(Translator.get("id_required"))
|
||||
.append(ERROR_MSG_SEPARATOR);
|
||||
} else {
|
||||
// @Data 重写了 equals 和 hashCode 方法
|
||||
excelExist = excelDataList.contains(data);
|
||||
}
|
||||
|
||||
if (excelExist) {
|
||||
// excel exist
|
||||
stringBuilder.append(Translator.get("test_case_already_exists_excel") + ":" + data.getName() + "; ");
|
||||
} else {
|
||||
if (!dbExist) {
|
||||
excelDataList.add(data);
|
||||
String customId = data.getCustomNum();
|
||||
if (StringUtils.isEmpty(customId)) {
|
||||
stringBuilder.append(Translator.get("id_required"))
|
||||
.append(ERROR_MSG_SEPARATOR);
|
||||
} else if (customIds.contains(customId.toLowerCase())) {
|
||||
stringBuilder.append(Translator.get("id_repeat_in_table"))
|
||||
.append(ERROR_MSG_SEPARATOR);
|
||||
} else if (isCreateModel() && request.getSavedCustomIds().contains(customId)) {
|
||||
stringBuilder.append(Translator.get("custom_num_is_exist"))
|
||||
.append(ERROR_MSG_SEPARATOR);
|
||||
} else if (isUpdateModel() && !request.getSavedCustomIds().contains(customId)) {
|
||||
stringBuilder.append(Translator.get("custom_num_is_not_exist"))
|
||||
.append(ERROR_MSG_SEPARATOR);
|
||||
} else {
|
||||
customIds.add(customId.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
request.getTestCaseNames().add(data.getName());
|
||||
excelDataList.add(data);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据自定义字段的选项值获取对应的选项id
|
||||
*
|
||||
* @param name
|
||||
* @param text
|
||||
* @param optionsStr
|
||||
|
@ -394,33 +562,22 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* 检验导入功能用例的状态
|
||||
*
|
||||
* @param status
|
||||
* @return
|
||||
*/
|
||||
private boolean checkCaseStatus(String status) {
|
||||
if (StringUtils.equalsAnyIgnoreCase(status, "Underway", "进行中", "進行中")) {
|
||||
return true;
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(status, "Prepare", "未开始", "未開始")) {
|
||||
return true;
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(status, "Completed", "已完成", "已完成")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private TestCaseWithBLOBs convert2TestCase(TestCaseExcelData data) {
|
||||
TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(testCase, data);
|
||||
TestCaseWithBLOBs testCase = parseData(data);
|
||||
testCase.setId(UUID.randomUUID().toString());
|
||||
testCase.setProjectId(request.getProjectId());
|
||||
testCase.setCreateTime(System.currentTimeMillis());
|
||||
testCase.setUpdateTime(System.currentTimeMillis());
|
||||
if (request.isUseCustomId()) {
|
||||
testCase.setCustomNum(data.getCustomNum());
|
||||
}
|
||||
return testCase;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TestCaseWithBLOBs parseData(TestCaseExcelData data) {
|
||||
TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(testCase, data);
|
||||
testCase.setProjectId(request.getProjectId());
|
||||
testCase.setUpdateTime(System.currentTimeMillis());
|
||||
|
||||
String nodePath = data.getNodePath();
|
||||
|
||||
|
@ -435,21 +592,10 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
//将标签设置为前端可解析的格式
|
||||
String modifiedTags = modifyTagPattern(data);
|
||||
testCase.setTags(modifiedTags);
|
||||
testCase.setType("functional");
|
||||
|
||||
String caseStatusValue = "";
|
||||
if (StringUtils.equalsAnyIgnoreCase(data.getStatus(), "Underway", "进行中", "進行中")) {
|
||||
caseStatusValue = "Underway";
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(data.getStatus(), "Prepare", "未开始", "未開始")) {
|
||||
caseStatusValue = "Prepare";
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(data.getStatus(), "Completed", "已完成", "已完成")) {
|
||||
caseStatusValue = "Completed";
|
||||
}
|
||||
data.setStatus(caseStatusValue);
|
||||
testCase.setType(TestCaseConstants.Type.Functional.getValue());
|
||||
data.setStatus(data.getStatus());
|
||||
|
||||
// todo 这里要获取模板的自定义字段再新建关联关系
|
||||
// String customFieldsJson = this.getCustomFieldsJson(data);
|
||||
// testCase.setCustomFields(customFieldsJson);
|
||||
if (StringUtils.isNotBlank(data.getMaintainer())) {
|
||||
testCase.setMaintainer(data.getMaintainer());
|
||||
}
|
||||
|
@ -472,51 +618,12 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
* @return
|
||||
*/
|
||||
private TestCaseWithBLOBs convert2TestCaseForUpdate(TestCaseExcelData data) {
|
||||
TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(testCase, data);
|
||||
testCase.setProjectId(request.getProjectId());
|
||||
TestCaseWithBLOBs testCase = parseData(data);
|
||||
testCase.setUpdateTime(System.currentTimeMillis());
|
||||
|
||||
//调整nodePath格式
|
||||
String nodePath = data.getNodePath();
|
||||
if (!nodePath.startsWith("/")) {
|
||||
nodePath = "/" + nodePath;
|
||||
}
|
||||
if (nodePath.endsWith("/")) {
|
||||
nodePath = nodePath.substring(0, nodePath.length() - 1);
|
||||
}
|
||||
testCase.setNodePath(nodePath);
|
||||
|
||||
String steps = getSteps(data);
|
||||
testCase.setSteps(steps);
|
||||
|
||||
JSONArray customArr = new JSONArray();
|
||||
String caseStatusValue = "";
|
||||
if (StringUtils.equalsAnyIgnoreCase(data.getStatus(), "Underway", "进行中", "進行中")) {
|
||||
caseStatusValue = "Underway";
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(data.getStatus(), "Prepare", "未开始", "未開始")) {
|
||||
caseStatusValue = "Prepare";
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(data.getStatus(), "Completed", "已完成", "已完成")) {
|
||||
caseStatusValue = "Completed";
|
||||
}
|
||||
data.setStatus(caseStatusValue);
|
||||
|
||||
// todo
|
||||
// String customFieldsJson = this.getCustomFieldsJson(data);
|
||||
// testCase.setCustomFields(customFieldsJson);
|
||||
if (StringUtils.isNotBlank(data.getMaintainer())) {
|
||||
testCase.setMaintainer(data.getMaintainer());
|
||||
}
|
||||
|
||||
//将标签设置为前端可解析的格式
|
||||
String modifiedTags = modifyTagPattern(data);
|
||||
testCase.setTags(modifiedTags);
|
||||
|
||||
if (!request.isUseCustomId()) {
|
||||
testCase.setNum(Integer.parseInt(data.getCustomNum()));
|
||||
testCase.setCustomNum(null);
|
||||
}
|
||||
|
||||
return testCase;
|
||||
}
|
||||
|
||||
|
@ -549,9 +656,21 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
public String getSteps(TestCaseExcelData data) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
|
||||
// 如果是合并单元格,则组合多条单元格的数据
|
||||
if (CollectionUtils.isNotEmpty(data.getMergeStepDesc())
|
||||
|| CollectionUtils.isNotEmpty(data.getMergeStepResult())) {
|
||||
for (int i = 0; i < data.getMergeStepDesc().size(); i++) {
|
||||
JSONObject step = new JSONObject(true);
|
||||
step.put("num", i + 1);
|
||||
step.put("desc", Optional.ofNullable(data.getMergeStepDesc().get(i)).orElse(""));
|
||||
step.put("result", Optional.ofNullable(data.getMergeStepResult().get(i)).orElse(""));
|
||||
jsonArray.add(step);
|
||||
}
|
||||
return jsonArray.toJSONString();
|
||||
}
|
||||
|
||||
List<String> stepDescList = new ArrayList<>();
|
||||
List<String> stepResList = new ArrayList<>();
|
||||
ListUtils<String> listUtils = new ListUtils<>();
|
||||
|
||||
Set<Integer> rowNums = new HashSet<>();
|
||||
if (data.getStepDesc() != null) {
|
||||
|
@ -643,6 +762,27 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
return rowInfo;
|
||||
}
|
||||
|
||||
private Integer getNameColIndex() {
|
||||
return findColIndex("name");
|
||||
}
|
||||
|
||||
private Integer getStepResultColIndex() {
|
||||
return findColIndex("stepResult");
|
||||
}
|
||||
|
||||
private Integer getStepDescColIndex() {
|
||||
return findColIndex("stepDesc");
|
||||
}
|
||||
|
||||
private Integer findColIndex(String colName) {
|
||||
for (Integer key : headMap.keySet()) {
|
||||
if (StringUtils.equals(headMap.get(key), colName)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private TestCaseExcelData parseDataToModel(Map<Integer, String> row) {
|
||||
TestCaseExcelData data = new TestCaseExcelDataFactory().getTestCaseExcelDataLocal();
|
||||
for (Map.Entry<Integer, String> headEntry : headMap.entrySet()) {
|
||||
|
@ -712,64 +852,6 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
}
|
||||
}
|
||||
|
||||
private String getCustomFieldsJson(TestCaseExcelData data) {
|
||||
JSONArray customArr = new JSONArray();
|
||||
for (Map.Entry<String, CustomFieldDao> customEntry : customFieldsMap.entrySet()) {
|
||||
String customName = customEntry.getKey();
|
||||
CustomFieldDao field = customEntry.getValue();
|
||||
|
||||
String value = null;
|
||||
if (StringUtils.equals(customName, "status")) {
|
||||
value = data.getStatus();
|
||||
} else if (StringUtils.equals(customName, "priority")) {
|
||||
value = data.getPriority();
|
||||
} else if (StringUtils.equals(customName, "maintainer")) {
|
||||
value = data.getMaintainer();
|
||||
} else {
|
||||
value = data.getCustomDatas().get(customName);
|
||||
}
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
value = "";
|
||||
}
|
||||
if (field.getType().equalsIgnoreCase("multipleSelect")) {
|
||||
value = modifyMultipleSelectPattern(value);
|
||||
}
|
||||
JSONObject statusObj = new JSONObject();
|
||||
statusObj.put("id", UUID.randomUUID().toString());
|
||||
statusObj.put("name", field.getName());
|
||||
statusObj.put("value", value);
|
||||
statusObj.put("customData", null);
|
||||
statusObj.put("type", field.getType());
|
||||
customArr.add(statusObj);
|
||||
}
|
||||
return customArr.toJSONString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整自定义多选下拉框格式,便于前端进行解析。
|
||||
* 例如对于:下拉值1,下拉值2。将调整为:["下拉值1","下拉值2"]。
|
||||
*/
|
||||
public String modifyMultipleSelectPattern(String values) {
|
||||
try {
|
||||
if (StringUtils.isNotBlank(values)) {
|
||||
JSONArray array = JSONArray.parseArray(values);
|
||||
return array.toJSONString();
|
||||
}
|
||||
return "[]";
|
||||
} catch (Exception e) {
|
||||
if (values != null) {
|
||||
Stream<String> stringStream = Arrays.stream(values.split("[,;,;]")); //当标签值以中英文的逗号和分号分隔时才能正确解析
|
||||
List<String> valueList = stringStream.map(multip -> multip = "\"" + multip + "\"")
|
||||
.collect(Collectors.toList());
|
||||
String modifiedValues = StringUtils.join(valueList, ",");
|
||||
modifiedValues = "[" + modifiedValues + "]";
|
||||
return modifiedValues;
|
||||
} else {
|
||||
return "[]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 获取注解里ExcelProperty的value
|
||||
*/
|
||||
|
@ -801,13 +883,4 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
public int index;
|
||||
public String rowInfo;
|
||||
}
|
||||
|
||||
public static boolean isNumericzidai(String str) {
|
||||
Pattern pattern = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
|
||||
Matcher isNum = pattern.matcher(str);
|
||||
if (!isNum.matches()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package io.metersphere.excel.listener;
|
||||
|
||||
import com.alibaba.excel.context.AnalysisContext;
|
||||
import com.alibaba.excel.enums.CellExtraTypeEnum;
|
||||
import com.alibaba.excel.event.AnalysisEventListener;
|
||||
import com.alibaba.excel.metadata.CellExtra;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.excel.domain.ExcelMergeInfo;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 数据预处理,读取合并的单元格信息
|
||||
*/
|
||||
public class TestCasePretreatmentListener extends AnalysisEventListener {
|
||||
|
||||
|
||||
Set<ExcelMergeInfo> mergeInfoSet;
|
||||
|
||||
public TestCasePretreatmentListener(Set<ExcelMergeInfo> mergeInfoSet) {
|
||||
this.mergeInfoSet = mergeInfoSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(Object integerStringMap, AnalysisContext analysisContext) {}
|
||||
|
||||
@Override
|
||||
public void extra(CellExtra extra, AnalysisContext context) {
|
||||
if (extra.getType() == CellExtraTypeEnum.MERGE) {
|
||||
// 将合并单元格信息保留
|
||||
ExcelMergeInfo mergeInfo = new ExcelMergeInfo();
|
||||
BeanUtils.copyBean(mergeInfo, extra);
|
||||
this.mergeInfoSet.add(mergeInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void doAfterAllAnalysed(AnalysisContext analysisContext) {}
|
||||
}
|
|
@ -4,17 +4,15 @@ import com.alibaba.excel.EasyExcel;
|
|||
import com.alibaba.excel.write.handler.WriteHandler;
|
||||
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
|
||||
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.exception.ExcelException;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Optional;
|
||||
|
||||
public class EasyExcelExporter {
|
||||
|
||||
|
@ -25,58 +23,74 @@ public class EasyExcelExporter {
|
|||
}
|
||||
|
||||
public void export(HttpServletResponse response, List data, String fileName, String sheetName) {
|
||||
response.setContentType("application/vnd.ms-excel");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
buildExportResponse(response, fileName);
|
||||
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
|
||||
contentWriteCellStyle.setWrapped(true);
|
||||
try {
|
||||
HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(null, contentWriteCellStyle);
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
|
||||
EasyExcel.write(response.getOutputStream(), this.clazz).registerWriteHandler(horizontalCellStyleStrategy).sheet(sheetName).doWrite(data);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
throw new ExcelException("Utf-8 encoding is not supported");
|
||||
EasyExcel.write(response.getOutputStream(), this.clazz)
|
||||
.registerWriteHandler(horizontalCellStyleStrategy)
|
||||
.sheet(sheetName)
|
||||
.doWrite(data);
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
throw new ExcelException("IO exception");
|
||||
LogUtil.error(e);
|
||||
MSException.throwException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void exportByCustomWriteHandler(HttpServletResponse response, List<List<String>> headList, List<List<Object>> data, String fileName, String sheetName) {
|
||||
if(CollectionUtils.isEmpty(headList)){
|
||||
headList = new ArrayList<>();
|
||||
}
|
||||
response.setContentType("application/vnd.ms-excel");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
public void exportByCustomWriteHandler(HttpServletResponse response, List<List<String>> headList,
|
||||
List<List<Object>> data, String fileName, String sheetName) {
|
||||
buildExportResponse(response, fileName);
|
||||
try {
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
|
||||
EasyExcel.write(response.getOutputStream()).head(headList).
|
||||
sheet(sheetName).doWrite(data);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
throw new ExcelException("Utf-8 encoding is not supported");
|
||||
EasyExcel.write(response.getOutputStream())
|
||||
.head(Optional.ofNullable(headList).orElse(new ArrayList<>()))
|
||||
.sheet(sheetName)
|
||||
.doWrite(data);
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
throw new ExcelException("IO exception");
|
||||
LogUtil.error(e);
|
||||
MSException.throwException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void exportByCustomWriteHandler(HttpServletResponse response, List<List<String>> headList, List<List<Object>> data, String fileName, String sheetName, WriteHandler writeHandler) {
|
||||
if(CollectionUtils.isEmpty(headList)){
|
||||
headList = new ArrayList<>();
|
||||
}
|
||||
response.setContentType("application/vnd.ms-excel");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
public void buildExportResponse(HttpServletResponse response, String fileName) {
|
||||
try {
|
||||
response.setContentType("application/vnd.ms-excel");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
|
||||
EasyExcel.write(response.getOutputStream()).head(headList).registerWriteHandler(writeHandler).
|
||||
sheet(sheetName).doWrite(data);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
throw new ExcelException("Utf-8 encoding is not supported");
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
throw new ExcelException("IO exception");
|
||||
LogUtil.error(e);
|
||||
MSException.throwException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void exportByCustomWriteHandler(HttpServletResponse response, List<List<String>> headList, List<List<Object>> data,
|
||||
String fileName, String sheetName, WriteHandler writeHandler) {
|
||||
buildExportResponse(response, fileName);
|
||||
try {
|
||||
EasyExcel.write(response.getOutputStream())
|
||||
.head(Optional.ofNullable(headList).orElse(new ArrayList<>()))
|
||||
.registerWriteHandler(writeHandler)
|
||||
.sheet(sheetName)
|
||||
.doWrite(data);
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e);
|
||||
MSException.throwException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void exportByCustomWriteHandler(HttpServletResponse response, List<List<String>> headList, List<List<Object>> data,
|
||||
String fileName, String sheetName, WriteHandler writeHandler1, WriteHandler writeHandler2) {
|
||||
buildExportResponse(response, fileName);
|
||||
try {
|
||||
EasyExcel.write(response.getOutputStream())
|
||||
.head(Optional.ofNullable(headList).orElse(new ArrayList<>()))
|
||||
.registerWriteHandler(writeHandler1)
|
||||
.registerWriteHandler(writeHandler2)
|
||||
.sheet(sheetName)
|
||||
.doWrite(data);
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e);
|
||||
MSException.throwException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ public class TestCaseController {
|
|||
public List<TestCaseDTO> listByMethod(@PathVariable String projectId) {
|
||||
QueryTestCaseRequest request = new QueryTestCaseRequest();
|
||||
request.setProjectId(projectId);
|
||||
return testCaseService.listTestCaseMthod(request);
|
||||
return testCaseService.listTestCaseMethod(request);
|
||||
}
|
||||
|
||||
@GetMapping("/relationship/case/{id}/{relationshipType}")
|
||||
|
|
|
@ -15,7 +15,6 @@ public class TestCaseDTO extends TestCaseWithBLOBs {
|
|||
|
||||
private String maintainerName;
|
||||
private String apiName;
|
||||
private String performName;
|
||||
private String lastResultId;
|
||||
private String projectName;
|
||||
private String createName;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package io.metersphere.track.service;
|
||||
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.EasyExcelFactory;
|
||||
import com.alibaba.excel.enums.CellExtraTypeEnum;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
@ -29,12 +31,11 @@ import io.metersphere.controller.request.ProjectVersionRequest;
|
|||
import io.metersphere.controller.request.ResetOrderRequest;
|
||||
import io.metersphere.controller.request.member.QueryMemberRequest;
|
||||
import io.metersphere.dto.*;
|
||||
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.domain.*;
|
||||
import io.metersphere.excel.handler.FunctionCaseMergeWriteHandler;
|
||||
import io.metersphere.excel.handler.FunctionCaseTemplateWriteHandler;
|
||||
import io.metersphere.excel.listener.TestCaseNoModelDataListener;
|
||||
import io.metersphere.excel.listener.TestCasePretreatmentListener;
|
||||
import io.metersphere.excel.utils.EasyExcelExporter;
|
||||
import io.metersphere.excel.utils.FunctionCaseImportEnum;
|
||||
import io.metersphere.i18n.Translator;
|
||||
|
@ -187,6 +188,9 @@ public class TestCaseService {
|
|||
private FileContentMapper fileContentMapper;
|
||||
@Resource
|
||||
private AttachmentService attachmentService;
|
||||
@Resource
|
||||
@Lazy
|
||||
private TestCaseTemplateService testCaseTemplateService;
|
||||
|
||||
private ThreadLocal<Integer> importCreateNum = new ThreadLocal<>();
|
||||
private ThreadLocal<Integer> beforeImportCreateNum = new ThreadLocal<>();
|
||||
|
@ -814,7 +818,7 @@ public class TestCaseService {
|
|||
}
|
||||
}
|
||||
|
||||
public List<TestCaseDTO> listTestCaseMthod(QueryTestCaseRequest request) {
|
||||
public List<TestCaseDTO> listTestCaseMethod(QueryTestCaseRequest request) {
|
||||
return extTestCaseMapper.listByMethod(request);
|
||||
}
|
||||
|
||||
|
@ -986,7 +990,6 @@ public class TestCaseService {
|
|||
testCaseNodeService.createNodes(xmindParser.getNodePaths(), projectId);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(xmindParser.getTestCase())) {
|
||||
// Collections.reverse(xmindParser.getTestCase());
|
||||
this.saveImportData(xmindParser.getTestCase(), request);
|
||||
names = xmindParser.getTestCase().stream().map(TestCase::getName).collect(Collectors.toList());
|
||||
ids = xmindParser.getTestCase().stream().map(TestCase::getId).collect(Collectors.toList());
|
||||
|
@ -1013,7 +1016,6 @@ public class TestCaseService {
|
|||
testCaseNodeService.createNodes(nodePathList, projectId);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(continueCaseList)) {
|
||||
// Collections.reverse(continueCaseList);
|
||||
this.saveImportData(continueCaseList, request);
|
||||
names.addAll(continueCaseList.stream().map(TestCase::getName).collect(Collectors.toList()));
|
||||
ids.addAll(continueCaseList.stream().map(TestCase::getId).collect(Collectors.toList()));
|
||||
|
@ -1037,7 +1039,7 @@ public class TestCaseService {
|
|||
String projectId = request.getProjectId();
|
||||
Set<String> userIds;
|
||||
Project project = projectService.getProjectById(projectId);
|
||||
boolean useCunstomId = projectService.useCustomNum(project);
|
||||
boolean useCustomId = projectService.useCustomNum(project);
|
||||
|
||||
Set<String> savedIds = new HashSet<>();
|
||||
Set<String> testCaseNames = new HashSet<>();
|
||||
|
@ -1046,7 +1048,7 @@ public class TestCaseService {
|
|||
|
||||
List<TestCase> testCases = getTestCaseForImport(projectId);
|
||||
for (TestCase testCase : testCases) {
|
||||
if (useCunstomId) {
|
||||
if (useCustomId) {
|
||||
savedIds.add(testCase.getCustomNum());
|
||||
} else {
|
||||
savedIds.add(String.valueOf(testCase.getNum()));
|
||||
|
@ -1077,8 +1079,14 @@ public class TestCaseService {
|
|||
request.setTestCaseNames(testCaseNames);
|
||||
request.setCustomFields(customFields);
|
||||
request.setSavedCustomIds(savedIds);
|
||||
request.setUseCustomId(useCunstomId);
|
||||
TestCaseNoModelDataListener easyExcelListener = new TestCaseNoModelDataListener(request, clazz);
|
||||
request.setUseCustomId(useCustomId);
|
||||
Set<ExcelMergeInfo> mergeInfoSet = new TreeSet<>();
|
||||
|
||||
// 预处理,查询合并单元格信息
|
||||
EasyExcel.read(multipartFile.getInputStream(), null, new TestCasePretreatmentListener(mergeInfoSet))
|
||||
.extraRead(CellExtraTypeEnum.MERGE).sheet().doRead();
|
||||
|
||||
TestCaseNoModelDataListener easyExcelListener = new TestCaseNoModelDataListener(request, clazz, mergeInfoSet);
|
||||
|
||||
//读取excel数据
|
||||
EasyExcelFactory.read(multipartFile.getInputStream(), easyExcelListener).sheet().doRead();
|
||||
|
@ -1250,40 +1258,6 @@ public class TestCaseService {
|
|||
}
|
||||
}
|
||||
|
||||
public void testCaseTemplateExport(String projectId, String importType, HttpServletResponse response) {
|
||||
try {
|
||||
TestCaseExcelData testCaseExcelData = new TestCaseExcelDataFactory().getTestCaseExcelDataLocal();
|
||||
|
||||
|
||||
boolean useCustomNum = projectService.useCustomNum(projectId);
|
||||
boolean importFileNeedNum = false;
|
||||
if (useCustomNum || StringUtils.equals(importType, FunctionCaseImportEnum.Update.name())) {
|
||||
//导入更新 or 开启使用自定义ID时,导出ID列
|
||||
importFileNeedNum = true;
|
||||
}
|
||||
|
||||
TestCaseTemplateService testCaseTemplateService = CommonBeanFactory.getBean(TestCaseTemplateService.class);
|
||||
TestCaseTemplateDao testCaseTemplate = testCaseTemplateService.getTemplate(projectId);
|
||||
List<CustomFieldDao> customFields = null;
|
||||
if (testCaseTemplate == null) {
|
||||
customFields = new ArrayList<>();
|
||||
} else {
|
||||
customFields = testCaseTemplate.getCustomFields();
|
||||
}
|
||||
|
||||
List<List<String>> headList = testCaseExcelData.getHead(importFileNeedNum, customFields);
|
||||
EasyExcelExporter easyExcelExporter = new EasyExcelExporter(testCaseExcelData.getClass());
|
||||
Map<String, List<String>> caseLevelAndStatusValueMap = testCaseTemplateService.getCaseLevelAndStatusMapByProjectId(projectId);
|
||||
FunctionCaseTemplateWriteHandler handler = new FunctionCaseTemplateWriteHandler(importFileNeedNum, headList, caseLevelAndStatusValueMap);
|
||||
easyExcelExporter.exportByCustomWriteHandler(response, headList, generateExportDatas(importFileNeedNum),
|
||||
Translator.get("test_case_import_template_name"), Translator.get("test_case_import_template_sheet"), handler);
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
MSException.throwException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void download(String fileName, HttpServletResponse res) throws IOException {
|
||||
if (StringUtils.isEmpty(fileName)) {
|
||||
fileName = "xmind.xml";
|
||||
|
@ -1326,75 +1300,64 @@ public class TestCaseService {
|
|||
}
|
||||
}
|
||||
|
||||
private List<List<Object>> generateExportDatas(boolean needCustomId) {
|
||||
List<List<Object>> list = new ArrayList<>();
|
||||
StringBuilder path = new StringBuilder("");
|
||||
List<String> types = TestCaseConstants.Type.getValues();
|
||||
SessionUser user = SessionUtils.getUser();
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
List<Object> rowData = new ArrayList<>();
|
||||
if (needCustomId) {
|
||||
rowData.add("");
|
||||
private List<TestCaseDTO> generateExportData(String projectId) {
|
||||
List<TestCaseDTO> list = new ArrayList<>();
|
||||
StringBuilder path = new StringBuilder();
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
path.append("/" + Translator.get("module") + i);
|
||||
TestCaseDTO testCaseDTO = new TestCaseDTO();
|
||||
testCaseDTO.setCustomNum("");
|
||||
testCaseDTO.setName(Translator.get("test_case") + i);
|
||||
testCaseDTO.setNodePath(path.toString());
|
||||
testCaseDTO.setPriority("P" + i % 4);
|
||||
testCaseDTO.setRemark(Translator.get("remark_optional"));
|
||||
testCaseDTO.setPrerequisite(Translator.get("preconditions_optional"));
|
||||
JSONArray steps = new JSONArray();
|
||||
for (int j = 1; j <= 2; j++) {
|
||||
JSONObject stepItem = new JSONObject(true);
|
||||
stepItem.put("desc", Translator.get("test_case_step_desc") + j);
|
||||
stepItem.put("result", Translator.get("test_case_step_result") + j);
|
||||
steps.add(stepItem);
|
||||
}
|
||||
rowData.add(Translator.get("test_case") + i);
|
||||
path.append("/" + Translator.get("module") + i);
|
||||
rowData.add(path.toString());
|
||||
rowData.add("");
|
||||
rowData.add(Translator.get("preconditions_optional"));
|
||||
rowData.add(Translator.get("remark_optional"));
|
||||
rowData.add("1. " + Translator.get("step_tip_separate") + "\n2. " + Translator.get("step_tip_order") + "\n3. " + Translator.get("step_tip_optional"));
|
||||
rowData.add("1. " + Translator.get("result_tip_separate") + "\n2. " + Translator.get("result_tip_order") + "\n3. " + Translator.get("result_tip_optional"));
|
||||
rowData.add("");
|
||||
rowData.add("P" + i % 4);
|
||||
list.add(rowData);
|
||||
testCaseDTO.setSteps(steps.toJSONString());
|
||||
testCaseDTO.setProjectId(projectId);
|
||||
list.add(testCaseDTO);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<TestCaseExcelData> generateExportTemplate() {
|
||||
List<TestCaseExcelData> list = new ArrayList<>();
|
||||
StringBuilder path = new StringBuilder("");
|
||||
List<String> types = TestCaseConstants.Type.getValues();
|
||||
SessionUser user = SessionUtils.getUser();
|
||||
TestCaseExcelDataFactory factory = new TestCaseExcelDataFactory();
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
TestCaseExcelData data = factory.getTestCaseExcelDataLocal();
|
||||
data.setName(Translator.get("test_case") + i);
|
||||
path.append("/" + Translator.get("module") + i);
|
||||
data.setNodePath(path.toString());
|
||||
data.setPriority("P" + i % 4);
|
||||
String type = types.get(i % 3);
|
||||
data.setPrerequisite(Translator.get("preconditions_optional"));
|
||||
data.setStepDesc("1. " + Translator.get("step_tip_separate") +
|
||||
"\n2. " + Translator.get("step_tip_order") + "\n3. " + Translator.get("step_tip_optional"));
|
||||
data.setStepResult("1. " + Translator.get("result_tip_separate") + "\n2. " + Translator.get("result_tip_order") + "\n3. " + Translator.get("result_tip_optional"));
|
||||
data.setMaintainer(user.getId());
|
||||
data.setRemark(Translator.get("remark_optional"));
|
||||
list.add(data);
|
||||
}
|
||||
|
||||
list.add(new TestCaseExcelData());
|
||||
return list;
|
||||
}
|
||||
|
||||
public void testCaseExport(HttpServletResponse response, TestCaseBatchRequest request) {
|
||||
try {
|
||||
String projectId = request.getProjectId();
|
||||
request.getCondition().setStatusIsNot(CommonConstants.TrashStatus);
|
||||
List<TestCaseDTO> testCaseList = getExportData(request);
|
||||
testCaseExport(response, projectId, testCaseList, true);
|
||||
}
|
||||
|
||||
TestCaseExcelData testCaseExcelData = new TestCaseExcelDataFactory().getTestCaseExcelDataLocal();
|
||||
TestCaseTemplateService testCaseTemplateService = CommonBeanFactory.getBean(TestCaseTemplateService.class);
|
||||
TestCaseTemplateDao testCaseTemplate = testCaseTemplateService.getTemplate(request.getProjectId());
|
||||
List<CustomFieldDao> customFields = Optional.ofNullable(testCaseTemplate.getCustomFields()).orElse(new ArrayList<>());
|
||||
public void testCaseExport(HttpServletResponse response, String projectId, List<TestCaseDTO> testCaseList, boolean needIdCol) {
|
||||
TestCaseExcelData testCaseExcelData = new TestCaseExcelDataFactory().getTestCaseExcelDataLocal();
|
||||
Map<Integer, Integer> rowMergeInfo = new HashMap<>();
|
||||
TestCaseTemplateDao testCaseTemplate = testCaseTemplateService.getTemplate(projectId);
|
||||
List<CustomFieldDao> customFields = Optional.ofNullable(testCaseTemplate.getCustomFields()).orElse(new ArrayList<>());
|
||||
List<List<String>> headList = testCaseExcelData.getHead(needIdCol, customFields);
|
||||
FunctionCaseMergeWriteHandler writeHandler = new FunctionCaseMergeWriteHandler(rowMergeInfo, headList);
|
||||
boolean isUseCustomId = projectService.useCustomNum(projectId);
|
||||
|
||||
List<List<String>> headList = testCaseExcelData.getHead(true, customFields);
|
||||
List<List<Object>> testCaseDataByExcelList = this.generateTestCaseExcel(headList, generateTestCaseExcel(request));
|
||||
EasyExcelExporter easyExcelExporter = new EasyExcelExporter(testCaseExcelData.getClass());
|
||||
easyExcelExporter.exportByCustomWriteHandler(response, headList, testCaseDataByExcelList,
|
||||
Translator.get("test_case_import_template_name"), Translator.get("test_case_import_template_sheet"));
|
||||
Map<String, List<String>> caseLevelAndStatusValueMap = testCaseTemplateService.getCaseLevelAndStatusMapByProjectId(projectId);
|
||||
FunctionCaseTemplateWriteHandler handler = new FunctionCaseTemplateWriteHandler(needIdCol, headList, caseLevelAndStatusValueMap);
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException(e);
|
||||
}
|
||||
List<TestCaseExcelData> excelData = parseCaseData2ExcelData(testCaseList, rowMergeInfo, isUseCustomId);
|
||||
List<List<Object>> data = parseExcelData2List(headList, excelData);
|
||||
new EasyExcelExporter(testCaseExcelData.getClass())
|
||||
.exportByCustomWriteHandler(response, headList, data, Translator.get("test_case_import_template_name"),
|
||||
Translator.get("test_case_import_template_sheet"), handler, writeHandler);
|
||||
}
|
||||
|
||||
public void testCaseTemplateExport(String projectId, String importType, HttpServletResponse response) {
|
||||
//导入更新 or 开启使用自定义ID时,导出ID列
|
||||
boolean needIdCol = projectService.useCustomNum(projectId) || StringUtils.equals(importType, FunctionCaseImportEnum.Update.name());
|
||||
testCaseExport(response, projectId, generateExportData(projectId), needIdCol);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1446,8 +1409,8 @@ public class TestCaseService {
|
|||
return rootMind;
|
||||
}
|
||||
|
||||
private List<List<Object>> generateTestCaseExcel(List<List<String>> headListParams, List<TestCaseExcelData> datas) {
|
||||
List<List<Object>> returnDatas = new ArrayList<>();
|
||||
private List<List<Object>> parseExcelData2List(List<List<String>> headListParams, List<TestCaseExcelData> data) {
|
||||
List<List<Object>> result = new ArrayList<>();
|
||||
//转化excel头
|
||||
List<String> headList = new ArrayList<>();
|
||||
for (List<String> list : headListParams) {
|
||||
|
@ -1456,17 +1419,17 @@ public class TestCaseService {
|
|||
}
|
||||
}
|
||||
|
||||
for (TestCaseExcelData model : datas) {
|
||||
List<Object> list = new ArrayList<>();
|
||||
for (TestCaseExcelData model : data) {
|
||||
List<Object> fields = new ArrayList<>();
|
||||
Map<String, String> customDataMaps = Optional.ofNullable(model.getCustomDatas()).orElse(new HashMap<>());
|
||||
|
||||
for (String head : headList) {
|
||||
if (StringUtils.equalsAnyIgnoreCase(head, "ID")) {
|
||||
list.add(model.getCustomNum());
|
||||
fields.add(model.getCustomNum());
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(head, "Name", "用例名稱", "用例名称")) {
|
||||
list.add(model.getName());
|
||||
fields.add(model.getName());
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(head, "Module", "所屬模塊", "所属模块")) {
|
||||
list.add(model.getNodePath());
|
||||
fields.add(model.getNodePath());
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(head, "Tag", "標簽", "标签")) {
|
||||
String tags = "";
|
||||
try {
|
||||
|
@ -1478,32 +1441,32 @@ public class TestCaseService {
|
|||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
list.add(tags);
|
||||
fields.add(tags);
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(head, "Prerequisite", "前置條件", "前置条件")) {
|
||||
list.add(model.getPrerequisite());
|
||||
fields.add(model.getPrerequisite());
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(head, "Remark", "備註", "备注")) {
|
||||
list.add(model.getRemark());
|
||||
fields.add(model.getRemark());
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(head, "Step description", "步驟描述", "步骤描述")) {
|
||||
list.add(model.getStepDesc());
|
||||
fields.add(model.getStepDesc());
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(head, "Step result", "預期結果", "预期结果")) {
|
||||
list.add(model.getStepResult());
|
||||
fields.add(model.getStepResult());
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(head, "Edit Model", "編輯模式", "编辑模式")) {
|
||||
list.add(model.getStepModel());
|
||||
fields.add(model.getStepModel());
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(head, "Priority", "用例等級", "用例等级")) {
|
||||
list.add(model.getPriority());
|
||||
fields.add(model.getPriority());
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(head, "Case status", "用例状态", "用例狀態")) {
|
||||
list.add(model.getStatus());
|
||||
fields.add(model.getStatus());
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(head, "Maintainer(ID)", "责任人(ID)", "維護人(ID)")) {
|
||||
list.add(model.getMaintainer());
|
||||
fields.add(model.getMaintainer());
|
||||
} else {
|
||||
String value = Optional.ofNullable(customDataMaps.get(head)).orElse("");
|
||||
list.add(value);
|
||||
fields.add(value);
|
||||
}
|
||||
}
|
||||
returnDatas.add(list);
|
||||
result.add(fields);
|
||||
}
|
||||
|
||||
return returnDatas;
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<TestCaseDTO> findByBatchRequest(TestCaseBatchRequest request) {
|
||||
|
@ -1526,18 +1489,16 @@ public class TestCaseService {
|
|||
return testCaseList;
|
||||
}
|
||||
|
||||
private List<TestCaseExcelData> generateTestCaseExcel(TestCaseBatchRequest request) {
|
||||
request.getCondition().setStatusIsNot("Trash");
|
||||
List<TestCaseDTO> testCaseList = this.getExportData(request);
|
||||
boolean isUseCustomId = projectService.useCustomNum(request.getProjectId());
|
||||
private List<TestCaseExcelData> parseCaseData2ExcelData(List<TestCaseDTO> testCaseList,
|
||||
Map<Integer, Integer> rowMergeInfo, Boolean isUseCustomId) {
|
||||
if (CollectionUtils.isEmpty(testCaseList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<TestCaseExcelData> list = new ArrayList<>();
|
||||
StringBuilder step = new StringBuilder();
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
Map<String, Map<String, String>> customSelectValueMap = new HashMap<>();
|
||||
Map<String, String> customNameMap = new HashMap<>();
|
||||
TestCaseTemplateService testCaseTemplateService = CommonBeanFactory.getBean(TestCaseTemplateService.class);
|
||||
TestCaseTemplateDao testCaseTemplate = testCaseTemplateService.getTemplate(request.getProjectId());
|
||||
TestCaseTemplateDao testCaseTemplate = testCaseTemplateService.getTemplate(testCaseList.get(0).getProjectId());
|
||||
|
||||
List<CustomFieldDao> customFieldList;
|
||||
if (testCaseTemplate == null) {
|
||||
|
@ -1545,6 +1506,113 @@ public class TestCaseService {
|
|||
} else {
|
||||
customFieldList = testCaseTemplate.getCustomFields();
|
||||
}
|
||||
|
||||
buildExportCustomFieldMap(customSelectValueMap, customNameMap, customFieldList);
|
||||
|
||||
for (int rowIndex = 0; rowIndex < testCaseList.size(); rowIndex++) {
|
||||
TestCaseDTO t = testCaseList.get(rowIndex);
|
||||
List<String> stepDescList = new ArrayList<>();
|
||||
List<String> stepResultList = new ArrayList<>();
|
||||
|
||||
setExportSystemField(t, customNameMap, customSelectValueMap);
|
||||
TestCaseExcelData data = new TestCaseExcelData();
|
||||
BeanUtils.copyBean(data, t);
|
||||
if (isUseCustomId) {
|
||||
data.setCustomNum(t.getCustomNum());
|
||||
} else {
|
||||
if (t.getNum() == null) {
|
||||
data.setCustomNum("");
|
||||
} else {
|
||||
data.setCustomNum(String.valueOf(t.getNum()));
|
||||
}
|
||||
}
|
||||
buildExportStep(t, stepDescList, stepResultList, data);
|
||||
buildExportCustomField(customSelectValueMap, customNameMap, t, data);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(stepDescList)) {
|
||||
// 如果有多条步骤则添加多条数据,之后合并单元格
|
||||
for (int i = 0; i < stepDescList.size(); i++) {
|
||||
TestCaseExcelData excelData;
|
||||
if (i == 0) {
|
||||
// 第一行存全量元素
|
||||
excelData = data;
|
||||
if (stepDescList.size() > 1) {
|
||||
// 保存合并单元格的下标和数量
|
||||
rowMergeInfo.put(list.size() + 1, stepDescList.size());
|
||||
}
|
||||
} else {
|
||||
// 之后的行只存步骤
|
||||
excelData = new TestCaseExcelData();
|
||||
}
|
||||
excelData.setStepDesc(stepDescList.get(i));
|
||||
excelData.setStepResult(stepResultList.get(i));
|
||||
list.add(excelData);
|
||||
}
|
||||
} else {
|
||||
list.add(data);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void buildExportCustomField(Map<String, Map<String, String>> customSelectValueMap, Map<String, String> customNameMap, TestCaseDTO t, TestCaseExcelData data) {
|
||||
try {
|
||||
List<CustomFieldResource> fields = customFieldTestCaseService.getByResourceId(t.getId());
|
||||
Map<String, String> map = new HashMap<>();
|
||||
for (int index = 0; index < fields.size(); index++) {
|
||||
CustomFieldResource field = fields.get(index);
|
||||
//进行key value对换
|
||||
String id = field.getFieldId();
|
||||
if (StringUtils.isNotBlank(field.getValue())) {
|
||||
String value = JSONObject.parse(field.getValue()).toString();
|
||||
if (customSelectValueMap.containsKey(id)
|
||||
&& customSelectValueMap.get(id).containsKey(value)) {
|
||||
value = customSelectValueMap.get(id).get(value);
|
||||
}
|
||||
map.put(customNameMap.get(id), value);
|
||||
}
|
||||
}
|
||||
data.setCustomDatas(map);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildExportStep(TestCaseDTO t, List<String> stepDescList, List<String> stepResultList, TestCaseExcelData data) {
|
||||
if (StringUtils.isBlank(t.getStepModel())) {
|
||||
data.setStepModel(TestCaseConstants.StepModel.STEP.name());
|
||||
} else {
|
||||
data.setStepModel(t.getStepModel());
|
||||
}
|
||||
if (StringUtils.equals(data.getStepModel(), TestCaseConstants.StepModel.TEXT.name())) {
|
||||
data.setStepDesc(t.getStepDescription());
|
||||
data.setStepResult(t.getExpectedResult());
|
||||
} else {
|
||||
String steps = t.getSteps();
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
//解决旧版本保存用例导出报错
|
||||
try {
|
||||
jsonArray = JSON.parseArray(steps);
|
||||
} catch (Exception e) {
|
||||
if (steps.contains("null") && !steps.contains("\"null\"")) {
|
||||
steps = steps.replace("null", "\"\"");
|
||||
jsonArray = JSON.parseArray(steps);
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < jsonArray.size(); j++) {
|
||||
// 将步骤存储起来,之后生成多条数据,再合并单元格
|
||||
JSONObject item = jsonArray.getJSONObject(j );
|
||||
String stepDesc = item.getString("desc");
|
||||
String stepResult = item.getString("result");
|
||||
if (StringUtils.isNotBlank(stepDesc) || StringUtils.isNotBlank(stepResult)) {
|
||||
stepDescList.add(Optional.ofNullable(stepDesc).orElse(""));
|
||||
stepResultList.add(Optional.ofNullable(stepResult).orElse(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void buildExportCustomFieldMap(Map<String, Map<String, String>> customSelectValueMap, Map<String, String> customNameMap, List<CustomFieldDao> customFieldList) {
|
||||
for (CustomFieldDao dto : customFieldList) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
if (StringUtils.equals("select", dto.getType())) {
|
||||
|
@ -1573,119 +1641,9 @@ public class TestCaseService {
|
|||
customSelectValueMap.put(dto.getId(), map);
|
||||
customNameMap.put(dto.getId(), dto.getName());
|
||||
}
|
||||
|
||||
|
||||
testCaseList.forEach(t -> {
|
||||
setExportSystemField(t, customNameMap, customSelectValueMap);
|
||||
TestCaseExcelData data = new TestCaseExcelData();
|
||||
data.setNum(t.getNum());
|
||||
data.setName(t.getName());
|
||||
data.setNodePath(t.getNodePath());
|
||||
data.setPriority(t.getPriority());
|
||||
if (isUseCustomId) {
|
||||
data.setCustomNum(t.getCustomNum());
|
||||
} else {
|
||||
data.setCustomNum(String.valueOf(t.getNum()));
|
||||
}
|
||||
if (StringUtils.isBlank(t.getStepModel())) {
|
||||
data.setStepModel(TestCaseConstants.StepModel.STEP.name());
|
||||
} else {
|
||||
data.setStepModel(t.getStepModel());
|
||||
}
|
||||
data.setPrerequisite(t.getPrerequisite());
|
||||
data.setTags(t.getTags());
|
||||
if (StringUtils.equals(t.getMethod(), "manual") || StringUtils.isBlank(t.getMethod())) {
|
||||
if (StringUtils.equals(data.getStepModel(), TestCaseConstants.StepModel.TEXT.name())) {
|
||||
data.setStepDesc(t.getStepDescription());
|
||||
data.setStepResult(t.getExpectedResult());
|
||||
} else {
|
||||
String steps = t.getSteps();
|
||||
String setp = "";
|
||||
setp = steps;
|
||||
JSONArray jsonArray = null;
|
||||
|
||||
//解决旧版本保存用例导出报错
|
||||
try {
|
||||
jsonArray = JSON.parseArray(setp);
|
||||
} catch (Exception e) {
|
||||
if (steps.contains("null") && !steps.contains("\"null\"")) {
|
||||
setp = steps.replace("null", "\"\"");
|
||||
jsonArray = JSON.parseArray(setp);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(jsonArray)) {
|
||||
for (int j = 0; j < jsonArray.size(); j++) {
|
||||
int num = j + 1;
|
||||
String stepItem = jsonArray.getJSONObject(j).getString("desc");
|
||||
if (StringUtils.isEmpty(stepItem)) {
|
||||
stepItem = "";
|
||||
}
|
||||
//正则去空格、回车、换行符、制表符
|
||||
stepItem = stepItem.replaceAll("\\s*|\t|\r|\n", "");
|
||||
step.append(num + "." + stepItem + "\n");
|
||||
String resultItem = jsonArray.getJSONObject(j).getString("result");
|
||||
if (StringUtils.isEmpty(resultItem)) {
|
||||
resultItem = "";
|
||||
}
|
||||
result.append(num + "." + resultItem + "\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
data.setStepDesc(step.toString());
|
||||
data.setStepResult(result.toString());
|
||||
step.setLength(0);
|
||||
result.setLength(0);
|
||||
}
|
||||
data.setRemark(t.getRemark());
|
||||
|
||||
} else if ("auto".equals(t.getMethod()) && "api".equals(t.getType())) {
|
||||
data.setStepDesc("");
|
||||
data.setStepResult("");
|
||||
if (t.getTestId() != null && "other".equals(t.getTestId())) {
|
||||
data.setRemark(t.getOtherTestName());
|
||||
} else {
|
||||
data.setRemark("[" + t.getApiName() + "]" + "\n" + t.getRemark());
|
||||
}
|
||||
|
||||
} else if ("auto".equals(t.getMethod()) && "performance".equals(t.getType())) {
|
||||
data.setStepDesc("");
|
||||
data.setStepResult("");
|
||||
if (t.getTestId() != null && "other".equals(t.getTestId())) {
|
||||
data.setRemark(t.getOtherTestName());
|
||||
} else {
|
||||
data.setRemark(t.getPerformName());
|
||||
}
|
||||
}
|
||||
data.setMaintainer(t.getMaintainer());
|
||||
data.setStatus(t.getStatus());
|
||||
try {
|
||||
List<CustomFieldResource> fields = customFieldTestCaseService.getByResourceId(t.getId());
|
||||
Map<String, String> map = new HashMap<>();
|
||||
for (int index = 0; index < fields.size(); index++) {
|
||||
CustomFieldResource field = fields.get(index);
|
||||
//进行key value对换
|
||||
String id = field.getFieldId();
|
||||
if (StringUtils.isNotBlank(field.getValue())) {
|
||||
String value = JSONObject.parse(field.getValue()).toString();
|
||||
if (customSelectValueMap.containsKey(id)
|
||||
&& customSelectValueMap.get(id).containsKey(value)) {
|
||||
value = customSelectValueMap.get(id).get(value);
|
||||
}
|
||||
map.put(customNameMap.get(id), value);
|
||||
}
|
||||
}
|
||||
data.setCustomDatas(map);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
list.add(data);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setExportSystemField(TestCaseDTO testCase, Map<String, String> customNameMap,
|
||||
public void setExportSystemField(TestCaseDTO testCase, Map<String, String> customNameMap,
|
||||
Map<String, Map<String, String>> customSelectValueMap) {
|
||||
String statusKey = null;
|
||||
for (String k : customNameMap.keySet()) {
|
||||
|
@ -2512,7 +2470,7 @@ public class TestCaseService {
|
|||
relationExample.createCriteria().andRelationTypeEqualTo(AttachmentType.TEST_CASE.type());
|
||||
List<AttachmentModuleRelation> relations = attachmentModuleRelationMapper.selectByExample(relationExample);
|
||||
Map<String, List<AttachmentModuleRelation>> relationGroup = relations.stream().collect(Collectors.groupingBy(AttachmentModuleRelation::getRelationId));
|
||||
for(Map.Entry<String, List<AttachmentModuleRelation>> entry : relationGroup.entrySet()) {
|
||||
for (Map.Entry<String, List<AttachmentModuleRelation>> entry : relationGroup.entrySet()) {
|
||||
final String caseId = entry.getKey();
|
||||
final String uploadPath = FileUtils.ATTACHMENT_DIR + File.separator + AttachmentType.TEST_CASE.type() + File.separator + caseId;
|
||||
// 获取同一用例关联的文件ID
|
||||
|
|
|
@ -47,12 +47,6 @@ tester=
|
|||
read_only_user=
|
||||
module=
|
||||
preconditions_optional=
|
||||
step_tip_separate=
|
||||
step_tip_order=
|
||||
step_tip_optional=
|
||||
result_tip_separate=
|
||||
result_tip_order=
|
||||
result_tip_optional=
|
||||
remark_optional=
|
||||
do_not_modify_header_order=
|
||||
module_created_automatically=
|
||||
|
|
|
@ -146,12 +146,6 @@ num_needed_modify_testcase=ID is needed when modifying testcase
|
|||
num_needless_create_testcase=ID is needless when creating testcase
|
||||
tag_tip_pattern=Labels should be separated by semicolons or commas
|
||||
preconditions_optional=Preconditions optional
|
||||
step_tip_separate=Each step is separated by a new line
|
||||
step_tip_order=Mark the serial number before the step
|
||||
step_tip_optional=Test steps and results optional
|
||||
result_tip_separate=Each result is separated by a new line
|
||||
result_tip_order=Mark the serial number before the result
|
||||
result_tip_optional=Test steps and results optional
|
||||
remark_optional=Remark optional
|
||||
do_not_modify_header_order=Do not modify the header order
|
||||
module_created_automatically=If there is no such module, will be created automatically
|
||||
|
|
|
@ -146,12 +146,6 @@ num_needed_modify_testcase=修改用例时ID必填
|
|||
num_needless_create_testcase=创建用例时无需ID
|
||||
tag_tip_pattern=标签之间以分号或者逗号隔开
|
||||
preconditions_optional=前置条件选填
|
||||
step_tip_separate=每个步骤以换行分隔
|
||||
step_tip_order=步骤前需标序号
|
||||
step_tip_optional=测试步骤和结果选填
|
||||
result_tip_separate=每条结果以换行分隔
|
||||
result_tip_order=结果前需标序号
|
||||
result_tip_optional=测试步骤和结果选填
|
||||
remark_optional=备注选填
|
||||
do_not_modify_header_order=请勿修改表头顺序
|
||||
module_created_automatically=若无该模块将自动创建
|
||||
|
|
|
@ -146,12 +146,6 @@ num_needed_modify_testcase=修改用例時ID必填
|
|||
num_needless_create_testcase=創建用例時無需ID
|
||||
tag_tip_pattern=標簽之間以分號或者逗號隔開
|
||||
preconditions_optional=前置條件選填
|
||||
step_tip_separate=每個步驟以換行分隔
|
||||
step_tip_order=步驟前需標序號
|
||||
step_tip_optional=測試步驟和結果選填
|
||||
result_tip_separate=每條結果以換行分隔
|
||||
result_tip_order=結果前需標序號
|
||||
result_tip_optional=測試步驟和結果選填
|
||||
remark_optional=備註選填
|
||||
do_not_modify_header_order=請勿修改表頭順序
|
||||
module_created_automatically=若無該模塊將自動創建
|
||||
|
|
Loading…
Reference in New Issue