diff --git a/backend/src/main/java/io/metersphere/base/domain/IssuesDao.java b/backend/src/main/java/io/metersphere/base/domain/IssuesDao.java index d155fd2a5b..9e8ed963c4 100644 --- a/backend/src/main/java/io/metersphere/base/domain/IssuesDao.java +++ b/backend/src/main/java/io/metersphere/base/domain/IssuesDao.java @@ -14,5 +14,6 @@ public class IssuesDao extends IssuesWithBLOBs { private String resourceName; private long caseCount; private List caseIds; + private String caseId; private int totalIssueCount; } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtIssuesMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtIssuesMapper.java index 4ed0cdb426..b12315220a 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtIssuesMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtIssuesMapper.java @@ -12,6 +12,8 @@ public interface ExtIssuesMapper { List getIssuesByCaseId(@Param("request") IssuesRequest issuesRequest); + List getIssueForMinder(@Param("caseIds") List caseIds); + List getIssues(@Param("request") IssuesRequest issuesRequest); List getRelateIssues(@Param("request") IssuesRequest request); diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtIssuesMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtIssuesMapper.xml index 3da5ec9853..ac4b2c52b1 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtIssuesMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtIssuesMapper.xml @@ -16,6 +16,19 @@ + + - select , diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.xml index 362fc9a66b..beebd732c8 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.xml @@ -448,6 +448,7 @@ t.type, t.node_id, t.steps, t.prerequisite, t.remark, + t.id as caseId, t.node_path, t.method, t.num, t.step_model, t.expected_result, t.step_description from test_plan_test_case pc inner join test_case t on pc.case_id = t.id diff --git a/backend/src/main/java/io/metersphere/track/controller/IssuesController.java b/backend/src/main/java/io/metersphere/track/controller/IssuesController.java index c61106324b..3e99e8c163 100644 --- a/backend/src/main/java/io/metersphere/track/controller/IssuesController.java +++ b/backend/src/main/java/io/metersphere/track/controller/IssuesController.java @@ -4,6 +4,7 @@ import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import io.metersphere.base.domain.Issues; import io.metersphere.base.domain.IssuesDao; +import io.metersphere.base.domain.IssuesWithBLOBs; import io.metersphere.commons.constants.NoticeConstants; import io.metersphere.commons.constants.OperLogConstants; import io.metersphere.commons.utils.PageUtils; @@ -44,8 +45,8 @@ public class IssuesController { @MsAuditLog(module = "track_bug", type = OperLogConstants.CREATE, content = "#msClass.getLogDetails(#issuesRequest)", msClass = IssuesService.class) @SendNotice(taskType = NoticeConstants.TaskType.DEFECT_TASK, target = "#issuesRequest", event = NoticeConstants.Event.CREATE, mailTemplate = "track/IssuesCreate", subject = "缺陷通知") - public void addIssues(@RequestBody IssuesUpdateRequest issuesRequest) { - issuesService.addIssues(issuesRequest); + public IssuesWithBLOBs addIssues(@RequestBody IssuesUpdateRequest issuesRequest) { + return issuesService.addIssues(issuesRequest); } @PostMapping("/update") diff --git a/backend/src/main/java/io/metersphere/track/controller/TestCaseController.java b/backend/src/main/java/io/metersphere/track/controller/TestCaseController.java index 3911cc6bb3..3f86e2da75 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestCaseController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestCaseController.java @@ -82,7 +82,7 @@ public class TestCaseController { } @PostMapping("/list/minder") - public List listDetail(@RequestBody QueryTestCaseRequest request) { + public List listDetail(@RequestBody QueryTestCaseRequest request) { checkPermissionService.checkProjectOwner(request.getProjectId()); return testCaseService.listTestCaseForMinder(request); } diff --git a/backend/src/main/java/io/metersphere/track/dto/TestCaseDTO.java b/backend/src/main/java/io/metersphere/track/dto/TestCaseDTO.java index e8161f2341..d79e9f75a5 100644 --- a/backend/src/main/java/io/metersphere/track/dto/TestCaseDTO.java +++ b/backend/src/main/java/io/metersphere/track/dto/TestCaseDTO.java @@ -1,5 +1,6 @@ package io.metersphere.track.dto; +import io.metersphere.base.domain.IssuesDao; import io.metersphere.base.domain.TestCaseWithBLOBs; import lombok.Getter; import lombok.Setter; @@ -19,4 +20,5 @@ public class TestCaseDTO extends TestCaseWithBLOBs { private String createName; private List caseTags = new ArrayList<>(); + private List issueList = new ArrayList<>(); } diff --git a/backend/src/main/java/io/metersphere/track/dto/TestPlanCaseDTO.java b/backend/src/main/java/io/metersphere/track/dto/TestPlanCaseDTO.java index cbe1fd2985..92d4271bc0 100644 --- a/backend/src/main/java/io/metersphere/track/dto/TestPlanCaseDTO.java +++ b/backend/src/main/java/io/metersphere/track/dto/TestPlanCaseDTO.java @@ -1,5 +1,6 @@ package io.metersphere.track.dto; +import io.metersphere.base.domain.IssuesDao; import io.metersphere.base.domain.TestCaseWithBLOBs; import lombok.Getter; import lombok.Setter; @@ -25,4 +26,5 @@ public class TestPlanCaseDTO extends TestCaseWithBLOBs { private int issuesCount; private List list; + private List issueList; } diff --git a/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java b/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java index dc2e1cc548..0c2476910f 100644 --- a/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java @@ -197,7 +197,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform { issuesMapper.insert(issues); } - protected void insertIssues(IssuesUpdateRequest issuesRequest) { + protected IssuesWithBLOBs insertIssues(IssuesUpdateRequest issuesRequest) { IssuesWithBLOBs issues = new IssuesWithBLOBs(); BeanUtils.copyBean(issues, issuesRequest); issues.setId(issuesRequest.getId()); @@ -207,6 +207,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform { issues.setNum(getNextNum(issuesRequest.getProjectId())); issues.setPlatformStatus(issuesRequest.getPlatformStatus()); issuesMapper.insert(issues); + return issues; } protected int getNextNum(String projectId) { diff --git a/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java b/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java index 140664d934..99248caed4 100644 --- a/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/IssuesPlatform.java @@ -1,6 +1,7 @@ package io.metersphere.track.issue; import io.metersphere.base.domain.IssuesDao; +import io.metersphere.base.domain.IssuesWithBLOBs; import io.metersphere.base.domain.Project; import io.metersphere.dto.UserDTO; import io.metersphere.track.dto.DemandDTO; @@ -27,7 +28,7 @@ public interface IssuesPlatform { * * @param issuesRequest issueRequest */ - void addIssue(IssuesUpdateRequest issuesRequest); + IssuesWithBLOBs addIssue(IssuesUpdateRequest issuesRequest); /** * 更新缺陷 diff --git a/backend/src/main/java/io/metersphere/track/issue/JiraPlatform.java b/backend/src/main/java/io/metersphere/track/issue/JiraPlatform.java index 0766c6514e..1841e06e72 100644 --- a/backend/src/main/java/io/metersphere/track/issue/JiraPlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/JiraPlatform.java @@ -139,7 +139,7 @@ public class JiraPlatform extends AbstractIssuePlatform { } @Override - public void addIssue(IssuesUpdateRequest issuesRequest) { + public IssuesWithBLOBs addIssue(IssuesUpdateRequest issuesRequest) { JiraConfig jiraConfig = setUserConfig(); JSONObject addJiraIssueParam = buildUpdateParam(issuesRequest, jiraConfig.getIssuetype()); @@ -160,10 +160,12 @@ public class JiraPlatform extends AbstractIssuePlatform { issuesRequest.setId(UUID.randomUUID().toString()); // 插入缺陷表 - insertIssues(issuesRequest); + IssuesWithBLOBs res = insertIssues(issuesRequest); // 用例与第三方缺陷平台中的缺陷关联 handleTestCaseIssues(issuesRequest); + + return res; } private JSONObject buildUpdateParam(IssuesUpdateRequest issuesRequest, String issuetypeStr) { diff --git a/backend/src/main/java/io/metersphere/track/issue/LocalPlatform.java b/backend/src/main/java/io/metersphere/track/issue/LocalPlatform.java index ac4c4ccbe4..c7ebc4cb6a 100644 --- a/backend/src/main/java/io/metersphere/track/issue/LocalPlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/LocalPlatform.java @@ -40,7 +40,7 @@ public class LocalPlatform extends LocalAbstractPlatform { } @Override - public void addIssue(IssuesUpdateRequest issuesRequest) { + public IssuesWithBLOBs addIssue(IssuesUpdateRequest issuesRequest) { String issueStatus = "new"; if (StringUtils.isNotBlank(issuesRequest.getCustomFields())) { List fields = JSONObject.parseArray(issuesRequest.getCustomFields(), TestCaseBatchRequest.CustomFiledRequest.class); @@ -67,6 +67,8 @@ public class LocalPlatform extends LocalAbstractPlatform { issuesRequest.setId(id); handleTestCaseIssues(issuesRequest); + + return issues; } @Override diff --git a/backend/src/main/java/io/metersphere/track/issue/TapdPlatform.java b/backend/src/main/java/io/metersphere/track/issue/TapdPlatform.java index 6e4c6c2f67..9fbe762c84 100644 --- a/backend/src/main/java/io/metersphere/track/issue/TapdPlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/TapdPlatform.java @@ -71,7 +71,7 @@ public class TapdPlatform extends AbstractIssuePlatform { } @Override - public void addIssue(IssuesUpdateRequest issuesRequest) { + public IssuesWithBLOBs addIssue(IssuesUpdateRequest issuesRequest) { MultiValueMap param = buildUpdateParam(issuesRequest); TapdBug bug = tapdClient.addIssue(param); @@ -82,10 +82,12 @@ public class TapdPlatform extends AbstractIssuePlatform { issuesRequest.setId(UUID.randomUUID().toString()); // 插入缺陷表 - insertIssues(issuesRequest); + IssuesWithBLOBs issues = insertIssues(issuesRequest); // 用例与第三方缺陷平台中的缺陷关联 handleTestCaseIssues(issuesRequest); + + return issues; } @Override diff --git a/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java b/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java index 061cbe40e0..eb76bf688b 100644 --- a/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java @@ -153,13 +153,15 @@ public class ZentaoPlatform extends AbstractIssuePlatform { } @Override - public void addIssue(IssuesUpdateRequest issuesRequest) { + public IssuesWithBLOBs addIssue(IssuesUpdateRequest issuesRequest) { setUserConfig(); MultiValueMap param = buildUpdateParam(issuesRequest); AddIssueResponse.Issue issue = zentaoClient.addIssue(param); issuesRequest.setPlatformStatus(issue.getStatus()); + IssuesWithBLOBs issues = null; + String id = issue.getId(); if (StringUtils.isNotBlank(id)) { issuesRequest.setPlatformId(id); @@ -170,12 +172,13 @@ public class ZentaoPlatform extends AbstractIssuePlatform { .andPlatformEqualTo(IssuesManagePlatform.Zentao.toString()); if (issuesMapper.selectByExample(issuesExample).size() <= 0) { // 插入缺陷表 - insertIssues(issuesRequest); + issues = insertIssues(issuesRequest); } // 用例与第三方缺陷平台中的缺陷关联 handleTestCaseIssues(issuesRequest); } + return issues; } @Override diff --git a/backend/src/main/java/io/metersphere/track/service/IssuesService.java b/backend/src/main/java/io/metersphere/track/service/IssuesService.java index fd9b5f9a2d..9b875e97a8 100644 --- a/backend/src/main/java/io/metersphere/track/service/IssuesService.java +++ b/backend/src/main/java/io/metersphere/track/service/IssuesService.java @@ -88,15 +88,17 @@ public class IssuesService { } - public void addIssues(IssuesUpdateRequest issuesRequest) { + public IssuesWithBLOBs addIssues(IssuesUpdateRequest issuesRequest) { List platformList = getAddPlatforms(issuesRequest); - platformList.forEach(platform -> { - platform.addIssue(issuesRequest); - }); + IssuesWithBLOBs issues = null; + for (AbstractIssuePlatform platform : platformList) { + issues = platform.addIssue(issuesRequest); + } issuesRequest.getTestCaseIds().forEach(l -> { testCaseIssueService.updateIssuesCount(l); }); saveFollows(issuesRequest.getId(), issuesRequest.getFollows()); + return issues; } diff --git a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java index a0f9d3caed..936b61ee88 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java @@ -15,6 +15,7 @@ import io.metersphere.api.service.ApiAutomationService; import io.metersphere.api.service.ApiTestCaseService; import io.metersphere.base.domain.*; import io.metersphere.base.mapper.*; +import io.metersphere.base.mapper.ext.ExtIssuesMapper; import io.metersphere.base.mapper.ext.ExtTestCaseMapper; import io.metersphere.commons.constants.TestCaseConstants; import io.metersphere.commons.constants.TestCaseReviewStatus; @@ -85,6 +86,9 @@ public class TestCaseService { @Resource ExtTestCaseMapper extTestCaseMapper; + @Resource + ExtIssuesMapper extIssuesMapper; + @Resource UserService userService; @@ -1567,9 +1571,34 @@ public class TestCaseService { return testCaseMapper.selectByExample(example); } - public List listTestCaseForMinder(QueryTestCaseRequest request) { + public List listTestCaseForMinder(QueryTestCaseRequest request) { setDefaultOrder(request); - return extTestCaseMapper.listForMinder(request); + List cases = extTestCaseMapper.listForMinder(request); + List caseIds = cases.stream().map(TestCaseDTO::getId).collect(Collectors.toList()); + HashMap> issueMap = buildMinderIssueMap(caseIds); + for (TestCaseDTO item : cases) { + List issues = issueMap.get(item.getId()); + if (issues != null) { + item.setIssueList(issues); + } + } + return cases; + } + + public HashMap> buildMinderIssueMap(List caseIds) { + HashMap> issueMap = new HashMap<>(); + if (CollectionUtils.isNotEmpty(caseIds)) { + List issues = extIssuesMapper.getIssueForMinder(caseIds); + for (IssuesDao item : issues) { + List list = issueMap.get(item.getCaseId()); + if (list == null) { + list = new ArrayList<>(); + } + list.add(item); + issueMap.put(item.getCaseId(), list); + } + } + return issueMap; } public List getTestCaseByIds(List testCaseIds) { diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanTestCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanTestCaseService.java index 79dc991719..83cea2585f 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanTestCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanTestCaseService.java @@ -63,6 +63,8 @@ public class TestPlanTestCaseService { private TestCaseTestMapper testCaseTestMapper; @Resource private TestCaseCommentService testCaseCommentService; + @Resource + private TestCaseService testCaseService; public List listAll() { TestPlanTestCaseExample example = new TestPlanTestCaseExample(); @@ -307,7 +309,16 @@ public class TestPlanTestCaseService { } }); request.setOrders(orders); - return extTestPlanTestCaseMapper.listForMinder(request); + List cases = extTestPlanTestCaseMapper.listForMinder(request); + List caseIds = cases.stream().map(TestPlanCaseDTO::getCaseId).collect(Collectors.toList()); + HashMap> issueMap = testCaseService.buildMinderIssueMap(caseIds); + for (TestPlanCaseDTO item : cases) { + List issues = issueMap.get(item.getCaseId()); + if (issues != null) { + item.setIssueList(issues); + } + } + return cases; } public void editTestCaseForMinder(List testPlanTestCases) { diff --git a/backend/src/main/java/io/metersphere/xpack b/backend/src/main/java/io/metersphere/xpack index 33d1b2a4d2..0a737ba93c 160000 --- a/backend/src/main/java/io/metersphere/xpack +++ b/backend/src/main/java/io/metersphere/xpack @@ -1 +1 @@ -Subproject commit 33d1b2a4d29059882f026cb3f70653fca18381e4 +Subproject commit 0a737ba93ccb914af26db8fed1ac6a927081816a diff --git a/frontend/package.json b/frontend/package.json index 04abffbcf9..fa17225c97 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -54,7 +54,7 @@ "vue-float-action-button": "^0.6.6", "vue-i18n": "^8.15.3", "vue-jsonpath-picker": "^1.1.5", - "vue-minder-editor-plus": "1.0.35", + "vue-minder-editor-plus": "1.0.36", "vue-papa-parse": "^2.0.0", "vue-pdf": "^4.2.0", "vue-router": "^3.1.3", diff --git a/frontend/src/business/components/track/case/components/IssueRelateList.vue b/frontend/src/business/components/track/case/components/IssueRelateList.vue index 9e4f446ede..3cfa423058 100644 --- a/frontend/src/business/components/track/case/components/IssueRelateList.vue +++ b/frontend/src/business/components/track/case/components/IssueRelateList.vue @@ -72,13 +72,15 @@ import {ISSUE_STATUS_MAP} from "@/common/js/table-constants"; import MsTablePagination from "@/business/components/common/pagination/TablePagination"; import {getPageInfo} from "@/common/js/tableUtils"; import {getCurrentProjectID} from "@/common/js/utils"; +import {getIssueTemplate} from "../../../../../network/custom-field-template"; export default { name: "IssueRelateList", components: {MsTablePagination, IssueDescriptionTableItem, MsTableColumn, MsTable, MsEditDialog}, data() { return { page: getPageInfo(), - visible: false + visible: false, + isThirdPart: false } }, computed: { @@ -89,7 +91,17 @@ export default { return getCurrentProjectID(); } }, - props: ['caseId', 'isThirdPart'], + props: ['caseId'], + created() { + getIssueTemplate() + .then((template) => { + if (template.platform === 'metersphere') { + this.isThirdPart = false; + } else { + this.isThirdPart = true; + } + }); + }, methods: { open() { this.getIssues(); @@ -107,7 +119,7 @@ export default { param.caseId = this.caseId; testCaseIssueRelate(param, () => { this.visible = false; - this.$emit('refresh'); + this.$emit('refresh', this.$refs.table.selectRows); }); } } diff --git a/frontend/src/business/components/track/case/components/TestCaseEditOtherInfo.vue b/frontend/src/business/components/track/case/components/TestCaseEditOtherInfo.vue index 0030d52341..3487d83417 100644 --- a/frontend/src/business/components/track/case/components/TestCaseEditOtherInfo.vue +++ b/frontend/src/business/components/track/case/components/TestCaseEditOtherInfo.vue @@ -13,15 +13,6 @@ - - - - - - - - - diff --git a/frontend/src/business/components/track/case/components/TestCaseIssueRelate.vue b/frontend/src/business/components/track/case/components/TestCaseIssueRelate.vue index 1ab1930811..248ec8c533 100644 --- a/frontend/src/business/components/track/case/components/TestCaseIssueRelate.vue +++ b/frontend/src/business/components/track/case/components/TestCaseIssueRelate.vue @@ -1,6 +1,6 @@ @@ -120,7 +120,8 @@ export default { exec: this.deleteIssue } ], - status: [] + status: [], + issueRelateVisible: false } }, props: ['caseId', 'readOnly','planId'], @@ -175,7 +176,7 @@ export default { this.page.result = result; } }, - appIssue() { + addIssue() { if (!this.caseId) { this.$warning(this.$t('api_test.automation.save_case_info')); return; diff --git a/frontend/src/business/components/track/case/components/TestPlanIssueEdit.vue b/frontend/src/business/components/track/case/components/TestPlanIssueEdit.vue index 7d26d3299f..a2f7373251 100644 --- a/frontend/src/business/components/track/case/components/TestPlanIssueEdit.vue +++ b/frontend/src/business/components/track/case/components/TestPlanIssueEdit.vue @@ -7,7 +7,7 @@ append-to-body ref="msEditDialog"> @@ -44,6 +44,9 @@ export default { }, confirm() { this.$refs.issueEditDetail.save(); + }, + refresh(data) { + this.$emit('refresh', data); } } }; diff --git a/frontend/src/business/components/track/common/minder/TestCaseMinder.vue b/frontend/src/business/components/track/common/minder/TestCaseMinder.vue index 121c9a265e..0f4c7217a3 100644 --- a/frontend/src/business/components/track/common/minder/TestCaseMinder.vue +++ b/frontend/src/business/components/track/common/minder/TestCaseMinder.vue @@ -1,20 +1,25 @@