feat: 脑图用例编辑
This commit is contained in:
parent
82b004df60
commit
b5709cc998
|
@ -18,6 +18,7 @@ import io.metersphere.track.dto.TestPlanCaseDTO;
|
|||
import io.metersphere.track.request.testcase.EditTestCaseRequest;
|
||||
import io.metersphere.track.request.testcase.QueryTestCaseRequest;
|
||||
import io.metersphere.track.request.testcase.TestCaseBatchRequest;
|
||||
import io.metersphere.track.request.testcase.TestCaseMinderEditRequest;
|
||||
import io.metersphere.track.request.testplan.FileOperationRequest;
|
||||
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
|
||||
import io.metersphere.track.service.TestCaseService;
|
||||
|
@ -59,6 +60,12 @@ public class TestCaseController {
|
|||
return testCaseService.listTestCase(request);
|
||||
}
|
||||
|
||||
@GetMapping("/list/detail/{projectId}")
|
||||
public List<TestCaseWithBLOBs> listDetail(@PathVariable String projectId) {
|
||||
checkPermissionService.checkProjectOwner(projectId);
|
||||
return testCaseService.listTestCaseDetail(projectId);
|
||||
}
|
||||
|
||||
/*jenkins项目下所有接口和性能测试用例*/
|
||||
@GetMapping("/list/method/{projectId}")
|
||||
public List<TestCaseDTO> listByMethod(@PathVariable String projectId) {
|
||||
|
@ -195,4 +202,11 @@ public class TestCaseController {
|
|||
return testCaseService.addTestCase(testCaseWithBLOBs);
|
||||
}
|
||||
|
||||
@PostMapping("/minder/edit")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public void minderEdit(@RequestBody TestCaseMinderEditRequest request) {
|
||||
testCaseService.minderEdit(request);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.track.request.testcase;
|
||||
|
||||
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TestCaseMinderEditRequest {
|
||||
private String projectId;
|
||||
List<TestCaseWithBLOBs> data;
|
||||
}
|
|
@ -32,6 +32,7 @@ import io.metersphere.track.dto.TestCaseDTO;
|
|||
import io.metersphere.track.request.testcase.EditTestCaseRequest;
|
||||
import io.metersphere.track.request.testcase.QueryTestCaseRequest;
|
||||
import io.metersphere.track.request.testcase.TestCaseBatchRequest;
|
||||
import io.metersphere.track.request.testcase.TestCaseMinderEditRequest;
|
||||
import io.metersphere.xmind.XmindCaseParser;
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -705,4 +706,23 @@ public class TestCaseService {
|
|||
return extTestCaseMapper.list(request);
|
||||
}
|
||||
|
||||
public List<TestCaseWithBLOBs> listTestCaseDetail(String projectId) {
|
||||
TestCaseExample testCaseExample = new TestCaseExample();
|
||||
testCaseExample.createCriteria().andProjectIdEqualTo(projectId);
|
||||
return testCaseMapper.selectByExampleWithBLOBs(testCaseExample);
|
||||
}
|
||||
|
||||
public void minderEdit(TestCaseMinderEditRequest request) {
|
||||
List<TestCaseWithBLOBs> data = request.getData();
|
||||
data.forEach(item -> {
|
||||
item.setProjectId(request.getProjectId());
|
||||
if (StringUtils.isBlank(item.getId()) || item.getId().length() < 20) {
|
||||
item.setId(UUID.randomUUID().toString());
|
||||
item.setMaintainer(SessionUtils.getUserId());
|
||||
addTestCase(item);
|
||||
} else {
|
||||
editTestCase(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<template>
|
||||
<div class="minder">
|
||||
<minder-editor v-if="isActive"
|
||||
<minder-editor
|
||||
v-if="isActive"
|
||||
class="minder-container"
|
||||
:import-json="importJson"
|
||||
:height="700"
|
||||
@save="save"
|
||||
/>
|
||||
</div>
|
||||
|
@ -20,10 +22,10 @@ export default {
|
|||
return []
|
||||
}
|
||||
},
|
||||
data: {
|
||||
type: Array,
|
||||
dataMap: {
|
||||
type: Map,
|
||||
default() {
|
||||
return []
|
||||
return new Map();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -52,7 +54,9 @@ export default {
|
|||
root: {
|
||||
data: {
|
||||
text: "全部用例",
|
||||
disable: true
|
||||
disable: true,
|
||||
id: "root",
|
||||
path: ""
|
||||
},
|
||||
children: []
|
||||
},
|
||||
|
@ -62,33 +66,46 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.parse(this.importJson.root, this.treeNodes);
|
||||
this.reload();
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
dataMap() {
|
||||
this.$nextTick(() => {
|
||||
this.parse(this.importJson.root, this.treeNodes);
|
||||
this.reload();
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
save(data) {
|
||||
console.log(data);
|
||||
// console.log(this.treeNodes);
|
||||
this.$emit('save', data)
|
||||
},
|
||||
parse(root, children) {
|
||||
root.children = [];
|
||||
// 添加数据节点
|
||||
let dataNodes = this.dataMap.get(root.data.id);
|
||||
if (dataNodes) {
|
||||
dataNodes.forEach((dataNode) => {
|
||||
root.children.push(dataNode);
|
||||
})
|
||||
}
|
||||
|
||||
if (children == null || children.length < 1) {
|
||||
return;
|
||||
}
|
||||
root.children = [];
|
||||
|
||||
children.forEach((item) => {
|
||||
let node = {
|
||||
data: {
|
||||
text: item.name,
|
||||
id: item.id,
|
||||
disable: true,
|
||||
// resource: ['#']
|
||||
path: root.data.path + "/" + item.name,
|
||||
expandState:"collapse"
|
||||
},
|
||||
}
|
||||
root.children.push(node);
|
||||
this.parse(node, item.children);
|
||||
})
|
||||
});
|
||||
},
|
||||
reload() {
|
||||
this.isActive = false;
|
||||
|
@ -101,4 +118,9 @@ export default {
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.minder-container >>> .save-btn {
|
||||
right: 30px;
|
||||
bottom: auto;
|
||||
top: 30px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -39,8 +39,9 @@
|
|||
@setCondition="setCondition"
|
||||
ref="testCaseList">
|
||||
</test-case-list>
|
||||
<testcase-minder
|
||||
<test-case-minder
|
||||
:tree-nodes="treeNodes"
|
||||
:project-id="projectId"
|
||||
v-if="activeDom === 'right'"
|
||||
ref="testCaseList"/>
|
||||
</ms-tab-button>
|
||||
|
@ -97,17 +98,17 @@ import SelectMenu from "../common/SelectMenu";
|
|||
import MsContainer from "../../common/components/MsContainer";
|
||||
import MsAsideContainer from "../../common/components/MsAsideContainer";
|
||||
import MsMainContainer from "../../common/components/MsMainContainer";
|
||||
import {checkoutTestManagerOrTestUser, getCurrentProjectID, getUUID, hasRoles} from "../../../../common/js/utils";
|
||||
import {checkoutTestManagerOrTestUser, getCurrentProjectID, getUUID} from "../../../../common/js/utils";
|
||||
import TestCaseNodeTree from "../common/TestCaseNodeTree";
|
||||
import {TrackEvent,LIST_CHANGE} from "@/business/components/common/head/ListEvent";
|
||||
import TestcaseMinder from "@/business/components/common/components/MsModuleMinder";
|
||||
|
||||
import MsTabButton from "@/business/components/common/components/MsTabButton";
|
||||
import TestCaseMinder from "@/business/components/track/case/components/minder/TestCaseMinder";
|
||||
|
||||
export default {
|
||||
name: "TestCase",
|
||||
components: {
|
||||
TestCaseMinder,
|
||||
MsTabButton,
|
||||
TestcaseMinder,
|
||||
TestCaseNodeTree,
|
||||
MsMainContainer,
|
||||
MsAsideContainer, MsContainer, TestCaseList, NodeTree, TestCaseEdit, SelectMenu
|
||||
|
@ -129,11 +130,13 @@ export default {
|
|||
renderComponent:true,
|
||||
loading: false,
|
||||
type:'',
|
||||
activeDom: 'left'
|
||||
activeDom: 'left',
|
||||
projectId: ""
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init(this.$route);
|
||||
this.projectId = getCurrentProjectID();
|
||||
},
|
||||
watch: {
|
||||
redirectID() {
|
||||
|
@ -193,7 +196,7 @@ export default {
|
|||
}
|
||||
},
|
||||
addTab(tab) {
|
||||
if (!getCurrentProjectID()) {
|
||||
if (!this.projectId) {
|
||||
this.$warning(this.$t('commons.check_project_tip'));
|
||||
return;
|
||||
}
|
||||
|
@ -253,7 +256,7 @@ export default {
|
|||
this.testCaseReadOnly = true;
|
||||
}
|
||||
let caseId = this.$route.params.caseId;
|
||||
if (!getCurrentProjectID()) {
|
||||
if (!this.projectId) {
|
||||
this.$warning(this.$t('commons.check_project_tip'));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -472,7 +472,6 @@ export default {
|
|||
reload() {
|
||||
this.isStepTableAlive = false;
|
||||
this.$nextTick(() => (this.isStepTableAlive = true));
|
||||
console.log(this.form)
|
||||
},
|
||||
open(testCase) {
|
||||
this.projectId = getCurrentProjectID();
|
||||
|
@ -552,9 +551,7 @@ export default {
|
|||
let tmp = {};
|
||||
Object.assign(tmp, testCase);
|
||||
tmp.steps = JSON.parse(testCase.steps);
|
||||
console.log(tmp)
|
||||
Object.assign(this.form, tmp);
|
||||
console.log(this.form)
|
||||
this.form.module = testCase.nodeId;
|
||||
this.getFileMetaData(testCase);
|
||||
},
|
||||
|
@ -631,7 +628,6 @@ export default {
|
|||
let param = this.buildParam();
|
||||
if (this.validate(param)) {
|
||||
let option = this.getOption(param);
|
||||
console.log(option)
|
||||
this.result = this.$request(option, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
if (this.operationType == 'add' && this.isCreateContinue) {
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
<template>
|
||||
<ms-module-minder
|
||||
:tree-nodes="treeNodes"/>
|
||||
v-loading="result.loading"
|
||||
:tree-nodes="treeNodes"
|
||||
:data-map="dataMap"
|
||||
@save="save"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -11,7 +15,8 @@ name: "TestCaseMinder",
|
|||
data() {
|
||||
return{
|
||||
testCase: [],
|
||||
dataMap: new Map()
|
||||
dataMap: new Map(),
|
||||
result: {}
|
||||
}
|
||||
},
|
||||
props: {
|
||||
|
@ -25,38 +30,147 @@ name: "TestCaseMinder",
|
|||
projectId: String
|
||||
},
|
||||
mounted() {
|
||||
// this.getTestCases();
|
||||
this.$nextTick(() => {
|
||||
this.getTestCases();
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getTestCases() {
|
||||
if (this.projectId) {
|
||||
this.result = this.$get('/test/case/list/detail/' + this.projectId,response => {
|
||||
this.testCase = response.data;
|
||||
console.log(this.testCase)
|
||||
this.parse();
|
||||
});
|
||||
}
|
||||
},
|
||||
parse() {
|
||||
this.testCase.forEach(item => {
|
||||
let mapItem = this.dataMap.get(item.moduleId);
|
||||
let nodeItem = {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
|
||||
save(data) {
|
||||
let saveCases = [];
|
||||
this.buildSaveCase(data.root, saveCases, undefined);
|
||||
console.log(saveCases);
|
||||
let param = {
|
||||
projectId: this.projectId,
|
||||
data: saveCases
|
||||
}
|
||||
this.result = this.$post('/test/case/minder/edit', param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
});
|
||||
},
|
||||
buildSaveCase(root, saveCases, parent) {
|
||||
let data = root.data;
|
||||
if (data.resource && data.resource.indexOf("用例") > -1) {
|
||||
this._buildSaveCase(root, saveCases, parent);
|
||||
} else {
|
||||
if (root.children) {
|
||||
root.children.forEach((childNode) => {
|
||||
this.buildSaveCase(childNode, saveCases, root.data);
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
_buildSaveCase(node, saveCases, parent) {
|
||||
let data = node.data;
|
||||
let isChange = false;
|
||||
let testCase = {
|
||||
id: data.id,
|
||||
name: data.text,
|
||||
nodeId: parent ? parent.id : "",
|
||||
nodePath: parent ? parent.path : "",
|
||||
type: data.type ? data.type : 'functional',
|
||||
method: data.method ? data.method: 'manual',
|
||||
maintainer: data.maintainer,
|
||||
priority: 'P' + data.priority,
|
||||
};
|
||||
if (data.changed) isChange = true;
|
||||
let steps = [];
|
||||
let stepNum = 1;
|
||||
if (node.children) {
|
||||
node.children.forEach((childNode) => {
|
||||
let childData = childNode.data;
|
||||
if (childData.resource && childData.resource.indexOf('前置条件') > -1) {
|
||||
testCase.prerequisite = childData.text;
|
||||
} else if (childData.resource && childData.resource.indexOf('备注') > -1) {
|
||||
testCase.remark = childData.text;
|
||||
} else {
|
||||
// 测试步骤
|
||||
let step = {};
|
||||
step.num = stepNum++;
|
||||
step.desc = childData.text;
|
||||
if (childNode.children) {
|
||||
let result = "";
|
||||
childNode.children.forEach((child) => {
|
||||
result += child.data.text;
|
||||
if (child.data.changed) isChange = true;
|
||||
})
|
||||
step.result = result;
|
||||
}
|
||||
steps.push(step);
|
||||
}
|
||||
if (childData.changed) isChange = true;
|
||||
})
|
||||
}
|
||||
testCase.steps = JSON.stringify(steps);
|
||||
if (isChange) {
|
||||
saveCases.push(testCase);
|
||||
}
|
||||
},
|
||||
parse() {
|
||||
let dataMap = new Map();
|
||||
this.testCase.forEach(item => {
|
||||
item.steps = JSON.parse(item.steps);
|
||||
// if (item.tags && item.tags.length > 0) {
|
||||
// item.tags = JSON.parse(item.tags);
|
||||
// }
|
||||
let mapItem = dataMap.get(item.nodeId);
|
||||
let nodeItem = {
|
||||
data: {
|
||||
id: item.id,
|
||||
text: item.name,
|
||||
priority: Number.parseInt(item.priority.substring(item.priority.length - 1 )),
|
||||
resource: ["用例"],
|
||||
type: item.type,
|
||||
method: item.method,
|
||||
maintainer: item.maintainer
|
||||
}
|
||||
}
|
||||
this.parseChildren(nodeItem, item);
|
||||
if (mapItem) {
|
||||
mapItem.push(item);
|
||||
mapItem.push(nodeItem);
|
||||
} else {
|
||||
mapItem = [];
|
||||
mapItem.push(item);
|
||||
}
|
||||
if (item.tags && item.tags.length > 0) {
|
||||
item.tags = JSON.parse(item.tags);
|
||||
mapItem.push(nodeItem);
|
||||
dataMap.set(item.nodeId, mapItem);
|
||||
}
|
||||
})
|
||||
this.dataMap = dataMap;
|
||||
},
|
||||
parseChildren(nodeItem, item) {
|
||||
nodeItem.children = [];
|
||||
let children = [];
|
||||
this._parseChildren(children, item.prerequisite, "前置条件");
|
||||
item.steps.forEach((step) => {
|
||||
let descNode = this._parseChildren(children, step.desc, "测试步骤");
|
||||
if (descNode) {
|
||||
descNode.data.num = step.num;
|
||||
descNode.children = [];
|
||||
this._parseChildren(descNode.children, step.result, "预期结果");
|
||||
}
|
||||
});
|
||||
this._parseChildren(children, item.remark, "备注");
|
||||
nodeItem.children = children;
|
||||
},
|
||||
_parseChildren(children, k, v) {
|
||||
if (k) {
|
||||
let node = {
|
||||
data: {
|
||||
text: k,
|
||||
resource: [v]
|
||||
}
|
||||
}
|
||||
children.push(node);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Reference in New Issue