feat(用例评审): 新增评审功能

This commit is contained in:
guoyuqi 2023-12-06 15:27:57 +08:00 committed by f2c-ci-robot[bot]
parent 25b374a286
commit 0bb49654df
14 changed files with 828 additions and 60 deletions

View File

@ -25,7 +25,9 @@ public class CaseReviewHistory implements Serializable {
@Size(min = 1, max = 50, message = "{case_review_history.case_id.length_range}", groups = {Created.class, Updated.class}) @Size(min = 1, max = 50, message = "{case_review_history.case_id.length_range}", groups = {Created.class, Updated.class})
private String caseId; private String caseId;
@Schema(description = "评审结果:通过/不通过") @Schema(description = "评审结果:通过/不通过/建议", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{case_review_history.status.not_blank}", groups = {Created.class})
@Size(min = 1, max = 64, message = "{case_review_history.status.length_range}", groups = {Created.class, Updated.class})
private String status; private String status;
@Schema(description = "通知人") @Schema(description = "通知人")
@ -37,8 +39,7 @@ public class CaseReviewHistory implements Serializable {
@Schema(description = "操作时间") @Schema(description = "操作时间")
private Long createTime; private Long createTime;
@Schema(description = "评审意见", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "评审意见")
@NotNull(message = "{case_review_history.content.not_blank}", groups = {Created.class})
private byte[] content; private byte[] content;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@ -40,7 +40,7 @@ CREATE INDEX idx_delete_time ON functional_case (delete_time desc);
CREATE INDEX idx_update_time ON functional_case (update_time desc); CREATE INDEX idx_update_time ON functional_case (update_time desc);
CREATE INDEX idx_num ON functional_case (num); CREATE INDEX idx_num ON functional_case (num);
CREATE INDEX idx_project_id ON functional_case (project_id); CREATE INDEX idx_project_id ON functional_case (project_id);
CREATE INDEX idx_pos ON functional_case(pos); CREATE INDEX idx_pos ON functional_case (pos);
CREATE TABLE IF NOT EXISTS functional_case_blob CREATE TABLE IF NOT EXISTS functional_case_blob
@ -182,25 +182,25 @@ CREATE INDEX idx_source_id ON functional_case_test (source_id);
CREATE TABLE IF NOT EXISTS functional_case_demand CREATE TABLE IF NOT EXISTS functional_case_demand
( (
`id` VARCHAR(50) NOT NULL COMMENT 'ID' , `id` VARCHAR(50) NOT NULL COMMENT 'ID',
`case_id` VARCHAR(50) NOT NULL COMMENT '功能用例ID' , `case_id` VARCHAR(50) NOT NULL COMMENT '功能用例ID',
`parent` VARCHAR(50) NOT NULL DEFAULT 'NONE' COMMENT '父需求id' , `parent` VARCHAR(50) NOT NULL DEFAULT 'NONE' COMMENT '父需求id',
`demand_id` VARCHAR(50) COMMENT '需求ID' , `demand_id` VARCHAR(50) COMMENT '需求ID',
`demand_name` VARCHAR(64) NOT NULL DEFAULT 'NONE' COMMENT '需求标题' , `demand_name` VARCHAR(64) NOT NULL DEFAULT 'NONE' COMMENT '需求标题',
`demand_url` VARCHAR(255) COMMENT '需求地址' , `demand_url` VARCHAR(255) COMMENT '需求地址',
`demand_platform` VARCHAR(64) NOT NULL DEFAULT 'LOCAL' COMMENT '需求所属平台' , `demand_platform` VARCHAR(64) NOT NULL DEFAULT 'LOCAL' COMMENT '需求所属平台',
`create_time` BIGINT NOT NULL COMMENT '创建时间' , `create_time` BIGINT NOT NULL COMMENT '创建时间',
`update_time` BIGINT NOT NULL COMMENT '更新时间' , `update_time` BIGINT NOT NULL COMMENT '更新时间',
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人' , `create_user` VARCHAR(50) NOT NULL COMMENT '创建人',
`update_user` VARCHAR(50) NOT NULL COMMENT '更新人' , `update_user` VARCHAR(50) NOT NULL COMMENT '更新人',
PRIMARY KEY (id) PRIMARY KEY (id)
) ENGINE = InnoDB ) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci COMMENT = '功能用例和需求的中间表'; COLLATE = utf8mb4_general_ci COMMENT = '功能用例和需求的中间表';
CREATE INDEX idx_case_id ON functional_case_demand(case_id); CREATE INDEX idx_case_id ON functional_case_demand (case_id);
CREATE INDEX idx_demand_platform ON functional_case_demand(demand_platform); CREATE INDEX idx_demand_platform ON functional_case_demand (demand_platform);
CREATE TABLE IF NOT EXISTS functional_minder_extra_node CREATE TABLE IF NOT EXISTS functional_minder_extra_node
( (
@ -230,43 +230,43 @@ CREATE TABLE IF NOT EXISTS functional_case_custom_field
CREATE TABLE IF NOT EXISTS case_review CREATE TABLE IF NOT EXISTS case_review
( (
`id` VARCHAR(50) NOT NULL COMMENT 'ID' , `id` VARCHAR(50) NOT NULL COMMENT 'ID',
`num` BIGINT NOT NULL COMMENT '业务ID' , `num` BIGINT NOT NULL COMMENT '业务ID',
`name` VARCHAR(255) NOT NULL COMMENT '名称' , `name` VARCHAR(255) NOT NULL COMMENT '名称',
`module_id` VARCHAR(50) NOT NULL COMMENT '模块id' , `module_id` VARCHAR(50) NOT NULL COMMENT '模块id',
`project_id` VARCHAR(50) NOT NULL COMMENT '项目ID' , `project_id` VARCHAR(50) NOT NULL COMMENT '项目ID',
`status` VARCHAR(64) NOT NULL DEFAULT 'PREPARE' COMMENT '评审状态:未开始/进行中/已完成/已结束/已归档' , `status` VARCHAR(64) NOT NULL DEFAULT 'PREPARE' COMMENT '评审状态:未开始/进行中/已完成/已结束/已归档',
`review_pass_rule` VARCHAR(64) NOT NULL DEFAULT 'SINGLE' COMMENT '通过标准:单人通过/全部通过' , `review_pass_rule` VARCHAR(64) NOT NULL DEFAULT 'SINGLE' COMMENT '通过标准:单人通过/全部通过',
`pos` BIGINT NOT NULL DEFAULT 0 COMMENT '自定义排序间隔5000' , `pos` BIGINT NOT NULL DEFAULT 0 COMMENT '自定义排序间隔5000',
`start_time` BIGINT COMMENT '评审开始时间' , `start_time` BIGINT COMMENT '评审开始时间',
`end_time` BIGINT COMMENT '评审结束时间' , `end_time` BIGINT COMMENT '评审结束时间',
`case_count` INT NOT NULL DEFAULT 0 COMMENT '用例数' , `case_count` INT NOT NULL DEFAULT 0 COMMENT '用例数',
`pass_rate` DECIMAL(5,2) NOT NULL DEFAULT 0.00 COMMENT '通过率(保留两位小数)' , `pass_rate` DECIMAL(5, 2) NOT NULL DEFAULT 0.00 COMMENT '通过率(保留两位小数)',
`tags` VARCHAR(1000) COMMENT '标签' , `tags` VARCHAR(1000) COMMENT '标签',
`description` VARCHAR(1000) COMMENT '描述' , `description` VARCHAR(1000) COMMENT '描述',
`create_time` BIGINT NOT NULL COMMENT '创建时间' , `create_time` BIGINT NOT NULL COMMENT '创建时间',
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人' , `create_user` VARCHAR(50) NOT NULL COMMENT '创建人',
`update_time` BIGINT NOT NULL COMMENT '更新时间' , `update_time` BIGINT NOT NULL COMMENT '更新时间',
`update_user` VARCHAR(50) NOT NULL COMMENT '更新人' , `update_user` VARCHAR(50) NOT NULL COMMENT '更新人',
PRIMARY KEY (id) PRIMARY KEY (id)
) ENGINE = InnoDB ) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci COMMENT = '用例评审'; COLLATE = utf8mb4_general_ci COMMENT = '用例评审';
CREATE INDEX idx_create_user ON case_review(create_user); CREATE INDEX idx_create_user ON case_review (create_user);
CREATE INDEX idx_project_id ON case_review(project_id); CREATE INDEX idx_project_id ON case_review (project_id);
CREATE INDEX idx_name ON case_review(name); CREATE INDEX idx_name ON case_review (name);
CREATE INDEX idx_status ON case_review(status); CREATE INDEX idx_status ON case_review (status);
CREATE INDEX idx_review_pass_rule ON case_review(review_pass_rule); CREATE INDEX idx_review_pass_rule ON case_review (review_pass_rule);
CREATE INDEX idx_create_time ON case_review(create_time desc); CREATE INDEX idx_create_time ON case_review (create_time desc);
CREATE INDEX idx_update_time ON case_review(update_time desc); CREATE INDEX idx_update_time ON case_review (update_time desc);
CREATE INDEX idx_update_user ON case_review(update_user); CREATE INDEX idx_update_user ON case_review (update_user);
CREATE INDEX idx_module_id ON case_review(module_id); CREATE INDEX idx_module_id ON case_review (module_id);
CREATE INDEX idx_pos ON case_review(pos); CREATE INDEX idx_pos ON case_review (pos);
CREATE INDEX idx_case_count ON case_review(case_count); CREATE INDEX idx_case_count ON case_review (case_count);
CREATE INDEX idx_pass_rate ON case_review(pass_rate); CREATE INDEX idx_pass_rate ON case_review (pass_rate);
CREATE INDEX idx_num ON case_review(num); CREATE INDEX idx_num ON case_review (num);
CREATE TABLE IF NOT EXISTS case_review_user CREATE TABLE IF NOT EXISTS case_review_user
@ -298,13 +298,14 @@ CREATE TABLE IF NOT EXISTS case_review_functional_case
CREATE INDEX idx_case_id ON case_review_functional_case (case_id); CREATE INDEX idx_case_id ON case_review_functional_case (case_id);
CREATE INDEX idx_review_id ON case_review_functional_case (review_id); CREATE INDEX idx_review_id ON case_review_functional_case (review_id);
CREATE INDEX idx_status ON case_review_functional_case (status); CREATE INDEX idx_status ON case_review_functional_case (status);
CREATE INDEX idx_pos ON case_review_functional_case(pos); CREATE INDEX idx_pos ON case_review_functional_case (pos);
CREATE TABLE IF NOT EXISTS case_review_functional_case_archive( CREATE TABLE IF NOT EXISTS case_review_functional_case_archive
(
`review_id` VARCHAR(50) NOT NULL COMMENT '用例评审ID', `review_id` VARCHAR(50) NOT NULL COMMENT '用例评审ID',
`case_id` VARCHAR(50) NOT NULL COMMENT '功能用例ID', `case_id` VARCHAR(50) NOT NULL COMMENT '功能用例ID',
`content` LONGBLOB COMMENT '功能用例快照JSON)' `content` LONGBLOB COMMENT '功能用例快照JSON)'
) ENGINE = InnoDB ) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci COMMENT = '用例评审归档表'; COLLATE = utf8mb4_general_ci COMMENT = '用例评审归档表';
@ -346,20 +347,22 @@ CREATE TABLE IF NOT EXISTS case_review_history
`id` VARCHAR(50) NOT NULL COMMENT 'ID', `id` VARCHAR(50) NOT NULL COMMENT 'ID',
`review_id` VARCHAR(50) NOT NULL COMMENT '评审ID', `review_id` VARCHAR(50) NOT NULL COMMENT '评审ID',
`case_id` VARCHAR(50) NOT NULL COMMENT '用例ID', `case_id` VARCHAR(50) NOT NULL COMMENT '用例ID',
`content` BLOB NOT NULL COMMENT '评审意见', `content` LONGBLOB COMMENT '评审意见',
`status` VARCHAR(64) COMMENT '评审结果:通过/不通过', `status` VARCHAR(64) NOT NULL COMMENT '评审结果:通过/不通过/建议',
`notifier` VARCHAR(1000) COMMENT '通知人', `notifier` VARCHAR(1000) COMMENT '通知人',
`create_user` VARCHAR(50) NOT NULL COMMENT '操作人', `create_user` VARCHAR(50) NOT NULL COMMENT '操作人',
`create_time` BIGINT NOT NULL COMMENT '操作时间', `create_time` BIGINT NOT NULL COMMENT '操作时间',
PRIMARY KEY (id) PRIMARY KEY (id)
) ENGINE = InnoDB ) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci COMMENT = '评审变更记录'; COLLATE = utf8mb4_general_ci COMMENT = '评审历史表';
CREATE INDEX idx_case_id ON case_review_history (case_id); CREATE INDEX idx_case_id ON case_review_history (case_id);
CREATE INDEX idx_review_id ON case_review_history (review_id); CREATE INDEX idx_review_id ON case_review_history (review_id);
CREATE INDEX idx_review_id_case_id ON case_review_history (review_id, case_id); CREATE INDEX idx_review_id_case_id ON case_review_history (review_id, case_id);
CREATE INDEX idx_status ON case_review_history (status);
CREATE TABLE IF NOT EXISTS case_review_module CREATE TABLE IF NOT EXISTS case_review_module
( (

View File

@ -145,3 +145,4 @@ case_review.archived=已归档
case_review.single=单人评审 case_review.single=单人评审
case_review.multiple=多人评审 case_review.multiple=多人评审
case_review.not.exist=用例评审不存在 case_review.not.exist=用例评审不存在
case_review_content.not.exist = 评审意见不能为空

View File

@ -162,3 +162,5 @@ case_review.archived=Archived
case_review.single=Single person review case_review.single=Single person review
case_review.multiple=Multiple reviewers case_review.multiple=Multiple reviewers
case_review.not.exist=Case review does not exist case_review.not.exist=Case review does not exist
case_review_content.not.exist = Review comments cannot be empty

View File

@ -161,3 +161,5 @@ case_review.archived=已归档
case_review.single=单人评审 case_review.single=单人评审
case_review.multiple=多人评审 case_review.multiple=多人评审
case_review.not.exist=用例评审不存在 case_review.not.exist=用例评审不存在
case_review_content.not.exist = 评审意见不能为空

View File

@ -162,4 +162,5 @@ case_review.archived=已歸檔
case_review.single=單人評審 case_review.single=單人評審
case_review.multiple=多人評審 case_review.multiple=多人評審
case_review.not.exist=用例評審不存在 case_review.not.exist=用例評審不存在
case_review_content.not.exist = 評審意見不能為空

View File

@ -0,0 +1,33 @@
package io.metersphere.functional.controller;
import io.metersphere.functional.request.ReviewFunctionalCaseRequest;
import io.metersphere.functional.service.ReviewFunctionalCaseService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.system.utils.SessionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "用例管理-用例评审-评审功能用例")
@RestController
@RequestMapping("/review/functional/case")
public class ReviewFunctionalCaseController {
@Resource
private ReviewFunctionalCaseService reviewFunctionalCaseService;
@PostMapping("/save")
@Operation(summary = "用例管理-用例评审-评审功能用例-提交评审")
@RequiresPermissions(PermissionConstants.CASE_REVIEW_REVIEW)
public void saveReview(@Validated @RequestBody ReviewFunctionalCaseRequest request) {
reviewFunctionalCaseService.saveReview(request, SessionUtils.getUserId());
}
}

View File

@ -13,4 +13,7 @@ public interface ExtCaseReviewFunctionalCaseMapper {
List<FunctionalCaseReviewDTO> list(@Param("request") FunctionalCaseReviewListRequest request); List<FunctionalCaseReviewDTO> list(@Param("request") FunctionalCaseReviewListRequest request);
void updateStatus(@Param("caseId") String caseId, @Param("reviewId") String reviewId, @Param("status") String status);
Long getUnCompletedCaseCount(@Param("reviewId") String reviewId, @Param("statusList") List<String> statusList);
} }

View File

@ -16,4 +16,23 @@
</if> </if>
</select> </select>
<select id="getUnCompletedCaseCount" resultType="java.lang.Long">
SELECT
count(1)
FROM
case_review_functional_case
where review_id = #{reviewId}
and status in
<foreach collection="statusList" item="status" open="(" separator="," close=")">
#{status}
</foreach>
</select>
<update id="updateStatus">
update case_review_functional_case
set status = #{status},
update_time = UNIX_TIMESTAMP()*1000
where review_id = #{reviewId} and case_id = #{caseId}
</update>
</mapper> </mapper>

View File

@ -0,0 +1,35 @@
package io.metersphere.functional.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class ReviewFunctionalCaseRequest {
@Schema(description = "项目Id")
@NotBlank(message = "{case_review.project_id.not_blank}")
private String projectId;
@Schema(description = "用例评审Id")
@NotBlank(message = "{case_review.review_id.not_blank}")
private String reviewId;
@Schema(description = "功能用例id")
@NotBlank(message = "{functional_case.case_id.not_blank}")
private String caseId;
@Schema(description = "评审规则")
@NotBlank(message = "{case_review.review_pass_rule.not_blank}")
private String reviewPassRule;
@Schema(description = "评审结果")
@NotBlank(message = "{functional_case.status.not_blank}")
private String status;
@Schema(description = "评审规则")
private String content;
@Schema(description = "评论@的人的Id, 多个以';'隔开")
private String notifier;
}

View File

@ -0,0 +1,215 @@
package io.metersphere.functional.service;
import io.metersphere.functional.constants.CaseReviewPassRule;
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.ReviewFunctionalCaseRequest;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.User;
import io.metersphere.system.mapper.UserMapper;
import io.metersphere.system.notice.NoticeModel;
import io.metersphere.system.notice.constants.NoticeConstants;
import io.metersphere.system.notice.utils.MessageTemplateUtils;
import io.metersphere.system.service.NoticeSendService;
import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@Service
@Transactional(rollbackFor = Exception.class)
public class ReviewFunctionalCaseService {
@Resource
private CaseReviewHistoryMapper caseReviewHistoryMapper;
@Resource
private ExtCaseReviewFunctionalCaseMapper extCaseReviewFunctionalCaseMapper;
@Resource
private CaseReviewFunctionalCaseUserMapper caseReviewFunctionalCaseUserMapper;
@Resource
private CaseReviewMapper caseReviewMapper;
@Resource
private UserMapper userMapper;
@Resource
private NoticeSendService noticeSendService;
@Resource
private FunctionalCaseMapper functionalCaseMapper;
/**
* 评审功能用例
*
* @param request 页面参数
* @param userId 当前操作人
*/
public void saveReview(ReviewFunctionalCaseRequest request, String userId) {
//保存评审历史
CaseReviewHistory caseReviewHistory = buildReviewHistory(request, userId);
caseReviewHistoryMapper.insert(caseReviewHistory);
//根据评审规则更新用例评审和功能用例关系表中的状态 1.单人评审直接更新评审结果 2.多人评审需要计算
String functionalCaseStatus = getFunctionalCaseStatus(request);
extCaseReviewFunctionalCaseMapper.updateStatus(request.getCaseId(), request.getReviewId(), functionalCaseStatus);
//更新用例评审状态(判断所有用例是否结束false进行中true已完成)
boolean completed = updateCaseReviewStatus(request.getCaseId(), request.getReviewId());
//检查是否有@发送@通知
if (StringUtils.isNotBlank(request.getNotifier())) {
List<String> relatedUsers = Arrays.asList(request.getNotifier().split(";"));
sendNotice(relatedUsers, userId, request,NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, NoticeConstants.Event.REVIEW_AT);
}
//发送评审通过不通过通知评审中不发
if (StringUtils.equalsIgnoreCase(request.getStatus(), FunctionalCaseReviewStatus.UN_PASS.toString())) {
sendNotice(new ArrayList<>(), userId, request,NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, NoticeConstants.Event.REVIEW_FAIL);
}
if (StringUtils.equalsIgnoreCase(request.getStatus(), FunctionalCaseReviewStatus.PASS.toString())) {
sendNotice(new ArrayList<>(), userId, request,NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, NoticeConstants.Event.REVIEW_PASSED);
}
//检查用例评审是否结束发送通知
if (completed) {
sendNotice(new ArrayList<>(), userId, request,NoticeConstants.TaskType.CASE_REVIEW_TASK, NoticeConstants.Event.REVIEW_COMPLETED);
}
}
@Async
public void sendNotice(List<String> relatedUsers, String userId,ReviewFunctionalCaseRequest request, String task, String event) {
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(request.getReviewId());
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(request.getCaseId());
Map<String, String> defaultTemplateMap = MessageTemplateUtils.getDefaultTemplateMap();
String template = defaultTemplateMap.get(task + "_" + event);
Map<String, String> defaultSubjectMap = MessageTemplateUtils.getDefaultTemplateSubjectMap();
String subject = defaultSubjectMap.get(task + "_" + event);
User user = userMapper.selectByPrimaryKey(userId);
Map paramMap;
if (StringUtils.equalsIgnoreCase(task,NoticeConstants.TaskType.CASE_REVIEW_TASK)) {
BeanMap beanMap = new BeanMap(caseReview);
paramMap = new HashMap<>(beanMap);
} else {
BeanMap beanMap = new BeanMap(functionalCase);
paramMap = new HashMap<>(beanMap);
paramMap.put("reviewName", caseReview.getName());
}
paramMap.put(NoticeConstants.RelatedUser.OPERATOR, user.getName());
NoticeModel noticeModel = NoticeModel.builder()
.operator(userId)
.context(template)
.subject(subject)
.paramMap(paramMap)
.event(event)
.status((String) paramMap.get("status"))
.excludeSelf(true)
.relatedUsers(relatedUsers)
.build();
noticeSendService.send(task, noticeModel);
}
/**
* 更新用例评审自身的状态
*
* @param caseId 功能用例Id
* @param reviewId 用例评审Id
* @return completed
*/
private boolean updateCaseReviewStatus(String caseId, String reviewId) {
boolean completed = false;
List<String> statusList = new ArrayList<>();
statusList.add(FunctionalCaseReviewStatus.UN_REVIEWED.toString());
statusList.add(FunctionalCaseReviewStatus.UNDER_REVIEWED.toString());
statusList.add(FunctionalCaseReviewStatus.RE_REVIEWED.toString());
Long unCompletedCaseCount = extCaseReviewFunctionalCaseMapper.getUnCompletedCaseCount(reviewId, statusList);
CaseReview caseReview = new CaseReview();
caseReview.setId(reviewId);
if (unCompletedCaseCount > 0L) {
caseReview.setStatus(CaseReviewStatus.UNDERWAY.toString());
} else {
completed = true;
caseReview.setStatus(CaseReviewStatus.COMPLETED.toString());
}
caseReviewMapper.updateByPrimaryKeySelective(caseReview);
return completed;
}
/**
* 计算当前评审的功能用例的评审结果
*
* @param request 评审规则
* @return 功能用例的评审结果
*/
private String getFunctionalCaseStatus(ReviewFunctionalCaseRequest request) {
String functionalCaseStatus;
if (StringUtils.equals(request.getReviewPassRule(), CaseReviewPassRule.SINGLE.toString())) {
functionalCaseStatus = request.getStatus();
} else {
//根据用例ID 查询所有评审人 再查所有评审人最后一次的评审结果只有通过/不通过算结果
CaseReviewHistoryExample caseReviewHistoryExample = new CaseReviewHistoryExample();
caseReviewHistoryExample.createCriteria().andCaseIdEqualTo(request.getCaseId()).andReviewIdEqualTo(request.getReviewId());
List<CaseReviewHistory> caseReviewHistories = caseReviewHistoryMapper.selectByExample(caseReviewHistoryExample);
Map<String, List<CaseReviewHistory>> hasReviewedUserMap = caseReviewHistories.stream().sorted(Comparator.comparingLong(CaseReviewHistory::getCreateTime).reversed()).collect(Collectors.groupingBy(CaseReviewHistory::getCreateUser, Collectors.toList()));
CaseReviewFunctionalCaseUserExample caseReviewFunctionalCaseUserExample = new CaseReviewFunctionalCaseUserExample();
caseReviewFunctionalCaseUserExample.createCriteria().andReviewIdEqualTo(request.getReviewId()).andCaseIdEqualTo(request.getCaseId());
long reviewerNum = caseReviewFunctionalCaseUserMapper.countByExample(caseReviewFunctionalCaseUserExample);
if ((int) reviewerNum > hasReviewedUserMap.size()) {
functionalCaseStatus = FunctionalCaseReviewStatus.UNDER_REVIEWED.toString();
} else {
AtomicBoolean hasUnPass = new AtomicBoolean(false);
AtomicInteger passCount = new AtomicInteger();
hasReviewedUserMap.forEach((k, v) -> {
if (StringUtils.equalsIgnoreCase(v.get(0).getStatus(), FunctionalCaseReviewStatus.UN_PASS.toString())) {
hasUnPass.set(true);
}
if (StringUtils.equalsIgnoreCase(v.get(0).getStatus(), FunctionalCaseReviewStatus.PASS.toString())) {
passCount.set(passCount.get() + 1);
}
});
if (hasUnPass.get()) {
functionalCaseStatus = FunctionalCaseReviewStatus.UN_PASS.toString();
} else {
//检查是否全部是通过全是才是PASS,否则是评审中
if (passCount.get() == hasReviewedUserMap.size()) {
functionalCaseStatus = FunctionalCaseReviewStatus.PASS.toString();
} else {
functionalCaseStatus = FunctionalCaseReviewStatus.UNDER_REVIEWED.toString();
}
}
}
}
return functionalCaseStatus;
}
/**
* 构建评审历史表
*
* @param request request
* @param userId 当前操作人
* @return CaseReviewHistory
*/
private static CaseReviewHistory buildReviewHistory(ReviewFunctionalCaseRequest request, String userId) {
CaseReviewHistory caseReviewHistory = new CaseReviewHistory();
caseReviewHistory.setId(IDGenerator.nextStr());
caseReviewHistory.setReviewId(request.getReviewId());
caseReviewHistory.setCaseId(request.getCaseId());
caseReviewHistory.setStatus(request.getStatus());
if (StringUtils.equalsIgnoreCase(request.getStatus(), FunctionalCaseReviewStatus.UN_PASS.toString())) {
if (StringUtils.isBlank(request.getContent())) {
throw new MSException(Translator.get("case_review_content.not.exist"));
}
} else {
if (StringUtils.isNotBlank(request.getContent())) {
caseReviewHistory.setContent(request.getContent().getBytes());
}
}
caseReviewHistory.setNotifier(request.getNotifier());
caseReviewHistory.setCreateUser(userId);
caseReviewHistory.setCreateTime(System.currentTimeMillis());
return caseReviewHistory;
}
}

View File

@ -0,0 +1,240 @@
package io.metersphere.functional.controller;
import io.metersphere.functional.constants.CaseReviewPassRule;
import io.metersphere.functional.constants.CaseReviewStatus;
import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
import io.metersphere.functional.domain.*;
import io.metersphere.functional.mapper.CaseReviewFunctionalCaseMapper;
import io.metersphere.functional.mapper.CaseReviewHistoryMapper;
import io.metersphere.functional.mapper.CaseReviewMapper;
import io.metersphere.functional.request.CaseReviewRequest;
import io.metersphere.functional.request.ReviewFunctionalCaseRequest;
import io.metersphere.project.domain.Notification;
import io.metersphere.project.domain.NotificationExample;
import io.metersphere.project.mapper.NotificationMapper;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.notice.constants.NoticeConstants;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig;
import java.util.ArrayList;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
public class ReviewFunctionalCaseControllerTests extends BaseTest {
private static final String projectId = "project-review-case-test";
private static final String SAVE_REVIEW = "/review/functional/case/save";
private static final String ADD_CASE_REVIEW = "/case/review/add";
@Resource
private CaseReviewMapper caseReviewMapper;
@Resource
private CaseReviewHistoryMapper caseReviewHistoryMapper;
@Resource
private NotificationMapper notificationMapper;
@Resource
private CaseReviewFunctionalCaseMapper caseReviewFunctionalCaseMapper;
@Test
@Order(0)
@Sql(scripts = {"/dml/init_review_case.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
public void saveReviewSuccess() throws Exception {
//单人评审通过
List<String> caseIds = new ArrayList<>();
caseIds.add("gyqReviewCaseTest");
caseIds.add("gyqReviewCaseTestOne");
List<String> reviewers = new ArrayList<>();
reviewers.add("admin");
reviewers.add("default-project-member-user-gyq");
List<CaseReview> caseReviews = addReview("创建用例评审1", caseIds, reviewers);
String reviewId = caseReviews.get(0).getId();
ReviewFunctionalCaseRequest reviewFunctionalCaseRequest = new ReviewFunctionalCaseRequest();
reviewFunctionalCaseRequest.setReviewId(reviewId);
reviewFunctionalCaseRequest.setCaseId("gyqReviewCaseTest");
reviewFunctionalCaseRequest.setProjectId(projectId);
reviewFunctionalCaseRequest.setStatus(FunctionalCaseReviewStatus.PASS.toString());
reviewFunctionalCaseRequest.setContent("通过了");
reviewFunctionalCaseRequest.setNotifier("default-project-member-user-gyq-2;");
reviewFunctionalCaseRequest.setReviewPassRule(CaseReviewPassRule.SINGLE.toString());
this.requestPostWithOk(SAVE_REVIEW, reviewFunctionalCaseRequest);
CaseReviewHistoryExample caseReviewHistoryExample = new CaseReviewHistoryExample();
caseReviewHistoryExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTest");
List<CaseReviewHistory> caseReviewHistories = caseReviewHistoryMapper.selectByExample(caseReviewHistoryExample);
Assertions.assertEquals(1, caseReviewHistories.size());
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTest");
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
Assertions.assertTrue(StringUtils.equalsIgnoreCase(caseReviewFunctionalCases.get(0).getStatus(),FunctionalCaseReviewStatus.PASS.toString()));
List<CaseReview> caseReviews1 = getCaseReviews("创建用例评审1");
Assertions.assertTrue(StringUtils.equals(caseReviews1.get(0).getStatus(), CaseReviewStatus.UNDERWAY.toString()));
//单人评审不通过
reviewFunctionalCaseRequest = new ReviewFunctionalCaseRequest();
reviewFunctionalCaseRequest.setReviewId(reviewId);
reviewFunctionalCaseRequest.setCaseId("gyqReviewCaseTestOne");
reviewFunctionalCaseRequest.setProjectId(projectId);
reviewFunctionalCaseRequest.setStatus(FunctionalCaseReviewStatus.UN_PASS.toString());
reviewFunctionalCaseRequest.setContent("不通过");
reviewFunctionalCaseRequest.setNotifier("default-project-member-user-gyq-2;");
reviewFunctionalCaseRequest.setReviewPassRule(CaseReviewPassRule.SINGLE.toString());
this.requestPostWithOk(SAVE_REVIEW, reviewFunctionalCaseRequest);
caseReviewHistoryExample = new CaseReviewHistoryExample();
caseReviewHistoryExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestOne");
caseReviewHistories = caseReviewHistoryMapper.selectByExample(caseReviewHistoryExample);
Assertions.assertEquals(1, caseReviewHistories.size());
caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestOne");
caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
Assertions.assertTrue(StringUtils.equalsIgnoreCase(caseReviewFunctionalCases.get(0).getStatus(),FunctionalCaseReviewStatus.UN_PASS.toString()));
caseReviews1 = getCaseReviews("创建用例评审1");
Assertions.assertTrue(StringUtils.equals(caseReviews1.get(0).getStatus(), CaseReviewStatus.COMPLETED.toString()));
NotificationExample notificationExample = new NotificationExample();
notificationExample.createCriteria().andResourceTypeEqualTo(NoticeConstants.TaskType.CASE_REVIEW_TASK);
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
Assertions.assertFalse(notifications.isEmpty());
notificationExample = new NotificationExample();
notificationExample.createCriteria().andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
Assertions.assertFalse(notifications.isEmpty());
}
@Test
@Order(1)
public void saveReviewMultipleSuccess() throws Exception {
//多人评审部分通过
List<String> caseIds = new ArrayList<>();
caseIds.add("gyqReviewCaseTestTwo");
List<String> reviewers = new ArrayList<>();
reviewers.add("admin");
reviewers.add("default-project-member-user-gyq");
List<CaseReview> caseReviews = addReview("创建用例评审2", caseIds, reviewers);
String reviewId = caseReviews.get(0).getId();
ReviewFunctionalCaseRequest reviewFunctionalCaseRequest = new ReviewFunctionalCaseRequest();
reviewFunctionalCaseRequest.setReviewId(reviewId);
reviewFunctionalCaseRequest.setCaseId("gyqReviewCaseTestTwo");
reviewFunctionalCaseRequest.setProjectId(projectId);
reviewFunctionalCaseRequest.setStatus(FunctionalCaseReviewStatus.PASS.toString());
reviewFunctionalCaseRequest.setContent("通过了");
reviewFunctionalCaseRequest.setNotifier("default-project-member-user-gyq-2");
reviewFunctionalCaseRequest.setReviewPassRule(CaseReviewPassRule.MULTIPLE.toString());
this.requestPostWithOk(SAVE_REVIEW, reviewFunctionalCaseRequest);
CaseReviewHistoryExample caseReviewHistoryExample = new CaseReviewHistoryExample();
caseReviewHistoryExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestTwo");
List<CaseReviewHistory> caseReviewHistories = caseReviewHistoryMapper.selectByExample(caseReviewHistoryExample);
Assertions.assertEquals(1, caseReviewHistories.size());
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestTwo");
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
Assertions.assertTrue(StringUtils.equalsIgnoreCase(caseReviewFunctionalCases.get(0).getStatus(),FunctionalCaseReviewStatus.UNDER_REVIEWED.toString()));
List<CaseReview> caseReviews1 = getCaseReviews("创建用例评审2");
Assertions.assertTrue(StringUtils.equals(caseReviews1.get(0).getStatus(), CaseReviewStatus.UNDERWAY.toString()));
}
@Test
@Order(2)
public void saveReviewMultipleAllSuccess() throws Exception {
//多人评审部分通过
List<String> caseIds = new ArrayList<>();
caseIds.add("gyqReviewCaseTestThree");
caseIds.add("gyqReviewCaseTestFour");
List<String> reviewers = new ArrayList<>();
reviewers.add("admin");
List<CaseReview> caseReviews = addReview("创建用例评审3", caseIds, reviewers);
String reviewId = caseReviews.get(0).getId();
ReviewFunctionalCaseRequest reviewFunctionalCaseRequest = new ReviewFunctionalCaseRequest();
reviewFunctionalCaseRequest.setReviewId(reviewId);
reviewFunctionalCaseRequest.setCaseId("gyqReviewCaseTestThree");
reviewFunctionalCaseRequest.setProjectId(projectId);
reviewFunctionalCaseRequest.setStatus(FunctionalCaseReviewStatus.PASS.toString());
reviewFunctionalCaseRequest.setContent("通过了");
reviewFunctionalCaseRequest.setNotifier("default-project-member-user-gyq-2");
reviewFunctionalCaseRequest.setReviewPassRule(CaseReviewPassRule.MULTIPLE.toString());
this.requestPostWithOk(SAVE_REVIEW, reviewFunctionalCaseRequest);
CaseReviewHistoryExample caseReviewHistoryExample = new CaseReviewHistoryExample();
caseReviewHistoryExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestThree");
List<CaseReviewHistory> caseReviewHistories = caseReviewHistoryMapper.selectByExample(caseReviewHistoryExample);
Assertions.assertEquals(1, caseReviewHistories.size());
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestThree");
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
Assertions.assertTrue(StringUtils.equalsIgnoreCase(caseReviewFunctionalCases.get(0).getStatus(),FunctionalCaseReviewStatus.PASS.toString()));
List<CaseReview> caseReviews1 = getCaseReviews("创建用例评审3");
Assertions.assertTrue(StringUtils.equals(caseReviews1.get(0).getStatus(), CaseReviewStatus.UNDERWAY.toString()));
reviewFunctionalCaseRequest = new ReviewFunctionalCaseRequest();
reviewFunctionalCaseRequest.setReviewId(reviewId);
reviewFunctionalCaseRequest.setCaseId("gyqReviewCaseTestFour");
reviewFunctionalCaseRequest.setProjectId(projectId);
reviewFunctionalCaseRequest.setStatus(FunctionalCaseReviewStatus.UN_PASS.toString());
reviewFunctionalCaseRequest.setContent("不通过");
reviewFunctionalCaseRequest.setNotifier("default-project-member-user-gyq-2");
reviewFunctionalCaseRequest.setReviewPassRule(CaseReviewPassRule.MULTIPLE.toString());
this.requestPostWithOk(SAVE_REVIEW, reviewFunctionalCaseRequest);
caseReviewHistoryExample = new CaseReviewHistoryExample();
caseReviewHistoryExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestFour");
caseReviewHistories = caseReviewHistoryMapper.selectByExample(caseReviewHistoryExample);
Assertions.assertEquals(1, caseReviewHistories.size());
caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestFour");
caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
Assertions.assertTrue(StringUtils.equalsIgnoreCase(caseReviewFunctionalCases.get(0).getStatus(),FunctionalCaseReviewStatus.UN_PASS.toString()));
caseReviews1 = getCaseReviews("创建用例评审3");
Assertions.assertTrue(StringUtils.equals(caseReviews1.get(0).getStatus(), CaseReviewStatus.COMPLETED.toString()));
}
@Test
@Order(3)
public void saveReviewFalse() throws Exception {
//多人评审部分通过
List<String> caseIds = new ArrayList<>();
caseIds.add("gyqReviewCaseTestThree");
caseIds.add("gyqReviewCaseTestFour");
List<String> reviewers = new ArrayList<>();
reviewers.add("admin");
List<CaseReview> caseReviews = addReview("创建用例评审4", caseIds, reviewers);
String reviewId = caseReviews.get(0).getId();
ReviewFunctionalCaseRequest reviewFunctionalCaseRequest = new ReviewFunctionalCaseRequest();
reviewFunctionalCaseRequest.setReviewId(reviewId);
reviewFunctionalCaseRequest.setCaseId("gyqReviewCaseTestFour");
reviewFunctionalCaseRequest.setProjectId(projectId);
reviewFunctionalCaseRequest.setStatus(FunctionalCaseReviewStatus.UN_PASS.toString());
reviewFunctionalCaseRequest.setNotifier("default-project-member-user-gyq-2");
reviewFunctionalCaseRequest.setReviewPassRule(CaseReviewPassRule.SINGLE.toString());
this.requestPost(SAVE_REVIEW, reviewFunctionalCaseRequest).andExpect(status().is5xxServerError());
}
private List<CaseReview> addReview(String name, List<String> caseIds, List<String> reviewers) throws Exception {
CaseReviewRequest caseReviewRequest = new CaseReviewRequest();
caseReviewRequest.setProjectId(projectId);
caseReviewRequest.setName(name);
caseReviewRequest.setModuleId("CASE_REVIEW_REAL_MODULE_ID");
caseReviewRequest.setReviewPassRule(CaseReviewPassRule.SINGLE.toString());
caseReviewRequest.setReviewers(reviewers);
caseReviewRequest.setCaseIds(caseIds);
List<String> tags = new ArrayList<>();
tags.add("11");
caseReviewRequest.setTags(tags);
this.requestPostWithOk(ADD_CASE_REVIEW, caseReviewRequest);
return getCaseReviews(name);
}
private List<CaseReview> getCaseReviews(String name) {
CaseReviewExample caseReviewExample = new CaseReviewExample();
caseReviewExample.createCriteria().andNameEqualTo(name);
return caseReviewMapper.selectByExample(caseReviewExample);
}
}

View File

@ -0,0 +1,210 @@
INSERT INTO organization(id, num, name, description, create_time, update_time, create_user, update_user, deleted,
delete_user, delete_time) VALUE
('organization-review-case-test', null, 'organization-review-case-test', 'organization-review-case-test',
UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'admin', 0, null, null);
INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time)
VALUES ('project-review-case-test', null, 'organization-review-case-test', '用例评论项目', '系统默认创建的项目',
'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000),
('project-review-case-test-1', null, 'organization-review-case-test', '用例评论项目1', '系统默认创建的项目1',
'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000),
('project-review-case-test-2', null, 'organization-review-case-test', '用例评论项目2', '系统默认创建的项目2',
'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000),
('project-review-case-test-3', null, 'organization-review-case-test', '用例评论项目3', '系统默认创建的项目3',
'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000);
INSERT INTO project_robot(id, project_id, name, platform, webhook, type, app_key, app_secret, enable, create_user,
create_time, update_user, update_time, description)
VALUES ('test_review_case_message_robot1', 'project-review-case-test', '测试机器人1', 'IN_SITE', 'NONE', null, null,
null, true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, null);
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('review-case_messageOne', 'UPDATE', 'CREATE_USER', 'test_review_case_message_robot1', 'CASE_REVIEW_TASK',
'NONE', 'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000,
true, true, 'message.title.case_review_task_update');
INSERT INTO message_task_blob(id, template)
VALUES ('review-case_messageOne', 'message.case_review_task_update');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('review-case_message2', 'UPDATE', 'FOLLOW_PEOPLE', 'test_review_case_message_robot1', 'CASE_REVIEW_TASK',
'NONE', 'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000,
true, true, 'message.title.case_review_task_update');
INSERT INTO message_task_blob(id, template)
VALUES ('review-case_message2', 'message.case_review_task_update');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('review-case_message3', 'DELETE', 'CREATE_USER', 'test_review_case_message_robot1', 'CASE_REVIEW_TASK', 'NONE',
'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true,
true, 'message.title.case_review_task_delete');
INSERT INTO message_task_blob(id, template)
VALUES ('review-case_message3', 'message.case_review_task_delete');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('review-case_message4', 'REVIEW_COMPLETED', 'CREATE_USER', 'test_review_case_message_robot1',
'CASE_REVIEW_TASK', 'NONE', 'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin',
unix_timestamp() * 1000, true, true, 'message.title.case_review_task_review_completed');
INSERT INTO message_task_blob(id, template)
VALUES ('review-case_message4', 'message.case_review_task_review_completed');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('review-case_messageA', 'REVIEW_COMPLETED', 'default-project-member-user-gyq',
'test_review_case_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-review-case-test', true, 'admin',
unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true,
'message.title.case_review_task_review_completed');
INSERT INTO message_task_blob(id, template)
VALUES ('review-case_messageA', 'message.case_review_task_review_completed');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('review-case_message5', 'CREATE', 'CREATE_USER', 'test_review_case_message_robot1', 'CASE_REVIEW_TASK', 'NONE',
'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true,
true, 'message.title.case_review_task_create');
INSERT INTO message_task_blob(id, template)
VALUES ('review-case_message5', 'message.case_review_task_create');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('review-case_message6', 'CREATE', 'default-project-member-user-gyq', 'test_review_case_message_robot1',
'CASE_REVIEW_TASK', 'NONE', 'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin',
unix_timestamp() * 1000, true, true, 'message.title.case_review_task_create');
INSERT INTO message_task_blob(id, template)
VALUES ('review-case_message6', 'message.case_review_task_create');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('review-case_message7', 'REVIEW_AT', 'NONE', 'test_review_case_message_robot1', 'FUNCTIONAL_CASE_TASK', 'NONE',
'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true,
true, 'message.title.functional_case_task_review_at');
INSERT INTO message_task_blob(id, template)
VALUES ('review-case_message7', 'message.functional_case_task_review_at');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('review-case_message8', 'REVIEW_PASSED', 'default-project-member-user-gyq-2', 'test_review_case_message_robot1',
'FUNCTIONAL_CASE_TASK', 'NONE', 'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin',
unix_timestamp() * 1000, true, true, 'message.title.functional_case_task_review_passed');
INSERT INTO message_task_blob(id, template)
VALUES ('review-case_message8', 'message.functional_case_task_review');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('review-case_message9', 'REVIEW_FAIL', 'default-project-member-user-gyq-2', 'test_review_case_message_robot1',
'FUNCTIONAL_CASE_TASK', 'NONE', 'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin',
unix_timestamp() * 1000, true, true, 'message.title.functional_case_task_review_fail');
INSERT INTO message_task_blob(id, template)
VALUES ('review-case_message9', 'message.functional_case_task_review');
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 ('gyqReviewCaseTest', 1000001, 'test_guo', 'project-review-case-test', 'test_guo', 'gyqTest', 'UN_REVIEWED',
null, 'text',
10001, '111', 'gyqReviewCaseTest', 'success', false, false, true, 'gyq', 'gyq', null, 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 ('gyqReviewCaseTestTwo', 1000001, 'test_guo', 'project-review-case-test', 'test_guo', 'gyqTest', 'UN_REVIEWED',
null, 'text',
10001, '111', 'gyqReviewCaseTestTwo', 'success', false, false, true, 'gyq', 'gyq', null, 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 ('gyqReviewCaseTestThree', 1000001, 'test_guo', 'project-review-case-test', 'test_guo', 'gyqTest', 'UN_REVIEWED',
null, 'text',
10001, '111', 'gyqReviewCaseTestThree', 'success', false, false, true, 'gyq', 'gyq', null, 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 ('gyqReviewCaseTestFour', 1000001, 'test_guo', 'project-review-case-test', 'test_guo', 'gyqTest', 'UN_REVIEWED',
null, 'text',
10001, '111', 'gyqReviewCaseTestFour', 'success', false, false, true, 'gyq', 'gyq', null, 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 ('gyqReviewCaseTestOne', 1000001, 'test_guo', 'project-review-case-test', 'test_guo', 'gyqTest1', 'UN_REVIEWED',
null, 'text',
10001, '111', 'gyqReviewCaseTestOne', 'success', false, false, true, 'gyq', 'gyq', null, 1698058347559,
1698058347559,
null);
INSERT INTO user(id, name, email, password, enable, create_time, update_time, language, last_organization_id, phone,
source,
last_project_id, create_user, update_user, deleted)
VALUES ('default-project-member-user-gyq', 'default-project-member-user1', 'project-member-gyq1@metersphere.io',
MD5('metersphere'),
true, UNIX_TIMESTAMP() * 1000,
UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false),
('default-project-member-user-gyq-1', 'default-project-member-user2', 'project-member-gyq2@metersphere.io',
MD5('metersphere'), true, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL,
'admin',
'admin', 0),
('default-project-member-user-gyq-2', 'default-project-member-user3', 'project-member-gyq3@metersphere.io',
MD5('metersphere'), true, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL,
'admin',
'admin', 0),
('default-project-member-user-gyq-3', 'default-project-member-user4', 'project-member-gyq4@metersphere.io',
MD5('metersphere'), true, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL,
'admin',
'admin', 0);
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
VALUES (UUID(), 'default-project-member-user-gyq', 'org_member', 'organization-review-case-test',
'organization-review-case-test', UNIX_TIMESTAMP() * 1000, 'admin'),
(UUID(), 'default-project-member-user-gyq-1', 'org_member', 'organization-review-case-test',
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
'admin'),
(UUID(), 'default-project-member-user-gyq-2', 'org_member', 'organization-review-case-test',
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
'admin'),
(UUID(), 'default-project-member-user-gyq-3', 'org_member', 'organization-review-case-test',
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
'admin');
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
VALUES (UUID(), 'default-project-member-user-gyq', 'project_admin', 'project-review-case-test',
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
'admin'),
(UUID(), 'default-project-member-user-gyq-1', 'project_admin', 'project-review-case-test',
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
'admin'),
(UUID(), 'default-project-member-user-gyq-2', 'project_admin', 'project-review-case-test',
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
'admin'),
(UUID(), 'default-project-member-user-gyq-3', 'project_admin', 'project-review-case-test',
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
'admin');
INSERT INTO user_role_permission(id, role_id, permission_id)
VALUES ('user_role_gyq_permission1', 'project_admin', 'FUNCTIONAL_CASE:READ+COMMENT');

View File

@ -1,6 +1,7 @@
package io.metersphere.system.config.interceptor; package io.metersphere.system.config.interceptor;
import io.metersphere.functional.domain.CaseReviewFunctionalCaseArchive; import io.metersphere.functional.domain.CaseReviewFunctionalCaseArchive;
import io.metersphere.functional.domain.CaseReviewHistory;
import io.metersphere.functional.domain.FunctionalCaseBlob; import io.metersphere.functional.domain.FunctionalCaseBlob;
import io.metersphere.sdk.util.CompressUtils; import io.metersphere.sdk.util.CompressUtils;
import io.metersphere.system.utils.MybatisInterceptorConfig; import io.metersphere.system.utils.MybatisInterceptorConfig;
@ -22,6 +23,8 @@ public class FunctionalCaseInterceptor {
configList.add(new MybatisInterceptorConfig(FunctionalCaseBlob.class, "expectedResult", CompressUtils.class, "zip", "unzip")); configList.add(new MybatisInterceptorConfig(FunctionalCaseBlob.class, "expectedResult", CompressUtils.class, "zip", "unzip"));
configList.add(new MybatisInterceptorConfig(FunctionalCaseBlob.class, "prerequisite", CompressUtils.class, "zip", "unzip")); configList.add(new MybatisInterceptorConfig(FunctionalCaseBlob.class, "prerequisite", CompressUtils.class, "zip", "unzip"));
configList.add(new MybatisInterceptorConfig(FunctionalCaseBlob.class, "description", CompressUtils.class, "zip", "unzip")); configList.add(new MybatisInterceptorConfig(FunctionalCaseBlob.class, "description", CompressUtils.class, "zip", "unzip"));
configList.add(new MybatisInterceptorConfig(CaseReviewHistory.class, "content", CompressUtils.class, "zip", "unzip"));
return configList; return configList;
} }
} }