feat(用例管理): 批量复制&批量移动&表头/高级搜索自定义字段选项接口
This commit is contained in:
parent
ea1a654c5d
commit
c322f69f2c
|
@ -11,6 +11,7 @@ import io.metersphere.functional.request.*;
|
|||
import io.metersphere.functional.service.FunctionalCaseLogService;
|
||||
import io.metersphere.functional.service.FunctionalCaseNoticeService;
|
||||
import io.metersphere.functional.service.FunctionalCaseService;
|
||||
import io.metersphere.project.dto.CustomFieldOptions;
|
||||
import io.metersphere.project.service.ProjectTemplateService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.constants.TemplateScene;
|
||||
|
@ -144,4 +145,29 @@ public class FunctionalCaseController {
|
|||
String userId = SessionUtils.getUserId();
|
||||
functionalCaseService.batchDeleteFunctionalCaseToGc(request, userId);
|
||||
}
|
||||
|
||||
@GetMapping("/custom/field/{projectId}")
|
||||
@Operation(summary = "功能用例-获取表头自定义字段(高级搜索中的自定义字段)")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ)
|
||||
public List<CustomFieldOptions> getTableCustomsField(@PathVariable String projectId) {
|
||||
return projectTemplateService.getTableCustomsField(projectId, TemplateScene.FUNCTIONAL.name());
|
||||
}
|
||||
|
||||
@PostMapping("/batch/move")
|
||||
@Operation(summary = "功能用例-批量移动用例")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE)
|
||||
public void batchMoveFunctionalCase(@Validated @RequestBody FunctionalCaseBatchMoveRequest request) {
|
||||
String userId = SessionUtils.getUserId();
|
||||
functionalCaseService.batchMoveFunctionalCase(request, userId);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/batch/copy")
|
||||
@Operation(summary = "功能用例-批量复制用例")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE)
|
||||
public void batchCopyFunctionalCase(@Validated @RequestBody FunctionalCaseBatchMoveRequest request) {
|
||||
String userId = SessionUtils.getUserId();
|
||||
functionalCaseService.batchCopyFunctionalCase(request, userId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ public class FunctionalCaseDetailDTO implements Serializable {
|
|||
@Schema(description = "模块ID")
|
||||
private String moduleId;
|
||||
|
||||
@Schema(description = "模块名称")
|
||||
private String moduleName;
|
||||
|
||||
@Schema(description = "项目ID")
|
||||
private String projectId;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.functional.mapper;
|
|||
import io.metersphere.functional.domain.FunctionalCase;
|
||||
import io.metersphere.functional.dto.FunctionalCasePageDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseVersionDTO;
|
||||
import io.metersphere.functional.request.FunctionalCaseBatchMoveRequest;
|
||||
import io.metersphere.functional.request.FunctionalCasePageRequest;
|
||||
import io.metersphere.system.dto.table.TableBatchProcessDTO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
@ -38,4 +39,6 @@ public interface ExtFunctionalCaseMapper {
|
|||
List<FunctionalCase> getLogInfo(@Param("ids") List<String> ids);
|
||||
|
||||
List<String> getRefIds(@Param("ids") List<String> ids);
|
||||
|
||||
void batchMoveModule(@Param("request") FunctionalCaseBatchMoveRequest request, @Param("ids") List<String> ids, @Param("userId") String userId);
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
id,
|
||||
num,
|
||||
NAME,
|
||||
module_id,
|
||||
version_id,
|
||||
create_user,
|
||||
create_time,
|
||||
|
@ -212,7 +213,7 @@
|
|||
and ${versionTable}.ref_id = #{request.refId}
|
||||
</if>
|
||||
<if test="request.versionId == null and request.refId == null">
|
||||
AND ${versionTable}.latest = 0
|
||||
AND ${versionTable}.latest = 1
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
|
@ -289,4 +290,18 @@
|
|||
</foreach>
|
||||
and deleted = false
|
||||
</select>
|
||||
|
||||
|
||||
<update id="batchMoveModule">
|
||||
update functional_case
|
||||
set module_id = #{request.moduleId},
|
||||
update_user = #{userId},
|
||||
update_time = UNIX_TIMESTAMP()*1000
|
||||
where ref_id in
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
and deleted = false
|
||||
and project_id = #{request.projectId}
|
||||
</update>
|
||||
</mapper>
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.functional.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author wx
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class FunctionalCaseBatchMoveRequest extends FunctionalCaseBatchRequest {
|
||||
|
||||
@Schema(description = "模块ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String moduleId;
|
||||
}
|
|
@ -27,7 +27,10 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -197,4 +200,26 @@ public class FunctionalCaseAttachmentService {
|
|||
functionalCaseAttachmentMapper.deleteByExample(example);
|
||||
deleteMinioFile(localAttachment, projectId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过caseId获取附件信息
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
public Map<String, List<FunctionalCaseAttachment>> getAttachmentByCaseIds(List<String> ids) {
|
||||
FunctionalCaseAttachmentExample example = new FunctionalCaseAttachmentExample();
|
||||
example.createCriteria().andCaseIdIn(ids);
|
||||
List<FunctionalCaseAttachment> caseAttachments = functionalCaseAttachmentMapper.selectByExample(example);
|
||||
Map<String, List<FunctionalCaseAttachment>> attachmentMap = new HashMap<>();
|
||||
if (CollectionUtils.isNotEmpty(caseAttachments)) {
|
||||
attachmentMap = caseAttachments.stream().collect(Collectors.groupingBy(FunctionalCaseAttachment::getCaseId));
|
||||
}
|
||||
return attachmentMap;
|
||||
}
|
||||
|
||||
public void batchSaveAttachment(List<FunctionalCaseAttachment> attachments) {
|
||||
functionalCaseAttachmentMapper.batchInsert(attachments);
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -107,4 +108,17 @@ public class FunctionalCaseCustomFieldService {
|
|||
public List<FunctionalCaseCustomField> getCustomFieldByCaseIds(List<String> ids) {
|
||||
return extFunctionalCaseCustomFieldMapper.getCustomFieldByCaseIds(ids);
|
||||
}
|
||||
|
||||
public Map<String, List<FunctionalCaseCustomField>> getCustomFieldMapByCaseIds(List<String> ids) {
|
||||
List<FunctionalCaseCustomField> customFieldList = getCustomFieldByCaseIds(ids);
|
||||
Map<String, List<FunctionalCaseCustomField>> caseCustomFieldMap = new HashMap<>();
|
||||
if (CollectionUtils.isNotEmpty(customFieldList)) {
|
||||
caseCustomFieldMap = customFieldList.stream().collect(Collectors.groupingBy(FunctionalCaseCustomField::getCaseId));
|
||||
}
|
||||
return caseCustomFieldMap;
|
||||
}
|
||||
|
||||
public void batchSaveCustomField(List<FunctionalCaseCustomField> customFields) {
|
||||
functionalCaseCustomFieldMapper.batchInsert(customFields);
|
||||
}
|
||||
}
|
|
@ -26,6 +26,10 @@ import io.metersphere.system.uid.NumGenerator;
|
|||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
@ -67,6 +71,9 @@ public class FunctionalCaseService {
|
|||
@Resource
|
||||
private DeleteFunctionalCaseService deleteFunctionalCaseService;
|
||||
|
||||
@Resource
|
||||
SqlSessionFactory sqlSessionFactory;
|
||||
|
||||
public FunctionalCase addFunctionalCase(FunctionalCaseAddRequest request, List<MultipartFile> files, String userId) {
|
||||
String caseId = IDGenerator.nextStr();
|
||||
//添加功能用例
|
||||
|
@ -407,4 +414,121 @@ public class FunctionalCaseService {
|
|||
return request.getSelectIds();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量移动用例
|
||||
*
|
||||
* @param request
|
||||
* @param userId
|
||||
*/
|
||||
public void batchMoveFunctionalCase(FunctionalCaseBatchMoveRequest request, String userId) {
|
||||
List<String> ids = doSelectIds(request, request.getProjectId());
|
||||
if (CollectionUtils.isNotEmpty(ids)) {
|
||||
List<String> refId = extFunctionalCaseMapper.getRefIds(ids);
|
||||
extFunctionalCaseMapper.batchMoveModule(request, refId, userId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量复制用例
|
||||
*
|
||||
* @param request
|
||||
* @param userId
|
||||
*/
|
||||
public void batchCopyFunctionalCase(FunctionalCaseBatchMoveRequest request, String userId) {
|
||||
List<String> ids = doSelectIds(request, request.getProjectId());
|
||||
if (CollectionUtils.isNotEmpty(ids)) {
|
||||
//基本信息
|
||||
Map<String, FunctionalCase> functionalCaseMap = copyBaseInfo(request.getProjectId(), ids);
|
||||
//大字段
|
||||
Map<String, FunctionalCaseBlob> functionalCaseBlobMap = copyBlobInfo(ids);
|
||||
//附件 本地附件
|
||||
Map<String, List<FunctionalCaseAttachment>> attachmentMap = functionalCaseAttachmentService.getAttachmentByCaseIds(ids);
|
||||
//TODO 文件库附件
|
||||
//自定义字段
|
||||
Map<String, List<FunctionalCaseCustomField>> customFieldMap = functionalCaseCustomFieldService.getCustomFieldMapByCaseIds(ids);
|
||||
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
FunctionalCaseMapper mapper = sqlSession.getMapper(FunctionalCaseMapper.class);
|
||||
Long nextOrder = getNextOrder(request.getProjectId());
|
||||
|
||||
try {
|
||||
for (int i = 0; i < ids.size(); i++) {
|
||||
String id = IDGenerator.nextStr();
|
||||
FunctionalCase functionalCase = functionalCaseMap.get(ids.get(i));
|
||||
FunctionalCaseBlob functionalCaseBlob = functionalCaseBlobMap.get(ids.get(i));
|
||||
List<FunctionalCaseAttachment> caseAttachments = attachmentMap.get(ids.get(i));
|
||||
List<FunctionalCaseCustomField> customFields = customFieldMap.get(ids.get(i));
|
||||
|
||||
Optional.ofNullable(functionalCase).ifPresent(functional -> {
|
||||
functional.setId(id);
|
||||
functional.setRefId(id);
|
||||
functional.setModuleId(request.getModuleId());
|
||||
functional.setNum(getNextNum(request.getProjectId()));
|
||||
functional.setName(getCopyName(functionalCase.getName()));
|
||||
functional.setReviewStatus(FunctionalCaseReviewStatus.UN_REVIEWED.name());
|
||||
functional.setPos(nextOrder + ORDER_STEP);
|
||||
functional.setLastExecuteResult(FunctionalCaseExecuteResult.UN_EXECUTED.name());
|
||||
functional.setCreateUser(userId);
|
||||
functional.setCreateTime(System.currentTimeMillis());
|
||||
functional.setUpdateTime(System.currentTimeMillis());
|
||||
mapper.insert(functional);
|
||||
|
||||
functionalCaseBlob.setId(id);
|
||||
functionalCaseBlobMapper.insert(functionalCaseBlob);
|
||||
});
|
||||
|
||||
if (CollectionUtils.isNotEmpty(caseAttachments)) {
|
||||
caseAttachments.stream().forEach(attachment -> {
|
||||
attachment.setId(IDGenerator.nextStr());
|
||||
attachment.setCaseId(id);
|
||||
attachment.setCreateUser(userId);
|
||||
attachment.setCreateTime(System.currentTimeMillis());
|
||||
});
|
||||
functionalCaseAttachmentService.batchSaveAttachment(caseAttachments);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(customFields)) {
|
||||
customFields.stream().forEach(customField -> {
|
||||
customField.setCaseId(id);
|
||||
});
|
||||
functionalCaseCustomFieldService.batchSaveCustomField(customFields);
|
||||
}
|
||||
|
||||
if (i % 50 == 0) {
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
} finally {
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getCopyName(String name) {
|
||||
String copyName = "copy_" + name + "_" + UUID.randomUUID().toString().substring(0, 4);
|
||||
if (copyName.length() > 255) {
|
||||
copyName = copyName.substring(0, 250) + copyName.substring(copyName.length() - 5);
|
||||
}
|
||||
return copyName;
|
||||
}
|
||||
|
||||
|
||||
private Map<String, FunctionalCaseBlob> copyBlobInfo(List<String> ids) {
|
||||
FunctionalCaseBlobExample blobExample = new FunctionalCaseBlobExample();
|
||||
blobExample.createCriteria().andIdIn(ids);
|
||||
List<FunctionalCaseBlob> functionalCaseBlobs = functionalCaseBlobMapper.selectByExampleWithBLOBs(blobExample);
|
||||
Map<String, FunctionalCaseBlob> functionalCaseBlobMap = functionalCaseBlobs.stream().collect(Collectors.toMap(FunctionalCaseBlob::getId, functionalCaseBlob -> functionalCaseBlob));
|
||||
return functionalCaseBlobMap;
|
||||
}
|
||||
|
||||
private Map<String, FunctionalCase> copyBaseInfo(String projectId, List<String> ids) {
|
||||
FunctionalCaseExample example = new FunctionalCaseExample();
|
||||
example.createCriteria().andProjectIdEqualTo(projectId).andDeletedEqualTo(false).andIdIn(ids);
|
||||
List<FunctionalCase> functionalCaseLists = functionalCaseMapper.selectByExample(example);
|
||||
Map<String, FunctionalCase> functionalMap = functionalCaseLists.stream().collect(Collectors.toMap(FunctionalCase::getId, functionalCase -> functionalCase));
|
||||
return functionalMap;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,9 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
|||
public static final String FUNCTIONAL_CASE_DELETE_URL = "/functional/case/delete";
|
||||
public static final String FUNCTIONAL_CASE_LIST_URL = "/functional/case/page";
|
||||
public static final String FUNCTIONAL_CASE_BATCH_DELETE_URL = "/functional/case/batch/delete-to-gc";
|
||||
public static final String FUNCTIONAL_CASE_TABLE_URL = "/functional/case/custom/field/";
|
||||
public static final String FUNCTIONAL_CASE_BATCH_MOVE_URL = "/functional/case/batch/move";
|
||||
public static final String FUNCTIONAL_CASE_BATCH_COPY_URL = "/functional/case/batch/copy";
|
||||
|
||||
@Resource
|
||||
private NotificationMapper notificationMapper;
|
||||
|
@ -280,7 +283,7 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
|||
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
@Order(19)
|
||||
public void testDeleteFunctionalCase() throws Exception {
|
||||
FunctionalCaseDeleteRequest request = new FunctionalCaseDeleteRequest();
|
||||
request.setId("TEST_FUNCTIONAL_CASE_ID");
|
||||
|
@ -301,7 +304,7 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
|||
|
||||
|
||||
@Test
|
||||
@Order(7)
|
||||
@Order(20)
|
||||
public void testBatchDelete() throws Exception {
|
||||
FunctionalCaseBatchRequest request = new FunctionalCaseBatchRequest();
|
||||
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||
|
@ -315,4 +318,37 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
|||
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_DELETE_URL, request);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(7)
|
||||
public void testTableCustomField() throws Exception {
|
||||
this.requestGetWithOkAndReturn(FUNCTIONAL_CASE_TABLE_URL + DEFAULT_PROJECT_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4)
|
||||
public void testBatchMove() throws Exception {
|
||||
FunctionalCaseBatchMoveRequest request = new FunctionalCaseBatchMoveRequest();
|
||||
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||
request.setModuleId("TEST_MOVE_MODULE_ID");
|
||||
request.setSelectAll(false);
|
||||
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_MOVE_URL, request);
|
||||
request.setSelectAll(true);
|
||||
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_MOVE_URL, request);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
public void testBatchCopy() throws Exception {
|
||||
FunctionalCaseBatchMoveRequest request = new FunctionalCaseBatchMoveRequest();
|
||||
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||
request.setModuleId("TEST_MOVE_MODULE_ID");
|
||||
request.setSelectIds(Arrays.asList("TEST"));
|
||||
request.setSelectAll(false);
|
||||
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_COPY_URL, request);
|
||||
request.setSelectIds(new ArrayList<>());
|
||||
request.setSelectAll(true);
|
||||
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_COPY_URL, request);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@ VALUES ('xiaomeinvGTestOne', 1000001, 'test_guo', '100001100001', 'test_guo', 'g
|
|||
1698058347559,
|
||||
null);
|
||||
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('xiaomeinvGTest', 'STEP', '1111', NULL, NULL, 'TEST');
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('xiaomeinvGTestOne', 'STEP', '1111', NULL, NULL, 'TEST');
|
||||
|
||||
INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
|
||||
last_project_id, create_user, update_user, deleted)
|
||||
VALUES ('default-project-member-user-guo', 'default-project-member-user1', 'project-member-guo1@metersphere.io',
|
||||
|
|
|
@ -26,4 +26,11 @@ INSERT INTO custom_field(id, name, scene, `type`, remark, internal, scope_type,
|
|||
VALUES('gyq_custom_id2', 'level', 'FUNCTIONAL', 'SELECT', '', 1, 'ORGANIZATION', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', '100001');
|
||||
|
||||
INSERT INTO functional_case_comment(id, case_id, create_user, status, parent_id, resource_id, notifier, content, reply_user, create_time, update_time)
|
||||
VALUES ('trash_comment_id', 'Trash_TEST_FUNCTIONAL_CASE_ID', 'gyq', null, null, null, 'gyq','你好', null, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000);
|
||||
VALUES ('trash_comment_id', 'Trash_TEST_FUNCTIONAL_CASE_ID', 'gyq', null, null, null, 'gyq','你好', null, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000);
|
||||
|
||||
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID', 'STEP', '1111', NULL, NULL, 'TEST');
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID_1', 'STEP', '1111', NULL, NULL, 'TEST');
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID_2', 'STEP', '1111', NULL, NULL, 'TEST');
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID_3', 'STEP', '1111', NULL, NULL, 'TEST');
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('Trash_TEST_FUNCTIONAL_CASE_ID_4', 'STEP', '1111', NULL, NULL, 'TEST');
|
|
@ -2,30 +2,37 @@ INSERT INTO file_metadata(id, name, type, size, create_time, update_time, projec
|
|||
INSERT INTO file_metadata(id, name, type, size, create_time, update_time, project_id, storage, create_user, update_user, tags, description, module_id, path, latest, ref_id, file_version) VALUES ('relate_file_meta_id_2', 'formItem', 'ts', 2502, 1698058347559, 1698058347559, '100001100001', 'MINIO', 'admin', 'admin', NULL, NULL, 'root', '100001100001/1127016598347779', b'1', '1127016598347779', '1127016598347779');
|
||||
|
||||
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID', 1, 'TEST_MOUDLE_ID', '100001100001', '100001', '测试', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'v1.0.0', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID', 1, 'TEST_MOUDLE_ID', '100001100001', '100001', '测试', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'v1.0.0', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
|
||||
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_1', 2, 'TEST_MOUDLE_ID', '100001100001', '100001', '测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_1', 2, 'TEST_MOUDLE_ID', '100001100001', '100001', '测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
|
||||
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_2', 3, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v2.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_2', 3, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v2.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
|
||||
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_3', 3, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_3', 3, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
|
||||
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_4', 4, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_4', 4, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
|
||||
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_5', 5, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID_1', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_5', 5, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID_1', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
|
||||
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_6', 6, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID_1', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_6', 6, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID_1', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
|
||||
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_7', 7, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID_2', 'UN_EXECUTED', b'0', b'0', b'0', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
VALUES ('TEST_FUNCTIONAL_CASE_ID_7', 7, 'TEST_MOUDLE_ID', '100001100001', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 0, 'v3.0.0', 'TEST_REF_ID_2', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
|
||||
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_CASE_ID', 'STEP', '1111', NULL, NULL, 'TEST');
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_CASE_ID_1', 'STEP', '1111', NULL, NULL, '1111');
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_CASE_ID_2', 'STEP', '2222', NULL, NULL, '2222');
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_CASE_ID_3', 'STEP', '3333', NULL, NULL, '3333');
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_CASE_ID_4', 'STEP', '4444', NULL, NULL, '4444');
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_CASE_ID_5', 'STEP', '5555', NULL, NULL, '5555');
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_CASE_ID_6', 'STEP', '6666', NULL, NULL, '6666');
|
||||
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_CASE_ID_7', 'STEP', '7777', NULL, NULL, '7777');
|
||||
|
||||
|
||||
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('TEST_FUNCTIONAL_CASE_ID', '100548878725546079', '22');
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package io.metersphere.project.dto;
|
||||
|
||||
import io.metersphere.system.domain.CustomFieldOption;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wx
|
||||
*/
|
||||
@Data
|
||||
public class CustomFieldOptions implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "ID")
|
||||
private String id;
|
||||
|
||||
@Schema(description = "自定义字段名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "自定义字段类型")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "是否内置字段")
|
||||
private Boolean internal;
|
||||
|
||||
@Schema(description = "自定义字段选项值")
|
||||
private List<CustomFieldOption> options;
|
||||
}
|
|
@ -3,27 +3,27 @@ package io.metersphere.project.service;
|
|||
import io.metersphere.plugin.platform.spi.Platform;
|
||||
import io.metersphere.plugin.sdk.spi.MsPlugin;
|
||||
import io.metersphere.project.domain.ProjectApplication;
|
||||
import io.metersphere.project.dto.CustomFieldOptions;
|
||||
import io.metersphere.project.dto.ProjectTemplateDTO;
|
||||
import io.metersphere.project.dto.ProjectTemplateOptionDTO;
|
||||
import io.metersphere.sdk.constants.InternalUser;
|
||||
import io.metersphere.sdk.constants.ProjectApplicationType;
|
||||
import io.metersphere.sdk.constants.TemplateScene;
|
||||
import io.metersphere.sdk.constants.TemplateScopeType;
|
||||
import io.metersphere.system.dto.sdk.TemplateDTO;
|
||||
import io.metersphere.system.dto.sdk.request.TemplateCustomFieldRequest;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.Plugin;
|
||||
import io.metersphere.system.domain.ServiceIntegration;
|
||||
import io.metersphere.system.domain.Template;
|
||||
import io.metersphere.system.domain.TemplateExample;
|
||||
import io.metersphere.system.domain.*;
|
||||
import io.metersphere.system.dto.ProjectDTO;
|
||||
import io.metersphere.system.dto.sdk.TemplateDTO;
|
||||
import io.metersphere.system.dto.sdk.request.TemplateCustomFieldRequest;
|
||||
import io.metersphere.system.mapper.CustomFieldOptionMapper;
|
||||
import io.metersphere.system.service.BaseTemplateService;
|
||||
import io.metersphere.system.service.PlatformPluginService;
|
||||
import io.metersphere.system.service.PluginLoadService;
|
||||
import io.metersphere.system.service.ServiceIntegrationService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -55,6 +55,9 @@ public class ProjectTemplateService extends BaseTemplateService {
|
|||
@Resource
|
||||
private ProjectApplicationService projectApplicationService;
|
||||
|
||||
@Resource
|
||||
private CustomFieldOptionMapper customFieldOptionMapper;
|
||||
|
||||
@Override
|
||||
public List list(String projectId, String scene) {
|
||||
projectService.checkResourceExist(projectId);
|
||||
|
@ -382,4 +385,41 @@ public class ProjectTemplateService extends BaseTemplateService {
|
|||
templateEnableConfig.put(scene.name(), !isOrganizationTemplateEnable(project.getOrganizationId(), scene.name())));
|
||||
return templateEnableConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表头可设置自定义字段(接口提供)
|
||||
* @param projectId
|
||||
* @param scene
|
||||
* @return
|
||||
*/
|
||||
public List<CustomFieldOptions> getTableCustomsField(String projectId, String scene) {
|
||||
TemplateExample example = new TemplateExample();
|
||||
example.createCriteria().andScopeIdEqualTo(projectId).andSceneEqualTo(scene);
|
||||
List<Template> templates = templateMapper.selectByExample(example);
|
||||
if (CollectionUtils.isNotEmpty(templates)) {
|
||||
List<String> templateIds = templates.stream().map(Template::getId).collect(Collectors.toList());
|
||||
List<TemplateCustomField> fieldList = baseTemplateCustomFieldService.getByTemplateIds(templateIds);
|
||||
List<String> fieldIds = fieldList.stream().map(TemplateCustomField::getFieldId).distinct().collect(Collectors.toList());
|
||||
List<CustomField> customFields = baseCustomFieldService.getByIds(fieldIds);
|
||||
CustomFieldOptionExample optionExample = new CustomFieldOptionExample();
|
||||
optionExample.createCriteria().andFieldIdIn(fieldIds);
|
||||
List<CustomFieldOption> customFieldOptions = customFieldOptionMapper.selectByExample(optionExample);
|
||||
Map<String, List<CustomFieldOption>> optionMap = customFieldOptions.stream().collect(Collectors.groupingBy(CustomFieldOption::getFieldId));
|
||||
List<CustomFieldOptions> collect = customFields.stream().map(customField -> {
|
||||
CustomFieldOptions optionDTO = new CustomFieldOptions();
|
||||
optionDTO.setId(customField.getId());
|
||||
if (customField.getInternal()) {
|
||||
customField.setName(baseCustomFieldService.translateInternalField(customField.getName()));
|
||||
} else {
|
||||
optionDTO.setName(customField.getName());
|
||||
}
|
||||
optionDTO.setOptions(optionMap.get(customField.getId()));
|
||||
optionDTO.setInternal(customField.getInternal());
|
||||
optionDTO.setType(customField.getType());
|
||||
return optionDTO;
|
||||
}).collect(Collectors.toList());
|
||||
return collect;
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
|
@ -467,4 +467,13 @@ public class ProjectTemplateControllerTests extends BaseTest {
|
|||
projectTemplateService.getTemplateDTOById("test_template_id", DEFAULT_PROJECT_ID, TemplateScene.FUNCTIONAL.name());
|
||||
projectTemplateService.getTemplateDTOById("test_template_id_1", "test_project_id_1", TemplateScene.FUNCTIONAL.name());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
public void getCustomFields() throws Exception {
|
||||
projectTemplateService.getTableCustomsField("DEFAULT_PROJECT_ID", TemplateScene.FUNCTIONAL.name());
|
||||
projectTemplateService.getTableCustomsField(DEFAULT_PROJECT_ID, TemplateScene.FUNCTIONAL.name());
|
||||
projectTemplateService.getTableCustomsField("test_project_id_2", TemplateScene.FUNCTIONAL.name());
|
||||
}
|
||||
}
|
|
@ -1,2 +1,10 @@
|
|||
INSERT INTO template (id, name, remark, internal, update_time, create_time, create_user, scope_type, scope_id, enable_third_part, ref_id, scene)
|
||||
VALUES ('test_template_id_1', 'functional_default', '', b'1', 1696992836000, 1696992836000, 'admin', 'ORGANIZATION', 'test_project_id_1', b'0', NULL, 'FUNCTIONAL');
|
||||
VALUES ('test_template_id_1', 'functional_default', '', b'1', 1696992836000, 1696992836000, 'admin', 'ORGANIZATION', 'test_project_id_1', b'0', NULL, 'FUNCTIONAL');
|
||||
|
||||
|
||||
INSERT INTO template (id, name, remark, internal, update_time, create_time, create_user, scope_type, scope_id, enable_third_part, ref_id, scene)
|
||||
VALUES ('test_template_id_2', 'functional_default', '', b'0', 1696992836000, 1696992836000, 'admin', 'ORGANIZATION', 'test_project_id_2', b'0', NULL, 'FUNCTIONAL');
|
||||
|
||||
INSERT INTO template_custom_field(id, field_id, template_id, required, pos, api_field_id, default_value) VALUES ('100555929702891957', '100555929702891955', 'test_template_id_2', b'1', 0, NULL, NULL);
|
||||
|
||||
INSERT INTO custom_field(id, name, scene, type, remark, internal, scope_type, create_time, update_time, create_user, ref_id, enable_option_key, scope_id) VALUES ('100555929702891955', '测试自定义字段', 'FUNCTIONAL', 'SELECT', '', b'0', 'ORGANIZATION', 1698810592000, 1698810592000, 'admin', NULL, b'0', '100001');
|
||||
|
|
Loading…
Reference in New Issue