feat(测试跟踪): 用例评审修改评审人,自动更新评审用例状态

This commit is contained in:
chenjianxing 2023-02-13 20:19:10 +08:00 committed by jianxing
parent 6fe78e7e3c
commit 285a8390de
11 changed files with 75 additions and 34 deletions

View File

@ -6,6 +6,8 @@ const message = {
commons: {
pre_page: 'Pre page',
next_page: 'Next page',
already_pre_page: 'It\'s already page one',
already_next_page: 'It\'s already last page',
table_select_row_count: 'Selected {0} Record',
header_custom_select_tips: 'Please customize table header by select field',
advance_search_total_suffix: 'results',

View File

@ -6,6 +6,8 @@ const message = {
commons: {
pre_page: '上一页',
next_page: '下一页',
already_pre_page: '已经是第一页',
already_next_page: '已经是最后一页',
table_select_row_count: '已选择 {0} 条',
header_custom_select_tips: '请选择列表中要展示的信息',
advance_search_total_suffix: '个结果',
@ -892,7 +894,7 @@ const message = {
code_segment_desc: '自定义代码片段',
test_case_custom_id: '测试用例自定义ID',
re_review: '重新提审',
re_review_info: '评审中的用例发生变更,用例状态自动切换为重新提审',
re_review_info: '评审活动中的用例发生变更,用例状态自动切换为重新提审',
test_case_custom_id_info: '用例ID默认为系统自增ID',
scenario_custom_id: '场景自定义ID',
scenario_custom_id_info: '场景用例ID默认为系统自增ID',

View File

@ -6,6 +6,8 @@ const message = {
commons: {
pre_page: '上一頁',
next_page: '下一頁',
already_pre_page: '已經是第一頁',
already_next_page: '已經是最後一頁',
table_select_row_count: '已選擇 {0} 條',
header_custom_select_tips: '請選擇列表中要展示的信息',
advance_search_total_suffix: '個結果',
@ -894,7 +896,7 @@ const message = {
scenario_custom_id: '場景自定義ID',
scenario_custom_id_info: '場景用例ID默認為系統自增ID',
re_review: '重新提審',
re_review_info: '評審中的用例發生變更,用例狀態自動切換為重新提審',
re_review_info: '評審活動中的用例發生變更,用例狀態自動切換為重新提審',
version: {
name: '版本',
read: '查看',

View File

@ -11,7 +11,7 @@ public interface ExtTestCaseReviewTestCaseMapper {
List<TestCaseReviewTestCase> getCaseStatusByReviewIds(@Param("reviewIds") List<String> reviewIds);
List<TestCaseReviewTestCase> selectForRuleChange(@Param("reviewId") String reviewId);
List<TestCaseReviewTestCase> selectForReviewChange(@Param("reviewId") String reviewId);
List<TestCaseReviewTestCase> selectForReReview(@Param("caseId") String caseId);
}

View File

@ -15,7 +15,7 @@
#{reviewId}
</foreach>
</select>
<select id="selectForRuleChange" resultType="io.metersphere.base.domain.TestCaseReviewTestCase">
<select id="selectForReviewChange" resultType="io.metersphere.base.domain.TestCaseReviewTestCase">
select id, case_id, status, review_id
from test_case_review_test_case
where review_id = #{reviewId} and (status = 'Pass' or status = 'UnPass' or status = 'Underway');

View File

@ -27,6 +27,7 @@ import io.metersphere.notice.service.NoticeSendService;
import io.metersphere.request.member.QueryMemberRequest;
import io.metersphere.request.testreview.*;
import io.metersphere.utils.ListUtil;
import jakarta.annotation.Resource;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
@ -39,8 +40,6 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@ -220,14 +219,7 @@ public class TestCaseReviewService {
public List<User> getUserByReviewId(TestCaseReview request) {
String reviewId = request.getId();
TestCaseReviewUsersExample testCaseReviewUsersExample = new TestCaseReviewUsersExample();
testCaseReviewUsersExample.createCriteria().andReviewIdEqualTo(reviewId);
List<TestCaseReviewUsers> testCaseReviewUsers = testCaseReviewUsersMapper.selectByExample(testCaseReviewUsersExample);
List<String> userIds = testCaseReviewUsers
.stream()
.map(TestCaseReviewUsers::getUserId)
.collect(Collectors.toList());
List<String> userIds = getReviewUserIds(reviewId);
UserExample userExample = new UserExample();
UserExample.Criteria criteria = userExample.createCriteria();
@ -314,10 +306,7 @@ public class TestCaseReviewService {
List<String> reviewerIds = testCaseReview.getUserIds();
String id = testCaseReview.getId();
TestCaseReviewUsersExample testCaseReviewUsersExample = new TestCaseReviewUsersExample();
testCaseReviewUsersExample.createCriteria().andReviewIdEqualTo(id);
List<TestCaseReviewUsers> testCaseReviewUsers = testCaseReviewUsersMapper.selectByExample(testCaseReviewUsersExample);
List<String> dbReviewIds = testCaseReviewUsers.stream().map(TestCaseReviewUsers::getUserId).collect(Collectors.toList());
List<String> dbReviewIds = getReviewUserIds(id);
reviewerIds.forEach(reviewerId -> {
if (!dbReviewIds.contains(reviewerId)) {
@ -332,18 +321,25 @@ public class TestCaseReviewService {
example.createCriteria().andReviewIdEqualTo(id).andUserIdNotIn(reviewerIds);
testCaseReviewUsersMapper.deleteByExample(example);
// 如果修改了评审人需要覆盖测试用例评审人
editCaseReviewUser(reviewerIds, dbReviewIds, id);
editCaseReviewUser(testCaseReview, reviewerIds, dbReviewIds, id);
}
private void editCaseReviewUser(List<String> reviewerIds, List<String> dbReviewIds, String id) {
private List<String> getReviewUserIds(String reviewId) {
TestCaseReviewUsersExample testCaseReviewUsersExample = new TestCaseReviewUsersExample();
testCaseReviewUsersExample.createCriteria().andReviewIdEqualTo(reviewId);
List<TestCaseReviewUsers> testCaseReviewUsers = testCaseReviewUsersMapper.selectByExample(testCaseReviewUsersExample);
return testCaseReviewUsers.stream().map(TestCaseReviewUsers::getUserId).collect(Collectors.toList());
}
private void editCaseReviewUser(SaveTestCaseReviewRequest testCaseReview, List<String> reviewerIds, List<String> dbReviewIds, String id) {
boolean equalFlag = ListUtil.equalsList(reviewerIds, dbReviewIds);
if (!equalFlag) {
TestCaseReviewTestCaseUsersExample testCaseReviewTestCaseUsersExample = new TestCaseReviewTestCaseUsersExample();
testCaseReviewTestCaseUsersExample.createCriteria().andReviewIdEqualTo(id);
testCaseReviewTestCaseUsersMapper.deleteByExample(testCaseReviewTestCaseUsersExample);
TestCaseReviewTestCaseExample testCaseReviewTestCaseExample = new TestCaseReviewTestCaseExample();
testCaseReviewTestCaseExample.createCriteria().andReviewIdEqualTo(id);
List<TestCaseReviewTestCase> testCaseReviewTestCases = testCaseReviewTestCaseMapper.selectByExample(testCaseReviewTestCaseExample);
List<TestCaseReviewTestCase> testCaseReviewTestCases = testReviewTestCaseService.selectForReviewChange(id);
if (CollectionUtils.isNotEmpty(testCaseReviewTestCases)) {
testCaseReviewTestCases.forEach(review -> {
reviewerIds.forEach(userId -> {
@ -355,6 +351,11 @@ public class TestCaseReviewService {
});
});
}
for (TestCaseReviewTestCase reviewTestCase : testCaseReviewTestCases) {
// 重新计算评审状态
testReviewTestCaseService.reCalcReviewCaseStatus(testCaseReview.getReviewPassRule(), reviewTestCase);
}
}
}
@ -697,11 +698,8 @@ public class TestCaseReviewService {
List<DetailColumn> columns = ReflexObjectUtil.getColumns(review, TestCaseReviewReference.testCaseReviewColumns);
String reviewId = review.getId();
TestCaseReviewUsersExample testCaseReviewUsersExample = new TestCaseReviewUsersExample();
testCaseReviewUsersExample.createCriteria().andReviewIdEqualTo(reviewId);
List<TestCaseReviewUsers> testCaseReviewUsers = testCaseReviewUsersMapper.selectByExample(testCaseReviewUsersExample);
List<String> userIds = getReviewUserIds(reviewId);
List<String> userIds = testCaseReviewUsers.stream().map(TestCaseReviewUsers::getUserId).collect(Collectors.toList());
UserExample example = new UserExample();
example.createCriteria().andIdIn(userIds);
List<User> users = userMapper.selectByExample(example);

View File

@ -28,13 +28,13 @@ import io.metersphere.request.testreview.QueryCaseReviewRequest;
import io.metersphere.request.testreview.TestCaseReviewTestCaseEditRequest;
import io.metersphere.utils.ListUtil;
import io.metersphere.xpack.version.service.ProjectVersionService;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.annotation.Resource;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@ -466,6 +466,15 @@ public class TestReviewTestCaseService {
testCaseReviewTestCaseUsersMapper.insert(insertData);
}
}
// 修改评审人后重新计算用例的评审状态
TestCaseReview testReview = testCaseReviewService.getTestReview(request.getReviewId());
List<TestCaseReviewTestCase> testCaseReviewTestCases = selectForReviewChange(request.getReviewId());
for (TestCaseReviewTestCase reviewTestCase : testCaseReviewTestCases) {
// 重新计算评审状态
reCalcReviewCaseStatus(testReview.getReviewPassRule(), reviewTestCase);
}
}
}
@ -643,13 +652,17 @@ public class TestReviewTestCaseService {
}
public void handlePassRuleChange(String originPassRule, TestCaseReview review) {
List<TestCaseReviewTestCase> reviewTestCases = extTestCaseReviewTestCaseMapper.selectForRuleChange(review.getId());
List<TestCaseReviewTestCase> reviewTestCases = selectForReviewChange(review.getId());
for (TestCaseReviewTestCase reviewTestCase : reviewTestCases) {
// 如果是已经评审过的用例则重新计算
updateReviewCaseStatusForRuleChange(originPassRule, reviewTestCase, review.getReviewPassRule());
}
}
public List<TestCaseReviewTestCase> selectForReviewChange(String reviewId) {
return extTestCaseReviewTestCaseMapper.selectForReviewChange(reviewId);
}
public void updateReviewCaseStatusForRuleChange(String originPassRule, TestCaseReviewTestCase reviewTestCase, String reviewPassRule) {
List<TestCaseCommentDTO> comments =
testCaseCommentService.getCaseComments(reviewTestCase.getCaseId(), TestCaseCommentType.REVIEW.name(), reviewTestCase.getReviewId());
@ -672,6 +685,24 @@ public class TestReviewTestCaseService {
updateReviewCaseStatus(reviewTestCase, reviewPassRule, comments, handleStatusChangeFunc);
}
/**
* 重新计算用例的评审状态
* @param reviewPassRule
* @param reviewTestCase
*/
public void reCalcReviewCaseStatus(String reviewPassRule, TestCaseReviewTestCase reviewTestCase) {
List<TestCaseCommentDTO> comments =
testCaseCommentService.getCaseComments(reviewTestCase.getCaseId(), TestCaseCommentType.REVIEW.name(), reviewTestCase.getReviewId());
comments = filterAgainComments(comments);
if (CollectionUtils.isEmpty(comments)) {
return;
}
updateReviewCaseStatus(reviewTestCase, reviewPassRule, comments, null);
}
/**
* 将已经评审过的用例改成重新提审状态
* @param caseId

View File

@ -32,7 +32,6 @@
</div>
<div class="bar-item click-item"
:disabled="countNum !== total || countNum >= total"
@click="handleNext">
<span>
{{ $t('commons.next_page') }}
@ -41,7 +40,6 @@
</div>
<div class="bar-item click-item"
:disabled="countNum === total || countNum <= 1"
@click="handlePre">
<i class="el-icon-arrow-left"/>
<span>
@ -126,9 +124,17 @@ export default {
},
methods: {
handlePre() {
if (this.countNum === 1) {
this.$error(this.$t('commons.already_pre_page'));
return;
}
this.$emit('pre');
},
handleNext() {
if (this.countNum >= this.total) {
this.$error(this.$t('commons.already_next_page'));
return;
}
this.$emit('next');
},
addComment(comment) {

View File

@ -73,7 +73,7 @@ const message = {
review_pass_rule: 'Review Pass Criteria',
review_pass_rule_all: 'All Pass',
review_pass_rule_single: 'Single Pass',
update_review_reviewer_tip: "Note: Modifying the reviewer will overwrite the reviewers associated with the use case. Please exercise caution!",
update_review_reviewer_tip: "Note: Modifying the reviewer will overwrite the reviewers associated with the use case, and update the review status of the use case, Please exercise caution!",
review_rule_tip: "All pass: Pass only if all reviewers pass <\/br> Single pass: Pass if any reviewers pass",
update_review_rule_tip: "Note: Modifying the standard will affect the reviewed use cases, please exercise caution!",
review_history: "Review History",

View File

@ -73,7 +73,7 @@ const message = {
review_pass_rule: "评审通过标准",
review_pass_rule_all: "全部通过",
review_pass_rule_single: "单人通过",
update_review_reviewer_tip: "注:修改评审人,会覆盖已关联用例的评审人,请谨慎操作!",
update_review_reviewer_tip: "注:修改评审人,会覆盖已关联用例的评审人,并且更新用例的评审状态,请谨慎操作!",
review_rule_tip: "全部通过:所有评审人都通过才通过<\/br>单人通过:任意评审人通过则通过",
update_review_rule_tip: "注:修改通过标准会影响已评审过的用例,请谨慎操作!",
review_history: "评审历史",

View File

@ -73,7 +73,7 @@ const message = {
review_pass_rule: '評審通過標準',
review_pass_rule_all: '全部通過',
review_pass_rule_single: '單人通過',
update_review_reviewer_tip: "註:修改評審人,會覆蓋已關聯用例的評審人,請謹慎操作!",
update_review_reviewer_tip: "註:修改評審人,會覆蓋已關聯用例的評審人,並且更新用例的評審狀態,請謹慎操作!",
review_rule_tip: "全部通過:所有評審人都通過才通過<\/br>單人通過:任意評審人通過則通過",
update_review_rule_tip: "註:修改通過標準會影響已評審過的用例,請謹慎操作!",
review_history: "評審歷史",