From 86ce86649a189a9d309cfd094206a650ff85c21a Mon Sep 17 00:00:00 2001 From: WangXu10 Date: Fri, 24 Nov 2023 15:13:03 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E7=94=A8=E4=BE=8B=E7=AE=A1=E7=90=86):?= =?UTF-8?q?=20=E8=A1=A5=E5=85=85=E6=89=B9=E9=87=8F=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E7=9B=B8=E5=85=B3=E9=99=84=E4=BB=B6=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91&=E5=8F=98=E6=9B=B4=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/FunctionalCaseHistory.java | 8 + .../domain/FunctionalCaseHistoryExample.java | 140 ++++++++++++++++++ .../mapper/FunctionalCaseHistoryMapper.xml | 56 ++++++- .../3.0.0/ddl/V3.0.0_10__functional_case.sql | 2 + .../constants/FunctionalCaseReviewStatus.java | 2 +- .../FunctionalCaseAttachmentController.java | 2 - .../functional/service/CaseReviewService.java | 2 +- .../FunctionalCaseAttachmentService.java | 18 ++- .../service/FunctionalCaseHistoryService.java | 7 + .../service/FunctionalCaseService.java | 119 ++++++++------- .../FunctionalCaseControllerTests.java | 2 +- .../FunctionalCaseModuleControllerTests.java | 2 +- .../resources/dml/init_file_metadata_test.sql | 2 +- .../mapper/ExtFileAssociationMapper.java | 3 + .../mapper/ExtFileAssociationMapper.xml | 9 +- .../service/FileAssociationService.java | 4 + .../FileManagementControllerTests.java | 1 + 17 files changed, 305 insertions(+), 74 deletions(-) rename backend/{framework/sdk/src/main/java/io/metersphere/sdk => services/case-management/src/main/java/io/metersphere/functional}/constants/FunctionalCaseReviewStatus.java (76%) create mode 100644 backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseHistoryService.java diff --git a/backend/framework/domain/src/main/java/io/metersphere/functional/domain/FunctionalCaseHistory.java b/backend/framework/domain/src/main/java/io/metersphere/functional/domain/FunctionalCaseHistory.java index 20c1d0c840..1fbdf61f63 100644 --- a/backend/framework/domain/src/main/java/io/metersphere/functional/domain/FunctionalCaseHistory.java +++ b/backend/framework/domain/src/main/java/io/metersphere/functional/domain/FunctionalCaseHistory.java @@ -26,6 +26,12 @@ public class FunctionalCaseHistory implements Serializable { @Schema(description = "变更记录批次号", requiredMode = Schema.RequiredMode.REQUIRED) private Integer num; + @Schema(description = "变更类型;IMPORT/EDIT/ROLLBACK", requiredMode = Schema.RequiredMode.REQUIRED) + private String type; + + @Schema(description = "回退来源") + private String rollbackSourceId; + @Schema(description = "操作人") private String createUser; @@ -42,6 +48,8 @@ public class FunctionalCaseHistory implements Serializable { id("id", "id", "VARCHAR", false), caseId("case_id", "caseId", "VARCHAR", false), num("num", "num", "INTEGER", false), + type("type", "type", "VARCHAR", true), + rollbackSourceId("rollback_source_id", "rollbackSourceId", "VARCHAR", false), createUser("create_user", "createUser", "VARCHAR", false), createTime("create_time", "createTime", "BIGINT", false), content("content", "content", "LONGVARBINARY", false); diff --git a/backend/framework/domain/src/main/java/io/metersphere/functional/domain/FunctionalCaseHistoryExample.java b/backend/framework/domain/src/main/java/io/metersphere/functional/domain/FunctionalCaseHistoryExample.java index daa3b7fb3d..366fe3ddb9 100644 --- a/backend/framework/domain/src/main/java/io/metersphere/functional/domain/FunctionalCaseHistoryExample.java +++ b/backend/framework/domain/src/main/java/io/metersphere/functional/domain/FunctionalCaseHistoryExample.java @@ -304,6 +304,146 @@ public class FunctionalCaseHistoryExample { return (Criteria) this; } + public Criteria andTypeIsNull() { + addCriterion("`type` is null"); + return (Criteria) this; + } + + public Criteria andTypeIsNotNull() { + addCriterion("`type` is not null"); + return (Criteria) this; + } + + public Criteria andTypeEqualTo(String value) { + addCriterion("`type` =", value, "type"); + return (Criteria) this; + } + + public Criteria andTypeNotEqualTo(String value) { + addCriterion("`type` <>", value, "type"); + return (Criteria) this; + } + + public Criteria andTypeGreaterThan(String value) { + addCriterion("`type` >", value, "type"); + return (Criteria) this; + } + + public Criteria andTypeGreaterThanOrEqualTo(String value) { + addCriterion("`type` >=", value, "type"); + return (Criteria) this; + } + + public Criteria andTypeLessThan(String value) { + addCriterion("`type` <", value, "type"); + return (Criteria) this; + } + + public Criteria andTypeLessThanOrEqualTo(String value) { + addCriterion("`type` <=", value, "type"); + return (Criteria) this; + } + + public Criteria andTypeLike(String value) { + addCriterion("`type` like", value, "type"); + return (Criteria) this; + } + + public Criteria andTypeNotLike(String value) { + addCriterion("`type` not like", value, "type"); + return (Criteria) this; + } + + public Criteria andTypeIn(List values) { + addCriterion("`type` in", values, "type"); + return (Criteria) this; + } + + public Criteria andTypeNotIn(List values) { + addCriterion("`type` not in", values, "type"); + return (Criteria) this; + } + + public Criteria andTypeBetween(String value1, String value2) { + addCriterion("`type` between", value1, value2, "type"); + return (Criteria) this; + } + + public Criteria andTypeNotBetween(String value1, String value2) { + addCriterion("`type` not between", value1, value2, "type"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdIsNull() { + addCriterion("rollback_source_id is null"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdIsNotNull() { + addCriterion("rollback_source_id is not null"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdEqualTo(String value) { + addCriterion("rollback_source_id =", value, "rollbackSourceId"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdNotEqualTo(String value) { + addCriterion("rollback_source_id <>", value, "rollbackSourceId"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdGreaterThan(String value) { + addCriterion("rollback_source_id >", value, "rollbackSourceId"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdGreaterThanOrEqualTo(String value) { + addCriterion("rollback_source_id >=", value, "rollbackSourceId"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdLessThan(String value) { + addCriterion("rollback_source_id <", value, "rollbackSourceId"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdLessThanOrEqualTo(String value) { + addCriterion("rollback_source_id <=", value, "rollbackSourceId"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdLike(String value) { + addCriterion("rollback_source_id like", value, "rollbackSourceId"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdNotLike(String value) { + addCriterion("rollback_source_id not like", value, "rollbackSourceId"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdIn(List values) { + addCriterion("rollback_source_id in", values, "rollbackSourceId"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdNotIn(List values) { + addCriterion("rollback_source_id not in", values, "rollbackSourceId"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdBetween(String value1, String value2) { + addCriterion("rollback_source_id between", value1, value2, "rollbackSourceId"); + return (Criteria) this; + } + + public Criteria andRollbackSourceIdNotBetween(String value1, String value2) { + addCriterion("rollback_source_id not between", value1, value2, "rollbackSourceId"); + return (Criteria) this; + } + public Criteria andCreateUserIsNull() { addCriterion("create_user is null"); return (Criteria) this; diff --git a/backend/framework/domain/src/main/java/io/metersphere/functional/mapper/FunctionalCaseHistoryMapper.xml b/backend/framework/domain/src/main/java/io/metersphere/functional/mapper/FunctionalCaseHistoryMapper.xml index b47603e8ad..b462d55456 100644 --- a/backend/framework/domain/src/main/java/io/metersphere/functional/mapper/FunctionalCaseHistoryMapper.xml +++ b/backend/framework/domain/src/main/java/io/metersphere/functional/mapper/FunctionalCaseHistoryMapper.xml @@ -5,6 +5,8 @@ + + @@ -70,7 +72,7 @@ - id, case_id, num, create_user, create_time + id, case_id, num, `type`, rollback_source_id, create_user, create_time content @@ -125,11 +127,11 @@ insert into functional_case_history (id, case_id, num, - create_user, create_time, content - ) + `type`, rollback_source_id, create_user, + create_time, content) values (#{id,jdbcType=VARCHAR}, #{caseId,jdbcType=VARCHAR}, #{num,jdbcType=INTEGER}, - #{createUser,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{content,jdbcType=LONGVARBINARY} - ) + #{type,jdbcType=VARCHAR}, #{rollbackSourceId,jdbcType=VARCHAR}, #{createUser,jdbcType=VARCHAR}, + #{createTime,jdbcType=BIGINT}, #{content,jdbcType=LONGVARBINARY}) insert into functional_case_history @@ -143,6 +145,12 @@ num, + + `type`, + + + rollback_source_id, + create_user, @@ -163,6 +171,12 @@ #{num,jdbcType=INTEGER}, + + #{type,jdbcType=VARCHAR}, + + + #{rollbackSourceId,jdbcType=VARCHAR}, + #{createUser,jdbcType=VARCHAR}, @@ -192,6 +206,12 @@ num = #{record.num,jdbcType=INTEGER}, + + `type` = #{record.type,jdbcType=VARCHAR}, + + + rollback_source_id = #{record.rollbackSourceId,jdbcType=VARCHAR}, + create_user = #{record.createUser,jdbcType=VARCHAR}, @@ -211,6 +231,8 @@ set id = #{record.id,jdbcType=VARCHAR}, case_id = #{record.caseId,jdbcType=VARCHAR}, num = #{record.num,jdbcType=INTEGER}, + `type` = #{record.type,jdbcType=VARCHAR}, + rollback_source_id = #{record.rollbackSourceId,jdbcType=VARCHAR}, create_user = #{record.createUser,jdbcType=VARCHAR}, create_time = #{record.createTime,jdbcType=BIGINT}, content = #{record.content,jdbcType=LONGVARBINARY} @@ -223,6 +245,8 @@ set id = #{record.id,jdbcType=VARCHAR}, case_id = #{record.caseId,jdbcType=VARCHAR}, num = #{record.num,jdbcType=INTEGER}, + `type` = #{record.type,jdbcType=VARCHAR}, + rollback_source_id = #{record.rollbackSourceId,jdbcType=VARCHAR}, create_user = #{record.createUser,jdbcType=VARCHAR}, create_time = #{record.createTime,jdbcType=BIGINT} @@ -238,6 +262,12 @@ num = #{num,jdbcType=INTEGER}, + + `type` = #{type,jdbcType=VARCHAR}, + + + rollback_source_id = #{rollbackSourceId,jdbcType=VARCHAR}, + create_user = #{createUser,jdbcType=VARCHAR}, @@ -254,6 +284,8 @@ update functional_case_history set case_id = #{caseId,jdbcType=VARCHAR}, num = #{num,jdbcType=INTEGER}, + `type` = #{type,jdbcType=VARCHAR}, + rollback_source_id = #{rollbackSourceId,jdbcType=VARCHAR}, create_user = #{createUser,jdbcType=VARCHAR}, create_time = #{createTime,jdbcType=BIGINT}, content = #{content,jdbcType=LONGVARBINARY} @@ -263,18 +295,20 @@ update functional_case_history set case_id = #{caseId,jdbcType=VARCHAR}, num = #{num,jdbcType=INTEGER}, + `type` = #{type,jdbcType=VARCHAR}, + rollback_source_id = #{rollbackSourceId,jdbcType=VARCHAR}, create_user = #{createUser,jdbcType=VARCHAR}, create_time = #{createTime,jdbcType=BIGINT} where id = #{id,jdbcType=VARCHAR} insert into functional_case_history - (id, case_id, num, create_user, create_time, content) + (id, case_id, num, `type`, rollback_source_id, create_user, create_time, content) values (#{item.id,jdbcType=VARCHAR}, #{item.caseId,jdbcType=VARCHAR}, #{item.num,jdbcType=INTEGER}, - #{item.createUser,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT}, #{item.content,jdbcType=LONGVARBINARY} - ) + #{item.type,jdbcType=VARCHAR}, #{item.rollbackSourceId,jdbcType=VARCHAR}, #{item.createUser,jdbcType=VARCHAR}, + #{item.createTime,jdbcType=BIGINT}, #{item.content,jdbcType=LONGVARBINARY}) @@ -296,6 +330,12 @@ #{item.num,jdbcType=INTEGER} + + #{item.type,jdbcType=VARCHAR} + + + #{item.rollbackSourceId,jdbcType=VARCHAR} + #{item.createUser,jdbcType=VARCHAR} diff --git a/backend/framework/domain/src/main/resources/migration/3.0.0/ddl/V3.0.0_10__functional_case.sql b/backend/framework/domain/src/main/resources/migration/3.0.0/ddl/V3.0.0_10__functional_case.sql index 636268f155..d0f6631a5e 100644 --- a/backend/framework/domain/src/main/resources/migration/3.0.0/ddl/V3.0.0_10__functional_case.sql +++ b/backend/framework/domain/src/main/resources/migration/3.0.0/ddl/V3.0.0_10__functional_case.sql @@ -233,6 +233,8 @@ CREATE TABLE IF NOT EXISTS functional_case_history `id` VARCHAR(50) NOT NULL COMMENT 'ID', `case_id` VARCHAR(50) NOT NULL COMMENT '用例ID', `num` INT NOT NULL COMMENT '变更记录批次号', + `type` VARCHAR(64) NOT NULL COMMENT '变更类型;IMPORT/EDIT/ROLLBACK', + `rollback_source_id` VARCHAR(50) COMMENT '回退来源', `content` BLOB NOT NULL COMMENT '修改内容', `create_user` VARCHAR(50) NOT NULL COMMENT '操作人', `create_time` BIGINT NOT NULL COMMENT '操作时间', diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/FunctionalCaseReviewStatus.java b/backend/services/case-management/src/main/java/io/metersphere/functional/constants/FunctionalCaseReviewStatus.java similarity index 76% rename from backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/FunctionalCaseReviewStatus.java rename to backend/services/case-management/src/main/java/io/metersphere/functional/constants/FunctionalCaseReviewStatus.java index 5751b31c20..5043434438 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/FunctionalCaseReviewStatus.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/constants/FunctionalCaseReviewStatus.java @@ -1,4 +1,4 @@ -package io.metersphere.sdk.constants; +package io.metersphere.functional.constants; /** * @author wx diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseAttachmentController.java b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseAttachmentController.java index 74afe295b8..b2a16d3039 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseAttachmentController.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseAttachmentController.java @@ -45,8 +45,6 @@ public class FunctionalCaseAttachmentController { private FileAssociationService fileAssociationService; - //TODO 附件操作:文件删除/文件下载/文件预览/文件转存/文件更新 - @PostMapping("/page") @Operation(summary = "用例管理-功能用例-附件-关联文件列表分页接口") @RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ) diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/CaseReviewService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/CaseReviewService.java index 2a7bdfd49e..c714f154b0 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/CaseReviewService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/CaseReviewService.java @@ -2,11 +2,11 @@ package io.metersphere.functional.service; import io.metersphere.functional.constants.CaseReviewStatus; +import io.metersphere.functional.constants.FunctionalCaseReviewStatus; import io.metersphere.functional.domain.*; import io.metersphere.functional.mapper.*; import io.metersphere.functional.request.CaseReviewAddRequest; import io.metersphere.functional.result.CaseManagementResultCode; -import io.metersphere.sdk.constants.FunctionalCaseReviewStatus; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.JSON; import io.metersphere.system.uid.IDGenerator; diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseAttachmentService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseAttachmentService.java index 44ec5293df..96963b1918 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseAttachmentService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseAttachmentService.java @@ -9,6 +9,7 @@ import io.metersphere.functional.dto.FunctionalCaseDetailDTO; import io.metersphere.functional.mapper.FunctionalCaseAttachmentMapper; import io.metersphere.functional.request.FunctionalCaseAddRequest; import io.metersphere.functional.request.FunctionalCaseFileRequest; +import io.metersphere.project.domain.FileAssociation; import io.metersphere.project.dto.filemanagement.FileInfo; import io.metersphere.project.dto.filemanagement.FileLogRecord; import io.metersphere.project.service.FileAssociationService; @@ -140,10 +141,10 @@ public class FunctionalCaseAttachmentService { */ public void deleteCaseAttachment(List deleteFileMetaIds, String caseId, String projectId) { FunctionalCaseAttachmentExample example = new FunctionalCaseAttachmentExample(); - example.createCriteria().andFileIdIn(deleteFileMetaIds).andCaseIdEqualTo(caseId).andLocalEqualTo(true); + example.createCriteria().andIdIn(deleteFileMetaIds).andCaseIdEqualTo(caseId).andLocalEqualTo(true); List delAttachment = functionalCaseAttachmentMapper.selectByExample(example); example.clear(); - example.createCriteria().andFileIdIn(deleteFileMetaIds).andCaseIdEqualTo(caseId); + example.createCriteria().andIdIn(deleteFileMetaIds); functionalCaseAttachmentMapper.deleteByExample(example); this.deleteMinioFile(delAttachment, projectId, caseId); } @@ -237,7 +238,7 @@ public class FunctionalCaseAttachmentService { FunctionalCaseAttachment attachment = caseAttachments.get(0); FileRequest fileRequest = new FileRequest(); fileRequest.setFileName(attachment.getFileName()); - fileRequest.setFolder(DefaultRepositoryDir.getFunctionalCaseDir(request.getProjectId(), request.getCaseId()) + "/" + request.getFileId()); + fileRequest.setFolder(DefaultRepositoryDir.getFunctionalCaseDir(request.getProjectId(), request.getCaseId()) + "/" + attachment.getFileId()); fileRequest.setStorage(StorageType.MINIO.name()); byte[] bytes = null; try { @@ -275,11 +276,20 @@ public class FunctionalCaseAttachmentService { public FunctionalCaseAttachment getAttachment(FunctionalCaseFileRequest request) { FunctionalCaseAttachmentExample example = new FunctionalCaseAttachmentExample(); - example.createCriteria().andFileIdEqualTo(request.getFileId()).andCaseIdEqualTo(request.getCaseId()); + example.createCriteria().andIdEqualTo(request.getFileId()).andCaseIdEqualTo(request.getCaseId()); List caseAttachments = functionalCaseAttachmentMapper.selectByExample(example); if (CollectionUtils.isNotEmpty(caseAttachments)) { return caseAttachments.get(0); } return new FunctionalCaseAttachment(); } + + public Map> getFileAssociationByCaseIds(List ids) { + List fileAssociations = fileAssociationService.getFileAssociations(ids, FileAssociationSourceUtil.SOURCE_TYPE_FUNCTIONAL_CASE); + Map> fileAssociationMap = new HashMap<>(); + if (CollectionUtils.isNotEmpty(fileAssociations)) { + fileAssociationMap = fileAssociations.stream().collect(Collectors.groupingBy(FileAssociation::getSourceId)); + } + return fileAssociationMap; + } } \ No newline at end of file diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseHistoryService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseHistoryService.java new file mode 100644 index 0000000000..63ba8cfbee --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseHistoryService.java @@ -0,0 +1,7 @@ +package io.metersphere.functional.service; + +import java.util.List; + +public interface FunctionalCaseHistoryService { + void saveHistoryLog(List caseIds); +} diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java index c5468dd279..16aaee6f23 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java @@ -1,19 +1,24 @@ package io.metersphere.functional.service; +import io.metersphere.functional.constants.FunctionalCaseReviewStatus; import io.metersphere.functional.domain.*; import io.metersphere.functional.dto.*; -import io.metersphere.functional.mapper.*; +import io.metersphere.functional.mapper.ExtFunctionalCaseMapper; +import io.metersphere.functional.mapper.FunctionalCaseBlobMapper; +import io.metersphere.functional.mapper.FunctionalCaseFollowerMapper; +import io.metersphere.functional.mapper.FunctionalCaseMapper; import io.metersphere.functional.request.*; import io.metersphere.functional.result.CaseManagementResultCode; +import io.metersphere.project.domain.FileAssociation; import io.metersphere.project.dto.ModuleCountDTO; import io.metersphere.project.mapper.ExtBaseProjectVersionMapper; import io.metersphere.project.service.ProjectTemplateService; import io.metersphere.sdk.constants.ApplicationNumScope; import io.metersphere.sdk.constants.FunctionalCaseExecuteResult; -import io.metersphere.sdk.constants.FunctionalCaseReviewStatus; import io.metersphere.sdk.constants.TemplateScene; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.BeanUtils; +import io.metersphere.sdk.util.CommonBeanFactory; import io.metersphere.sdk.util.JSON; import io.metersphere.system.dto.sdk.TemplateCustomFieldDTO; import io.metersphere.system.dto.sdk.TemplateDTO; @@ -80,6 +85,7 @@ public class FunctionalCaseService { private static final String ADD_FUNCTIONAL_CASE_FILE_LOG_URL = "/functional/case/add"; 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"; public FunctionalCase addFunctionalCase(FunctionalCaseAddRequest request, List files, String userId) { String caseId = IDGenerator.nextStr(); @@ -94,11 +100,18 @@ public class FunctionalCaseService { functionalCaseAttachmentService.association(request.getRelateFileMetaIds(), caseId, userId, ADD_FUNCTIONAL_CASE_FILE_LOG_URL, request.getProjectId()); } - //TODO 记录变更历史 + saveHistory(Collections.singletonList(caseId)); return functionalCase; } + private void saveHistory(List ids) { + FunctionalCaseHistoryService functionalCaseHistoryService = CommonBeanFactory.getBean(FunctionalCaseHistoryService.class); + if (functionalCaseHistoryService != null) { + functionalCaseHistoryService.saveHistoryLog(ids); + } + } + /** * 添加功能用例 * @@ -169,7 +182,7 @@ public class FunctionalCaseService { BeanUtils.copyBean(functionalCaseDetailDTO, caseBlob); //模板校验 获取自定义字段 - functionalCaseDetailDTO = checkTemplateCustomField(functionalCaseDetailDTO, functionalCase); + checkTemplateCustomField(functionalCaseDetailDTO, functionalCase); //是否关注用例 Boolean isFollow = checkIsFollowCase(functionalCase.getId(), userId); @@ -268,7 +281,7 @@ public class FunctionalCaseService { functionalCaseAttachmentService.association(request.getRelateFileMetaIds(), request.getId(), userId, UPDATE_FUNCTIONAL_CASE_FILE_LOG_URL, request.getProjectId()); } - //TODO 记录变更历史 addFunctionalCaseHistory + saveHistory(Collections.singletonList(request.getId())); return functionalCase; @@ -455,64 +468,61 @@ public class FunctionalCaseService { Map functionalCaseBlobMap = copyBlobInfo(ids); //附件 本地附件 Map> attachmentMap = functionalCaseAttachmentService.getAttachmentByCaseIds(ids); - //TODO 文件库附件 + //文件库附件 + Map> fileAssociationMap = functionalCaseAttachmentService.getFileAssociationByCaseIds(ids); //自定义字段 Map> 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 caseAttachments = attachmentMap.get(ids.get(i)); - List customFields = customFieldMap.get(ids.get(i)); + 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 caseAttachments = attachmentMap.get(ids.get(i)); + List fileAssociationList = fileAssociationMap.get(ids.get(i)); + List 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); + 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()); + functionalCaseMapper.insert(functional); - functionalCaseBlob.setId(id); - functionalCaseBlobMapper.insert(functionalCaseBlob); + functionalCaseBlob.setId(id); + functionalCaseBlobMapper.insert(functionalCaseBlob); + }); + + if (CollectionUtils.isNotEmpty(caseAttachments)) { + caseAttachments.forEach(attachment -> { + attachment.setId(IDGenerator.nextStr()); + attachment.setCaseId(id); + attachment.setCreateUser(userId); + attachment.setCreateTime(System.currentTimeMillis()); }); - - if (CollectionUtils.isNotEmpty(caseAttachments)) { - caseAttachments.forEach(attachment -> { - attachment.setId(IDGenerator.nextStr()); - attachment.setCaseId(id); - attachment.setCreateUser(userId); - attachment.setCreateTime(System.currentTimeMillis()); - }); - functionalCaseAttachmentService.batchSaveAttachment(caseAttachments); - } - - if (CollectionUtils.isNotEmpty(customFields)) { - customFields.forEach(customField -> { - customField.setCaseId(id); - }); - functionalCaseCustomFieldService.batchSaveCustomField(customFields); - } - - if (i % 50 == 0) { - sqlSession.flushStatements(); - } + functionalCaseAttachmentService.batchSaveAttachment(caseAttachments); } - sqlSession.flushStatements(); - } finally { - SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); + + if (CollectionUtils.isNotEmpty(customFields)) { + customFields.forEach(customField -> { + customField.setCaseId(id); + }); + functionalCaseCustomFieldService.batchSaveCustomField(customFields); + } + + if (CollectionUtils.isNotEmpty(fileAssociationList)) { + List fileIds = fileAssociationList.stream().map(FileAssociation::getFileId).collect(Collectors.toList()); + functionalCaseAttachmentService.association(fileIds, id, userId, FUNCTIONAL_CASE_BATCH_COPY_FILE_LOG_URL, request.getProjectId()); + } + } } } @@ -554,6 +564,7 @@ public class FunctionalCaseService { handleTags(request, userId, ids); //自定义字段处理 handleCustomFields(request, userId, ids); + saveHistory(ids); } } diff --git a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseControllerTests.java b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseControllerTests.java index 84ef1b7de0..c4a982b8a9 100644 --- a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseControllerTests.java +++ b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseControllerTests.java @@ -181,7 +181,7 @@ public class FunctionalCaseControllerTests extends BaseTest { Assertions.assertNotNull(resultHolder); //设置删除文件id - request.setDeleteFileMetaIds(Arrays.asList("delete_file_meta_id_1")); + request.setDeleteFileMetaIds(Arrays.asList("TEST_CASE_ATTACHMENT_ID_2")); request.setUnLinkFilesIds(Arrays.asList("relate_file_meta_id_1")); request.setRelateFileMetaIds(Arrays.asList("relate_file_meta_id_1", "relate_file_meta_id_2")); paramMap = new LinkedMultiValueMap<>(); diff --git a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseModuleControllerTests.java b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseModuleControllerTests.java index 574aea2f40..c21d5fa904 100644 --- a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseModuleControllerTests.java +++ b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseModuleControllerTests.java @@ -1,5 +1,6 @@ package io.metersphere.functional.controller; +import io.metersphere.functional.constants.FunctionalCaseReviewStatus; import io.metersphere.functional.domain.FunctionalCase; import io.metersphere.functional.domain.FunctionalCaseModule; import io.metersphere.functional.domain.FunctionalCaseModuleExample; @@ -11,7 +12,6 @@ import io.metersphere.functional.service.FunctionalCaseModuleService; import io.metersphere.project.domain.Project; import io.metersphere.project.mapper.ProjectMapper; import io.metersphere.sdk.constants.FunctionalCaseExecuteResult; -import io.metersphere.sdk.constants.FunctionalCaseReviewStatus; import io.metersphere.sdk.constants.ModuleConstants; import io.metersphere.sdk.constants.SessionConstants; import io.metersphere.sdk.util.JSON; diff --git a/backend/services/case-management/src/test/resources/dml/init_file_metadata_test.sql b/backend/services/case-management/src/test/resources/dml/init_file_metadata_test.sql index 4043af9bfa..eb3ea21992 100644 --- a/backend/services/case-management/src/test/resources/dml/init_file_metadata_test.sql +++ b/backend/services/case-management/src/test/resources/dml/init_file_metadata_test.sql @@ -1,7 +1,7 @@ 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_1', 'formItem', 'ts', 2502, 1698058347559, 1698058347559, '100001100001', 'MINIO', 'admin', 'admin', NULL, NULL, 'root', '100001100001/1127016598347779', b'1', '1127016598347779', '1127016598347779'); 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 file_association(id, source_type, source_id, file_id, file_ref_id, file_version, create_time, update_user, update_time, create_user) VALUES ('file_association_1', 'functional_case', 'TEST_FUNCTIONAL_CASE_ID', 'relate_file_meta_id_1', '1', '1', 1698983271536, 'admin', 1698983271536, 'admin'); +INSERT INTO file_association(id, source_type, source_id, file_id, file_ref_id, file_version, create_time, update_user, update_time, create_user) VALUES ('file_association_1', 'FUNCTIONAL_CASE', 'TEST_FUNCTIONAL_CASE_ID', 'relate_file_meta_id_1', '1', '1', 1698983271536, 'admin', 1698983271536, 'admin'); 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) diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileAssociationMapper.java b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileAssociationMapper.java index 9ca80137d3..48298dbd92 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileAssociationMapper.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileAssociationMapper.java @@ -1,5 +1,6 @@ package io.metersphere.project.mapper; +import io.metersphere.project.domain.FileAssociation; import io.metersphere.project.dto.filemanagement.FileAssociationSource; import io.metersphere.project.dto.filemanagement.FileInfo; import org.apache.ibatis.annotations.Param; @@ -15,4 +16,6 @@ public interface ExtFileAssociationMapper { List selectAssociationSourceBySourceTableAndIdList(@Param("querySql") String querySql, @Param("idList") List sourceIdList); List selectAssociationFileInfo(@Param("sourceId") String sourceId, @Param("sourceType") String sourceType); + + List selectFileIdsBySourceId(@Param("sourceIds")List sourceIds, @Param("sourceType")String sourceType); } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileAssociationMapper.xml b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileAssociationMapper.xml index 5b3dc2767c..565c876015 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileAssociationMapper.xml +++ b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileAssociationMapper.xml @@ -19,7 +19,7 @@ SELECT file_association.id AS id, file_association.file_id AS fileId, - CONCAT( file_metadata.`name`, file_metadata.type ) AS fileName, + CONCAT( file_metadata.`name`, '.', file_metadata.type ) AS fileName, file_metadata.size AS size, 'false' AS local, file_association.create_user AS createUser, @@ -31,4 +31,11 @@ file_association.source_id = #{sourceId} AND file_association.source_type = #{sourceType} + + \ No newline at end of file diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/FileAssociationService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/FileAssociationService.java index b1c979c7c0..e17e453f76 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/FileAssociationService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/FileAssociationService.java @@ -326,4 +326,8 @@ public class FileAssociationService { public List getFiles(String sourceId, String sourceType) { return extFileAssociationMapper.selectAssociationFileInfo(sourceId, sourceType); } + + public List getFileAssociations(List sourceIds, String sourceType) { + return extFileAssociationMapper.selectFileIdsBySourceId(sourceIds, sourceType); + } } diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/filemanagement/FileManagementControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/filemanagement/FileManagementControllerTests.java index 914de24285..8d41831511 100644 --- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/filemanagement/FileManagementControllerTests.java +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/filemanagement/FileManagementControllerTests.java @@ -2330,5 +2330,6 @@ public class FileManagementControllerTests extends BaseTest { @Order(91) public void testQuery() throws Exception { fileAssociationService.getFiles("TEST", FileAssociationSourceUtil.SOURCE_TYPE_FUNCTIONAL_CASE); + fileAssociationService.getFileAssociations(Collections.singletonList("TEST"), FileAssociationSourceUtil.SOURCE_TYPE_FUNCTIONAL_CASE); } }