fix: 解决冲突

This commit is contained in:
chenjianxing 2021-05-21 17:57:15 +08:00 committed by jianxing
parent f2e8340be1
commit 1bef9ff84b
18 changed files with 255 additions and 63 deletions

View File

@ -11,4 +11,6 @@ public interface ExtIssuesMapper {
List<IssuesDao> getIssuesByCaseId(@Param("request") IssuesRequest issuesRequest);
List<IssuesDao> getIssuesByProjectId(@Param("request") IssuesRequest issuesRequest);
List<IssuesDao> getRelateIssues(@Param("request") IssuesRequest request);
}

View File

@ -20,6 +20,17 @@
<include refid="queryWhereCondition"/>
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>
</select>
<select id="getRelateIssues" resultType="io.metersphere.base.domain.IssuesDao">
select issues.id, issues.title, issues.project_id, issues.create_time, issues.update_time,
issues.description, issues.status, issues.platform, issues.custom_fields,
issues.lastmodify
from issues
left join
test_case_issues on issues.id = test_case_issues.issues_id
<include refid="queryWhereCondition"/>
and test_case_issues.issues_id is null
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>
</select>
<sql id="queryWhereCondition">
<where>

View File

@ -17,15 +17,11 @@ public class TestCaseExcelData {
@ExcelIgnore
private String nodePath;
@ExcelIgnore
private String type;
@ExcelIgnore
private String maintainer;
@ExcelIgnore
private String priority;
@ExcelIgnore
private String tags;
// @ExcelIgnore
// private String method;
@ExcelIgnore
private String prerequisite;
@ExcelIgnore

View File

@ -1,5 +1,6 @@
package io.metersphere.excel.domain;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import io.metersphere.excel.annotation.NotRequired;
@ -34,11 +35,6 @@ public class TestCaseExcelDataCn extends TestCaseExcelData {
@Pattern(regexp = "^(?!.*//).*$", message = "{incorrect_format}")
private String nodePath;
@NotBlank(message = "{cannot_be_null}")
@ExcelProperty("用例类型")
@Pattern(regexp = "(^functional$)|(^performance$)|(^api$)", message = "{test_case_type_validate}")
private String type;
@NotBlank(message = "{cannot_be_null}")
@ExcelProperty("维护人")
private String maintainer;

View File

@ -34,11 +34,6 @@ public class TestCaseExcelDataTw extends TestCaseExcelData {
@Pattern(regexp = "^(?!.*//).*$", message = "{incorrect_format}")
private String nodePath;
@NotBlank(message = "{cannot_be_null}")
@ExcelProperty("用例類型")
@Pattern(regexp = "(^functional$)|(^performance$)|(^api$)", message = "{test_case_type_validate}")
private String type;
@NotBlank(message = "{cannot_be_null}")
@ExcelProperty("維護人")
private String maintainer;

View File

@ -35,11 +35,6 @@ public class TestCaseExcelDataUs extends TestCaseExcelData {
@Pattern(regexp = "^(?!.*//).*$", message = "{incorrect_format}")
private String nodePath;
@NotBlank(message = "{cannot_be_null}")
@ExcelProperty("Type")
@Pattern(regexp = "(^functional$)|(^performance$)|(^api$)", message = "{test_case_type_validate}")
private String type;
@NotBlank(message = "{cannot_be_null}")
@ExcelProperty("Maintainer")
private String maintainer;

View File

@ -32,6 +32,12 @@ public class IssuesController {
return PageUtils.setPageInfo(page, issuesService.list(request));
}
@PostMapping("/list/relate/{goPage}/{pageSize}")
public Pager<List<IssuesDao>> relateList(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody IssuesRequest request) {
Page<List<Issues>> page = PageHelper.startPage(goPage, pageSize, true);
return PageUtils.setPageInfo(page, issuesService.relateList(request));
}
@PostMapping("/add")
@MsAuditLog(module = "track_bug", type = OperLogConstants.CREATE, content = "#msClass.getLogDetails(#issuesRequest)", msClass = IssuesService.class)
public void addIssues(@RequestBody IssuesUpdateRequest issuesRequest) {

View File

@ -22,4 +22,9 @@ public class TestCaseIssuesController {
public List<TestCaseDTO> list(@RequestBody IssuesRelevanceRequest request) {
return testCaseIssueService.list(request);
}
@PostMapping("/relate")
public void relate(@RequestBody IssuesRelevanceRequest request) {
testCaseIssueService.relate(request);
}
}

View File

@ -15,6 +15,8 @@ public class IssuesRelevanceRequest {
*/
private String issuesId;
private String caseId;
/**
* 当选择关联全部用例时把加载条件送到后台从后台查询
*/
@ -25,5 +27,7 @@ public class IssuesRelevanceRequest {
*/
private List<String> testCaseIds = new ArrayList<>();
private List<String> issueIds;
private Boolean checked;
}

View File

@ -423,4 +423,8 @@ public class IssuesService {
}
return null;
}
public List<IssuesDao> relateList(IssuesRequest request) {
return extIssuesMapper.getRelateIssues(request);
}
}

View File

@ -6,6 +6,7 @@ import io.metersphere.base.mapper.IssuesMapper;
import io.metersphere.base.mapper.TestCaseIssuesMapper;
import io.metersphere.track.dto.TestCaseDTO;
import io.metersphere.track.request.issues.IssuesRelevanceRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -13,6 +14,7 @@ import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@Service
@ -58,4 +60,30 @@ public class TestCaseIssueService {
.map(TestCaseIssues::getTestCaseId)
.collect(Collectors.toList());
}
public void relate(IssuesRelevanceRequest request) {
if (StringUtils.isNotBlank(request.getCaseId())) {
List<String> issueIds = request.getIssueIds();
if (!CollectionUtils.isEmpty(issueIds)) {
issueIds.forEach(issueId -> {
create(request.getCaseId(), issueId);
});
}
} else if (StringUtils.isNotBlank(request.getIssuesId())) {
List<String> caseIds = request.getTestCaseIds();
if (!CollectionUtils.isEmpty(caseIds)) {
caseIds.forEach(caseId -> {
create(caseId, request.getIssuesId());
});
}
}
}
public void create(String caseId, String issueId) {
TestCaseIssues testCaseIssues = new TestCaseIssues();
testCaseIssues.setId(UUID.randomUUID().toString());
testCaseIssues.setTestCaseId(caseId);
testCaseIssues.setIssuesId(issueId);
testCaseIssuesMapper.insert(testCaseIssues);
}
}

View File

@ -0,0 +1,102 @@
<template>
<ms-edit-dialog
:visible.sync="visible"
:title="'关联缺陷'"
@confirm="save"
ref="relevanceDialog">
<ms-table
v-loading="page.result.loading"
:data="page.data"
:condition="page.condition"
:total="total"
:page-size.sync="page.pageSize"
:show-select-all="false"
@handlePageChange="getIssues"
@refresh="getIssues"
ref="table">
<ms-table-column
:label="$t('test_track.issue.id')"
prop="id">
</ms-table-column>
<ms-table-column
:label="$t('test_track.issue.title')"
prop="title">
</ms-table-column>
<ms-table-column
:label="$t('test_track.issue.status')"
prop="status">
<template v-slot="scope">
<span>{{ issueStatusMap[scope.row.status] ? issueStatusMap[scope.row.status] : scope.row.status }}</span>
</template>
</ms-table-column>
<ms-table-column
:label="$t('test_track.issue.platform')"
prop="platform">
</ms-table-column>
<issue-description-table-item/>
</ms-table>
<ms-table-pagination :change="getIssues" :current-page.sync="page.currentPage" :page-size.sync="page.pageSize" :total="page.total"/>
</ms-edit-dialog>
</template>
<script>
import MsEditDialog from "@/business/components/common/components/MsEditDialog";
import MsTable from "@/business/components/common/components/table/MsTable";
import MsTableColumn from "@/business/components/common/components/table/Ms-table-column";
import {getRelateIssues, testCaseIssueRelate} from "@/network/Issue";
import IssueDescriptionTableItem from "@/business/components/track/issue/IssueDescriptionTableItem";
import {ISSUE_STATUS_MAP} from "@/common/js/table-constants";
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
import {getPageInfo} from "@/common/js/tableUtils";
export default {
name: "IssueRelateList",
components: {MsTablePagination, IssueDescriptionTableItem, MsTableColumn, MsTable, MsEditDialog},
data() {
return {
page: getPageInfo(),
visible: false
}
},
computed: {
issueStatusMap() {
return ISSUE_STATUS_MAP;
},
projectId() {
return this.$store.state.projectId;
}
},
props: ['caseId'],
methods: {
open() {
this.getIssues();
this.visible = true;
},
getIssues() {
this.page.condition.projectId = this.projectId;
this.page.result = getRelateIssues(this.page);
},
save() {
let param = {};
param.caseId = this.caseId;
param.issueIds = Array.from(this.$refs.table.selectRows).map(i => i.id);
param.caseId = this.caseId;
testCaseIssueRelate(param, () => {
this.visible = false;
this.$emit('refresh');
});
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,6 +1,7 @@
<template>
<div>
<el-button class="add-btn" :disabled="readOnly" type="primary" size="mini" @click="appIssue">{{ $t('test_track.issue.add_issue') }}</el-button>
<el-button class="add-btn" :disabled="readOnly" type="primary" size="mini" @click="relateIssue">{{ $t('test_track.case.relate_issue') }}</el-button>
<el-tooltip class="item" effect="dark"
:content="$t('test_track.issue.platform_tip')"
placement="right">
@ -61,6 +62,7 @@
</ms-table>
<test-plan-issue-edit :case-id="caseId" @refresh="getIssues" ref="issueEdit"/>
<IssueRelateList :case-id="caseId" @refresh="getIssues" ref="issueRelate"/>
</div>
</template>
@ -70,9 +72,10 @@ import MsTable from "@/business/components/common/components/table/MsTable";
import MsTableColumn from "@/business/components/common/components/table/Ms-table-column";
import IssueDescriptionTableItem from "@/business/components/track/issue/IssueDescriptionTableItem";
import {ISSUE_STATUS_MAP} from "@/common/js/table-constants";
import IssueRelateList from "@/business/components/track/case/components/IssueRelateList";
export default {
name: "TestCaseIssueRelate",
components: {IssueDescriptionTableItem, MsTableColumn, MsTable, TestPlanIssueEdit},
components: {IssueRelateList, IssueDescriptionTableItem, MsTableColumn, MsTable, TestPlanIssueEdit},
data() {
return {
issues: [],
@ -100,6 +103,13 @@ export default {
}
this.$refs.issueEdit.open();
},
relateIssue() {
if (!this.caseId) {
this.$warning(this.$t('api_test.automation.save_case_info'));
return;
}
this.$refs.issueRelate.open();
},
closeIssue(row) {
if (row.status === 'closed') {
this.$success(this.$t('test_track.issue.close_success'));

View File

@ -1,5 +1,5 @@
<template>
<el-main v-loading="result.loading" class="container">
<el-main v-loading="result.loading" class="container" :style="isPlan ? '' : 'height: calc(100vh - 62px)'">
<el-scrollbar>
<el-form :model="form" :rules="rules" label-position="right" label-width="140px" ref="form">
@ -264,9 +264,6 @@ export default {
<style scoped>
.container {
height: calc(100vh - 62px);
}
.filed-list {
margin-top: 30px;

View File

@ -3,16 +3,16 @@
<el-card>
<template v-slot:header>
<ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="getIssues" @create="handleCreate"
<ms-table-header :is-tester-permission="true" :condition.sync="page.condition" @search="getIssues" @create="handleCreate"
:create-tip="$t('test_track.issue.create_issue')" :title="$t('test_track.issue.issue_list')" :tip="$t('issue.search_name')" :have-search="false"/>
</template>
<ms-table
v-loading="result.loading"
:data="tableData"
:condition="condition"
:total="total"
:page-size.sync="pageSize"
v-loading="page.result.loading"
:data="page.data"
:condition="page.condition"
:total="page.total"
:page-size.sync="page.pageSize"
:operators="operators"
:show-select-all="false"
@handlePageChange="getIssues"
@ -50,7 +50,7 @@
</ms-table>
<ms-table-pagination :change="getIssues" :current-page.sync="currentPage" :page-size.sync="pageSize" :total="total"/>
<ms-table-pagination :change="getIssues" :current-page.sync="page.currentPage" :page-size.sync="page.pageSize" :total="page.total"/>
<issue-edit @refresh="getIssues" ref="issueEdit"/>
@ -74,6 +74,8 @@ import {
import MsTableHeader from "@/business/components/common/components/MsTableHeader";
import IssueDescriptionTableItem from "@/business/components/track/issue/IssueDescriptionTableItem";
import IssueEdit from "@/business/components/track/issue/IssueEdit";
import {getIssues} from "@/network/Issue";
import {getPageInfo} from "@/common/js/tableUtils";
export default {
name: "CustomFieldList",
components: {
@ -83,12 +85,7 @@ export default {
MsTablePagination, MsTableButton, MsTableOperators, MsTableColumn, MsTable},
data() {
return {
tableData: [],
condition: {},
total: 0,
pageSize: 10,
currentPage: 1,
result: {},
page: getPageInfo(),
operators: [
{
tip: this.$t('commons.edit'), icon: "el-icon-edit",
@ -131,31 +128,8 @@ export default {
},
methods: {
getIssues() {
this.condition.projectId = this.projectId;
this.result = this.$post('issues/list/' + this.currentPage + '/' + this.pageSize,
this.condition, (response) => {
let data = response.data;
this.total = data.itemCount;
this.tableData = data.listObject;
for (let i = 0; i < this.tableData.length; i++) {
if (this.tableData[i]) {
if (this.tableData[i].platform !== 'Local') {
this.result = this.$post("issues/get/platform/issue", this.tableData[i]).then(response => {
let issues = response.data.data;
if (issues) {
this.$set(this.tableData[i], "title", issues.title ? issues.title : "--");
this.$set(this.tableData[i], "description", issues.description ? issues.description : "--");
this.$set(this.tableData[i], "status", issues.status ? issues.status : 'delete');
}
}).catch(() => {
this.$set(this.tableData[i], "title", "--");
this.$set(this.tableData[i], "description", "--");
this.$set(this.tableData[i], "status", "--");
});
}
}
}
});
this.page.condition.projectId = this.projectId;
this.page.result = getIssues(this.page);
},
handleEdit(data) {
this.$refs.issueEdit.open(data);
@ -171,7 +145,7 @@ export default {
this.$refs.issueEdit.open(copyData);
},
handleDelete(data) {
this.result = this.$get('issues/delete/' + data.id, () => {
this.page.result = this.$get('issues/delete/' + data.id, () => {
this.$success(this.$t('commons.delete_success'));
this.getIssues();
});

View File

@ -192,3 +192,13 @@ export function deepClone(source) {
return targetObj;
}
export function getPageInfo() {
return {
total: 0,
pageSize: 10,
currentPage: 1,
result: {},
data: [],
condition: {},
}
}

View File

@ -0,0 +1,52 @@
import {post} from "@/common/js/ajax";
import {getPageDate} from "@/network/network-utils";
export function buildIssues(data, page) {
for (let i = 0; i < data.length; i++) {
if (data[i]) {
if (data[i].platform !== 'Local') {
page.result = buildPlatformIssue(data[i]);
}
}
}
page.data = data;
}
export function getIssues(page) {
return post('issues/list/' + page.currentPage + '/' + page.pageSize, page.condition, (response) => {
let data = getPageDate(response, page);
buildIssues(data, page);
});
}
export function buildPlatformIssue(data) {
return post("issues/get/platform/issue", data).then(response => {
let issues = response.data.data;
if (issues) {
data.title = issues.title ? issues.title : '--';
data.description = issues.description ? issues.description : '--';
data.status = issues.status ? issues.status : 'delete';
}
}).catch(() => {
data.title = '--';
data.description = '--';
data.status = '--';
});
}
export function testCaseIssueRelate(param, success) {
return post('test/case/issues/relate', param, (response) => {
if (success) {
success(response);
}
});
}
export function getRelateIssues(page) {
return post('issues/list/relate/' + page.currentPage + '/' + page.pageSize, page.condition, (response) => {
let data = getPageDate(response, page);
buildIssues(data, page);
});
}

View File

@ -0,0 +1,5 @@
export function getPageDate(response, page) {
let data = response.data;
page.total = data.itemCount;
return data.listObject;
}