diff --git a/backend/src/main/java/io/metersphere/track/controller/TestCaseReviewController.java b/backend/src/main/java/io/metersphere/track/controller/TestCaseReviewController.java index 664612f156..dd0921a569 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestCaseReviewController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestCaseReviewController.java @@ -67,7 +67,7 @@ public class TestCaseReviewController { @PostMapping("/edit") @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) - public void editCaseReview(@RequestBody TestCaseReview testCaseReview) { + public void editCaseReview(@RequestBody SaveTestCaseReviewRequest testCaseReview) { testCaseReviewService.editCaseReview(testCaseReview); } diff --git a/backend/src/main/java/io/metersphere/track/service/TestCaseReviewService.java b/backend/src/main/java/io/metersphere/track/service/TestCaseReviewService.java index 7a4079c695..2587823c4b 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestCaseReviewService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestCaseReviewService.java @@ -26,6 +26,8 @@ import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; @@ -54,6 +56,10 @@ public class TestCaseReviewService { ExtProjectMapper extProjectMapper; @Resource UserService userService; + @Resource + TestCaseMapper testCaseMapper; + @Resource + TestCaseReviewTestCaseMapper testCaseReviewTestCaseMapper; public void saveTestCaseReview(SaveTestCaseReviewRequest reviewRequest) { checkCaseReviewExist(reviewRequest); @@ -119,20 +125,87 @@ public class TestCaseReviewService { .collect(Collectors.toList()); UserExample userExample = new UserExample(); - userExample.createCriteria().andIdIn(userIds); - return userMapper.selectByExample(userExample); + UserExample.Criteria criteria = userExample.createCriteria(); + if (!CollectionUtils.isEmpty(userIds)) { + criteria.andIdIn(userIds); + return userMapper.selectByExample(userExample); + } + return new ArrayList<>(); } public List recent(String currentWorkspaceId) { return extTestCaseReviewMapper.listByWorkspaceId(currentWorkspaceId); } - public void editCaseReview(TestCaseReview testCaseReview) { + public void editCaseReview(SaveTestCaseReviewRequest testCaseReview) { + editCaseReviewer(testCaseReview); + editCaseReviewProject(testCaseReview); testCaseReview.setUpdateTime(System.currentTimeMillis()); checkCaseReviewExist(testCaseReview); testCaseReviewMapper.updateByPrimaryKeySelective(testCaseReview); } + private void editCaseReviewer(SaveTestCaseReviewRequest testCaseReview) { + // 要更新的reviewerIds + List reviewerIds = testCaseReview.getUserIds(); + + String id = testCaseReview.getId(); + TestCaseReviewUsersExample testCaseReviewUsersExample = new TestCaseReviewUsersExample(); + testCaseReviewUsersExample.createCriteria().andReviewIdEqualTo(id); + List testCaseReviewUsers = testCaseReviewUsersMapper.selectByExample(testCaseReviewUsersExample); + List dbReviewIds = testCaseReviewUsers.stream().map(TestCaseReviewUsers::getUserId).collect(Collectors.toList()); + + reviewerIds.forEach(reviewerId -> { + if (!dbReviewIds.contains(reviewerId)) { + TestCaseReviewUsers caseReviewUser = new TestCaseReviewUsers(); + caseReviewUser.setUserId(reviewerId); + caseReviewUser.setReviewId(id); + testCaseReviewUsersMapper.insertSelective(caseReviewUser); + } + }); + + TestCaseReviewUsersExample example = new TestCaseReviewUsersExample(); + example.createCriteria().andReviewIdEqualTo(id).andUserIdNotIn(reviewerIds); + testCaseReviewUsersMapper.deleteByExample(example); + } + + private void editCaseReviewProject(SaveTestCaseReviewRequest testCaseReview) { + List projectIds = testCaseReview.getProjectIds(); + String id = testCaseReview.getId(); + if (!CollectionUtils.isEmpty(projectIds)) { + TestCaseReviewProjectExample testCaseReviewProjectExample = new TestCaseReviewProjectExample(); + testCaseReviewProjectExample.createCriteria().andReviewIdEqualTo(id); + List testCaseReviewProjects = testCaseReviewProjectMapper.selectByExample(testCaseReviewProjectExample); + List dbProjectIds = testCaseReviewProjects.stream().map(TestCaseReviewProject::getProjectId).collect(Collectors.toList()); + projectIds.forEach(projectId -> { + if (!dbProjectIds.contains(projectId)) { + TestCaseReviewProject testCaseReviewProject = new TestCaseReviewProject(); + testCaseReviewProject.setReviewId(id); + testCaseReviewProject.setProjectId(projectId); + testCaseReviewProjectMapper.insert(testCaseReviewProject); + } + }); + + TestCaseReviewProjectExample example = new TestCaseReviewProjectExample(); + example.createCriteria().andReviewIdEqualTo(id).andProjectIdNotIn(projectIds); + testCaseReviewProjectMapper.deleteByExample(example); + + + // 关联的项目下的用例idList + TestCaseExample testCaseExample = new TestCaseExample(); + testCaseExample.createCriteria().andProjectIdIn(projectIds); + List caseList = testCaseMapper.selectByExample(testCaseExample); + List caseIds = caseList.stream().map(TestCase::getId).collect(Collectors.toList()); + + TestCaseReviewTestCaseExample testCaseReviewTestCaseExample = new TestCaseReviewTestCaseExample(); + TestCaseReviewTestCaseExample.Criteria criteria = testCaseReviewTestCaseExample.createCriteria().andReviewIdEqualTo(id); + if (!CollectionUtils.isEmpty(caseIds)) { + criteria.andCaseIdNotIn(caseIds); + } + testCaseReviewTestCaseMapper.deleteByExample(testCaseReviewTestCaseExample); + } + } + private void checkCaseReviewExist(TestCaseReview testCaseReview) { if (testCaseReview.getName() != null) { TestCaseReviewExample example = new TestCaseReviewExample(); diff --git a/backend/src/main/java/io/metersphere/xpack b/backend/src/main/java/io/metersphere/xpack index de612c8ef4..321c869938 160000 --- a/backend/src/main/java/io/metersphere/xpack +++ b/backend/src/main/java/io/metersphere/xpack @@ -1 +1 @@ -Subproject commit de612c8ef47f93c8720ac918d22aaa172977b6f7 +Subproject commit 321c869938357e8c2253e5bd86c963828664ae23 diff --git a/frontend/src/business/components/track/review/components/TestCaseReviewEdit.vue b/frontend/src/business/components/track/review/components/TestCaseReviewEdit.vue index 3ea4a3dfbd..a0941ffb98 100644 --- a/frontend/src/business/components/track/review/components/TestCaseReviewEdit.vue +++ b/frontend/src/business/components/track/review/components/TestCaseReviewEdit.vue @@ -25,7 +25,6 @@ { - this.$success(this.$t('commons.save_success')); - this.dialogFormVisible = false; - this.$emit("refresh"); - }); + + if (this.operationType === 'edit') { + const nowIds = param.projectIds; + let sign = true; + this.dbProjectIds.forEach(dbId => { + if (nowIds.indexOf(dbId) === -1 && sign) { + sign = false; + this.$confirm('取消项目关联会同时取消该项目下已关联的测试用例', '提示', { + confirmButtonText: this.$t('commons.confirm'), + cancelButtonText: this.$t('commons.cancel'), + type: 'warning' + }).then(() => { + this.editTestReview(param); + }).catch(() => { + this.$info(this.$t('commons.cancel')) + }); + } + }); + if (sign) { + this.editTestReview(param); + } + } else { + this.editTestReview(param); + } + + } else { return false; } }); }, + editTestReview(param) { + this.$post('/test/case/review/' + this.operationType, param, () => { + this.$success(this.$t('commons.save_success')); + this.dialogFormVisible = false; + this.$emit("refresh"); + }); + }, getProjects() { this.result = this.$get("/project/listAll", (response) => { if (response.success) { @@ -204,7 +232,8 @@ export default { }); }, statusChange(status) { - + this.form.status = status; + this.$forceUpdate(); }, close() { removeGoBackListener(this.close); diff --git a/frontend/src/business/components/track/review/components/TestCaseReviewList.vue b/frontend/src/business/components/track/review/components/TestCaseReviewList.vue index b708fa6886..6ac142939a 100644 --- a/frontend/src/business/components/track/review/components/TestCaseReviewList.vue +++ b/frontend/src/business/components/track/review/components/TestCaseReviewList.vue @@ -37,42 +37,14 @@ - - - - - - - - - - - + + + + @@ -105,7 +77,7 @@ - + @@ -217,9 +189,6 @@ export default { _sort(column, this.condition); this.initTableData(); }, - reCreate() { - - } } } diff --git a/frontend/src/business/components/track/review/view/components/TestReviewTestCaseList.vue b/frontend/src/business/components/track/review/view/components/TestReviewTestCaseList.vue index c37a0632a5..6b30ffc5fc 100644 --- a/frontend/src/business/components/track/review/view/components/TestReviewTestCaseList.vue +++ b/frontend/src/business/components/track/review/view/components/TestReviewTestCaseList.vue @@ -108,20 +108,8 @@ column-key="status" :label="$t('test_track.plan_view.execute_result')"> @@ -459,6 +447,7 @@ export default { }, startReview() { if (this.tableData.length !== 0) { + this.isReadOnly = false; this.$refs.testReviewTestCaseEdit.openTestCaseEdit(this.tableData[0]); } else { this.$warning("没有关联的评审!"); diff --git a/frontend/src/business/components/xpack b/frontend/src/business/components/xpack index 6ae17a7ced..f2d5a342c8 160000 --- a/frontend/src/business/components/xpack +++ b/frontend/src/business/components/xpack @@ -1 +1 @@ -Subproject commit 6ae17a7ced8f8175531f959ed0a0a6a707ba27dc +Subproject commit f2d5a342c82e629f510550d5778d752bb73bf5e7