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