feat(功能用例): 变更历史
This commit is contained in:
parent
3927bb271b
commit
8e0ff36aef
|
@ -17,6 +17,8 @@ import io.metersphere.project.dto.CustomFieldOptions;
|
||||||
import io.metersphere.project.service.ProjectTemplateService;
|
import io.metersphere.project.service.ProjectTemplateService;
|
||||||
import io.metersphere.sdk.constants.PermissionConstants;
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
import io.metersphere.sdk.constants.TemplateScene;
|
import io.metersphere.sdk.constants.TemplateScene;
|
||||||
|
import io.metersphere.system.dto.OperationHistoryDTO;
|
||||||
|
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||||
import io.metersphere.system.dto.sdk.TemplateDTO;
|
import io.metersphere.system.dto.sdk.TemplateDTO;
|
||||||
import io.metersphere.system.dto.sdk.request.PosRequest;
|
import io.metersphere.system.dto.sdk.request.PosRequest;
|
||||||
import io.metersphere.system.log.annotation.Log;
|
import io.metersphere.system.log.annotation.Log;
|
||||||
|
@ -236,4 +238,14 @@ public class FunctionalCaseController {
|
||||||
String organizationId = SessionUtils.getCurrentOrganizationId();
|
String organizationId = SessionUtils.getCurrentOrganizationId();
|
||||||
return functionalCaseFileService.importExcel(request, userId, file, organizationId);
|
return functionalCaseFileService.importExcel(request, userId, file, organizationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/operation-history")
|
||||||
|
@Operation(summary = "用例管理-功能用例-变更历史")
|
||||||
|
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ)
|
||||||
|
@CheckOwner(resourceId = "#request.getSourceId()", resourceType = "functional_case")
|
||||||
|
public Pager<List<OperationHistoryDTO>> operationHistoryList(@Validated @RequestBody OperationHistoryRequest request) {
|
||||||
|
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
|
||||||
|
org.apache.commons.lang3.StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "create_time desc");
|
||||||
|
return PageUtils.setPageInfo(page, functionalCaseService.operationHistoryList(request));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,12 @@ import io.metersphere.sdk.constants.HttpMethodConstants;
|
||||||
import io.metersphere.sdk.constants.TemplateScene;
|
import io.metersphere.sdk.constants.TemplateScene;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.util.BeanUtils;
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
|
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
import io.metersphere.sdk.util.Translator;
|
import io.metersphere.sdk.util.Translator;
|
||||||
import io.metersphere.system.domain.CustomFieldOption;
|
import io.metersphere.system.domain.CustomFieldOption;
|
||||||
|
import io.metersphere.system.dto.OperationHistoryDTO;
|
||||||
|
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||||
import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO;
|
import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO;
|
||||||
import io.metersphere.system.dto.sdk.TemplateDTO;
|
import io.metersphere.system.dto.sdk.TemplateDTO;
|
||||||
|
@ -116,6 +119,8 @@ public class FunctionalCaseService {
|
||||||
private static final String UPDATE_FUNCTIONAL_CASE_FILE_LOG_URL = "/functional/case/update";
|
private static final String UPDATE_FUNCTIONAL_CASE_FILE_LOG_URL = "/functional/case/update";
|
||||||
private static final String FUNCTIONAL_CASE_BATCH_COPY_FILE_LOG_URL = "/functional/case/batch/copy";
|
private static final String FUNCTIONAL_CASE_BATCH_COPY_FILE_LOG_URL = "/functional/case/batch/copy";
|
||||||
|
|
||||||
|
private static final String CASE_TABLE = "functional_case";
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private FunctionalCaseDemandMapper functionalCaseDemandMapper;
|
private FunctionalCaseDemandMapper functionalCaseDemandMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -1030,4 +1035,12 @@ public class FunctionalCaseService {
|
||||||
FunctionalCaseHistoryLogDTO historyLogDTO = new FunctionalCaseHistoryLogDTO(functionalCase, functionalCaseBlob, customFields, caseAttachments, fileAssociationList);
|
FunctionalCaseHistoryLogDTO historyLogDTO = new FunctionalCaseHistoryLogDTO(functionalCase, functionalCaseBlob, customFields, caseAttachments, fileAssociationList);
|
||||||
return historyLogDTO;
|
return historyLogDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<OperationHistoryDTO> operationHistoryList(OperationHistoryRequest request) {
|
||||||
|
XpackFunctionalCaseService functionalCaseService = CommonBeanFactory.getBean(XpackFunctionalCaseService.class);
|
||||||
|
if (functionalCaseService != null) {
|
||||||
|
return functionalCaseService.listHis(request, CASE_TABLE);
|
||||||
|
}
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package io.metersphere.functional.service;
|
||||||
|
|
||||||
|
import io.metersphere.system.dto.OperationHistoryDTO;
|
||||||
|
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用例管理Xpack功能接口
|
||||||
|
*/
|
||||||
|
public interface XpackFunctionalCaseService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 功能用例变更历史分页列表
|
||||||
|
* @param request 请求参数
|
||||||
|
* @return 变更历史集合
|
||||||
|
*/
|
||||||
|
List<OperationHistoryDTO> listHis(OperationHistoryRequest request,String table);
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package io.metersphere.functional.config;
|
package io.metersphere.functional.config;
|
||||||
|
|
||||||
|
import io.metersphere.functional.service.XpackFunctionalCaseService;
|
||||||
import io.metersphere.provider.BaseAssociateApiProvider;
|
import io.metersphere.provider.BaseAssociateApiProvider;
|
||||||
import io.metersphere.provider.BaseAssociateBugProvider;
|
import io.metersphere.provider.BaseAssociateBugProvider;
|
||||||
import io.metersphere.provider.BaseAssociateScenarioProvider;
|
import io.metersphere.provider.BaseAssociateScenarioProvider;
|
||||||
|
@ -18,4 +19,7 @@ public class CaseTestConfiguration {
|
||||||
@MockBean
|
@MockBean
|
||||||
BaseAssociateBugProvider baseAssociateBugProvider;
|
BaseAssociateBugProvider baseAssociateBugProvider;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
XpackFunctionalCaseService xpackFunctionalCaseService;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,18 @@ import io.metersphere.sdk.util.Translator;
|
||||||
import io.metersphere.system.base.BaseTest;
|
import io.metersphere.system.base.BaseTest;
|
||||||
import io.metersphere.system.controller.handler.ResultHolder;
|
import io.metersphere.system.controller.handler.ResultHolder;
|
||||||
import io.metersphere.system.domain.CustomField;
|
import io.metersphere.system.domain.CustomField;
|
||||||
|
import io.metersphere.system.dto.OperationHistoryDTO;
|
||||||
|
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||||
import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO;
|
import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO;
|
||||||
import io.metersphere.system.dto.sdk.TemplateDTO;
|
import io.metersphere.system.dto.sdk.TemplateDTO;
|
||||||
import io.metersphere.system.dto.sdk.request.PosRequest;
|
import io.metersphere.system.dto.sdk.request.PosRequest;
|
||||||
import io.metersphere.system.mapper.CustomFieldMapper;
|
import io.metersphere.system.mapper.CustomFieldMapper;
|
||||||
import io.metersphere.system.notice.constants.NoticeConstants;
|
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||||
|
import io.metersphere.system.service.OperationHistoryService;
|
||||||
import io.metersphere.system.uid.IDGenerator;
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
import io.metersphere.system.utils.Pager;
|
import io.metersphere.system.utils.Pager;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
@ -73,6 +77,7 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
||||||
public static final String DOWNLOAD_EXCEL_TEMPLATE_URL = "/functional/case/download/excel/template/";
|
public static final String DOWNLOAD_EXCEL_TEMPLATE_URL = "/functional/case/download/excel/template/";
|
||||||
public static final String CHECK_EXCEL_URL = "/functional/case/pre-check/excel";
|
public static final String CHECK_EXCEL_URL = "/functional/case/pre-check/excel";
|
||||||
public static final String IMPORT_EXCEL_URL = "/functional/case/import/excel";
|
public static final String IMPORT_EXCEL_URL = "/functional/case/import/excel";
|
||||||
|
public static final String OPERATION_HISTORY_URL = "/functional/case/operation-history";
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private NotificationMapper notificationMapper;
|
private NotificationMapper notificationMapper;
|
||||||
|
@ -83,6 +88,11 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
||||||
private ProjectTemplateService projectTemplateService;
|
private ProjectTemplateService projectTemplateService;
|
||||||
@Resource
|
@Resource
|
||||||
private FunctionalCaseCustomFieldMapper functionalCaseCustomFieldMapper;
|
private FunctionalCaseCustomFieldMapper functionalCaseCustomFieldMapper;
|
||||||
|
@Resource
|
||||||
|
private OperationHistoryService operationHistoryService;
|
||||||
|
|
||||||
|
protected static String functionalCaseId;
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(1)
|
@Order(1)
|
||||||
|
@ -121,7 +131,6 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
||||||
String functionalCaseData = functionalCaseMvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
String functionalCaseData = functionalCaseMvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||||
ResultHolder functionalCaseResultHolder = JSON.parseObject(functionalCaseData, ResultHolder.class);
|
ResultHolder functionalCaseResultHolder = JSON.parseObject(functionalCaseData, ResultHolder.class);
|
||||||
FunctionalCase functionalCase = JSON.parseObject(JSON.toJSONString(functionalCaseResultHolder.getData()), FunctionalCase.class);
|
FunctionalCase functionalCase = JSON.parseObject(JSON.toJSONString(functionalCaseResultHolder.getData()), FunctionalCase.class);
|
||||||
|
|
||||||
NotificationExample notificationExample = new NotificationExample();
|
NotificationExample notificationExample = new NotificationExample();
|
||||||
notificationExample.createCriteria().andResourceNameEqualTo(functionalCase.getName()).andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
notificationExample.createCriteria().andResourceNameEqualTo(functionalCase.getName()).andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
||||||
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
|
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
|
||||||
|
@ -134,6 +143,7 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
||||||
paramMap.add("request", JSON.toJSONString(request));
|
paramMap.add("request", JSON.toJSONString(request));
|
||||||
paramMap.add("files", new LinkedMultiValueMap<>());
|
paramMap.add("files", new LinkedMultiValueMap<>());
|
||||||
functionalCaseMvcResult = this.requestMultipartWithOkAndReturn(FUNCTIONAL_CASE_ADD_URL, paramMap);
|
functionalCaseMvcResult = this.requestMultipartWithOkAndReturn(FUNCTIONAL_CASE_ADD_URL, paramMap);
|
||||||
|
functionalCaseId = functionalCase.getId();
|
||||||
// 获取返回值
|
// 获取返回值
|
||||||
returnData = functionalCaseMvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
returnData = functionalCaseMvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||||
resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||||
|
@ -631,4 +641,34 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
||||||
paramMap.add("file", file2);
|
paramMap.add("file", file2);
|
||||||
this.requestMultipart(IMPORT_EXCEL_URL, paramMap);
|
this.requestMultipart(IMPORT_EXCEL_URL, paramMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(22)
|
||||||
|
public void operationHistoryList() throws Exception {
|
||||||
|
OperationHistoryRequest request = new OperationHistoryRequest();
|
||||||
|
request.setSourceId(functionalCaseId);
|
||||||
|
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
|
request.setCurrent(1);
|
||||||
|
request.setPageSize(10);
|
||||||
|
request.setSort(Map.of("createTime", "asc"));
|
||||||
|
|
||||||
|
MvcResult mvcResult = this.requestPostWithOkAndReturn(OPERATION_HISTORY_URL, request);
|
||||||
|
// 获取返回值
|
||||||
|
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||||
|
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||||
|
// 返回请求正常
|
||||||
|
Assertions.assertNotNull(resultHolder);
|
||||||
|
Pager<?> pageData = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), Pager.class);
|
||||||
|
// 返回值不为空
|
||||||
|
Assertions.assertNotNull(pageData);
|
||||||
|
// 返回值的页码和当前页码相同
|
||||||
|
Assertions.assertEquals(pageData.getCurrent(), request.getCurrent());
|
||||||
|
// 返回的数据量不超过规定要返回的数据量相同
|
||||||
|
Assertions.assertTrue(JSON.parseArray(JSON.toJSONString(pageData.getList())).size() <= request.getPageSize());
|
||||||
|
request.setSort(Map.of());
|
||||||
|
this.requestPost(OPERATION_HISTORY_URL, request);
|
||||||
|
List<OperationHistoryDTO> operationHistoryDTOS = operationHistoryService.listWidthLimit(request, "functional_case");
|
||||||
|
Assertions.assertTrue(CollectionUtils.isNotEmpty(operationHistoryDTOS));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,4 +16,6 @@ public interface BaseOperationHistoryMapper {
|
||||||
void deleteByIds(@Param("sourceId") String sourceId, @Param("ids") List<Long> ids);
|
void deleteByIds(@Param("sourceId") String sourceId, @Param("ids") List<Long> ids);
|
||||||
|
|
||||||
List<OperationHistoryDTO> list(@Param("request") OperationHistoryRequest request);
|
List<OperationHistoryDTO> list(@Param("request") OperationHistoryRequest request);
|
||||||
|
|
||||||
|
List<OperationHistoryDTO> listWidthLimit(@Param("request") OperationHistoryRequest request, @Param("table") String table);
|
||||||
}
|
}
|
|
@ -40,4 +40,28 @@
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="listWidthLimit" resultType="io.metersphere.system.dto.OperationHistoryDTO">
|
||||||
|
SELECT operation_history.id, operation_history.project_id, operation_history.create_time, operation_history.create_user, operation_history.source_id, operation_history.`type`, operation_history.`module`, operation_history.ref_id, project_version.name as versionName
|
||||||
|
FROM operation_history
|
||||||
|
LEFT JOIN ${table} sourceTable ON sourceTable.id = operation_history.source_id
|
||||||
|
LEFT JOIN project_version ON project_version.id = sourceTable.version_id
|
||||||
|
<where>
|
||||||
|
<if test="request.projectId != null and request.projectId != ''">
|
||||||
|
AND operation_history.project_id = #{request.projectId,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="request.sourceId != null and request.sourceId != ''">
|
||||||
|
AND operation_history.source_id = #{request.sourceId,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="request.createUser != null and request.createUser != ''">
|
||||||
|
AND operation_history.create_user = #{request.createUser,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="request.type != null and request.type != ''">
|
||||||
|
AND operation_history.`type` = #{request.type,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="request.module != null and request.module != ''">
|
||||||
|
AND operation_history.`module` = #{request.module,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
@ -46,6 +46,23 @@ public class OperationHistoryService {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<OperationHistoryDTO> listWidthLimit(OperationHistoryRequest request, String table) {
|
||||||
|
List<OperationHistoryDTO> list = baseOperationHistoryMapper.listWidthLimit(request, table);
|
||||||
|
if (CollectionUtils.isNotEmpty(list)) {
|
||||||
|
List<String> userIds = list.stream().distinct()
|
||||||
|
.map(OperationHistoryDTO::getCreateUser).toList();
|
||||||
|
|
||||||
|
Map<String, String> userMap = baseUserMapper.selectUserOptionByIds(userIds).stream()
|
||||||
|
.collect(Collectors.toMap(OptionDTO::getId, OptionDTO::getName));
|
||||||
|
|
||||||
|
list.forEach(item -> item.setCreateUserName(userMap.getOrDefault(item.getCreateUser(), StringUtils.EMPTY)));
|
||||||
|
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void associationRefId(Long refLogId, Long logId) {
|
public void associationRefId(Long refLogId, Long logId) {
|
||||||
OperationHistory operationHistory = operationHistoryMapper.selectByPrimaryKey(logId);
|
OperationHistory operationHistory = operationHistoryMapper.selectByPrimaryKey(logId);
|
||||||
operationHistory.setRefId(refLogId);
|
operationHistory.setRefId(refLogId);
|
||||||
|
|
Loading…
Reference in New Issue