提交 d511800c 编写于 作者: C chenjianxing

查看编辑测试用例报告

上级 61256ee9
package io.metersphere.controller;
import io.metersphere.base.domain.TestCaseReport;
import io.metersphere.controller.request.testCaseReport.CreateReportRequest;
import io.metersphere.service.TestCaseReportService;
import org.springframework.web.bind.annotation.*;
......@@ -25,8 +26,8 @@ public class TestCaseReportController {
}
@PostMapping("/add")
public void add(@RequestBody TestCaseReport TestCaseReport){
testCaseReportService.addTestCaseReport(TestCaseReport);
public Long addByTemplateId(@RequestBody CreateReportRequest request){
return testCaseReportService.addTestCaseReportByTemplateId(request);
}
@PostMapping("/edit")
......
package io.metersphere.controller;
import io.metersphere.base.domain.TestCaseReportTemplate;
import io.metersphere.controller.request.testCaseReport.QueryTemplateRequest;
import io.metersphere.service.TestCaseReportTemplateService;
import org.springframework.web.bind.annotation.*;
......@@ -15,7 +16,7 @@ public class TestCaseReportTemplateController {
TestCaseReportTemplateService testCaseReportTemplateService;
@PostMapping("/list")
public List<TestCaseReportTemplate> list(@RequestBody TestCaseReportTemplate request) {
public List<TestCaseReportTemplate> list(@RequestBody QueryTemplateRequest request) {
return testCaseReportTemplateService.listTestCaseReportTemplate(request);
}
......
......@@ -49,7 +49,7 @@ public class TestPlanController {
}
@PostMapping("/get/{testPlanId}")
public List<TestPlan> getTestPlan(@PathVariable String testPlanId){
public TestPlan getTestPlan(@PathVariable String testPlanId){
return testPlanService.getTestPlan(testPlanId);
}
......
package io.metersphere.controller.request.testCaseReport;
import lombok.Data;
@Data
public class CreateReportRequest {
String planId;
Long templateId;
}
package io.metersphere.controller.request.testCaseReport;
import io.metersphere.base.domain.TestCaseReportTemplate;
import lombok.Data;
@Data
public class QueryTemplateRequest extends TestCaseReportTemplate {
Boolean queryDefault;
}
......@@ -2,7 +2,13 @@ package io.metersphere.service;
import io.metersphere.base.domain.TestCaseReport;
import io.metersphere.base.domain.TestCaseReportExample;
import io.metersphere.base.domain.TestCaseReportTemplate;
import io.metersphere.base.domain.TestPlan;
import io.metersphere.base.mapper.TestCaseReportMapper;
import io.metersphere.base.mapper.TestCaseReportTemplateMapper;
import io.metersphere.base.mapper.TestPlanMapper;
import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.controller.request.testCaseReport.CreateReportRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -17,6 +23,12 @@ public class TestCaseReportService {
@Resource
TestCaseReportMapper testCaseReportMapper;
@Resource
TestPlanMapper testPlanMapper;
@Resource
TestCaseReportTemplateMapper testCaseReportTemplateMapper;
public List<TestCaseReport> listTestCaseReport(TestCaseReport request) {
TestCaseReportExample example = new TestCaseReportExample();
if ( StringUtils.isNotBlank(request.getName()) ) {
......@@ -40,4 +52,18 @@ public class TestCaseReportService {
public int deleteTestCaseReport(Long id) {
return testCaseReportMapper.deleteByPrimaryKey(id);
}
public Long addTestCaseReportByTemplateId(CreateReportRequest request) {
TestCaseReportTemplate template = testCaseReportTemplateMapper.selectByPrimaryKey(request.getTemplateId());
TestCaseReport report = new TestCaseReport();
BeanUtils.copyBean(report, template);
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getPlanId());
report.setName(testPlan.getName());
report.setId(null);
testCaseReportMapper.insert(report);
testPlan.setReportId(report.getId());
testPlanMapper.updateByPrimaryKeySelective(testPlan);
return report.getId();
}
}
......@@ -4,6 +4,7 @@ import io.metersphere.base.domain.TestCaseReportTemplate;
import io.metersphere.base.domain.TestCaseReportTemplateExample;
import io.metersphere.base.mapper.TestCaseReportMapper;
import io.metersphere.base.mapper.TestCaseReportTemplateMapper;
import io.metersphere.controller.request.testCaseReport.QueryTemplateRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -18,15 +19,21 @@ public class TestCaseReportTemplateService {
@Resource
TestCaseReportTemplateMapper testCaseReportTemplateMapper;
public List<TestCaseReportTemplate> listTestCaseReportTemplate(TestCaseReportTemplate request) {
public List<TestCaseReportTemplate> listTestCaseReportTemplate(QueryTemplateRequest request) {
TestCaseReportTemplateExample example = new TestCaseReportTemplateExample();
TestCaseReportTemplateExample.Criteria criteria1 = example.createCriteria();
TestCaseReportTemplateExample.Criteria criteria2 = example.createCriteria();
if ( StringUtils.isNotBlank(request.getName()) ) {
example.createCriteria().andNameEqualTo(request.getName());
criteria1.andNameLike("%" + request.getName() + "%");
criteria2.andNameLike("%" + request.getName() + "%");
}
if ( StringUtils.isNotBlank(request.getWorkspaceId()) ) {
example.createCriteria().andWorkspaceIdEqualTo(request.getWorkspaceId());
criteria1.andWorkspaceIdEqualTo(request.getWorkspaceId());
}
if (request.getQueryDefault() != null) {
criteria2.andWorkspaceIdIsNull();
example.or(criteria2);
}
example.or(example.createCriteria().andWorkspaceIdIsNull());
return testCaseReportTemplateMapper.selectByExample(example);
}
......
......@@ -53,10 +53,8 @@ public class TestPlanService {
}
public List<TestPlan> getTestPlan(String testPlanId) {
TestPlanExample testPlanExample = new TestPlanExample();
testPlanExample.createCriteria().andIdEqualTo(testPlanId);
return testPlanMapper.selectByExampleWithBLOBs(testPlanExample);
public TestPlan getTestPlan(String testPlanId) {
return testPlanMapper.selectByPrimaryKey(testPlanId);
}
public int editTestPlan(TestPlan testPlan) {
......
......@@ -56,9 +56,6 @@
this.result = this.$post('/case/report/template/list', this.condition, response => {
this.templates = response.data;
});
},
templateCreate() {
},
templateEdit(id) {
this.$refs.templateEdit.open(id);
......@@ -69,5 +66,8 @@
<style scoped>
.el-card {
min-height: 300px;
}
</style>
......@@ -89,16 +89,15 @@
),
components: [4],
previews: [],
template: {}
template: {},
isReport: false
}
},
props: {
},
watch: {
},
methods: {
open(id) {
open(id, isReport) {
if (isReport) {
this.isReport = isReport;
}
this.template = {
name: '',
content: {
......@@ -190,7 +189,11 @@
}
},
getTemplateById(id) {
this.$get('/case/report/template/get/' + id, (response) =>{
let url = '/case/report/template/get/';
if (this.isReport) {
url = '/case/report/get/';
}
this.$get(url + id, (response) =>{
this.template = response.data;
this.template.content = JSON.parse(response.data.content);
if (this.template.content.customComponent) {
......@@ -206,7 +209,11 @@
}
let param = {};
this.buildParam(param);
this.$post('/case/report/template/' + this.type, param, () =>{
let url = '/case/report/template/';
if (this.isReport) {
url = '/case/report/';
}
this.$post(url + this.type, param, () =>{
this.$success('保存成功');
this.showDialog = false;
this.$emit('refresh');
......@@ -229,6 +236,8 @@
param.content = JSON.stringify(content);
if (this.type == 'edit') {
param.id = this.template.id;
} else {
param.workspaceId = localStorage.getItem(WORKSPACE_ID);
}
if (this.template.workspaceId) {
param.workspaceId = localStorage.getItem(WORKSPACE_ID);
......
<template>
<div>
<el-drawer
:before-close="handleClose"
:visible.sync="showDialog"
:with-header="false"
size="100%"
ref="drawer"
v-loading="result.loading">
<template v-slot:default="scope">
<el-row type="flex" class="head-bar">
<el-col :span="12">
<div class="name-edit">
<el-button plain size="mini" icon="el-icon-back" @click="handleClose">{{$t('test_track.return')}}</el-button>
&nbsp;
<span>{{report.name}}</span>
</div>
</el-col>
<el-col :span="12" class="head-right">
<el-button plain size="mini" @click="handleEdit">编辑组件</el-button>
</el-col>
</el-row>
<div class="container">
<el-main>
<div class="preview" v-for="item in previews" :key="item.id">
<base-info-component v-if="item.id == 1"/>
<test-result-component v-if="item.id == 2"/>
<test-result-chart-component v-if="item.id == 3"/>
<rich-text-component :preview="item" v-if="item.type != 'system'"/>
</div>
</el-main>
</div>
</template>
</el-drawer>
<test-case-report-template-edit ref="templateEdit" @refresh="getReport"/>
</div>
</template>
<script>
import {jsonToMap} from "../../../../../../common/js/utils";
import BaseInfoComponent from "../../../../settings/workspace/components/TemplateComponent/BaseInfoComponent";
import TestResultChartComponent from "../../../../settings/workspace/components/TemplateComponent/TestResultChartComponent";
import TestResultComponent from "../../../../settings/workspace/components/TemplateComponent/TestResultComponent";
import RichTextComponent from "../../../../settings/workspace/components/TemplateComponent/RichTextComponent";
import TestCaseReportTemplateEdit from "../../../../settings/workspace/components/TestCaseReportTemplateEdit";
export default {
name: "TestCaseReportView",
components: {
TestCaseReportTemplateEdit,
RichTextComponent, TestResultComponent, TestResultChartComponent, BaseInfoComponent},
data() {
return {
result: {},
showDialog: false,
previews: [],
report: {},
reportId: '',
componentMap: new Map(
[
[1, { name: "基础信息", id: 1 , type: 'system'}],
[2, { name: "测试结果", id: 2 , type: 'system'}],
[3, { name: "测试结果分布", id: 3 ,type: 'system'}],
[4, { name: "自定义模块", id: 4 ,type: 'custom'}]
]
)
}
},
methods: {
open(id) {
if (id) {
this.reportId = id;
}
this.getReport();
this.showDialog = true;
},
getReport() {
this.result = this.$get('/case/report/get/' + this.reportId, response => {
this.report = response.data;
this.report.content = JSON.parse(response.data.content);
if (this.report.content.customComponent) {
this.report.content.customComponent = jsonToMap(this.report.content.customComponent);
}
this.initPreviews();
});
},
initPreviews() {
this.previews = [];
this.report.content.components.forEach(item => {
let preview = this.componentMap.get(item);
if (preview && preview.type != 'custom') {
this.previews.push(preview);
} else {
if (this.report.content.customComponent) {
let customComponent = this.report.content.customComponent.get(item.toString());
if (customComponent) {
this.previews.push({id: item, title: customComponent.title, content: customComponent.content});
}
}
}
});
},
handleClose() {
this.showDialog = false;
},
handleEdit() {
this.$refs.templateEdit.open(this.reportId, true);
}
}
}
</script>
<style scoped>
.el-main {
height: calc(100vh - 70px);
width: 100%;
}
.head-bar {
background: white;
height: 45px;
line-height: 45px;
padding: 0 10px;
border: 1px solid #EBEEF5;
box-shadow: 0 0 2px 0 rgba(31,31,31,0.15), 0 1px 2px 0 rgba(31,31,31,0.15);
}
.container {
height: 100vh;
background: #F5F5F5;
}
.el-card {
width: 70%;
margin: 5px auto;
}
.head-right {
text-align: right;
}
</style>
<template>
<el-card v-loading="result.loading">
<template v-slot:header>
<ms-table-header :condition.sync="condition" @search="initTableData" :show-create="false">
<template v-slot:title>
<node-breadcrumb class="table-title" :node-names="selectNodeNames" @refresh="refresh"/>
</template>
<template v-slot:button>
<ms-table-button v-if="!showMyTestCase" icon="el-icon-s-custom" :content="$t('test_track.plan_view.my_case')" @click="searchMyTestCase"/>
<ms-table-button v-if="showMyTestCase" icon="el-icon-files" :content="$t('test_track.plan_view.all_case')" @click="searchMyTestCase"/>
<ms-table-button icon="el-icon-connection" :content="$t('test_track.plan_view.relevance_test_case')" @click="$emit('openTestCaseRelevanceDialog')"/>
<ms-table-button icon="el-icon-edit-outline" :content="$t('test_track.plan_view.change_execution_results')" @click="handleBatch('status')"/>
<ms-table-button icon="el-icon-user" :content="$t('test_track.plan_view.change_executor')" @click="handleBatch('executor')"/>
<ms-table-button icon="el-icon-document" :content="$t('测试报告')" @click="openTestReport"/>
</template>
</ms-table-header>
</template>
<template v-slot:header>
<ms-table-header :condition.sync="condition" @search="initTableData" :show-create="false">
<template v-slot:title>
<node-breadcrumb class="table-title" :node-names="selectNodeNames" @refresh="refresh"/>
</template>
<template v-slot:button>
<ms-table-button v-if="!showMyTestCase" icon="el-icon-s-custom" :content="$t('test_track.plan_view.my_case')" @click="searchMyTestCase"/>
<ms-table-button v-if="showMyTestCase" icon="el-icon-files" :content="$t('test_track.plan_view.all_case')" @click="searchMyTestCase"/>
<ms-table-button icon="el-icon-connection" :content="$t('test_track.plan_view.relevance_test_case')" @click="$emit('openTestCaseRelevanceDialog')"/>
<ms-table-button icon="el-icon-edit-outline" :content="$t('test_track.plan_view.change_execution_results')" @click="handleBatch('status')"/>
<ms-table-button icon="el-icon-user" :content="$t('test_track.plan_view.change_executor')" @click="handleBatch('executor')"/>
<ms-table-button v-if="!testPlan.reportId" icon="el-icon-document" :content="$t('创建测试报告')" @click="openTestReport"/>
<ms-table-button v-if="testPlan.reportId" icon="el-icon-document" :content="$t('查看测试报告')" @click="openReport"/>
</template>
</ms-table-header>
</template>
<executor-edit ref="executorEdit" :select-ids="selectIds" @refresh="initTableData"/>
<status-edit ref="statusEdit" :select-ids="selectIds" @refresh="initTableData"/>
<executor-edit ref="executorEdit" :select-ids="selectIds" @refresh="initTableData"/>
<status-edit ref="statusEdit" :select-ids="selectIds" @refresh="initTableData"/>
<el-table
@select-all="handleSelectAll"
@select="handleSelectionChange"
row-key="id"
:data="tableData">
<el-table
@select-all="handleSelectAll"
@select="handleSelectionChange"
row-key="id"
:data="tableData">
<el-table-column
type="selection"></el-table-column>
<el-table-column
type="selection"></el-table-column>
<el-table-column
prop="name"
:label="$t('commons.name')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="priority"
:filters="priorityFilters"
:filter-method="filter"
:label="$t('test_track.case.priority')">
<template v-slot:default="scope">
<priority-table-item :value="scope.row.priority" ref="priority"/>
</template>
</el-table-column>
<el-table-column
prop="name"
:label="$t('commons.name')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="priority"
:filters="priorityFilters"
:filter-method="filter"
:label="$t('test_track.case.priority')">
<template v-slot:default="scope">
<priority-table-item :value="scope.row.priority" ref="priority"/>
</template>
</el-table-column>
<el-table-column
prop="type"
:filters="typeFilters"
:filter-method="filter"
:label="$t('test_track.case.type')"
show-overflow-tooltip>
<template v-slot:default="scope">
<type-table-item :value="scope.row.type"/>
</template>
</el-table-column>
<el-table-column
prop="type"
:filters="typeFilters"
:filter-method="filter"
:label="$t('test_track.case.type')"
show-overflow-tooltip>
<template v-slot:default="scope">
<type-table-item :value="scope.row.type"/>
</template>
</el-table-column>
<el-table-column
prop="method"
:filters="methodFilters"
:filter-method="filter"
:label="$t('test_track.case.method')"
show-overflow-tooltip>
<template v-slot:default="scope">
<method-table-item :value="scope.row.method"/>
</template>
</el-table-column>
<el-table-column
prop="method"
:filters="methodFilters"
:filter-method="filter"
:label="$t('test_track.case.method')"
show-overflow-tooltip>
<template v-slot:default="scope">
<method-table-item :value="scope.row.method"/>
</template>
</el-table-column>
<el-table-column
prop="executor"
:label="$t('test_track.plan_view.executor')">
</el-table-column>
<el-table-column
prop="executor"
:label="$t('test_track.plan_view.executor')">
</el-table-column>
<el-table-column
prop="status"
:filters="statusFilters"
:filter-method="filter"
:label="$t('test_track.plan_view.execute_result')">
<template v-slot:default="scope">
<status-table-item :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column
prop="status"
:filters="statusFilters"
:filter-method="filter"
:label="$t('test_track.plan_view.execute_result')">
<template v-slot:default="scope">
<status-table-item :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column
sortable
prop="updateTime"
:label="$t('commons.update_time')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column
:label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator-button :tip="$t('commons.edit')" icon="el-icon-edit" @exec="handleEdit(scope.row)" />
<ms-table-operator-button :tip="$t('test_track.plan_view.cancel_relevance')" icon="el-icon-unlock" type="danger" @exec="handleDelete(scope.row)"/>
</template>
</el-table-column>
</el-table>
<el-table-column
sortable
prop="updateTime"
:label="$t('commons.update_time')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column
:label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator-button :tip="$t('commons.edit')" icon="el-icon-edit" @exec="handleEdit(scope.row)" />
<ms-table-operator-button :tip="$t('test_track.plan_view.cancel_relevance')" icon="el-icon-unlock" type="danger" @exec="handleDelete(scope.row)"/>
</template>
</el-table-column>
</el-table>
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize"
:total="total"/>
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize"
:total="total"/>
<test-plan-test-case-edit
ref="testPlanTestCaseEdit"
:search-param="condition"
@refresh="refresh"
@refreshTable="search"/>
<test-plan-test-case-edit
ref="testPlanTestCaseEdit"
:search-param="condition"
@refresh="refresh"
@refreshTable="search"/>
<test-report-template-list @openReport="openReport" :plan-id="planId" ref="testReporTtemplateList"/>
<test-case-report-view ref="testCaseReportView"/>
</el-card>
</template>
......@@ -128,10 +132,14 @@
import MethodTableItem from "../../../common/tableItems/planview/MethodTableItem";
import MsTableOperator from "../../../../common/components/MsTableOperator";
import MsTableOperatorButton from "../../../../common/components/MsTableOperatorButton";
import TestReportTemplateList from "./TestReportTemplateList";
import TestCaseReportView from "./TestCaseReportView";
export default {
name: "TestPlanTestCaseList",
components: {
TestCaseReportView,
TestReportTemplateList,
MsTableOperatorButton,
MsTableOperator,
MethodTableItem,
......@@ -150,6 +158,7 @@
pageSize: 10,
total: 0,
selectIds: new Set(),
testPlan: {},
priorityFilters: [
{text: 'P0', value: 'P0'},
{text: 'P1', value: 'P1'},
......@@ -186,13 +195,15 @@
},
watch: {
planId() {
this.getTestPlanById();
this.initTableData();
},
selectNodeIds() {
this.search();
}
},
created: function () {
mounted() {
this.getTestPlanById();
this.initTableData();
},
methods: {
......@@ -281,7 +292,20 @@
return row[property] === value;
},
openTestReport() {
this.$refs.testReporTtemplateList.open();
},
getTestPlanById() {
if (this.planId) {
this.$post('/test/plan/get/' + this.planId, {}, response => {
this.testPlan = response.data;
});
}
},
openReport(id) {
if (!id) {
id = this.testPlan.reportId;
}
this.$refs.testCaseReportView.open(id);
}
}
}
......
<template>
<el-dialog :title="'选择模版'"
:visible.sync="templateVisible"
width="50%">
<el-main>
<testcase-template-item v-for="item in templates" :key="item.id"
:template="item" @templateEdit="createTemplate" @refresh="initData"/>
</el-main>
</el-dialog>
</template>
<script>
import TestcaseTemplateItem from "../../../../settings/workspace/components/TestcaseTemplateItem";
import {WORKSPACE_ID} from "../../../../../../common/js/constants";
export default {
name: "TestReportTemplateList",
components: {TestcaseTemplateItem},
data() {
return {
templateVisible: false,
templates: []
}
},
props: {
planId: {
type: String
}
},
methods: {
initData() {
let condition = {};
condition.queryDefault = true;
condition.workspaceId = localStorage.getItem(WORKSPACE_ID);
this.result = this.$post('/case/report/template/list', condition, response => {
this.templates = response.data;
});
},
createTemplate(templateId) {
let param = {};
param.planId = this.planId;
param.templateId = templateId;
this.$post('/case/report/add', param, response => {
this.$emit('openReport', response.data);
this.templateVisible = false;
});
},
open() {
this.templateVisible = true;
this.initData();
}
}
}
</script>
<style scoped>
.el-main >>> .testcase-template:hover i{
display: none;
}
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册