refactor(测试用例): 用例导出优化
This commit is contained in:
parent
c2108ecc15
commit
3f91e67ed7
|
@ -0,0 +1,7 @@
|
|||
-- set innodb lock wait timeout
|
||||
SET SESSION innodb_lock_wait_timeout = 7200;
|
||||
|
||||
|
||||
-- 项目管理员、项目成员增加权限
|
||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'FUNCTIONAL_CASE:READ+EXPORT');
|
||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'FUNCTIONAL_CASE:READ+EXPORT');
|
|
@ -28,7 +28,12 @@ public class ExportMsgDTO implements Serializable {
|
|||
*/
|
||||
private int count;
|
||||
/**
|
||||
* 消息类型(LINK-链接标识,HEARTBEAT-心跳检查标识,EXEC_START-开始执行标识,EXEC_RESULT-执行结果标识)
|
||||
* 导出状态
|
||||
*/
|
||||
private boolean isSuccessful;
|
||||
|
||||
/**
|
||||
* 消息类型(CONNECT-链接标识,HEARTBEAT-心跳检查标识,EXEC_START-开始执行标识,EXEC_RESULT-执行结果标识)
|
||||
*/
|
||||
private String msgType;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.alibaba.excel.util.StringUtils;
|
|||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.functional.domain.FunctionalCase;
|
||||
import io.metersphere.functional.dto.ExportTaskDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseDetailDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCasePageDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseVersionDTO;
|
||||
|
@ -272,8 +273,8 @@ public class FunctionalCaseController {
|
|||
@PostMapping("/export/excel")
|
||||
@Operation(summary = "用例管理-功能用例-excel导出")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_EXPORT)
|
||||
public void testCaseExport(@Validated @RequestBody FunctionalCaseExportRequest request) {
|
||||
functionalCaseFileService.export(SessionUtils.getUserId(), request);
|
||||
public String testCaseExport(@Validated @RequestBody FunctionalCaseExportRequest request) {
|
||||
return functionalCaseFileService.export(SessionUtils.getUserId(), request);
|
||||
}
|
||||
|
||||
@GetMapping("/stop/{taskId}")
|
||||
|
@ -312,14 +313,14 @@ public class FunctionalCaseController {
|
|||
@PostMapping("/export/xmind")
|
||||
@Operation(summary = "用例管理-功能用例-xmind导出")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_EXPORT)
|
||||
public void caseExportXmind(@Validated @RequestBody FunctionalCaseExportRequest request) {
|
||||
functionalCaseXmindService.exportFunctionalCaseXmind(request, SessionUtils.getUserId());
|
||||
public String caseExportXmind(@Validated @RequestBody FunctionalCaseExportRequest request) {
|
||||
return functionalCaseXmindService.exportFunctionalCaseXmind(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@GetMapping(value = "/check/export-task")
|
||||
@Operation(summary = "用例管理-功能用例-导出任务校验")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_EXPORT)
|
||||
public String checkExportTask() {
|
||||
public ExportTaskDTO checkExportTask() {
|
||||
return functionalCaseFileService.checkExportTask(SessionUtils.getCurrentProjectId(), SessionUtils.getUserId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.functional.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author wx
|
||||
*/
|
||||
@Data
|
||||
public class ExportTaskDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Schema(description = "文件id")
|
||||
private String fileId;
|
||||
|
||||
@Schema(description = "任务id")
|
||||
private String taskId;
|
||||
}
|
|
@ -10,6 +10,7 @@ import com.alibaba.excel.write.metadata.style.WriteCellStyle;
|
|||
import com.alibaba.excel.write.metadata.style.WriteFont;
|
||||
import io.metersphere.functional.constants.FunctionalCaseTypeConstants;
|
||||
import io.metersphere.functional.domain.*;
|
||||
import io.metersphere.functional.dto.ExportTaskDTO;
|
||||
import io.metersphere.functional.dto.response.FunctionalCaseImportResponse;
|
||||
import io.metersphere.functional.excel.constants.FunctionalCaseImportFiled;
|
||||
import io.metersphere.functional.excel.converter.FunctionalCaseExportConverter;
|
||||
|
@ -298,7 +299,7 @@ public class FunctionalCaseFileService {
|
|||
*
|
||||
* @return FunctionalCaseImportResponse
|
||||
*/
|
||||
public FunctionalCaseImportResponse preCheckXMind(FunctionalCaseImportRequest request,SessionUser user, MultipartFile multipartFile) {
|
||||
public FunctionalCaseImportResponse preCheckXMind(FunctionalCaseImportRequest request, SessionUser user, MultipartFile multipartFile) {
|
||||
if (multipartFile == null) {
|
||||
throw new MSException(Translator.get("file_cannot_be_null"));
|
||||
}
|
||||
|
@ -313,11 +314,11 @@ public class FunctionalCaseFileService {
|
|||
Long lasePos = nextPos + ((long) ServiceUtils.POS_STEP * Integer.parseInt(request.getCount()));
|
||||
//获取当前项目默认模板的自定义字段
|
||||
List<TemplateCustomFieldDTO> customFields = getCustomFields(request.getProjectId());
|
||||
XMindCaseParser xMindParser = new XMindCaseParser(request, customFields, user,lasePos);
|
||||
XMindCaseParser xMindParser = new XMindCaseParser(request, customFields, user, lasePos);
|
||||
errList = xMindParser.parse(multipartFile);
|
||||
xMindParser.clear();
|
||||
response.setErrorMessages(errList);
|
||||
response.setSuccessCount(xMindParser.getList().size()+xMindParser.getUpdateList().size());
|
||||
response.setSuccessCount(xMindParser.getList().size() + xMindParser.getUpdateList().size());
|
||||
response.setFailCount(errList.size());
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
|
@ -381,7 +382,7 @@ public class FunctionalCaseFileService {
|
|||
Long lasePos = nextPos + ((long) ServiceUtils.POS_STEP * Integer.parseInt(request.getCount()));
|
||||
//获取当前项目默认模板的自定义字段
|
||||
List<TemplateCustomFieldDTO> customFields = getCustomFields(request.getProjectId());
|
||||
XMindCaseParser xmindParser = new XMindCaseParser(request, customFields, user,lasePos);
|
||||
XMindCaseParser xmindParser = new XMindCaseParser(request, customFields, user, lasePos);
|
||||
errList = xmindParser.parse(multipartFile);
|
||||
if (CollectionUtils.isEmpty(xmindParser.getList())
|
||||
&& CollectionUtils.isEmpty(xmindParser.getUpdateList())) {
|
||||
|
@ -394,7 +395,7 @@ public class FunctionalCaseFileService {
|
|||
xmindParser.saveData();
|
||||
xmindParser.clear();
|
||||
response.setErrorMessages(errList);
|
||||
response.setSuccessCount(xmindParser.getList().size()+xmindParser.getUpdateList().size());
|
||||
response.setSuccessCount(xmindParser.getList().size() + xmindParser.getUpdateList().size());
|
||||
response.setFailCount(errList.size());
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
|
@ -403,21 +404,24 @@ public class FunctionalCaseFileService {
|
|||
}
|
||||
}
|
||||
|
||||
public void export(String userId, FunctionalCaseExportRequest request) {
|
||||
public String export(String userId, FunctionalCaseExportRequest request) {
|
||||
try {
|
||||
ExportTaskExample exportTaskExample = new ExportTaskExample();
|
||||
exportTaskExample.createCriteria().andTypeEqualTo(ExportConstants.ExportType.CASE.toString()).andStateEqualTo(ExportConstants.ExportState.PREPARED.toString());
|
||||
long preparedCount = exportTaskMapper.countByExample(exportTaskExample);
|
||||
if (preparedCount > 0) {
|
||||
throw new MSException(Translator.get("export_case_task_existed"));
|
||||
}
|
||||
exportTaskManager.exportAsyncTask(request.getProjectId(), request.getFileId(), userId, ExportConstants.ExportType.CASE.toString(), request, t -> exportFunctionalCaseZip(request, userId));
|
||||
exportCheck(request, userId);
|
||||
ExportTask exportTask = exportTaskManager.exportAsyncTask(request.getProjectId(), request.getFileId(), userId, ExportConstants.ExportType.CASE.toString(), request, t -> exportFunctionalCaseZip(request, userId));
|
||||
return exportTask.getId();
|
||||
} catch (InterruptedException e) {
|
||||
LogUtils.error("导出失败:" + e);
|
||||
throw new MSException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void exportCheck(FunctionalCaseExportRequest request, String userId) {
|
||||
List<ExportTask> exportTasks = getExportTasks(request.getProjectId(), userId);
|
||||
if (CollectionUtils.isNotEmpty(exportTasks)) {
|
||||
throw new MSException(Translator.get("export_case_task_existed"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
|
@ -462,9 +466,11 @@ public class FunctionalCaseFileService {
|
|||
} else {
|
||||
taskId = MsgType.CONNECT.name();
|
||||
}
|
||||
ExportMsgDTO exportMsgDTO = new ExportMsgDTO(request.getFileId(), taskId, ids.size(), MsgType.CONNECT.name());
|
||||
ExportMsgDTO exportMsgDTO = new ExportMsgDTO(request.getFileId(), taskId, ids.size(), true, MsgType.EXEC_RESULT.name());
|
||||
ExportWebSocketHandler.sendMessageSingle(exportMsgDTO);
|
||||
} catch (Exception e) {
|
||||
ExportMsgDTO exportMsgDTO = new ExportMsgDTO(request.getFileId(), "", 0, false, MsgType.EXEC_RESULT.name());
|
||||
ExportWebSocketHandler.sendMessageSingle(exportMsgDTO);
|
||||
List<ExportTask> exportTasks = getExportTasks(request.getProjectId(), userId);
|
||||
if (CollectionUtils.isNotEmpty(exportTasks)) {
|
||||
updateExportTask(ExportConstants.ExportState.ERROR.name(), exportTasks.getFirst().getId(), fileType);
|
||||
|
@ -862,7 +868,7 @@ public class FunctionalCaseFileService {
|
|||
public ResponseEntity<byte[]> downloadFile(String projectId, String fileId, String userId) {
|
||||
List<ExportTask> exportTasks = getExportTasksByFileId(projectId, userId, fileId);
|
||||
if (CollectionUtils.isEmpty(exportTasks)) {
|
||||
throw new MSException("任务不存在");
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
ExportTask tasksFirst = exportTasks.getFirst();
|
||||
Project project = projectMapper.selectByPrimaryKey(projectId);
|
||||
|
@ -900,12 +906,15 @@ public class FunctionalCaseFileService {
|
|||
exportTaskManager.sendStopMessage(taskId, userId);
|
||||
}
|
||||
|
||||
public String checkExportTask(String projectId, String userId) {
|
||||
public ExportTaskDTO checkExportTask(String projectId, String userId) {
|
||||
ExportTaskDTO exportTaskDTO = new ExportTaskDTO();
|
||||
List<ExportTask> exportTasks = getExportTasks(projectId, userId);
|
||||
if (CollectionUtils.isNotEmpty(exportTasks)) {
|
||||
return exportTasks.getFirst().getFileId();
|
||||
exportTaskDTO.setFileId(exportTasks.getFirst().getFileId());
|
||||
exportTaskDTO.setTaskId(exportTasks.getFirst().getId());
|
||||
return exportTaskDTO;
|
||||
} else {
|
||||
return StringUtils.EMPTY;
|
||||
return exportTaskDTO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,9 +95,11 @@ public class FunctionalCaseXmindService {
|
|||
*
|
||||
* @param request
|
||||
*/
|
||||
public void exportFunctionalCaseXmind(FunctionalCaseExportRequest request, String userId) {
|
||||
public String exportFunctionalCaseXmind(FunctionalCaseExportRequest request, String userId) {
|
||||
try {
|
||||
exportTaskManager.exportAsyncTask(request.getProjectId(), request.getFileId(), userId, ExportConstants.ExportType.CASE.toString(), request, t -> exportXmind(request, userId));
|
||||
functionalCaseFileService.exportCheck(request, userId);
|
||||
ExportTask exportTask = exportTaskManager.exportAsyncTask(request.getProjectId(), request.getFileId(), userId, ExportConstants.ExportType.CASE.toString(), request, t -> exportXmind(request, userId));
|
||||
return exportTask.getId();
|
||||
} catch (InterruptedException e) {
|
||||
LogUtils.error("导出失败:" + e);
|
||||
throw new MSException(e);
|
||||
|
@ -130,9 +132,11 @@ public class FunctionalCaseXmindService {
|
|||
} else {
|
||||
taskId = MsgType.CONNECT.name();
|
||||
}
|
||||
ExportMsgDTO exportMsgDTO = new ExportMsgDTO(request.getFileId(), taskId, ids.size(), MsgType.CONNECT.name());
|
||||
ExportMsgDTO exportMsgDTO = new ExportMsgDTO(request.getFileId(), taskId, ids.size(), true, MsgType.EXEC_RESULT.name());
|
||||
ExportWebSocketHandler.sendMessageSingle(exportMsgDTO);
|
||||
} catch (Exception e) {
|
||||
ExportMsgDTO exportMsgDTO = new ExportMsgDTO(request.getFileId(), "", 0, false, MsgType.EXEC_RESULT.name());
|
||||
ExportWebSocketHandler.sendMessageSingle(exportMsgDTO);
|
||||
List<ExportTask> exportTasks = functionalCaseFileService.getExportTasks(request.getProjectId(), userId);
|
||||
if (CollectionUtils.isNotEmpty(exportTasks)) {
|
||||
functionalCaseFileService.updateExportTask(ExportConstants.ExportState.ERROR.name(), exportTasks.getFirst().getId(), XMIND);
|
||||
|
|
|
@ -49,7 +49,7 @@ public class ExportWebSocketHandler {
|
|||
ONLINE_EXPORT_EXCEL_SESSIONS.put(fileId, session);
|
||||
RemoteEndpoint.Async async = session.getAsyncRemote();
|
||||
if (async != null) {
|
||||
async.sendText(JSON.toJSONString(new ExportMsgDTO(fileId, "", 0, MsgType.CONNECT.name())));
|
||||
async.sendText(JSON.toJSONString(new ExportMsgDTO(fileId, "", 0, true, MsgType.CONNECT.name())));
|
||||
session.setMaxIdleTimeout(180000);
|
||||
}
|
||||
LogUtils.info("客户端: [" + fileId + "] : 连接成功!" + ExportWebSocketHandler.ONLINE_EXPORT_EXCEL_SESSIONS.size(), fileId);
|
||||
|
@ -92,7 +92,7 @@ public class ExportWebSocketHandler {
|
|||
@Scheduled(fixedRate = 60000)
|
||||
public void heartbeatCheck() {
|
||||
ExportWebSocketHandler.sendMessageSingle(
|
||||
new ExportMsgDTO(MsgType.HEARTBEAT.name(), MsgType.HEARTBEAT.name(), 0, "heartbeat check")
|
||||
new ExportMsgDTO(MsgType.HEARTBEAT.name(), MsgType.HEARTBEAT.name(), 0, true, MsgType.HEARTBEAT.name())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ public class XmindExportUtil {
|
|||
//文本描述
|
||||
ITopic textDesTopic = workbook.createTopic();
|
||||
String desc = dto.getTextDescription();
|
||||
textDesTopic.setTitleText(desc == null ? Translator.get("xmind_textDescription").concat(": ") : Translator.get("xmind_textDescription").concat(": ").concat(Translator.get("xmind_textDescription")).concat(": ").concat(desc));
|
||||
textDesTopic.setTitleText(desc == null ? Translator.get("xmind_textDescription").concat(": ") : Translator.get("xmind_textDescription").concat(": ").concat(desc));
|
||||
if (style != null) {
|
||||
textDesTopic.setStyleId(style.getId());
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
{
|
||||
"id": "FUNCTIONAL_CASE:READ+IMPORT"
|
||||
},
|
||||
{
|
||||
"id": "FUNCTIONAL_CASE:READ+EXPORT"
|
||||
},
|
||||
{
|
||||
"id": "FUNCTIONAL_CASE:READ+MINDER",
|
||||
"name": "permission.functional_case.minder"
|
||||
|
|
|
@ -6,6 +6,7 @@ import io.metersphere.functional.dto.FunctionalCaseAttachmentDTO;
|
|||
import io.metersphere.functional.dto.FunctionalCasePageDTO;
|
||||
import io.metersphere.functional.dto.response.FunctionalCaseImportResponse;
|
||||
import io.metersphere.functional.excel.domain.FunctionalCaseHeader;
|
||||
import io.metersphere.functional.mapper.ExportTaskMapper;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseAttachmentMapper;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
||||
|
@ -113,6 +114,8 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
|||
private FunctionalCaseMapper functionalCaseMapper;
|
||||
|
||||
protected static String functionalCaseId;
|
||||
@Resource
|
||||
private ExportTaskMapper exportTaskMapper;
|
||||
|
||||
|
||||
@Test
|
||||
|
@ -990,11 +993,30 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
|||
@Test
|
||||
@Order(24)
|
||||
public void downloadFile() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(DOWNLOAD_FILE_URL + DEFAULT_PROJECT_ID + "/" + "123142342")
|
||||
download("12222");
|
||||
ExportTask exportTask = new ExportTask();
|
||||
exportTask.setId("12314234222");
|
||||
exportTask.setProjectId(DEFAULT_PROJECT_ID);
|
||||
exportTask.setFileId("123142342");
|
||||
exportTask.setFileType("xlsx");
|
||||
exportTask.setType("CASE");
|
||||
exportTask.setState("SUCCESS");
|
||||
exportTask.setCreateTime(System.currentTimeMillis());
|
||||
exportTask.setCreateUser("admin");
|
||||
exportTask.setUpdateUser("admin");
|
||||
exportTask.setUpdateTime(System.currentTimeMillis());
|
||||
exportTaskMapper.insertSelective(exportTask);
|
||||
download("123142342");
|
||||
|
||||
}
|
||||
|
||||
private void download(String fileId) throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(DOWNLOAD_FILE_URL + DEFAULT_PROJECT_ID + "/" + fileId)
|
||||
.header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||
.header(SessionConstants.CSRF_TOKEN, csrfToken));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Order(25)
|
||||
public void stopExport() throws Exception {
|
||||
|
@ -1033,7 +1055,7 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
|||
}};
|
||||
request.setOtherFields(otherHeaders);
|
||||
|
||||
request.setFileId("123142342");
|
||||
request.setFileId("1231423421");
|
||||
this.requestPost(EXPORT_XMIND_URL, request);
|
||||
request.setSelectIds(new ArrayList<>());
|
||||
this.requestPost(EXPORT_XMIND_URL, request);
|
||||
|
@ -1044,7 +1066,7 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
|||
@Test
|
||||
@Order(4)
|
||||
public void checkExportTask() throws Exception {
|
||||
this.requestGetExcel( EXPORT_XMIND_CHECK_URL);
|
||||
this.requestGetExcel(EXPORT_XMIND_CHECK_URL);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public class ExportTaskManager {
|
|||
public static final String EXPORT_CONSUME = "export_consume";
|
||||
|
||||
|
||||
public <T> void exportAsyncTask(String projectId, String fileId, String userId, String type, T t, Function<Object, Object> selectListFunc) throws InterruptedException {
|
||||
public <T> ExportTask exportAsyncTask(String projectId, String fileId, String userId, String type, T t, Function<Object, Object> selectListFunc) throws InterruptedException {
|
||||
ExportTask exportTask = buildExportTask(projectId, fileId, userId, type);
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(1);
|
||||
Future<?> future = executorService.submit(() -> {
|
||||
|
@ -46,9 +46,10 @@ public class ExportTaskManager {
|
|||
LogUtils.info("Thread has been interrupted.");
|
||||
});
|
||||
map.put(exportTask.getId(), future);
|
||||
return exportTask;
|
||||
}
|
||||
|
||||
private ExportTask buildExportTask(String projectId, String fileId, String userId, String type) {
|
||||
public ExportTask buildExportTask(String projectId, String fileId, String userId, String type) {
|
||||
ExportTask exportTask = new ExportTask();
|
||||
exportTask.setId(IDGenerator.nextStr());
|
||||
exportTask.setType(type);
|
||||
|
@ -59,7 +60,7 @@ public class ExportTaskManager {
|
|||
exportTask.setUpdateTime(System.currentTimeMillis());
|
||||
exportTask.setProjectId(projectId);
|
||||
exportTask.setFileType(fileId);
|
||||
exportTaskMapper.insert(exportTask);
|
||||
exportTaskMapper.insertSelective(exportTask);
|
||||
return exportTask;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue