feat: 脑图用例编辑

This commit is contained in:
chenjianxing 2021-03-15 16:20:51 +08:00
parent 82b004df60
commit b5709cc998
7 changed files with 226 additions and 43 deletions

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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);
}
});
}
}

View File

@ -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() {
},
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>

View File

@ -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;
}

View File

@ -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) {

View File

@ -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
}
if (mapItem) {
mapItem.push(item);
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 {
mapItem = [];
mapItem.push(item);
}
if (item.tags && item.tags.length > 0) {
item.tags = JSON.parse(item.tags);
}
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(nodeItem);
} else {
mapItem = [];
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>