fix(测试跟踪):用例导出支持单元格内容换行

--bug=1029175 --user=宋昌昌 【测试跟踪】功能用例-导出为excel-同一步骤中的内容未换行显示 https://www.tapd.cn/55049933/s/1406643
This commit is contained in:
song-cc-rock 2023-08-21 18:57:06 +08:00 committed by 刘瑞斌
parent f1c6d031cb
commit b431dd14f5
2 changed files with 77 additions and 46 deletions

View File

@ -3,6 +3,8 @@ package io.metersphere.excel.handler;
import com.alibaba.excel.util.BooleanUtils; import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext; import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import io.metersphere.commons.utils.JSON; import io.metersphere.commons.utils.JSON;
import io.metersphere.excel.constants.TestCaseImportFiled; import io.metersphere.excel.constants.TestCaseImportFiled;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
@ -43,7 +45,7 @@ public class FunctionCaseTemplateWriteHandler implements RowWriteHandler {
public FunctionCaseTemplateWriteHandler(boolean isNeedId, List<List<String>> headList, Map<String, List<String>> caseLevelAndStatusValueMap) { public FunctionCaseTemplateWriteHandler(boolean isNeedId, List<List<String>> headList, Map<String, List<String>> caseLevelAndStatusValueMap) {
this.isNeedId = isNeedId; this.isNeedId = isNeedId;
this.initIndex(headList); initIndex(headList);
this.caseLevelAndStatusValueMap = caseLevelAndStatusValueMap; this.caseLevelAndStatusValueMap = caseLevelAndStatusValueMap;
} }
@ -122,4 +124,11 @@ public class FunctionCaseTemplateWriteHandler implements RowWriteHandler {
comment.setString(new XSSFRichTextString(text)); comment.setString(new XSSFRichTextString(text));
sheet.getRow(0).getCell(1).setCellComment(comment); sheet.getRow(0).getCell(1).setCellComment(comment);
} }
public static HorizontalCellStyleStrategy getHorizontalWrapStrategy() {
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
// 设置自动换行
contentWriteCellStyle.setWrapped(true);
return new HorizontalCellStyleStrategy(null, contentWriteCellStyle);
}
} }

View File

@ -229,7 +229,7 @@ public class TestCaseService {
request.setDemandName(request.getDemandName()); request.setDemandName(request.getDemandName());
request.setCreateUser(SessionUtils.getUserId()); request.setCreateUser(SessionUtils.getUserId());
request.setLastExecuteResult(null); request.setLastExecuteResult(null);
this.setNode(request); setNode(request);
request.setOrder(ServiceUtils.getNextOrder(request.getProjectId(), extTestCaseMapper::getLastOrder)); request.setOrder(ServiceUtils.getNextOrder(request.getProjectId(), extTestCaseMapper::getLastOrder));
//直接点保存 || 复制走的逻辑 //直接点保存 || 复制走的逻辑
if (StringUtils.isAllBlank(request.getRefId(), request.getVersionId())) { if (StringUtils.isAllBlank(request.getRefId(), request.getVersionId())) {
@ -820,7 +820,7 @@ public class TestCaseService {
public List<TestCaseDTO> listTestCase(QueryTestCaseRequest request, boolean isSampleInfo) { public List<TestCaseDTO> listTestCase(QueryTestCaseRequest request, boolean isSampleInfo) {
boolean queryUi = DiscoveryUtil.hasService(MicroServiceName.UI_TEST); boolean queryUi = DiscoveryUtil.hasService(MicroServiceName.UI_TEST);
request.setQueryUi(queryUi); request.setQueryUi(queryUi);
this.initRequest(request, true); initRequest(request, true);
setDefaultOrder(request); setDefaultOrder(request);
ServiceUtils.setBaseQueryRequestCustomMultipleFields(request); ServiceUtils.setBaseQueryRequestCustomMultipleFields(request);
if (request.getFilters() != null && !request.getFilters().containsKey("status")) { if (request.getFilters() != null && !request.getFilters().containsKey("status")) {
@ -876,7 +876,7 @@ public class TestCaseService {
} }
public void setPublicListRequestParam(QueryTestCaseRequest request) { public void setPublicListRequestParam(QueryTestCaseRequest request) {
this.initRequest(request, true); initRequest(request, true);
setDefaultOrder(request); setDefaultOrder(request);
if (request.getFilters() != null && !request.getFilters().containsKey("status")) { if (request.getFilters() != null && !request.getFilters().containsKey("status")) {
request.getFilters().put("status", new ArrayList<>(0)); request.getFilters().put("status", new ArrayList<>(0));
@ -1163,12 +1163,12 @@ public class TestCaseService {
testCaseNodeService.createNodes(xmindParser.getNodePaths(), projectId); testCaseNodeService.createNodes(xmindParser.getNodePaths(), projectId);
} }
if (CollectionUtils.isNotEmpty(xmindParser.getTestCase())) { if (CollectionUtils.isNotEmpty(xmindParser.getTestCase())) {
this.saveImportData(testCase, request, null); saveImportData(testCase, request, null);
names = testCase.stream().map(TestCase::getName).collect(Collectors.toList()); names = testCase.stream().map(TestCase::getName).collect(Collectors.toList());
ids = testCase.stream().map(TestCase::getId).collect(Collectors.toList()); ids = testCase.stream().map(TestCase::getId).collect(Collectors.toList());
} }
if (CollectionUtils.isNotEmpty(xmindParser.getUpdateTestCase())) { if (CollectionUtils.isNotEmpty(xmindParser.getUpdateTestCase())) {
this.updateImportData(xmindParser.getUpdateTestCase(), request, null); updateImportData(xmindParser.getUpdateTestCase(), request, null);
names.addAll(xmindParser.getUpdateTestCase().stream().map(TestCase::getName).collect(Collectors.toList())); names.addAll(xmindParser.getUpdateTestCase().stream().map(TestCase::getName).collect(Collectors.toList()));
ids.addAll(xmindParser.getUpdateTestCase().stream().map(TestCase::getId).collect(Collectors.toList())); ids.addAll(xmindParser.getUpdateTestCase().stream().map(TestCase::getId).collect(Collectors.toList()));
} }
@ -1180,7 +1180,7 @@ public class TestCaseService {
if (CollectionUtils.isNotEmpty(continueCaseList) || CollectionUtils.isNotEmpty(xmindParser.getUpdateTestCase())) { if (CollectionUtils.isNotEmpty(continueCaseList) || CollectionUtils.isNotEmpty(xmindParser.getUpdateTestCase())) {
if (CollectionUtils.isNotEmpty(xmindParser.getUpdateTestCase())) { if (CollectionUtils.isNotEmpty(xmindParser.getUpdateTestCase())) {
continueCaseList.removeAll(xmindParser.getUpdateTestCase()); continueCaseList.removeAll(xmindParser.getUpdateTestCase());
this.updateImportData(xmindParser.getUpdateTestCase(), request, null); updateImportData(xmindParser.getUpdateTestCase(), request, null);
names = testCase.stream().map(TestCase::getName).collect(Collectors.toList()); names = testCase.stream().map(TestCase::getName).collect(Collectors.toList());
ids = testCase.stream().map(TestCase::getId).collect(Collectors.toList()); ids = testCase.stream().map(TestCase::getId).collect(Collectors.toList());
} }
@ -1189,7 +1189,7 @@ public class TestCaseService {
testCaseNodeService.createNodes(nodePathList, projectId); testCaseNodeService.createNodes(nodePathList, projectId);
} }
if (CollectionUtils.isNotEmpty(continueCaseList)) { if (CollectionUtils.isNotEmpty(continueCaseList)) {
this.saveImportData(continueCaseList, request, null); saveImportData(continueCaseList, request, null);
names.addAll(continueCaseList.stream().map(TestCase::getName).collect(Collectors.toList())); names.addAll(continueCaseList.stream().map(TestCase::getName).collect(Collectors.toList()));
ids.addAll(continueCaseList.stream().map(TestCase::getId).collect(Collectors.toList())); ids.addAll(continueCaseList.stream().map(TestCase::getId).collect(Collectors.toList()));
@ -1487,7 +1487,7 @@ public class TestCaseService {
// 发送给客户端的数据 // 发送给客户端的数据
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.getClassLoader().getResourceAsStream("xmind/" + fileName));) { BufferedInputStream bis = new BufferedInputStream(TestCaseService.class.getClassLoader().getResourceAsStream("xmind/" + 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);
@ -1555,7 +1555,7 @@ public class TestCaseService {
File tmpDir = null; File tmpDir = null;
try { try {
tmpDir = new File(this.getClass().getClassLoader().getResource(StringUtils.EMPTY).getPath() + tmpDir = new File(getClass().getClassLoader().getResource(StringUtils.EMPTY).getPath() +
EXPORT_CASE_TMP_DIR + File.separatorChar + EXPORT_CASE_TMP_DIR + "_" + UUID.randomUUID().toString()); EXPORT_CASE_TMP_DIR + File.separatorChar + EXPORT_CASE_TMP_DIR + "_" + UUID.randomUUID().toString());
// 生成tmp随机目录 // 生成tmp随机目录
FileUtils.deleteDir(tmpDir.getPath()); FileUtils.deleteDir(tmpDir.getPath());
@ -1647,6 +1647,7 @@ public class TestCaseService {
.head(Optional.ofNullable(headList).orElse(new ArrayList<>())) .head(Optional.ofNullable(headList).orElse(new ArrayList<>()))
.registerWriteHandler(handler) .registerWriteHandler(handler)
.registerWriteHandler(writeHandler) .registerWriteHandler(writeHandler)
.registerWriteHandler(FunctionCaseTemplateWriteHandler.getHorizontalWrapStrategy())
.excelType(ExcelTypeEnum.XLSX).sheet(Translator.get("test_case_import_template_sheet")).doWrite(data); .excelType(ExcelTypeEnum.XLSX).sheet(Translator.get("test_case_import_template_sheet")).doWrite(data);
tmpExportExcelList.add(createFile); tmpExportExcelList.add(createFile);
}); });
@ -1654,7 +1655,7 @@ public class TestCaseService {
} }
public void cleanUpTmpDirOfClassPath() { public void cleanUpTmpDirOfClassPath() {
File tmpDir = new File(this.getClass().getClassLoader().getResource(StringUtils.EMPTY).getPath() + EXPORT_CASE_TMP_DIR); File tmpDir = new File(getClass().getClassLoader().getResource(StringUtils.EMPTY).getPath() + EXPORT_CASE_TMP_DIR);
if (tmpDir.exists()) { if (tmpDir.exists()) {
FileUtils.deleteDir(tmpDir.getPath()); FileUtils.deleteDir(tmpDir.getPath());
} }
@ -1662,7 +1663,11 @@ public class TestCaseService {
@NotNull @NotNull
private List<List<String>> getTestcaseExportHeads(TestCaseExportRequest request) { private List<List<String>> getTestcaseExportHeads(TestCaseExportRequest request) {
List<List<String>> headList = new ArrayList<>() {{ List<List<String>> headList = new ArrayList<>() {
@Serial
private static final long serialVersionUID = 5726921174161850104L;
{
addAll(request.getBaseHeaders() addAll(request.getBaseHeaders()
.stream() .stream()
.map(item -> Arrays.asList(item.getName())) .map(item -> Arrays.asList(item.getName()))
@ -1675,7 +1680,8 @@ public class TestCaseService {
.stream() .stream()
.map(item -> Arrays.asList(item.getName())) .map(item -> Arrays.asList(item.getName()))
.collect(Collectors.toList())); .collect(Collectors.toList()));
}}; }
};
return headList; return headList;
} }
@ -1717,9 +1723,9 @@ public class TestCaseService {
// 导出所有用例, 勾选ID清空 // 导出所有用例, 勾选ID清空
request.setIds(null); request.setIds(null);
} }
List<TestCaseDTO> testCaseDTOList = this.findByBatchRequest(request); List<TestCaseDTO> testCaseDTOList = findByBatchRequest(request);
TestCaseXmindData rootXmindData = this.generateTestCaseXmind(testCaseDTOList); TestCaseXmindData rootXmindData = generateTestCaseXmind(testCaseDTOList);
boolean isUseCustomId = trackProjectService.useCustomNum(request.getProjectId()); boolean isUseCustomId = trackProjectService.useCustomNum(request.getProjectId());
XmindExportUtil xmindExportUtil = new XmindExportUtil(isUseCustomId); XmindExportUtil xmindExportUtil = new XmindExportUtil(isUseCustomId);
xmindExportUtil.exportXmind(response, rootXmindData); xmindExportUtil.exportXmind(response, rootXmindData);
@ -1820,7 +1826,7 @@ public class TestCaseService {
private TestCaseBatchRequest setTestCaseExportParamIds(TestCaseBatchRequest param) { private TestCaseBatchRequest setTestCaseExportParamIds(TestCaseBatchRequest param) {
boolean queryUi = DiscoveryUtil.hasService(MicroServiceName.UI_TEST); boolean queryUi = DiscoveryUtil.hasService(MicroServiceName.UI_TEST);
param.getCondition().setQueryUi(queryUi); param.getCondition().setQueryUi(queryUi);
this.initRequest(param.getCondition(), true); initRequest(param.getCondition(), true);
setDefaultOrder(param.getCondition()); setDefaultOrder(param.getCondition());
ServiceUtils.setBaseQueryRequestCustomMultipleFields(param.getCondition()); ServiceUtils.setBaseQueryRequestCustomMultipleFields(param.getCondition());
Map<String, List<String>> filters = param.getCondition().getFilters(); Map<String, List<String>> filters = param.getCondition().getFilters();
@ -1873,7 +1879,7 @@ public class TestCaseService {
buildExportCustomField(customSelectValueMap, customNameMap, t, data, textFields); buildExportCustomField(customSelectValueMap, customNameMap, t, data, textFields);
buildExportOtherField(data, t, otherHeaders); buildExportOtherField(data, t, otherHeaders);
this.validateExportTextField(data); validateExportTextField(data);
if (CollectionUtils.isNotEmpty(stepDescList)) { if (CollectionUtils.isNotEmpty(stepDescList)) {
// 如果有多条步骤则添加多条数据之后合并单元格 // 如果有多条步骤则添加多条数据之后合并单元格
buildExportMergeData(rowMergeInfo, list, stepDescList, stepResultList, data); buildExportMergeData(rowMergeInfo, list, stepDescList, stepResultList, data);
@ -1966,7 +1972,7 @@ public class TestCaseService {
//进行key value对换 //进行key value对换
String id = field.getFieldId(); String id = field.getFieldId();
if (textFields.contains(id)) { if (textFields.contains(id)) {
map.put(customNameMap.get(id), this.validateExportText(field.getTextValue())); map.put(customNameMap.get(id), validateExportText(field.getTextValue()));
continue; continue;
} }
if (StringUtils.isNotBlank(field.getValue())) { if (StringUtils.isNotBlank(field.getValue())) {
@ -2235,9 +2241,10 @@ public class TestCaseService {
batchCopy.setNum(nextNum++); batchCopy.setNum(nextNum++);
mapper.insert(batchCopy); mapper.insert(batchCopy);
dealWithCopyOtherInfo(batchCopy, oldTestCaseId); dealWithCopyOtherInfo(batchCopy, oldTestCaseId);
if (i % 50 == 0) if (i % 50 == 0) {
sqlSession.flushStatements(); sqlSession.flushStatements();
} }
}
sqlSession.flushStatements(); sqlSession.flushStatements();
} finally { } finally {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
@ -2245,7 +2252,7 @@ public class TestCaseService {
} }
public void deleteTestCaseBath(TestCaseBatchRequest request) { public void deleteTestCaseBath(TestCaseBatchRequest request) {
TestCaseExample example = this.getBatchExample(request); TestCaseExample example = getBatchExample(request);
//删除全部版本的数据根据 RefId //删除全部版本的数据根据 RefId
List<String> refIds = testCaseMapper.selectByExample(example).stream().map(TestCase::getRefId).collect(Collectors.toList()); List<String> refIds = testCaseMapper.selectByExample(example).stream().map(TestCase::getRefId).collect(Collectors.toList());
example.clear(); example.clear();
@ -2413,7 +2420,7 @@ public class TestCaseService {
MSException.throwException(Translator.get("edit_trash_case_error")); MSException.throwException(Translator.get("edit_trash_case_error"));
} }
request.setNum(testCaseWithBLOBs.getNum()); request.setNum(testCaseWithBLOBs.getNum());
this.setNode(request); setNode(request);
return editTestCase(request); return editTestCase(request);
} }
@ -2450,7 +2457,7 @@ public class TestCaseService {
testCaseFileMapper.insert(testCaseFile); testCaseFileMapper.insert(testCaseFile);
}); });
} }
this.setNode(request); setNode(request);
request.setStatus(null); // 不更新状态 request.setStatus(null); // 不更新状态
request.setRefId(testCaseWithBLOBs.getRefId()); request.setRefId(testCaseWithBLOBs.getRefId());
request.setVersionId(testCaseWithBLOBs.getVersionId()); request.setVersionId(testCaseWithBLOBs.getVersionId());
@ -2756,9 +2763,10 @@ public class TestCaseService {
TestCaseWithBLOBs t = new TestCaseWithBLOBs(); TestCaseWithBLOBs t = new TestCaseWithBLOBs();
t.setCasePublic(false); t.setCasePublic(false);
mapper.updateByExampleSelective(t, e); mapper.updateByExampleSelective(t, e);
if (i % 50 == 0) if (i % 50 == 0) {
sqlSession.flushStatements(); sqlSession.flushStatements();
} }
}
sqlSession.flushStatements(); sqlSession.flushStatements();
} }
} finally { } finally {
@ -3017,6 +3025,7 @@ public class TestCaseService {
/** /**
* 测试计划功能用例页面和脑图页面批量修改执行结果时记录下操作日志用例的变更日志需要查看 * 测试计划功能用例页面和脑图页面批量修改执行结果时记录下操作日志用例的变更日志需要查看
*
* @param ids * @param ids
* @param status * @param status
*/ */
@ -3053,7 +3062,7 @@ public class TestCaseService {
public void updateLastExecuteStatus(String id, String status) { public void updateLastExecuteStatus(String id, String status) {
if (StringUtils.isNotBlank(id) && StringUtils.isNotBlank(status)) { if (StringUtils.isNotBlank(id) && StringUtils.isNotBlank(status)) {
this.updateLastExecuteStatus(Arrays.asList(id), status); updateLastExecuteStatus(Arrays.asList(id), status);
} }
} }
@ -3069,7 +3078,7 @@ public class TestCaseService {
public void updateReviewStatus(String id, String status) { public void updateReviewStatus(String id, String status) {
if (StringUtils.isNotBlank(id) && StringUtils.isNotBlank(status)) { if (StringUtils.isNotBlank(id) && StringUtils.isNotBlank(status)) {
this.updateReviewStatus(Arrays.asList(id), status); updateReviewStatus(Arrays.asList(id), status);
} }
} }
@ -3199,7 +3208,9 @@ public class TestCaseService {
ServiceUtils.getSelectAllIds(request, request.getCondition(), ServiceUtils.getSelectAllIds(request, request.getCondition(),
(query) -> extTestCaseMapper.selectIds(query)); (query) -> extTestCaseMapper.selectIds(query));
List<String> ids = request.getIds(); List<String> ids = request.getIds();
if (CollectionUtils.isEmpty(ids)) return; if (CollectionUtils.isEmpty(ids)) {
return;
}
List<TestCaseWithBLOBs> testCases = getTestCasesWithBLOBs(ids); List<TestCaseWithBLOBs> testCases = getTestCasesWithBLOBs(ids);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
TestCaseMapper mapper = sqlSession.getMapper(TestCaseMapper.class); TestCaseMapper mapper = sqlSession.getMapper(TestCaseMapper.class);
@ -3235,9 +3246,10 @@ public class TestCaseService {
dealWithCopyOtherInfo(testCase, oldTestCaseId); dealWithCopyOtherInfo(testCase, oldTestCaseId);
copyCustomFields(oldTestCaseId, id); copyCustomFields(oldTestCaseId, id);
if (i % 50 == 0) if (i % 50 == 0) {
sqlSession.flushStatements(); sqlSession.flushStatements();
} }
}
sqlSession.flushStatements(); sqlSession.flushStatements();
} finally { } finally {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
@ -3264,20 +3276,30 @@ public class TestCaseService {
QueryTestCaseRequest request = new QueryTestCaseRequest(); QueryTestCaseRequest request = new QueryTestCaseRequest();
request.setRefId(testCase.getRefId()); request.setRefId(testCase.getRefId());
if (CommonConstants.TrashStatus.equalsIgnoreCase(testCase.getStatus())) { if (CommonConstants.TrashStatus.equalsIgnoreCase(testCase.getStatus())) {
request.setFilters(new HashMap<>() {{ request.setFilters(new HashMap<>() {
put("status", new ArrayList() {{ @Serial
private static final long serialVersionUID = 7656278760319683749L;
{
put("status", new ArrayList() {
@Serial
private static final long serialVersionUID = 2599911267062544334L;
{
add(CommonConstants.TrashStatus); add(CommonConstants.TrashStatus);
}});
}});
} }
return this.listTestCase(request); });
}
});
}
return listTestCase(request);
} }
public TestCaseDTO getTestCaseByVersion(String refId, String version) { public TestCaseDTO getTestCaseByVersion(String refId, String version) {
QueryTestCaseRequest request = new QueryTestCaseRequest(); QueryTestCaseRequest request = new QueryTestCaseRequest();
request.setRefId(refId); request.setRefId(refId);
request.setVersionId(version); request.setVersionId(version);
List<TestCaseDTO> testCaseList = this.listTestCase(request); List<TestCaseDTO> testCaseList = listTestCase(request);
if (CollectionUtils.isEmpty(testCaseList)) { if (CollectionUtils.isEmpty(testCaseList)) {
return null; return null;
} }