测试计划前端及后端代码完善
This commit is contained in:
@@ -8,7 +8,7 @@ import com.test.test.service.ITestPlanProjectService;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -30,7 +30,7 @@ public class TestPlanProjectController extends BaseController {
|
||||
/**
|
||||
* 查询测试计划需求关联列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@PostMapping("/list")
|
||||
public TableDataInfo list(@RequestBody IDQO qo) {
|
||||
startPage();
|
||||
List<TestPlanProjectVo> list = testPlanProjectService.selectTestPlanProjectList(qo.getId());
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
package com.test.test.controller;
|
||||
|
||||
import com.test.common.annotation.Log;
|
||||
import com.test.common.core.controller.BaseController;
|
||||
import com.test.common.core.domain.AjaxResult;
|
||||
import com.test.common.core.page.TableDataInfo;
|
||||
import com.test.common.enums.BusinessType;
|
||||
import com.test.test.domain.qo.IDQO;
|
||||
import com.test.test.domain.qo.TestReportAddQO;
|
||||
import com.test.test.domain.vo.TestReportVo;
|
||||
import com.test.test.service.ITestReportService;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -31,10 +36,21 @@ public class TestReportController extends BaseController {
|
||||
* 查询测试计划关联测试报告列表
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/reportList")
|
||||
@PostMapping("/reportList")
|
||||
public TableDataInfo list(@RequestBody IDQO qo) {
|
||||
startPage();
|
||||
List<TestReportVo> list = testReportService.selectTestReportList(qo.getId());
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增测试报告及关联测试计划
|
||||
* @param testReportAddQO
|
||||
* @return
|
||||
*/
|
||||
@Log(title = "测试报告", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/addTestReport")
|
||||
public AjaxResult addTestReport(@RequestBody TestReportAddQO testReportAddQO) {
|
||||
return toAjax(testReportService.addTestReport(testReportAddQO));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.test.test.domain.qo;
|
||||
|
||||
import com.test.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 测试报告新增参数QO
|
||||
*/
|
||||
@Data
|
||||
public class TestReportAddQO extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = -6325566452451878775L;
|
||||
|
||||
/**
|
||||
* 测试报告id
|
||||
*/
|
||||
private Long reportId;
|
||||
|
||||
/**
|
||||
* 测试计划id
|
||||
*/
|
||||
private Long planId;
|
||||
|
||||
/**
|
||||
* 测试用例类型(0,冒烟测试,1,功能测试,2,回归测试,3,准生产测试,4,生产验证)
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/** 测试报告编码 */
|
||||
private String serialNumber;
|
||||
|
||||
/** 测试报告名称 */
|
||||
private String name;
|
||||
|
||||
/** 测试结果(0,未通过,1,通过) */
|
||||
private String result;
|
||||
|
||||
/** 测试报告发送状态(0,未发送,1,已发送) */
|
||||
private String status;
|
||||
|
||||
/** 测试报告(jason格式存储) */
|
||||
private String report;
|
||||
|
||||
/** 版本 */
|
||||
private String version;
|
||||
|
||||
/** 0,正常,1,删除 */
|
||||
private String delFlag;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.test.test.mapper;
|
||||
|
||||
import com.test.test.domain.qo.TestReportAddQO;
|
||||
|
||||
public interface TestPlanReportMapper {
|
||||
|
||||
/**
|
||||
* 新增测试计划关联测试报告
|
||||
* @param testReportAddQO
|
||||
* @return
|
||||
*/
|
||||
int insertTestPlanReport(TestReportAddQO testReportAddQO);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.test.test.mapper;
|
||||
|
||||
import com.test.test.domain.TestReport;
|
||||
import com.test.test.domain.vo.TestReportVo;
|
||||
import java.util.List;
|
||||
|
||||
@@ -12,4 +13,11 @@ public interface TestReportMapper {
|
||||
* @return
|
||||
*/
|
||||
List<TestReportVo> selectTestReportList(Long planId);
|
||||
|
||||
/**
|
||||
* 新增测试报告
|
||||
* @param testReport
|
||||
* @return
|
||||
*/
|
||||
int addTestReport(TestReport testReport);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.test.test.service;
|
||||
|
||||
import com.test.test.domain.TestReport;
|
||||
import com.test.test.domain.qo.TestReportAddQO;
|
||||
import com.test.test.domain.vo.TestReportVo;
|
||||
import java.util.List;
|
||||
|
||||
@@ -14,4 +16,11 @@ public interface ITestReportService {
|
||||
* @return
|
||||
*/
|
||||
List<TestReportVo> selectTestReportList(Long planId);
|
||||
|
||||
/**
|
||||
* 新增测试报告
|
||||
* @param testReportAddQO
|
||||
* @return
|
||||
*/
|
||||
public int addTestReport(TestReportAddQO testReportAddQO);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
package com.test.test.service.impl;
|
||||
|
||||
import com.test.common.utils.DateUtils;
|
||||
import com.test.common.utils.SecurityUtils;
|
||||
import com.test.common.utils.bean.BeanUtils;
|
||||
import com.test.test.domain.TestReport;
|
||||
import com.test.test.domain.qo.TestReportAddQO;
|
||||
import com.test.test.domain.vo.TestReportVo;
|
||||
import com.test.test.mapper.TestPlanReportMapper;
|
||||
import com.test.test.mapper.TestReportMapper;
|
||||
import com.test.test.service.ITestReportService;
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
@@ -19,6 +26,9 @@ public class TestReportServiceImpl implements ITestReportService {
|
||||
@Resource
|
||||
private TestReportMapper testReportMapper;
|
||||
|
||||
@Resource
|
||||
private TestPlanReportMapper testPlanReportMapper;
|
||||
|
||||
/**
|
||||
* 查询测试报告列表
|
||||
* @param planId
|
||||
@@ -28,4 +38,34 @@ public class TestReportServiceImpl implements ITestReportService {
|
||||
public List<TestReportVo> selectTestReportList(Long planId) {
|
||||
return testReportMapper.selectTestReportList(planId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增测试报告
|
||||
* @param testReportAddQO
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int addTestReport(TestReportAddQO testReportAddQO) {
|
||||
TestReport testReport = new TestReport();
|
||||
BeanUtils.copyProperties(testReportAddQO,testReport);
|
||||
testReport.setSerialNumber(generateSerialNumber());
|
||||
testReport.setResult("0");
|
||||
testReport.setStatus("0");
|
||||
testReport.setCreateTime(DateUtils.getNowDate());
|
||||
testReport.setDelFlag("0");
|
||||
testReport.setUpdateBy(SecurityUtils.getUsername());
|
||||
testReportMapper.addTestReport(testReport);
|
||||
testReportAddQO.setReportId(testReport.getId());
|
||||
testReportAddQO.setCreateTime(DateUtils.getNowDate());
|
||||
testReportAddQO.setDelFlag("0");
|
||||
return testPlanReportMapper.insertTestPlanReport(testReportAddQO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机序列号
|
||||
* @return
|
||||
*/
|
||||
private String generateSerialNumber() {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.test.test.mapper.TestPlanReportMapper">
|
||||
|
||||
<insert id="insertTestPlanReport" parameterType="testPlanAddQO">
|
||||
insert into test_plan_report
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="planId != null and planId != ''">plan_id,</if>
|
||||
<if test="reportId != null and reportId != ''">report_id,</if>
|
||||
<if test="type != null">type,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="version != null">version,</if>
|
||||
<if test="delFlag != null and delFlag != ''">del_flag,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="planId != null and planId != ''">#{planId},</if>
|
||||
<if test="reportId != null and reportId != ''">#{reportId},</if>
|
||||
<if test="type != null">#{type},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="version != null">#{version},</if>
|
||||
<if test="delFlag != null and delFlag != ''">#{delFlag},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
</mapper>
|
||||
@@ -3,6 +3,33 @@
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.test.test.mapper.TestReportMapper">
|
||||
<insert id="addTestReport" parameterType="TestReport" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into test_report
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="serialNumber != null and serialNumber != ''">serial_number,</if>
|
||||
<if test="name != null and name != ''">name,</if>
|
||||
<if test="result != null and result != ''">result,</if>
|
||||
<if test="status != null and status != ''">status,</if>
|
||||
<if test="report != null">report,</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="version != null">version,</if>
|
||||
<if test="delFlag != null and delFlag != ''">del_flag,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="serialNumber != null and serialNumber != ''">#{serialNumber},</if>
|
||||
<if test="name != null and name != ''">#{name},</if>
|
||||
<if test="result != null and result != ''">#{result},</if>
|
||||
<if test="status != null and status != ''">#{status},</if>
|
||||
<if test="report != null">#{report},</if>
|
||||
<if test="updateBy != null and updateBy != ''">#{updateBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="version != null">#{version},</if>
|
||||
<if test="delFlag != null and delFlag != ''">#{delFlag},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<select id="selectTestReportList" parameterType="Long" resultType="TestReportVo">
|
||||
SELECT
|
||||
|
||||
@@ -3,7 +3,12 @@ import request from '@/utils/request'
|
||||
const api = {
|
||||
testPlanList: 'test/testPlan/testPlanList',
|
||||
addTestPlan: 'test/testPlan/addPlan',
|
||||
delTestPlan: 'test/testPlan/deletePlan'
|
||||
delTestPlan: 'test/testPlan/deletePlan',
|
||||
updateTestPlan: 'test/testPlan/updatePlan',
|
||||
testPlanDetail: 'test/testPlan/planDetail',
|
||||
testPlanProjectList: '/test/testPlanProject/list',
|
||||
addTestReport: 'test/testReport/addTestReport',
|
||||
getTestReportList: 'test/testReport/reportList'
|
||||
}
|
||||
|
||||
export function getTestPlanList(data) {
|
||||
@@ -29,3 +34,43 @@ export function delTestPlan(id) {
|
||||
data: {id}
|
||||
})
|
||||
}
|
||||
|
||||
export function updateTestPlan(data) {
|
||||
return request({
|
||||
url: api.updateTestPlan,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function getTestPlanDetail(id) {
|
||||
return request({
|
||||
url: api.testPlanDetail,
|
||||
method: 'post',
|
||||
data: {id}
|
||||
})
|
||||
}
|
||||
|
||||
export function getTestPlanProjectList(id) {
|
||||
return request({
|
||||
url: api.testPlanProjectList,
|
||||
method: 'post',
|
||||
data: {id}
|
||||
})
|
||||
}
|
||||
|
||||
export function addTestReport(data) {
|
||||
return request({
|
||||
url: api.addTestReport,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function getTestReportList(id) {
|
||||
return request({
|
||||
url: api.getTestReportList,
|
||||
method: 'post',
|
||||
data: {id}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -130,20 +130,6 @@ export const constantRoutes = [
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/testplan/execute',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/test/testplan/execute/index'),
|
||||
name: 'PlanExecute',
|
||||
noCache: true,
|
||||
meta: { title: '计划执行', activeMenu: '/testplan' }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/task/detail',
|
||||
component: Layout,
|
||||
|
||||
@@ -406,7 +406,6 @@ export default {
|
||||
const form = {
|
||||
...this.form,
|
||||
}
|
||||
console.log('submit', form)
|
||||
this.$refs?.form.validate((valid) => {
|
||||
if (!valid) {
|
||||
return
|
||||
|
||||
160
test-ui/src/views/test/testplan/caseReport/caseReport.vue
Normal file
160
test-ui/src/views/test/testplan/caseReport/caseReport.vue
Normal file
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 页面标题 -->
|
||||
<div class="page-header">
|
||||
<h3 style="font-size: 20px;color: #000000">测试报告</h3>
|
||||
</div>
|
||||
<div v-show="total <= 0" class="button-new">
|
||||
<el-button icon="el-icon-plus" type="primary" size="medium" @click="addReportVue">
|
||||
新建报告
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-show="total > 0">
|
||||
<el-tabs style="margin-top: 10px;">
|
||||
<el-Table v-loading="loading" :data="list">
|
||||
<el-table-column prop="name" label="测试报告名称" align="center"/>
|
||||
<el-table-column prop="result" label="测试结果" align="center">
|
||||
</el-table-column>
|
||||
<el-table-column prop="type" label="测试阶段" align="center">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :options="dict.type.test_type" :value="row.type"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="发送状态" align="center">
|
||||
</el-table-column>
|
||||
<el-table-column prop="updateBy" label="最后更新人" align="center"/>
|
||||
<el-table-column prop="updateTime" label="最后更新时间" align="center"/>
|
||||
</el-Table>
|
||||
</el-tabs>
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
<el-dialog :title="title" :visible.sync="addOpen" width="40%">
|
||||
<el-form ref="form" :rules="rules" :model="form" label-width="110px" label-position="right">
|
||||
<el-form-item label="报告名称:" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入报告名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="测试阶段:" prop="type">
|
||||
<el-select v-model="form.type" placeholder="请选择测试阶段" clearable>
|
||||
<simple-options :options="dict.type.test_type"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="addOpen = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import SimpleOptions from "@/components/FormItem/option/SimpleOptions.vue";
|
||||
import {addTestReport, getTestReportList} from "@/api/test/testPlan";
|
||||
|
||||
export default {
|
||||
name: 'caseReport',
|
||||
components: {SimpleOptions},
|
||||
dicts: ['test_type'],
|
||||
props: {
|
||||
planId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
addOpen: false,
|
||||
loading: false,
|
||||
submitLoading: false,
|
||||
form: {
|
||||
name: '',
|
||||
type: '',
|
||||
planId: '',
|
||||
},
|
||||
queryParams: {
|
||||
planId: '',
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
rules: {
|
||||
name: [{required: true, message: '请输入报告名称', trigger: 'blur'}],
|
||||
type: [{required: true, message: '请选择测试阶段', trigger: 'blur'}]
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.loading = true
|
||||
this.queryParams.planId = this.planId
|
||||
getTestReportList(this.queryParams.planId).then(res => {
|
||||
this.list = res.rows
|
||||
this.total = res.total
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
addReportVue() {
|
||||
this.title = '新建报告'
|
||||
this.addOpen = true
|
||||
this.reset()
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
const form = {}
|
||||
Object.keys(this.form).forEach((key) => {
|
||||
form[key] = ''
|
||||
})
|
||||
this.form = form
|
||||
this.resetForm('form')
|
||||
},
|
||||
submitForm() {
|
||||
const form = {
|
||||
...this.form,
|
||||
planId: this.planId,
|
||||
}
|
||||
this.$refs.form.validate(valid => {
|
||||
if (!valid) {
|
||||
return
|
||||
}
|
||||
addTestReport(form)
|
||||
.then(() => {
|
||||
this.$message.success('新建成功')
|
||||
this.addOpen = false
|
||||
this.getList()
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message.error('新建失败')
|
||||
})
|
||||
.finally(() => {
|
||||
this.submitLoading = false
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
.page-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.button-new {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 200px;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -83,6 +83,16 @@ export default {
|
||||
name: 'project',
|
||||
components: {page1, SimpleOptions, RelateCase},
|
||||
dicts: ['priority_level', 'project_source', 'project_type', 'status'],
|
||||
props: {
|
||||
planId: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: '0',
|
||||
@@ -113,8 +123,8 @@ export default {
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.queryParams.planId = this.$route.query.id;
|
||||
this.title = this.$route.query.name;
|
||||
this.queryParams.planId = this.planId;
|
||||
this.title = this.name;
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
@@ -255,8 +255,6 @@
|
||||
<el-table-column prop="defectNum" label="缺陷数" align="left"/>
|
||||
<el-table-column label="操作" align="left" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-view" @click.native.stop="handlePlanRun(scope.row)">计划执行
|
||||
</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click.native.stop="handleDelete(scope.row.id)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -311,7 +309,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {addProject, delProject, getProjectList, managerList, updateProject} from "@/api/test/project";
|
||||
import {getProjectList, managerList, updateProject} from "@/api/test/project";
|
||||
import SimpleOptions from "@/components/FormItem/option/SimpleOptions.vue";
|
||||
import {addTestPlan, delTestPlan, getTestPlanList} from "@/api/test/testPlan";
|
||||
|
||||
@@ -373,7 +371,11 @@ export default {
|
||||
computed: {},
|
||||
methods: {
|
||||
handleRowClick(row) {
|
||||
this.$tab.openPage(`测试计划概览`, "/testplan/overview", {id: row.id});
|
||||
this.$tab.openPage(`测试计划概览`, "/testplan/overview",
|
||||
{id: row.id,
|
||||
name: row.name,
|
||||
testStatus: row.status,
|
||||
});
|
||||
},
|
||||
handleTabClick(tab) {
|
||||
this.activeTab = tab.name;
|
||||
@@ -480,9 +482,6 @@ export default {
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
});
|
||||
},
|
||||
handlePlanRun(row) {
|
||||
this.$tab.openPage(`计划执行[${row.name}]`, "/testplan/execute", {id: row.id, name: row.name});
|
||||
},
|
||||
editSubmitForm() {
|
||||
const form = {
|
||||
...this.editForm,
|
||||
|
||||
@@ -2,45 +2,143 @@
|
||||
<div class="app-container">
|
||||
<!-- 页面标题 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="24">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item>测试计划</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>概览</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<el-col :span="24" class="page-header">
|
||||
<el-page-header :title="testTitle" @back="goBack">
|
||||
</el-page-header>
|
||||
<el-dropdown :value="testStatus" trigger="click" @command="handleCommand">
|
||||
<span class="el-dropdown-link">{{ dropdownText }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item
|
||||
v-for="(text, key) in statusMap"
|
||||
:key="key"
|
||||
:command="key"
|
||||
:disabled="key === testStatus">
|
||||
{{ text }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
|
||||
<el-menu-item index="1">概览</el-menu-item>
|
||||
<el-menu-item index="2">执行</el-menu-item>
|
||||
<el-menu-item index="3">报告</el-menu-item>
|
||||
<el-menu-item index="4">缺陷</el-menu-item>
|
||||
<el-menu-item index="5">设置</el-menu-item>
|
||||
</el-menu>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 测试计划详情 -->
|
||||
<el-card class="box-card">
|
||||
|
||||
</el-card>
|
||||
|
||||
<!-- 测试用例 -->
|
||||
<el-card class="box-card">
|
||||
|
||||
</el-card>
|
||||
<!-- 测试计划界面 -->
|
||||
<probably-view :planId="planId" v-show="activeIndex === '1'"></probably-view>
|
||||
<case-execute :planId="planId" :name="testTitle" v-show="activeIndex === '2'"></case-execute>
|
||||
<case-report :planId="planId" v-show="activeIndex === '3'"></case-report>
|
||||
<test-defects v-show="activeIndex === '4'"></test-defects>
|
||||
<test-setting v-show="activeIndex === '5'"></test-setting>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LineChart from '@/views/dashboard/LineChart';
|
||||
import router from "@/router";
|
||||
import {getTestPlanDetail, updateTestPlan} from "@/api/test/testPlan";
|
||||
import ProbablyView from "@/views/test/testplan/probablyView/probablyView.vue";
|
||||
import CaseReport from "@/views/test/testplan/caseReport/caseReport.vue";
|
||||
import caseExecute from "@/views/test/testplan/execute/caseExecute.vue";
|
||||
import TestDefects from "@/views/test/testplan/defects/testDefects.vue";
|
||||
import TestSetting from "@/views/test/testplan/setting/testSetting.vue";
|
||||
|
||||
export default {
|
||||
name: 'overview',
|
||||
components: {
|
||||
LineChart,
|
||||
TestSetting,
|
||||
TestDefects,
|
||||
caseExecute,
|
||||
CaseReport,
|
||||
ProbablyView,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
editForm: {},
|
||||
statusMap: {
|
||||
'0': '未开始',
|
||||
'1': '进行中',
|
||||
'2': '已完成',
|
||||
'3': '已终止'
|
||||
},
|
||||
planId: '',
|
||||
testStatus: '',
|
||||
testTitle: '',
|
||||
activeTab: 'overview',// 默认选中的标签页
|
||||
activeIndex: '1',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 可以在这里添加更多的方法来处理数据或事件
|
||||
computed: {
|
||||
dropdownText() {
|
||||
return this.statusMap[this.testStatus] || '进行中';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCommand(command) {
|
||||
this.$confirm(`确定切换为【${this.statusMap[command]}】状态?`, '操作确认', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.testStatus = command; // 更新选中状态
|
||||
this.editForm.status = command;
|
||||
const form = {
|
||||
...this.editForm
|
||||
}
|
||||
updateTestPlan(form)
|
||||
.then(() => {
|
||||
this.$message.success(`切换成功:${this.statusMap[command]}`);
|
||||
})
|
||||
// 执行数据刷新等操作
|
||||
}).catch(() => {
|
||||
// 用户取消操作时的处理(可选)
|
||||
});
|
||||
},
|
||||
goBack() {
|
||||
this.$router.back();
|
||||
// 关闭当前页面
|
||||
this.$tab.closePage(router.currentRoute);
|
||||
},
|
||||
handleSelect(key) {
|
||||
this.activeIndex = key
|
||||
},
|
||||
},
|
||||
created() {
|
||||
getTestPlanDetail(this.$route.query.id).then(res => {
|
||||
this.editForm = res.data
|
||||
})
|
||||
this.planId = this.$route.query.id;
|
||||
console.log(this.planId)
|
||||
this.testTitle = this.$route.query.name
|
||||
this.testStatus = this.$route.query.testStatus
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: #409EFF;
|
||||
}
|
||||
|
||||
.el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
::v-deep.el-page-header__title {
|
||||
font-size: 20px;
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: solid 1px #e6e6e6;
|
||||
}
|
||||
</style>
|
||||
|
||||
335
test-ui/src/views/test/testplan/probablyView/probablyView.vue
Normal file
335
test-ui/src/views/test/testplan/probablyView/probablyView.vue
Normal file
@@ -0,0 +1,335 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 页面标题 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="24" class="page-header">
|
||||
<h3 style="font-size: 20px;color: #000000">测试计划概览</h3>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 测试计划详情 -->
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="24">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-row>
|
||||
<span style="font-size: 18px;color: #3A71A8">测试计划详情</span>
|
||||
</el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="5">
|
||||
<!-- <span>起止时间:{{ startToEndTime }}</span>-->
|
||||
<span>起止时间:2020-04-01 ~ 2020-04-30</span>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<span>当前测试计划已经开始 3 天,距离截止时间还有 52 天</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span>负责人:{{ manager }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover">
|
||||
<div class="progress-content">
|
||||
<div id="executionProgressChart" style="width: 70%; height: 200px;"></div>
|
||||
<div class="progress-text">
|
||||
<p style="font-size: 40px;margin: auto">100%</p>
|
||||
<p>执行进度</p>
|
||||
<p>用例总数 1</p>
|
||||
<p><span style="color: #409EFF">●</span> 已执行用例 1</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover">
|
||||
<div class="progress-content">
|
||||
<el-row :gutter="10">
|
||||
<el-col class="rate-content" :span="12">
|
||||
<p>100%</p>
|
||||
<el-progress :percentage="100" status="success"></el-progress>
|
||||
<p>执行用例通过率</p>
|
||||
</el-col>
|
||||
<el-col class="rate-content" :span="12">
|
||||
<p>100%</p>
|
||||
<el-progress :percentage="100" status="success"></el-progress>
|
||||
<p>总体用例通过率</p>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover">
|
||||
<div class="progress-content">
|
||||
<div class="defect-content">
|
||||
<p>0</p>
|
||||
<p>缺陷数</p>
|
||||
<el-row>
|
||||
<el-col :span="4">0</el-col>
|
||||
<el-col :span="4">0</el-col>
|
||||
<el-col :span="4">0</el-col>
|
||||
<el-col :span="4">0</el-col>
|
||||
<el-col :span="4">0</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="4">待确认</el-col>
|
||||
<el-col :span="4">修复中</el-col>
|
||||
<el-col :span="4">待验证</el-col>
|
||||
<el-col :span="4">无效缺陷</el-col>
|
||||
<el-col :span="4">挂起</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 测试用例 -->
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="10">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>用例执行分布</span>
|
||||
</div>
|
||||
<el-card shadow="hover">
|
||||
<div class="distribution-content">
|
||||
<el-progress type="circle" :percentage="100" color="#67C23A"></el-progress>
|
||||
<div class="distribution-text">
|
||||
<p><span style="background-color: #67C23A; display: inline-block; width: 10px; height: 10px;"></span> 通过 1</p>
|
||||
<p><span style="background-color: #F56C6C; display: inline-block; width: 10px; height: 10px;"></span> 失败 0</p>
|
||||
<p><span style="background-color: #E6A23C; display: inline-block; width: 10px; height: 10px;"></span> 阻塞 0</p>
|
||||
<p><span style="background-color: #F56C6C; display: inline-block; width: 10px; height: 10px;"></span> 跳过 0</p>
|
||||
<p><span style="background-color: #909399; display: inline-block; width: 10px; height: 10px;"></span> 未执行 0</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>用例执行情况趋势</span>
|
||||
</div>
|
||||
<el-card shadow="hover">
|
||||
<div class="distribution-text" style="height: 200px">
|
||||
<line-chart :data="trendData" :chart-data="trendData"></line-chart>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-card class="box-card">
|
||||
<div>
|
||||
关联需求信息
|
||||
<!-- 标签页 -->
|
||||
<el-tabs style="margin-top: 10px;">
|
||||
<el-Table v-loading="loading" :data="list">
|
||||
<el-table-column prop="serialNumber" label="ID" align="center"/>
|
||||
<el-table-column prop="version" label="版本" align="center"/>
|
||||
<el-table-column prop="outline" label="概要" align="center"/>
|
||||
<el-table-column prop="priority" label="优先级" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="priorityColor[scope.row.priority]">{{ scope.row.priority }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" align="center">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :options="dict.type.status" :value="row.status"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="manager" label="负责人" align="center"/>
|
||||
<el-table-column prop="createTime" label="创建时间" align="center"/>
|
||||
</el-Table>
|
||||
</el-tabs>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LineChart from '@/views/dashboard/LineChart';
|
||||
import * as echarts from 'echarts';
|
||||
import {getTestPlanProjectList} from "@/api/test/testPlan";
|
||||
|
||||
export default {
|
||||
name: 'probablyView',
|
||||
components: {
|
||||
LineChart,
|
||||
},
|
||||
props: {
|
||||
planId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
dicts: ['priority_level', 'project_source', 'project_type', 'status'],
|
||||
mounted() {
|
||||
this.initExecutionProgressChart();
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
priorityColor: {
|
||||
P0: 'danger', // 红色
|
||||
P1: 'warning', // 黄色
|
||||
P2: 'info', // 蓝色
|
||||
P3: 'success', // 绿色
|
||||
p4: 'success'
|
||||
},
|
||||
total: 0,
|
||||
list: [],
|
||||
loading: false,
|
||||
myChart: null,
|
||||
startToEndTime: '',
|
||||
defectSlider: 0,
|
||||
queryParams: {
|
||||
planId: '',
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
trendData: {
|
||||
labels: ['2025-04-01', '2025-04-02', '2025-04-03'],
|
||||
datasets: [
|
||||
{
|
||||
label: '通过',
|
||||
backgroundColor: '#67C23A',
|
||||
data: [0, 0.5, 1],
|
||||
},
|
||||
{
|
||||
label: '失败',
|
||||
backgroundColor: '#F56C6C',
|
||||
data: [0, 0, 0],
|
||||
},
|
||||
{
|
||||
label: '跳过',
|
||||
backgroundColor: '#E6A23C',
|
||||
data: [0, 0, 0],
|
||||
},
|
||||
{
|
||||
label: '阻塞',
|
||||
backgroundColor: '#909399',
|
||||
data: [0, 0, 0],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.loading = true;
|
||||
this.queryParams.planId = this.planId;
|
||||
getTestPlanProjectList(this.queryParams.planId).then(response => {
|
||||
this.list = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
})
|
||||
},
|
||||
// 初始化执行进度饼图
|
||||
initExecutionProgressChart() {
|
||||
const chartDom = document.getElementById('executionProgressChart');
|
||||
const myChart = echarts.init(chartDom);
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
top: '5%',
|
||||
left: 'center'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Access From',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 40,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{value: 1},
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
myChart.setOption(option);
|
||||
// 监听窗口大小变化,自动调整图表大小
|
||||
window.addEventListener('resize', () => {
|
||||
myChart.resize();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
.page-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.box-card {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.progress-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 200px;
|
||||
|
||||
.progress-text {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.rate-content {
|
||||
|
||||
}
|
||||
|
||||
.defect-content {
|
||||
text-align: center;
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.distribution-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.distribution-text {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.trend-content {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user