parent
4c6f17201d
commit
ab122c6252
|
@ -126,7 +126,7 @@
|
|||
</select>
|
||||
|
||||
<select id="getTestCaseNames" resultType="io.metersphere.base.domain.TestCase">
|
||||
select test_case.id, test_case.name, test_case.priority, test_case.type, test_case.review_status
|
||||
select test_case.id, test_case.name, test_case.priority, test_case.type, test_case.review_status,test_case.num,test_case.custom_num
|
||||
from test_case
|
||||
<where>
|
||||
<if test="request.combine != null">
|
||||
|
|
|
@ -4,10 +4,15 @@ import com.alibaba.excel.annotation.ExcelIgnore;
|
|||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TestCaseExcelData {
|
||||
|
||||
private String id;
|
||||
|
||||
@ExcelIgnore
|
||||
private Integer num;
|
||||
@ExcelIgnore
|
||||
|
@ -32,4 +37,14 @@ public class TestCaseExcelData {
|
|||
private String stepResult;
|
||||
@ExcelIgnore
|
||||
private String stepModel;
|
||||
|
||||
public Set<String> getExcludeColumnFiledNames(boolean needNum){
|
||||
Set<String> excludeColumnFiledNames = new HashSet<>();
|
||||
if(!needNum){
|
||||
excludeColumnFiledNames.add("num");
|
||||
}
|
||||
excludeColumnFiledNames.add("customNum");
|
||||
|
||||
return excludeColumnFiledNames;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,12 +13,12 @@ import javax.validation.constraints.Pattern;
|
|||
@ColumnWidth(15)
|
||||
public class TestCaseExcelDataCn extends TestCaseExcelData {
|
||||
|
||||
@ExcelProperty("ID")
|
||||
@NotRequired
|
||||
private Integer num;
|
||||
// @ExcelProperty("ID")
|
||||
// @NotRequired
|
||||
// private Integer num;
|
||||
|
||||
@ColumnWidth(50)
|
||||
@ExcelProperty("自定义ID")
|
||||
@ExcelProperty("ID")
|
||||
@NotRequired
|
||||
private String customNum;
|
||||
|
||||
|
|
|
@ -15,4 +15,14 @@ public class TestCaseExcelDataFactory implements ExcelDataFactory {
|
|||
}
|
||||
return TestCaseExcelDataCn.class;
|
||||
}
|
||||
|
||||
public TestCaseExcelData getTestCaseExcelDataLocal(){
|
||||
Locale locale = LocaleContextHolder.getLocale();
|
||||
if (Locale.US.toString().equalsIgnoreCase(locale.toString())) {
|
||||
return new TestCaseExcelDataUs();
|
||||
} else if (Locale.TRADITIONAL_CHINESE.toString().equalsIgnoreCase(locale.toString())) {
|
||||
return new TestCaseExcelDataTw();
|
||||
}
|
||||
return new TestCaseExcelDataCn();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,12 +13,12 @@ import javax.validation.constraints.Pattern;
|
|||
@ColumnWidth(15)
|
||||
public class TestCaseExcelDataTw extends TestCaseExcelData {
|
||||
|
||||
@ExcelProperty("ID")
|
||||
@NotRequired
|
||||
private Integer num;
|
||||
// @ExcelProperty("ID")
|
||||
// @NotRequired
|
||||
// private Integer num;
|
||||
|
||||
@ColumnWidth(50)
|
||||
@ExcelProperty("自定義ID")
|
||||
@ExcelProperty("ID")
|
||||
@NotRequired
|
||||
private String customNum;
|
||||
|
||||
|
|
|
@ -14,12 +14,12 @@ import javax.validation.constraints.Pattern;
|
|||
@ColumnWidth(15)
|
||||
public class TestCaseExcelDataUs extends TestCaseExcelData {
|
||||
|
||||
@ExcelProperty("ID")
|
||||
@NotRequired
|
||||
private Integer num;
|
||||
// @ExcelProperty("ID")
|
||||
// @NotRequired
|
||||
// private Integer num;
|
||||
|
||||
@ColumnWidth(50)
|
||||
@ExcelProperty("Custom ID")
|
||||
@ExcelProperty("ID")
|
||||
@NotRequired
|
||||
private String customNum;
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@ import org.apache.poi.xssf.usermodel.XSSFRichTextString;
|
|||
*/
|
||||
public class FunctionCaseTemplateWriteHandler extends AbstractRowHeightStyleStrategy {
|
||||
|
||||
private boolean isNeedId;
|
||||
public FunctionCaseTemplateWriteHandler(boolean isNeedId){
|
||||
this.isNeedId = isNeedId;
|
||||
}
|
||||
@Override
|
||||
public void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer rowIndex, Integer relativeRowIndex, Boolean isHead) {
|
||||
|
||||
|
@ -35,44 +39,72 @@ public class FunctionCaseTemplateWriteHandler extends AbstractRowHeightStyleStra
|
|||
Sheet sheet = writeSheetHolder.getSheet();
|
||||
Drawing<?> drawingPatriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
// 在第一行 第3列创建一个批注
|
||||
Comment comment1 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 2, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment1.setString(new XSSFRichTextString(Translator.get("do_not_modify_header_order") + "," + Translator.get("num_needed_modify_testcase") + "," + Translator.get("num_needless_create_testcase")));
|
||||
if(isNeedId){
|
||||
// 在第一行 第1列创建一个批注
|
||||
Comment comment1 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 0, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment1.setString(new XSSFRichTextString(Translator.get("do_not_modify_header_order")));
|
||||
|
||||
// 在第一行 第4列创建一个批注
|
||||
Comment comment2 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment2.setString(new XSSFRichTextString(Translator.get("module_created_automatically")));
|
||||
// 在第一行 第3列创建一个批注
|
||||
Comment comment2 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 2, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment2.setString(new XSSFRichTextString(Translator.get("module_created_automatically")));
|
||||
|
||||
// 在第一行 第5列创建一个批注
|
||||
Comment comment3 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 4, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment3.setString(new XSSFRichTextString(Translator.get("options") + "(functional、performance、api)"));
|
||||
// // 在第一行 第5列创建一个批注
|
||||
// Comment comment3 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 4, 0, (short) 3, 1));
|
||||
// // 输入批注信息
|
||||
// comment3.setString(new XSSFRichTextString(Translator.get("options") + "(functional、performance、api)"));
|
||||
|
||||
|
||||
// 在第一行 第6列创建一个批注
|
||||
Comment comment4 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 5, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment4.setString(new XSSFRichTextString(Translator.get("please_input_workspace_member")));
|
||||
// 在第一行 第4列创建一个批注
|
||||
Comment comment4 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment4.setString(new XSSFRichTextString(Translator.get("please_input_workspace_member")));
|
||||
|
||||
// 在第一行 第7列创建一个批注
|
||||
Comment comment5 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 6, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment5.setString(new XSSFRichTextString(Translator.get("options") + "(P0、P1、P2、P3)"));
|
||||
// 在第一行 第5列创建一个批注
|
||||
Comment comment5 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 4, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment5.setString(new XSSFRichTextString(Translator.get("options") + "(P0、P1、P2、P3)"));
|
||||
|
||||
// 在第一行 第8列创建一个批注
|
||||
Comment comment6 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 7, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment6.setString(new XSSFRichTextString(Translator.get("tag_tip_pattern")));
|
||||
// 在第一行 第6列创建一个批注
|
||||
Comment comment6 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 5, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment6.setString(new XSSFRichTextString(Translator.get("tag_tip_pattern")));
|
||||
|
||||
// 将批注添加到单元格对象中
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment1);
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment2);
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment4);
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment5);
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment6);
|
||||
}else {
|
||||
// 在第一行 第2列创建一个批注
|
||||
Comment comment2 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 1, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment2.setString(new XSSFRichTextString(Translator.get("do_not_modify_header_order") + ","+Translator.get("module_created_automatically")));
|
||||
|
||||
// 在第一行 第3列创建一个批注
|
||||
Comment comment4 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 2, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment4.setString(new XSSFRichTextString(Translator.get("please_input_workspace_member")));
|
||||
|
||||
// 在第一行 第4列创建一个批注
|
||||
Comment comment5 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment5.setString(new XSSFRichTextString(Translator.get("options") + "(P0、P1、P2、P3)"));
|
||||
|
||||
// 在第一行 第5列创建一个批注
|
||||
Comment comment6 = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 4, 0, (short) 3, 1));
|
||||
// 输入批注信息
|
||||
comment6.setString(new XSSFRichTextString(Translator.get("tag_tip_pattern")));
|
||||
|
||||
// 将批注添加到单元格对象中
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment2);
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment4);
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment5);
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment6);
|
||||
}
|
||||
|
||||
// 将批注添加到单元格对象中
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment1);
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment2);
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment3);
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment4);
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment5);
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment6);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.metersphere.commons.utils.LogUtil;
|
|||
import io.metersphere.excel.domain.ExcelErrData;
|
||||
import io.metersphere.excel.domain.TestCaseExcelData;
|
||||
import io.metersphere.excel.utils.ExcelValidateHelper;
|
||||
import io.metersphere.excel.utils.FunctionCaseImportEnum;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.track.service.TestCaseService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -32,8 +33,16 @@ public class TestCaseDataIgnoreErrorListener extends EasyExcelListener<TestCaseE
|
|||
|
||||
protected boolean isUpdated = false; //判断是否更新过用例,将会传给前端
|
||||
|
||||
public boolean isUseCustomId;
|
||||
|
||||
public String importType;
|
||||
|
||||
Set<String> testCaseNames;
|
||||
|
||||
Set<String> customIds;
|
||||
|
||||
Set<String> savedCustomIds;
|
||||
|
||||
Set<String> userIds;
|
||||
|
||||
private List<String> names = new LinkedList<>();
|
||||
|
@ -59,18 +68,42 @@ public class TestCaseDataIgnoreErrorListener extends EasyExcelListener<TestCaseE
|
|||
return isUpdated;
|
||||
}
|
||||
|
||||
public TestCaseDataIgnoreErrorListener(Class clazz, String projectId, Set<String> testCaseNames, Set<String> userIds) {
|
||||
public TestCaseDataIgnoreErrorListener(Class clazz, String projectId, Set<String> testCaseNames, Set<String> savedCustomIds, Set<String> userIds,boolean isUseCustomId,String importType) {
|
||||
this.clazz = clazz;
|
||||
this.testCaseService = (TestCaseService) CommonBeanFactory.getBean("testCaseService");
|
||||
this.projectId = projectId;
|
||||
this.testCaseNames = testCaseNames;
|
||||
this.userIds = userIds;
|
||||
this.isUseCustomId = isUseCustomId;
|
||||
this.importType = importType;
|
||||
this.customIds = new HashSet<>();
|
||||
this.savedCustomIds = savedCustomIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String validate(TestCaseExcelData data, String errMsg) {
|
||||
String nodePath = data.getNodePath();
|
||||
StringBuilder stringBuilder = new StringBuilder(errMsg);
|
||||
|
||||
if(isUseCustomId || StringUtils.equals(this.importType,FunctionCaseImportEnum.Update.name())){
|
||||
if(data.getCustomNum() == null){
|
||||
stringBuilder.append(Translator.get("id_required")+";");
|
||||
}else {
|
||||
String customId = data.getCustomNum().toString();
|
||||
if(StringUtils.isEmpty(customId)){
|
||||
stringBuilder.append(Translator.get("id_required")+";");
|
||||
}else if(customIds.contains(customId)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String nodePath = data.getNodePath();
|
||||
//校验”所属模块"
|
||||
if (nodePath != null) {
|
||||
String[] nodes = nodePath.split("/");
|
||||
|
@ -107,50 +140,62 @@ public class TestCaseDataIgnoreErrorListener extends EasyExcelListener<TestCaseE
|
|||
有的话校验ID是否已在当前项目中存在,存在则更新用例,
|
||||
不存在则继续校验看是否重复,不重复则新建用例。
|
||||
*/
|
||||
if (null != data.getNum()) { //当前读取的数据有ID
|
||||
if (null != testCaseService.checkIdExist(data.getNum(), projectId)) { //该ID在当前项目中存在
|
||||
//如果前面所经过的校验都没报错
|
||||
if (StringUtils.isEmpty(stringBuilder)) {
|
||||
updateList.add(data); //将当前数据存入更新列表
|
||||
stringBuilder.append("update_testcase"); //该信息用于在invoke方法中判断是否该更新用例
|
||||
if (null != data.getCustomNum()) { //当前读取的数据有ID
|
||||
if(StringUtils.equals(this.importType,FunctionCaseImportEnum.Update.name())){
|
||||
String checkResult = null;
|
||||
if(isUseCustomId){
|
||||
checkResult = testCaseService.checkCustomIdExist(data.getCustomNum().toString(), projectId);
|
||||
}else {
|
||||
checkResult = testCaseService.checkIdExist(Integer.parseInt(data.getCustomNum()), projectId);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
} else {
|
||||
if (null != checkResult) { //该ID在当前项目中存在
|
||||
//如果前面所经过的校验都没报错
|
||||
if (StringUtils.isEmpty(stringBuilder)) {
|
||||
updateList.add(data); //将当前数据存入更新列表
|
||||
stringBuilder.append("update_testcase"); //该信息用于在invoke方法中判断是否该更新用例
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
} else {
|
||||
/*
|
||||
该ID在当前数据库中不存在,应当继续校验用例是否重复,
|
||||
在下面的校验过程中,num的值会被用于判断是否重复,所以应当先设置为null
|
||||
*/
|
||||
data.setNum(null);
|
||||
if(!StringUtils.equals(this.importType,FunctionCaseImportEnum.Update.name())){
|
||||
data.setNum(null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
校验用例
|
||||
*/
|
||||
if (testCaseNames.contains(data.getName())) {
|
||||
TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(testCase, data);
|
||||
testCase.setProjectId(projectId);
|
||||
String steps = getSteps(data);
|
||||
testCase.setSteps(steps);
|
||||
boolean dbExist = testCaseService.exist(testCase);
|
||||
boolean excelExist = false;
|
||||
if (dbExist) {
|
||||
// db exist
|
||||
stringBuilder.append(Translator.get("test_case_already_exists") + ":" + data.getName() + "; ");
|
||||
} else {
|
||||
// @Data 重写了 equals 和 hashCode 方法
|
||||
excelExist = excelDataList.contains(data);
|
||||
}
|
||||
if (excelExist) {
|
||||
// excel exist
|
||||
stringBuilder.append(Translator.get("test_case_already_exists_excel") + ":" + data.getName() + "; ");
|
||||
} else {
|
||||
excelDataList.add(data);
|
||||
}
|
||||
} else {
|
||||
// if (testCaseNames.contains(data.getName())) {
|
||||
// TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
|
||||
// BeanUtils.copyBean(testCase, data);
|
||||
// testCase.setProjectId(projectId);
|
||||
// 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() + "; ");
|
||||
// } else {
|
||||
// // @Data 重写了 equals 和 hashCode 方法
|
||||
// excelExist = excelDataList.contains(data);
|
||||
// }
|
||||
// if (excelExist) {
|
||||
// // excel exist
|
||||
// stringBuilder.append(Translator.get("test_case_already_exists_excel") + ":" + data.getName() + "; ");
|
||||
// } else {
|
||||
// excelDataList.add(data);
|
||||
// }
|
||||
// } else {
|
||||
testCaseNames.add(data.getName());
|
||||
excelDataList.add(data);
|
||||
}
|
||||
// }
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
|
@ -171,7 +216,11 @@ public class TestCaseDataIgnoreErrorListener extends EasyExcelListener<TestCaseE
|
|||
List<TestCaseWithBLOBs> result2 = updateList.stream()
|
||||
.map(item -> this.convert2TestCaseForUpdate(item))
|
||||
.collect(Collectors.toList());
|
||||
testCaseService.updateImportDataCarryId(result2, projectId);
|
||||
if(this.isUseCustomId){
|
||||
testCaseService.updateImportDataCustomId(result2, projectId);
|
||||
}else {
|
||||
testCaseService.updateImportDataCarryId(result2, projectId);
|
||||
}
|
||||
this.setNames(result2.stream().map(TestCase::getName).collect(Collectors.toList()));
|
||||
this.setIds(result2.stream().map(TestCase::getId).collect(Collectors.toList()));
|
||||
this.isUpdated = true;
|
||||
|
@ -188,7 +237,9 @@ public class TestCaseDataIgnoreErrorListener extends EasyExcelListener<TestCaseE
|
|||
testCase.setProjectId(this.projectId);
|
||||
testCase.setCreateTime(System.currentTimeMillis());
|
||||
testCase.setUpdateTime(System.currentTimeMillis());
|
||||
testCase.setCustomNum(data.getCustomNum());
|
||||
if(this.isUseCustomId){
|
||||
testCase.setCustomNum(data.getCustomNum().toString());
|
||||
}
|
||||
String nodePath = data.getNodePath();
|
||||
|
||||
if (!nodePath.startsWith("/")) {
|
||||
|
@ -202,7 +253,7 @@ public class TestCaseDataIgnoreErrorListener extends EasyExcelListener<TestCaseE
|
|||
//将标签设置为前端可解析的格式
|
||||
String modifiedTags = modifyTagPattern(data);
|
||||
testCase.setTags(modifiedTags);
|
||||
|
||||
testCase.setType("functional");
|
||||
if (StringUtils.isNotBlank(data.getStepModel())
|
||||
&& StringUtils.equals(data.getStepModel(), TestCaseConstants.StepModel.TEXT.name())) {
|
||||
testCase.setStepDescription(data.getStepDesc());
|
||||
|
@ -243,6 +294,10 @@ public class TestCaseDataIgnoreErrorListener extends EasyExcelListener<TestCaseE
|
|||
String modifiedTags = modifyTagPattern(data);
|
||||
testCase.setTags(modifiedTags);
|
||||
|
||||
if(!isUseCustomId){
|
||||
testCase.setNum(Integer.parseInt(data.getCustomNum()));
|
||||
testCase.setCustomNum(null);
|
||||
}
|
||||
return testCase;
|
||||
}
|
||||
|
||||
|
@ -276,22 +331,59 @@ public class TestCaseDataIgnoreErrorListener extends EasyExcelListener<TestCaseE
|
|||
public String getSteps(TestCaseExcelData data) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
|
||||
String[] stepDesc = new String[1];
|
||||
String[] stepRes = new String[1];
|
||||
List<String> stepDescList = new ArrayList<>();
|
||||
List<String> stepResList = new ArrayList<>();
|
||||
// String[] stepDesc = new String[1];
|
||||
// String[] stepRes = new String[1];
|
||||
|
||||
if (data.getStepDesc() != null) {
|
||||
stepDesc = data.getStepDesc().split("\r\n|\n");
|
||||
String[] stepDesc = data.getStepDesc().split("\r\n|\n");
|
||||
StringBuffer stepBuffer = new StringBuffer();
|
||||
int stepIndex = 1;
|
||||
for (String row : stepDesc) {
|
||||
if(StringUtils.startsWithAny(row,
|
||||
stepIndex+")","("+stepIndex+")","(\"+stepIndex+\")",
|
||||
stepIndex+".",stepIndex+",",stepIndex+",")){
|
||||
stepDescList.add(stepBuffer.toString());
|
||||
stepBuffer = new StringBuffer();
|
||||
stepIndex++;
|
||||
stepBuffer.append(row);
|
||||
}else {
|
||||
stepBuffer.append(row);
|
||||
}
|
||||
}
|
||||
if(StringUtils.isNotEmpty(stepBuffer.toString())){
|
||||
stepDescList.add(stepBuffer.toString());
|
||||
}
|
||||
} else {
|
||||
stepDesc[0] = "";
|
||||
stepDescList.add("");
|
||||
}
|
||||
|
||||
if (data.getStepResult() != null) {
|
||||
stepRes = data.getStepResult().split("\r\n|\n");
|
||||
String [] stepRes = data.getStepResult().split("\r\n|\n");
|
||||
StringBuffer stepBuffer = new StringBuffer();
|
||||
int stepIndex = 1;
|
||||
for (String row : stepRes) {
|
||||
if(StringUtils.startsWithAny(row,
|
||||
stepIndex+")","("+stepIndex+")","(\"+stepIndex+\")",
|
||||
stepIndex+".",stepIndex+",",stepIndex+",")){
|
||||
stepResList.add(stepBuffer.toString());
|
||||
stepBuffer = new StringBuffer();
|
||||
stepIndex++;
|
||||
stepBuffer.append(row);
|
||||
}else {
|
||||
stepBuffer.append(row);
|
||||
}
|
||||
}
|
||||
if(StringUtils.isNotEmpty(stepBuffer.toString())){
|
||||
stepResList.add(stepBuffer.toString());
|
||||
}
|
||||
} else {
|
||||
stepRes[0] = "";
|
||||
stepResList.add("");
|
||||
}
|
||||
|
||||
String pattern = "(^\\d+)(\\.)?";
|
||||
int index = stepDesc.length > stepRes.length ? stepDesc.length : stepRes.length;
|
||||
int index = stepDescList.size() > stepResList.size() ? stepDescList.size() : stepResList.size();
|
||||
|
||||
for (int i = 0; i < index; i++) {
|
||||
|
||||
|
@ -302,21 +394,21 @@ public class TestCaseDataIgnoreErrorListener extends EasyExcelListener<TestCaseE
|
|||
Pattern descPattern = Pattern.compile(pattern);
|
||||
Pattern resPattern = Pattern.compile(pattern);
|
||||
|
||||
if (i < stepDesc.length) {
|
||||
Matcher descMatcher = descPattern.matcher(stepDesc[i]);
|
||||
if (i < stepDescList.size()) {
|
||||
Matcher descMatcher = descPattern.matcher(stepDescList.get(i));
|
||||
if (descMatcher.find()) {
|
||||
step.put("desc", descMatcher.replaceAll(""));
|
||||
} else {
|
||||
step.put("desc", stepDesc[i]);
|
||||
step.put("desc", stepDescList.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (i < stepRes.length) {
|
||||
Matcher resMatcher = resPattern.matcher(stepRes[i]);
|
||||
if (i < stepResList.size()) {
|
||||
Matcher resMatcher = resPattern.matcher(stepResList.get(i));
|
||||
if (resMatcher.find()) {
|
||||
step.put("result", resMatcher.replaceAll(""));
|
||||
} else {
|
||||
step.put("result", stepRes[i]);
|
||||
step.put("result", stepResList.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.metersphere.commons.utils.LogUtil;
|
|||
import io.metersphere.excel.domain.ExcelErrData;
|
||||
import io.metersphere.excel.domain.TestCaseExcelData;
|
||||
import io.metersphere.excel.utils.ExcelValidateHelper;
|
||||
import io.metersphere.excel.utils.FunctionCaseImportEnum;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.track.service.TestCaseService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -32,8 +33,16 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
|
||||
protected boolean isUpdated = false; //判断是否更新过用例,将会传给前端
|
||||
|
||||
public boolean isUseCustomId;
|
||||
|
||||
public String importType;
|
||||
|
||||
Set<String> testCaseNames;
|
||||
|
||||
Set<String> customIds;
|
||||
|
||||
Set<String> savedCustomIds;
|
||||
|
||||
Set<String> userIds;
|
||||
|
||||
private List<String> names = new LinkedList<>();
|
||||
|
@ -43,19 +52,41 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
return isUpdated;
|
||||
}
|
||||
|
||||
public TestCaseDataListener(Class clazz, String projectId, Set<String> testCaseNames, Set<String> userIds) {
|
||||
public TestCaseDataListener(Class clazz, String projectId, Set<String> testCaseNames,Set<String> savedCustomIds, Set<String> userIds,boolean isUseCustomId,String importType) {
|
||||
this.clazz = clazz;
|
||||
this.testCaseService = (TestCaseService) CommonBeanFactory.getBean("testCaseService");
|
||||
this.projectId = projectId;
|
||||
this.testCaseNames = testCaseNames;
|
||||
this.userIds = userIds;
|
||||
this.isUseCustomId = isUseCustomId;
|
||||
this.importType = importType;
|
||||
customIds = new HashSet<>();
|
||||
this.savedCustomIds = savedCustomIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String validate(TestCaseExcelData data, String errMsg) {
|
||||
String nodePath = data.getNodePath();
|
||||
StringBuilder stringBuilder = new StringBuilder(errMsg);
|
||||
if(isUseCustomId || StringUtils.equals(this.importType,FunctionCaseImportEnum.Update.name())){
|
||||
if(data.getCustomNum() == null){
|
||||
stringBuilder.append(Translator.get("id_required")+";");
|
||||
}else {
|
||||
String customId = data.getCustomNum().toString();
|
||||
if(StringUtils.isEmpty(customId)){
|
||||
stringBuilder.append(Translator.get("id_required")+";");
|
||||
}else if(customIds.contains(customId)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String nodePath = data.getNodePath();
|
||||
//校验”所属模块"
|
||||
if (nodePath != null) {
|
||||
String[] nodes = nodePath.split("/");
|
||||
|
@ -83,10 +114,6 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
}
|
||||
}
|
||||
|
||||
// if (StringUtils.equals(data.getType(), TestCaseConstants.Type.Functional.getValue()) && StringUtils.equals(data.getMethod(), TestCaseConstants.Method.Auto.getValue())) {
|
||||
// stringBuilder.append(Translator.get("functional_method_tip") + "; ");
|
||||
// }
|
||||
|
||||
|
||||
//校验维护人
|
||||
if (!userIds.contains(data.getMaintainer())) {
|
||||
|
@ -98,57 +125,68 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
有的话校验ID是否已在当前项目中存在,存在则更新用例,
|
||||
不存在则继续校验看是否重复,不重复则新建用例。
|
||||
*/
|
||||
if (null != data.getNum()) { //当前读取的数据有ID
|
||||
if (null != data.getCustomNum()) { //当前读取的数据有ID
|
||||
|
||||
if (null != testCaseService.checkIdExist(data.getNum(), projectId)) { //该ID在当前项目中存在
|
||||
//如果前面所经过的校验都没报错
|
||||
if (StringUtils.isEmpty(stringBuilder)) {
|
||||
updateList.add(data); //将当前数据存入更新列表
|
||||
stringBuilder.append("update_testcase"); //该信息用于在invoke方法中判断是否该更新用例
|
||||
if(StringUtils.equals(this.importType,FunctionCaseImportEnum.Update.name())){
|
||||
String checkResult = null;
|
||||
if(isUseCustomId){
|
||||
checkResult = testCaseService.checkCustomIdExist(data.getCustomNum().toString(), projectId);
|
||||
}else {
|
||||
checkResult = testCaseService.checkIdExist(Integer.parseInt(data.getCustomNum()), projectId);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
} else {
|
||||
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);
|
||||
data.setNum(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
校验用例
|
||||
*/
|
||||
if (testCaseNames.contains(data.getName())) {
|
||||
TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(testCase, data);
|
||||
testCase.setProjectId(projectId);
|
||||
String steps = getSteps(data);
|
||||
testCase.setSteps(steps);
|
||||
|
||||
boolean dbExist = testCaseService.exist(testCase);
|
||||
boolean excelExist = false;
|
||||
|
||||
if (dbExist) {
|
||||
// db exist
|
||||
stringBuilder.append(Translator.get("test_case_already_exists") + ":" + data.getName() + "; ");
|
||||
} else {
|
||||
// @Data 重写了 equals 和 hashCode 方法
|
||||
excelExist = excelDataList.contains(data);
|
||||
}
|
||||
|
||||
if (excelExist) {
|
||||
// excel exist
|
||||
stringBuilder.append(Translator.get("test_case_already_exists_excel") + ":" + data.getName() + "; ");
|
||||
} else {
|
||||
excelDataList.add(data);
|
||||
}
|
||||
|
||||
} else {
|
||||
// if (testCaseNames.contains(data.getName())) {
|
||||
// TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
|
||||
// BeanUtils.copyBean(testCase, data);
|
||||
// testCase.setProjectId(projectId);
|
||||
// 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() + "; ");
|
||||
// } else {
|
||||
// // @Data 重写了 equals 和 hashCode 方法
|
||||
// excelExist = excelDataList.contains(data);
|
||||
// }
|
||||
//
|
||||
// if (excelExist) {
|
||||
// // excel exist
|
||||
// stringBuilder.append(Translator.get("test_case_already_exists_excel") + ":" + data.getName() + "; ");
|
||||
// } else {
|
||||
// excelDataList.add(data);
|
||||
// }
|
||||
//
|
||||
// } else {
|
||||
testCaseNames.add(data.getName());
|
||||
excelDataList.add(data);
|
||||
}
|
||||
// }
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
|
@ -191,7 +229,11 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
List<TestCaseWithBLOBs> result2 = updateList.stream()
|
||||
.map(item -> this.convert2TestCaseForUpdate(item))
|
||||
.collect(Collectors.toList());
|
||||
testCaseService.updateImportDataCarryId(result2, projectId);
|
||||
if(this.isUseCustomId){
|
||||
testCaseService.updateImportDataCustomId(result2, projectId);
|
||||
}else {
|
||||
testCaseService.updateImportDataCarryId(result2, projectId);
|
||||
}
|
||||
this.isUpdated = true;
|
||||
this.setNames(result2.stream().map(TestCase::getName).collect(Collectors.toList()));
|
||||
this.setIds(result2.stream().map(TestCase::getId).collect(Collectors.toList()));
|
||||
|
@ -208,7 +250,10 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
testCase.setProjectId(this.projectId);
|
||||
testCase.setCreateTime(System.currentTimeMillis());
|
||||
testCase.setUpdateTime(System.currentTimeMillis());
|
||||
testCase.setCustomNum(data.getCustomNum());
|
||||
if(this.isUseCustomId){
|
||||
testCase.setCustomNum(data.getCustomNum().toString());
|
||||
}
|
||||
|
||||
String nodePath = data.getNodePath();
|
||||
|
||||
if (!nodePath.startsWith("/")) {
|
||||
|
@ -222,6 +267,7 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
//将标签设置为前端可解析的格式
|
||||
String modifiedTags = modifyTagPattern(data);
|
||||
testCase.setTags(modifiedTags);
|
||||
testCase.setType("functional");
|
||||
|
||||
if (StringUtils.isNotBlank(data.getStepModel())
|
||||
&& StringUtils.equals(data.getStepModel(), TestCaseConstants.StepModel.TEXT.name())) {
|
||||
|
@ -263,6 +309,11 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
String modifiedTags = modifyTagPattern(data);
|
||||
testCase.setTags(modifiedTags);
|
||||
|
||||
if(!isUseCustomId){
|
||||
testCase.setNum(Integer.parseInt(data.getCustomNum()));
|
||||
testCase.setCustomNum(null);
|
||||
}
|
||||
|
||||
return testCase;
|
||||
}
|
||||
|
||||
|
@ -296,22 +347,69 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
public String getSteps(TestCaseExcelData data) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
|
||||
String[] stepDesc = new String[1];
|
||||
String[] stepRes = new String[1];
|
||||
List<String> stepDescList = new ArrayList<>();
|
||||
List<String> stepResList = new ArrayList<>();
|
||||
// String[] stepDesc = new String[1];
|
||||
// String[] stepRes = new String[1];
|
||||
|
||||
if (data.getStepDesc() != null) {
|
||||
stepDesc = data.getStepDesc().split("\r\n|\n");
|
||||
String[] stepDesc = data.getStepDesc().split("\r\n|\n");
|
||||
StringBuffer stepBuffer = new StringBuffer();
|
||||
int stepIndex = 1;
|
||||
for (String row : stepDesc) {
|
||||
if(StringUtils.startsWithAny(row,
|
||||
stepIndex+")","("+stepIndex+")","(\"+stepIndex+\")",
|
||||
stepIndex+".",stepIndex+",",stepIndex+",")){
|
||||
if(StringUtils.isNotEmpty(stepBuffer.toString())){
|
||||
stepDescList.add(stepBuffer.toString());
|
||||
}
|
||||
stepBuffer = new StringBuffer();
|
||||
stepIndex++;
|
||||
stepBuffer.append(row);
|
||||
}else {
|
||||
if(StringUtils.isNotEmpty(stepBuffer.toString())){
|
||||
stepBuffer.append("\r\n");
|
||||
}
|
||||
stepBuffer.append(row);
|
||||
}
|
||||
}
|
||||
if(StringUtils.isNotEmpty(stepBuffer.toString())){
|
||||
stepDescList.add(stepBuffer.toString());
|
||||
}
|
||||
} else {
|
||||
stepDesc[0] = "";
|
||||
stepDescList.add("");
|
||||
}
|
||||
|
||||
if (data.getStepResult() != null) {
|
||||
stepRes = data.getStepResult().split("\r\n|\n");
|
||||
String [] stepRes = data.getStepResult().split("\r\n|\n");
|
||||
StringBuffer stepBuffer = new StringBuffer();
|
||||
int stepIndex = 1;
|
||||
for (String row : stepRes) {
|
||||
if(StringUtils.startsWithAny(row,
|
||||
stepIndex+")","("+stepIndex+")","(\"+stepIndex+\")",
|
||||
stepIndex+".",stepIndex+",",stepIndex+",")){
|
||||
if(StringUtils.isNotEmpty(stepBuffer.toString())){
|
||||
stepResList.add(stepBuffer.toString());
|
||||
}
|
||||
stepBuffer = new StringBuffer();
|
||||
stepIndex++;
|
||||
stepBuffer.append(row);
|
||||
}else {
|
||||
if(StringUtils.isNotEmpty(stepBuffer.toString())){
|
||||
stepBuffer.append("\r\n");
|
||||
}
|
||||
stepBuffer.append(row);
|
||||
}
|
||||
}
|
||||
if(StringUtils.isNotEmpty(stepBuffer.toString())){
|
||||
stepResList.add(stepBuffer.toString());
|
||||
}
|
||||
} else {
|
||||
stepRes[0] = "";
|
||||
stepResList.add("");
|
||||
}
|
||||
|
||||
String pattern = "(^\\d+)(\\.)?";
|
||||
int index = stepDesc.length > stepRes.length ? stepDesc.length : stepRes.length;
|
||||
int index = stepDescList.size() > stepResList.size() ? stepDescList.size() : stepResList.size();
|
||||
|
||||
for (int i = 0; i < index; i++) {
|
||||
|
||||
|
@ -322,21 +420,21 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
Pattern descPattern = Pattern.compile(pattern);
|
||||
Pattern resPattern = Pattern.compile(pattern);
|
||||
|
||||
if (i < stepDesc.length) {
|
||||
Matcher descMatcher = descPattern.matcher(stepDesc[i]);
|
||||
if (i < stepDescList.size()) {
|
||||
Matcher descMatcher = descPattern.matcher(stepDescList.get(i));
|
||||
if (descMatcher.find()) {
|
||||
step.put("desc", descMatcher.replaceAll(""));
|
||||
} else {
|
||||
step.put("desc", stepDesc[i]);
|
||||
step.put("desc", stepDescList.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (i < stepRes.length) {
|
||||
Matcher resMatcher = resPattern.matcher(stepRes[i]);
|
||||
if (i < stepResList.size()) {
|
||||
Matcher resMatcher = resPattern.matcher(stepResList.get(i));
|
||||
if (resMatcher.find()) {
|
||||
step.put("result", resMatcher.replaceAll(""));
|
||||
} else {
|
||||
step.put("result", stepRes[i]);
|
||||
step.put("result", stepResList.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,14 @@ import com.alibaba.excel.write.metadata.style.WriteCellStyle;
|
|||
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
|
||||
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.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class EasyExcelExporter {
|
||||
|
||||
|
@ -39,12 +41,19 @@ public class EasyExcelExporter {
|
|||
}
|
||||
}
|
||||
|
||||
public void exportByCustomWriteHandler(HttpServletResponse response, List data, String fileName, String sheetName, WriteHandler writeHandler) {
|
||||
public void exportByCustomWriteHandler(HttpServletResponse response, Set<String> excludeColumnFiledNames, List data, String fileName, String sheetName, WriteHandler writeHandler) {
|
||||
response.setContentType("application/vnd.ms-excel");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
try {
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
|
||||
EasyExcel.write(response.getOutputStream(), this.clazz).registerWriteHandler(writeHandler).sheet(sheetName).doWrite(data);
|
||||
if(CollectionUtils.isNotEmpty(excludeColumnFiledNames)){
|
||||
EasyExcel.write(response.getOutputStream(), this.clazz).
|
||||
registerWriteHandler(writeHandler).
|
||||
excludeColumnFiledNames(excludeColumnFiledNames).
|
||||
sheet(sheetName).doWrite(data);
|
||||
}else {
|
||||
EasyExcel.write(response.getOutputStream(), this.clazz).registerWriteHandler(writeHandler).sheet(sheetName).doWrite(data);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
throw new ExcelException("Utf-8 encoding is not supported");
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package io.metersphere.excel.utils;
|
||||
|
||||
/**
|
||||
* @author song.tianyang
|
||||
* @Date 2021/5/24 1:52 下午
|
||||
*/
|
||||
public enum FunctionCaseImportEnum {
|
||||
Create,Update
|
||||
}
|
|
@ -219,6 +219,21 @@ public class ProjectService {
|
|||
return projectMapper.selectByPrimaryKey(id);
|
||||
}
|
||||
|
||||
public boolean useCustomNum(String projectId){
|
||||
Project project = this.getProjectById(projectId);
|
||||
if (project != null) {
|
||||
Boolean customNum = project.getCustomNum();
|
||||
// 未开启自定义ID
|
||||
if (!customNum) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Project> getByCaseTemplateId(String templateId) {
|
||||
ProjectExample example = new ProjectExample();
|
||||
example.createCriteria()
|
||||
|
|
|
@ -153,31 +153,31 @@ public class TestCaseController {
|
|||
return testCaseService.deleteTestCase(testCaseId);
|
||||
}
|
||||
|
||||
@PostMapping("/import/{projectId}/{userId}")
|
||||
@PostMapping("/import/{projectId}/{userId}/{importType}")
|
||||
@MsAuditLog(module = "track_test_case", type = OperLogConstants.IMPORT, project = "#projectId")
|
||||
public ExcelResponse testCaseImport(MultipartFile file, @PathVariable String projectId, @PathVariable String userId, HttpServletRequest request) {
|
||||
public ExcelResponse testCaseImport(MultipartFile file, @PathVariable String projectId, @PathVariable String userId, @PathVariable String importType, HttpServletRequest request) {
|
||||
checkPermissionService.checkProjectOwner(projectId);
|
||||
return testCaseService.testCaseImport(file, projectId, userId, request);
|
||||
return testCaseService.testCaseImport(file, projectId, userId, importType,request);
|
||||
}
|
||||
|
||||
@PostMapping("/importIgnoreError/{projectId}/{userId}")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_CASE_READ_IMPORT)
|
||||
@MsAuditLog(module = "track_test_case", type = OperLogConstants.IMPORT, project = "#projectId")
|
||||
public ExcelResponse testCaseImportIgnoreError(MultipartFile file, @PathVariable String projectId, @PathVariable String userId, HttpServletRequest request) {
|
||||
public ExcelResponse testCaseImportIgnoreError(MultipartFile file, @PathVariable String projectId, @PathVariable String userId, @PathVariable String importType, HttpServletRequest request) {
|
||||
checkPermissionService.checkProjectOwner(projectId);
|
||||
return testCaseService.testCaseImportIgnoreError(file, projectId, userId, request);
|
||||
return testCaseService.testCaseImportIgnoreError(file, projectId, userId,importType, request);
|
||||
}
|
||||
|
||||
@GetMapping("/export/template")
|
||||
@GetMapping("/export/template/{projectId}/{importType}")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_CASE_READ_EXPORT)
|
||||
public void testCaseTemplateExport(HttpServletResponse response) {
|
||||
testCaseService.testCaseTemplateExport(response);
|
||||
public void testCaseTemplateExport(@PathVariable String projectId,@PathVariable String importType,HttpServletResponse response) {
|
||||
testCaseService.testCaseTemplateExport(projectId,importType,response);
|
||||
}
|
||||
|
||||
@GetMapping("/export/xmindTemplate")
|
||||
@GetMapping("/export/xmindTemplate/{projectId}/{importType}")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_CASE_READ_EXPORT)
|
||||
public void xmindTemplate(HttpServletResponse response) {
|
||||
testCaseService.testCaseXmindTemplateExport(response);
|
||||
public void xmindTemplate(@PathVariable String projectId,@PathVariable String importType,HttpServletResponse response) {
|
||||
testCaseService.testCaseXmindTemplateExport(projectId,importType,response);
|
||||
}
|
||||
|
||||
@PostMapping("/export/testcase")
|
||||
|
|
|
@ -24,6 +24,7 @@ import io.metersphere.excel.handler.FunctionCaseTemplateWriteHandler;
|
|||
import io.metersphere.excel.listener.TestCaseDataIgnoreErrorListener;
|
||||
import io.metersphere.excel.listener.TestCaseDataListener;
|
||||
import io.metersphere.excel.utils.EasyExcelExporter;
|
||||
import io.metersphere.excel.utils.FunctionCaseImportEnum;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.log.utils.ReflexObjectUtil;
|
||||
import io.metersphere.log.vo.DetailColumn;
|
||||
|
@ -252,17 +253,33 @@ public class TestCaseService {
|
|||
* 根据id和pojectId查询id是否在数据库中存在。
|
||||
* 在数据库中单id的话是可重复的,id与projectId的组合是唯一的
|
||||
*/
|
||||
public Integer checkIdExist(Integer id, String projectId) {
|
||||
public String checkIdExist(Integer id, String projectId) {
|
||||
TestCaseExample example = new TestCaseExample();
|
||||
TestCaseExample.Criteria criteria = example.createCriteria();
|
||||
if (null != id) {
|
||||
criteria.andNumEqualTo(id);
|
||||
criteria.andProjectIdEqualTo(projectId);
|
||||
long count = testCaseMapper.countByExample(example); //查询是否有包含此ID的数据
|
||||
if (count == 0) { //如果ID不存在
|
||||
List<TestCase> testCaseList = testCaseMapper.selectByExample(example); //查询是否有包含此ID的数据
|
||||
if (testCaseList.isEmpty()) { //如果ID不存在
|
||||
return null;
|
||||
} else { //有对应ID的数据
|
||||
return id;
|
||||
return testCaseList.get(0).getId();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String checkCustomIdExist(String id, String projectId) {
|
||||
TestCaseExample example = new TestCaseExample();
|
||||
TestCaseExample.Criteria criteria = example.createCriteria();
|
||||
if (null != id) {
|
||||
criteria.andCustomNumEqualTo(id);
|
||||
criteria.andProjectIdEqualTo(projectId);
|
||||
List<TestCase> testCaseList = testCaseMapper.selectByExample(example); //查询是否有包含此ID的数据
|
||||
if (testCaseList.isEmpty()) { //如果ID不存在
|
||||
return null;
|
||||
} else { //有对应ID的数据
|
||||
return testCaseList.get(0).getId();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -399,24 +416,33 @@ public class TestCaseService {
|
|||
}
|
||||
|
||||
|
||||
public ExcelResponse testCaseImport(MultipartFile multipartFile, String projectId, String userId, HttpServletRequest request) {
|
||||
public ExcelResponse testCaseImport(MultipartFile multipartFile, String projectId, String userId,String importType, HttpServletRequest request) {
|
||||
|
||||
ExcelResponse excelResponse = new ExcelResponse();
|
||||
boolean isUpdated = false; //判断是否更新了用例
|
||||
String currentWorkspaceId = SessionUtils.getCurrentWorkspaceId();
|
||||
QueryTestCaseRequest queryTestCaseRequest = new QueryTestCaseRequest();
|
||||
queryTestCaseRequest.setProjectId(projectId);
|
||||
boolean useCunstomId = projectService.useCustomNum(projectId);
|
||||
List<TestCase> testCases = extTestCaseMapper.getTestCaseNames(queryTestCaseRequest);
|
||||
Set<String> testCaseNames = testCases.stream()
|
||||
.map(TestCase::getName)
|
||||
.collect(Collectors.toSet());
|
||||
Set<String> savedIds = new HashSet<>();
|
||||
Set<String> testCaseNames = new HashSet<>();
|
||||
for (TestCase testCase : testCases) {
|
||||
if(useCunstomId){
|
||||
savedIds.add(testCase.getCustomNum());
|
||||
}else {
|
||||
savedIds.add(String.valueOf(testCase.getNum()));
|
||||
}
|
||||
|
||||
testCaseNames.add(testCase.getName());
|
||||
}
|
||||
List<ExcelErrData<TestCaseExcelData>> errList = null;
|
||||
if (multipartFile == null) {
|
||||
MSException.throwException(Translator.get("upload_fail"));
|
||||
}
|
||||
if (multipartFile.getOriginalFilename().endsWith(".xmind")) {
|
||||
try {
|
||||
XmindCaseParser xmindParser = new XmindCaseParser(this, userId, projectId, testCaseNames);
|
||||
XmindCaseParser xmindParser = new XmindCaseParser(this, userId, projectId, testCaseNames,useCunstomId,importType);
|
||||
errList = xmindParser.parse(multipartFile);
|
||||
if (CollectionUtils.isEmpty(xmindParser.getNodePaths())
|
||||
&& CollectionUtils.isEmpty(xmindParser.getTestCase())
|
||||
|
@ -470,7 +496,7 @@ public class TestCaseService {
|
|||
//根据本地语言环境选择用哪种数据对象进行存放读取的数据
|
||||
Class clazz = new TestCaseExcelDataFactory().getExcelDataByLocal();
|
||||
|
||||
TestCaseDataListener easyExcelListener = new TestCaseDataListener(clazz, projectId, testCaseNames, userIds);
|
||||
TestCaseDataListener easyExcelListener = new TestCaseDataListener(clazz, projectId, testCaseNames,savedIds, userIds,useCunstomId,importType);
|
||||
//读取excel数据
|
||||
EasyExcelFactory.read(multipartFile.getInputStream(), clazz, easyExcelListener).sheet().doRead();
|
||||
request.setAttribute("ms-req-title", String.join(",", easyExcelListener.getNames()));
|
||||
|
@ -534,7 +560,9 @@ public class TestCaseService {
|
|||
testcase.setUpdateTime(System.currentTimeMillis());
|
||||
testcase.setNodeId(nodePathMap.get(testcase.getNodePath()));
|
||||
testcase.setSort(sort.getAndIncrement());
|
||||
testcase.setNum(num.decrementAndGet());
|
||||
if(testcase.getNum() == null){
|
||||
testcase.setNum(num.decrementAndGet());
|
||||
}
|
||||
testcase.setReviewStatus(TestCaseReviewStatus.Prepare.name());
|
||||
mapper.updateByPrimaryKeySelective(testcase);
|
||||
});
|
||||
|
@ -581,23 +609,76 @@ public class TestCaseService {
|
|||
sqlSession.flushStatements();
|
||||
}
|
||||
|
||||
/**
|
||||
* 把Excel中带ID的数据更新到数据库
|
||||
* feat(测试跟踪):通过Excel导入导出时有ID字段,可通过Excel导入来更新用例。 (#1727)
|
||||
*
|
||||
* @param testCases
|
||||
* @param projectId
|
||||
*/
|
||||
public void updateImportDataCustomId(List<TestCaseWithBLOBs> testCases, String projectId) {
|
||||
Map<String, String> nodePathMap = testCaseNodeService.createNodeByTestCases(testCases, projectId);
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
TestCaseMapper mapper = sqlSession.getMapper(TestCaseMapper.class);
|
||||
|
||||
public void testCaseTemplateExport(HttpServletResponse response) {
|
||||
/*
|
||||
获取用例的“网页上所显示id”与“数据库ID”映射。
|
||||
*/
|
||||
List<String> customIds = testCases.stream()
|
||||
.map(TestCase::getCustomNum)
|
||||
.collect(Collectors.toList());
|
||||
TestCaseExample example = new TestCaseExample();
|
||||
example.createCriteria().andCustomNumIn(customIds)
|
||||
.andProjectIdEqualTo(projectId);
|
||||
List<TestCase> testCasesList = testCaseMapper.selectByExample(example);
|
||||
Map<String, String> customIdMap = testCasesList.stream()
|
||||
.collect(Collectors.toMap(TestCase::getCustomNum, TestCase::getId));
|
||||
|
||||
|
||||
if (!testCases.isEmpty()) {
|
||||
AtomicInteger sort = new AtomicInteger();
|
||||
testCases.forEach(testcase -> {
|
||||
testcase.setUpdateTime(System.currentTimeMillis());
|
||||
testcase.setNodeId(nodePathMap.get(testcase.getNodePath()));
|
||||
testcase.setSort(sort.getAndIncrement());
|
||||
testcase.setId(customIdMap.get(testcase.getCustomNum()));
|
||||
mapper.updateByPrimaryKeySelective(testcase);
|
||||
});
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
|
||||
public void testCaseTemplateExport(String projectId,String importType,HttpServletResponse response) {
|
||||
try {
|
||||
EasyExcelExporter easyExcelExporter = new EasyExcelExporter(new TestCaseExcelDataFactory().getExcelDataByLocal());
|
||||
FunctionCaseTemplateWriteHandler handler = new FunctionCaseTemplateWriteHandler();
|
||||
easyExcelExporter.exportByCustomWriteHandler(response, generateExportTemplate(),
|
||||
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;
|
||||
}
|
||||
//不包含ID列
|
||||
Set<String> excludeColumnFiledNames = testCaseExcelData.getExcludeColumnFiledNames(importFileNeedNum);
|
||||
EasyExcelExporter easyExcelExporter = new EasyExcelExporter(testCaseExcelData.getClass());
|
||||
FunctionCaseTemplateWriteHandler handler = new FunctionCaseTemplateWriteHandler(importFileNeedNum);
|
||||
easyExcelExporter.exportByCustomWriteHandler(response,excludeColumnFiledNames, generateExportTemplate(),
|
||||
Translator.get("test_case_import_template_name"), Translator.get("test_case_import_template_sheet"), handler);
|
||||
|
||||
} catch (Exception e) {
|
||||
MSException.throwException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void download(HttpServletResponse res) throws IOException {
|
||||
public void download(String fileName,HttpServletResponse res) throws IOException {
|
||||
if(StringUtils.isEmpty(fileName)){
|
||||
fileName = "xmind.xml";
|
||||
}
|
||||
// 发送给客户端的数据
|
||||
byte[] buff = new byte[1024];
|
||||
try (OutputStream outputStream = res.getOutputStream();
|
||||
BufferedInputStream bis = new BufferedInputStream(TestCaseService.class.getResourceAsStream("/io/metersphere/xmind/template/xmind.xml"));) {
|
||||
BufferedInputStream bis = new BufferedInputStream(TestCaseService.class.getResourceAsStream("/io/metersphere/xmind/template/"+fileName));) {
|
||||
int i = bis.read(buff);
|
||||
while (i != -1) {
|
||||
outputStream.write(buff, 0, buff.length);
|
||||
|
@ -610,12 +691,23 @@ public class TestCaseService {
|
|||
}
|
||||
}
|
||||
|
||||
public void testCaseXmindTemplateExport(HttpServletResponse response) {
|
||||
public void testCaseXmindTemplateExport(String projectId,String importType,HttpServletResponse response) {
|
||||
try {
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
boolean isUseCustomId = projectService.useCustomNum(projectId);
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("思维导图用例模版", "UTF-8") + ".xmind");
|
||||
download(response);
|
||||
String fileName = null;
|
||||
if(StringUtils.equals(importType,FunctionCaseImportEnum.Update.name())){
|
||||
fileName = "xmind_update.xml";
|
||||
}else{
|
||||
if(isUseCustomId){
|
||||
fileName = "xmind_custom_id.xml";
|
||||
}else {
|
||||
fileName = "xmind_system_id.xml";
|
||||
}
|
||||
}
|
||||
download(fileName,response);
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
|
@ -1063,7 +1155,7 @@ public class TestCaseService {
|
|||
extTestCaseMapper.updateTestCaseCustomNumByProjectId(projectId);
|
||||
}
|
||||
|
||||
public ExcelResponse testCaseImportIgnoreError(MultipartFile multipartFile, String projectId, String userId, HttpServletRequest request) {
|
||||
public ExcelResponse testCaseImportIgnoreError(MultipartFile multipartFile, String projectId, String userId, String importType,HttpServletRequest request) {
|
||||
|
||||
ExcelResponse excelResponse = new ExcelResponse();
|
||||
boolean isUpdated = false; //判断是否更新了用例
|
||||
|
@ -1071,16 +1163,24 @@ public class TestCaseService {
|
|||
QueryTestCaseRequest queryTestCaseRequest = new QueryTestCaseRequest();
|
||||
queryTestCaseRequest.setProjectId(projectId);
|
||||
List<TestCase> testCases = extTestCaseMapper.getTestCaseNames(queryTestCaseRequest);
|
||||
Set<String> testCaseNames = testCases.stream()
|
||||
.map(TestCase::getName)
|
||||
.collect(Collectors.toSet());
|
||||
boolean useCunstomId = projectService.useCustomNum(projectId);
|
||||
Set<String> savedIds = new HashSet<>();
|
||||
Set<String> testCaseNames = new HashSet<>();
|
||||
for (TestCase testCase : testCases) {
|
||||
if(useCunstomId){
|
||||
savedIds.add(testCase.getCustomNum());
|
||||
}else {
|
||||
savedIds.add(String.valueOf(testCase.getNum()));
|
||||
}
|
||||
testCaseNames.add(testCase.getName());
|
||||
}
|
||||
List<ExcelErrData<TestCaseExcelData>> errList = null;
|
||||
if (multipartFile == null) {
|
||||
MSException.throwException(Translator.get("upload_fail"));
|
||||
}
|
||||
if (multipartFile.getOriginalFilename().endsWith(".xmind")) {
|
||||
try {
|
||||
XmindCaseParser xmindParser = new XmindCaseParser(this, userId, projectId, testCaseNames);
|
||||
XmindCaseParser xmindParser = new XmindCaseParser(this, userId, projectId, testCaseNames,useCunstomId,importType);
|
||||
errList = xmindParser.parse(multipartFile);
|
||||
if (CollectionUtils.isEmpty(xmindParser.getNodePaths())
|
||||
&& CollectionUtils.isEmpty(xmindParser.getTestCase())
|
||||
|
@ -1138,8 +1238,7 @@ public class TestCaseService {
|
|||
try {
|
||||
//根据本地语言环境选择用哪种数据对象进行存放读取的数据
|
||||
Class clazz = new TestCaseExcelDataFactory().getExcelDataByLocal();
|
||||
|
||||
TestCaseDataIgnoreErrorListener easyExcelListener = new TestCaseDataIgnoreErrorListener(clazz, projectId, testCaseNames, userIds);
|
||||
TestCaseDataIgnoreErrorListener easyExcelListener = new TestCaseDataIgnoreErrorListener(clazz, projectId, testCaseNames,savedIds, userIds,useCunstomId, importType);
|
||||
|
||||
//读取excel数据
|
||||
EasyExcelFactory.read(multipartFile.getInputStream(), clazz, easyExcelListener).sheet().doRead();
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.metersphere.commons.constants.TestCaseConstants;
|
|||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.excel.domain.ExcelErrData;
|
||||
import io.metersphere.excel.domain.TestCaseExcelData;
|
||||
import io.metersphere.excel.utils.FunctionCaseImportEnum;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.track.service.TestCaseService;
|
||||
import io.metersphere.xmind.parser.XmindParser;
|
||||
|
@ -63,7 +64,11 @@ public class XmindCaseParser {
|
|||
|
||||
private List<String> errorPath;
|
||||
|
||||
public XmindCaseParser(TestCaseService testCaseService, String userId, String projectId, Set<String> testCaseNames) {
|
||||
private boolean isUseCustomId;
|
||||
|
||||
private String importType;
|
||||
|
||||
public XmindCaseParser(TestCaseService testCaseService, String userId, String projectId, Set<String> testCaseNames,boolean isUseCustomId,String importType) {
|
||||
this.testCaseService = testCaseService;
|
||||
this.maintainer = userId;
|
||||
this.projectId = projectId;
|
||||
|
@ -75,6 +80,8 @@ public class XmindCaseParser {
|
|||
nodePaths = new ArrayList<>();
|
||||
continueValidatedCase = new ArrayList<>();
|
||||
errorPath = new ArrayList<>();
|
||||
this.isUseCustomId = isUseCustomId;
|
||||
this.importType = importType;
|
||||
}
|
||||
|
||||
private static final String TC_REGEX = "(?:tc:|tc:|tc)";
|
||||
|
@ -92,11 +99,19 @@ public class XmindCaseParser {
|
|||
}
|
||||
|
||||
public List<TestCaseWithBLOBs> getTestCase() {
|
||||
return this.testCases;
|
||||
if(StringUtils.equals(this.importType,FunctionCaseImportEnum.Create.name())){
|
||||
return this.testCases;
|
||||
}else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<TestCaseWithBLOBs> getUpdateTestCase() {
|
||||
return this.updateTestCases;
|
||||
if(StringUtils.equals(this.importType,FunctionCaseImportEnum.Update.name())){
|
||||
return this.updateTestCases;
|
||||
}else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getNodePaths() {
|
||||
|
@ -183,18 +198,19 @@ public class XmindCaseParser {
|
|||
process.add(Translator.get("functional_method_tip"), nodePath + data.getName());
|
||||
}
|
||||
|
||||
if (testCaseNames.contains(data.getName())) {
|
||||
TestCaseWithBLOBs bloBs = testCaseService.checkTestCaseExist(data);
|
||||
if (bloBs != null) {
|
||||
// process.add(Translator.get("test_case_already_exists_excel"), nodePath + "/" + data.getName());
|
||||
// 记录需要变更的用例
|
||||
BeanUtils.copyBean(bloBs, data, "id");
|
||||
updateTestCases.add(bloBs);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
testCaseNames.add(data.getName());
|
||||
}
|
||||
// if (testCaseNames.contains(data.getName())) {
|
||||
// TestCaseWithBLOBs bloBs = testCaseService.checkTestCaseExist(data);
|
||||
// if (bloBs != null) {
|
||||
// // process.add(Translator.get("test_case_already_exists_excel"), nodePath + "/" + data.getName());
|
||||
// // 记录需要变更的用例
|
||||
// BeanUtils.copyBean(bloBs, data, "id");
|
||||
// updateTestCases.add(bloBs);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// } else {
|
||||
// testCaseNames.add(data.getName());
|
||||
// }
|
||||
|
||||
// 用例等级和用例性质处理
|
||||
if (!priorityList.contains(data.getPriority())) {
|
||||
|
@ -214,6 +230,45 @@ public class XmindCaseParser {
|
|||
process.add(Translator.get("test_case_already_exists_excel"), nodePath + "/" + compartData.getName());
|
||||
}
|
||||
compartDatas.add(compartData);
|
||||
|
||||
|
||||
//自定义ID判断
|
||||
if(StringUtils.isEmpty(data.getCustomNum())){
|
||||
if(StringUtils.equals(this.importType, FunctionCaseImportEnum.Update.name())){
|
||||
validatePass = false;
|
||||
process.add(Translator.get("id_required"), nodePath + "/" + compartData.getName());
|
||||
return false;
|
||||
}else{
|
||||
if(isUseCustomId){
|
||||
validatePass = false;
|
||||
process.add(Translator.get("custom_num_is_not_exist"), nodePath + "/" + compartData.getName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//判断更新
|
||||
if(StringUtils.equals(this.importType,FunctionCaseImportEnum.Update.name())) {
|
||||
String checkResult = null;
|
||||
if (isUseCustomId) {
|
||||
checkResult = testCaseService.checkCustomIdExist(data.getCustomNum().toString(), projectId);
|
||||
} else {
|
||||
checkResult = testCaseService.checkIdExist(Integer.parseInt(data.getCustomNum()), projectId);
|
||||
}
|
||||
if (null != checkResult) { //该ID在当前项目中存在
|
||||
//如果前面所经过的校验都没报错
|
||||
if(!isUseCustomId){
|
||||
data.setNum(Integer.parseInt(data.getCustomNum()));
|
||||
data.setCustomNum(null);
|
||||
}
|
||||
data.setId(checkResult);
|
||||
updateTestCases.add(data);
|
||||
}else {
|
||||
process.add(Translator.get("custom_num_is_not_exist"), nodePath + "/" + compartData.getName());
|
||||
validatePass = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (validatePass) {
|
||||
this.continueValidatedCase.add(data);
|
||||
}
|
||||
|
@ -351,7 +406,10 @@ public class XmindCaseParser {
|
|||
});
|
||||
}
|
||||
testCase.setRemark(rc.toString());
|
||||
testCase.setCustomNum(customId.toString());
|
||||
if(isUseCustomId || StringUtils.equals(importType,FunctionCaseImportEnum.Update.name())){
|
||||
testCase.setCustomNum(customId.toString());
|
||||
}
|
||||
|
||||
testCase.setTags(JSON.toJSONString(tags));
|
||||
testCase.setSteps(this.getSteps(steps));
|
||||
// 校验合规性
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -64,5 +64,7 @@ password_format_is_incorrect=
|
|||
please_input_workspace_member=
|
||||
test_case_report_template_repeat=
|
||||
custom_field_already=
|
||||
id_required=
|
||||
id_repeat_in_table=
|
||||
template_already=
|
||||
expect_name_exists=
|
||||
|
|
|
@ -156,6 +156,9 @@ test_case_module_already_exists=The module name already exists at the same level
|
|||
api_test_name_already_exists=Test name already exists
|
||||
functional_method_tip=Functional test not support auto method
|
||||
custom_num_is_exist=Use case custom ID already exists
|
||||
custom_num_is_not_exist=Use case custom ID not exists
|
||||
id_required=ID required
|
||||
id_repeat_in_table=ID is repeat in table
|
||||
#ldap
|
||||
ldap_url_is_null=LDAP address is empty
|
||||
ldap_dn_is_null=LDAP binding DN is empty
|
||||
|
|
|
@ -156,6 +156,9 @@ test_case_module_already_exists=同层级下已存在该模块名称
|
|||
api_test_name_already_exists=测试名称已经存在
|
||||
functional_method_tip=功能测试不支持自动方式
|
||||
custom_num_is_exist=用例自定义ID已存在
|
||||
custom_num_is_not_exist=用例自定义ID不存在
|
||||
id_required=ID必填
|
||||
id_repeat_in_table=表格内ID重复
|
||||
#ldap
|
||||
ldap_url_is_null=LDAP地址为空
|
||||
ldap_dn_is_null=LDAP绑定DN为空
|
||||
|
|
|
@ -156,6 +156,9 @@ test_case_module_already_exists=同層級下已存在該模塊名稱
|
|||
api_test_name_already_exists=測試名稱已經存在
|
||||
functional_method_tip=功能測試不支持自動方式
|
||||
custom_num_is_exist=用例自定義ID已存在
|
||||
custom_num_is_not_exist=用例自定義ID不存在
|
||||
id_required=ID必填
|
||||
id_repeat_in_table=表格內ID重複
|
||||
#ldap
|
||||
ldap_url_is_null=LDAP地址為空
|
||||
ldap_dn_is_null=LDAP綁定DN為空
|
||||
|
|
|
@ -4,9 +4,36 @@
|
|||
|
||||
<el-tabs v-model="activeName" @tab-click="clickTabs" simple>
|
||||
<el-tab-pane :label="$t('test_track.case.import.excel_title')" name="excelImport">
|
||||
<el-row class="import-row" style="margin-left: 34px">
|
||||
<el-radio v-model="importType" label="Create">导入新建</el-radio>
|
||||
<el-radio v-model="importType" label="Update">导入更新</el-radio>
|
||||
</el-row>
|
||||
<el-row class="import-row">
|
||||
<div class="el-step__icon is-text" style="background-color: #C9E6F8;border-color: #C9E6F8;margin-right: 10px">
|
||||
<div class="el-step__icon-inner">1</div>
|
||||
</div>
|
||||
<label class="ms-license-label">{{$t('test_track.case.import.import_desc')}}</label>
|
||||
</el-row>
|
||||
<el-row class="import-row">
|
||||
<div style="margin-left: 34px">
|
||||
<div v-if="importType === 'Create'">
|
||||
项目设置中“测试用例自定义ID” 开关开启时ID为必填项
|
||||
</div>
|
||||
<div v-else >
|
||||
导入更新时ID为必填项
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</el-row>
|
||||
<el-row class="import-row">
|
||||
<div class="el-step__icon is-text"
|
||||
style="background-color: #C9E6F8;border-color: #C9E6F8;margin-right: 10px ">
|
||||
<div class="el-step__icon-inner">2</div>
|
||||
</div>
|
||||
<label class="ms-license-label">{{$t('test_track.case.import.import_file')}}</label>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-link type="primary" class="download-template"
|
||||
<el-link type="primary" class="download-template" style="margin: 20px 34px;"
|
||||
@click="downloadTemplate"
|
||||
>{{ $t('test_track.case.import.download_template') }}
|
||||
</el-link>
|
||||
|
@ -56,19 +83,31 @@
|
|||
</el-tab-pane>
|
||||
<!-- Xmind 导入 -->
|
||||
<el-tab-pane :label="$t('test_track.case.import.xmind_title')" name="xmindImport" style="border: 0px">
|
||||
<el-row class="import-row" style="margin-left: 34px">
|
||||
<el-radio v-model="importType" label="Create">导入新建</el-radio>
|
||||
<el-radio v-model="importType" label="Update">导入更新</el-radio>
|
||||
</el-row>
|
||||
<el-row class="import-row">
|
||||
<div class="el-step__icon is-text" style="background-color: #C9E6F8;border-color: #C9E6F8;margin-right: 10px">
|
||||
<div class="el-step__icon-inner">1</div>
|
||||
</div>
|
||||
<label class="ms-license-label">{{$t('test_track.case.import.import_desc')}}</label>
|
||||
</el-row>
|
||||
<el-row class="import-row">
|
||||
<el-card :body-style="{ padding: '0px' }">
|
||||
<img src="../../../../../assets/xmind.jpg"
|
||||
class="testcase-import-img">
|
||||
</el-card>
|
||||
|
||||
<el-row class="import-row" style="margin-left: 34px">
|
||||
<div v-if="importType === 'Create'">
|
||||
项目设置中“测试用例自定义ID” 开关开启时ID为必填项
|
||||
</div>
|
||||
<div v-else >
|
||||
导入更新时ID为必填项
|
||||
</div>
|
||||
</el-row>
|
||||
<!-- <el-row class="import-row">-->
|
||||
<!-- <el-card :body-style="{ padding: '0px' }">-->
|
||||
<!-- <img src="../../../../../assets/xmind.jpg"-->
|
||||
<!-- class="testcase-import-img">-->
|
||||
<!-- </el-card>-->
|
||||
|
||||
<!-- </el-row>-->
|
||||
<el-row class="import-row">
|
||||
<div class="el-step__icon is-text"
|
||||
style="background-color: #C9E6F8;border-color: #C9E6F8;margin-right: 10px ">
|
||||
|
@ -77,7 +116,7 @@
|
|||
<label class="ms-license-label">{{$t('test_track.case.import.import_file')}}</label>
|
||||
</el-row>
|
||||
<el-row class="import-row">
|
||||
<el-link type="primary" class="download-template"
|
||||
<el-link type="primary" class="download-template" style="margin: 0px 34px;"
|
||||
@click="downloadXmindTemplate"
|
||||
>{{$t('test_track.case.import.download_template')}}
|
||||
</el-link>
|
||||
|
@ -144,6 +183,7 @@
|
|||
fileList: [],
|
||||
lastXmindFile: null,
|
||||
lastExcelFile: null,
|
||||
importType:"Create",
|
||||
errList: [],
|
||||
xmindErrList: [],
|
||||
isLoading: false,
|
||||
|
@ -227,10 +267,11 @@
|
|||
}
|
||||
},
|
||||
downloadTemplate() {
|
||||
this.$fileDownload('/test/case/export/template');
|
||||
|
||||
this.$fileDownload('/test/case/export/template/'+this.projectId+"/"+this.importType);
|
||||
},
|
||||
downloadXmindTemplate() {
|
||||
axios.get('/test/case/export/xmindTemplate', {responseType: 'blob'})
|
||||
axios.get('/test/case/export/xmindTemplate/'+this.projectId+"/"+this.importType, {responseType: 'blob'})
|
||||
.then(response => {
|
||||
let fileName = window.decodeURI(response.headers['content-disposition'].split('=')[1]);
|
||||
let link = document.createElement("a");
|
||||
|
@ -246,7 +287,7 @@
|
|||
|
||||
let user = JSON.parse(localStorage.getItem(TokenKey));
|
||||
|
||||
this.result = this.$fileUpload('/test/case/import/' + this.projectId + '/' + user.id, file.file, null, {}, response => {
|
||||
this.result = this.$fileUpload('/test/case/import/' + this.projectId + '/' + user.id+'/'+this.importType, file.file, null, {}, response => {
|
||||
let res = response.data;
|
||||
if (res.success) {
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
|
@ -279,7 +320,7 @@
|
|||
this.uploadIgnoreError = true;
|
||||
file = this.lastExcelFile;
|
||||
}
|
||||
this.result = this.$fileUpload('/test/case/importIgnoreError/' + this.projectId + '/' + user.id, file, null, {}, response => {
|
||||
this.result = this.$fileUpload('/test/case/importIgnoreError/' + this.projectId + '/' + user.id+'/'+this.importType, file, null, {}, response => {
|
||||
let res = response.data;
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
this.dialogVisible = false;
|
||||
|
@ -305,7 +346,7 @@
|
|||
this.lastXmindFile = file.file;
|
||||
let user = JSON.parse(localStorage.getItem(TokenKey));
|
||||
|
||||
this.result = this.$fileUpload('/test/case/import/' + this.projectId + '/' + user.id, file.file, null, {}, response => {
|
||||
this.result = this.$fileUpload('/test/case/import/' + this.projectId + '/' + user.id+'/'+this.importType, file.file, null, {}, response => {
|
||||
let res = response.data;
|
||||
if (res.success) {
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
|
|
Loading…
Reference in New Issue