feat: 增加测试用例和测试计划的高级搜索

This commit is contained in:
Captain.B 2020-07-22 13:22:54 +08:00
parent 0b1a0964d1
commit 23351a71e2
3 changed files with 377 additions and 248 deletions

View File

@ -1,6 +1,100 @@
<?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="io.metersphere.base.mapper.ext.ExtTestPlanTestCaseMapper">
<sql id="condition">
<choose>
<when test='${object}.operator == "like"'>
like CONCAT('%', #{${object}.value},'%')
</when>
<when test='${object}.operator == "not like"'>
not like CONCAT('%', #{${object}.value},'%')
</when>
<when test='${object}.operator == "in"'>
in
<foreach collection="${object}.value" item="v" separator="," open="(" close=")">
#{v}
</foreach>
</when>
<when test='${object}.operator == "not in"'>
not in
<foreach collection="${object}.value" item="v" separator="," open="(" close=")">
#{v}
</foreach>
</when>
<when test='${object}.operator == "between"'>
between #{${object}.value[0]} and #{${object}.value[1]}
</when>
<when test='${object}.operator == "gt"'>
&gt; #{${object}.value}
</when>
<when test='${object}.operator == "lt"'>
&lt; #{${object}.value}
</when>
<when test='${object}.operator == "ge"'>
&gt;= #{${object}.value}
</when>
<when test='${object}.operator == "le"'>
&lt;= #{${object}.value}
</when>
<when test='${object}.operator == "current user"'>
= '${@io.metersphere.commons.utils.SessionUtils@getUserId()}'
</when>
<otherwise>
= #{${object}.value}
</otherwise>
</choose>
</sql>
<sql id="combine">
<if test="${condition}.name != null">
and test_case.name
<include refid="condition">
<property name="object" value="${condition}.name"/>
</include>
</if>
<if test="${condition}.module != null">
and test_case.node_path
<include refid="condition">
<property name="object" value="${condition}.module"/>
</include>
</if>
<if test="${condition}.priority != null">
and test_case.priority
<include refid="condition">
<property name="object" value="${condition}.priority"/>
</include>
</if>
<if test="${condition}.createTime != null">
and test_case.create_time
<include refid="condition">
<property name="object" value="${condition}.createTime"/>
</include>
</if>
<if test="${condition}.type != null">
and test_case.type
<include refid="condition">
<property name="object" value="${condition}.type"/>
</include>
</if>
<if test="${condition}.updateTime != null">
and test_case.update_time
<include refid="condition">
<property name="object" value="${condition}.updateTime"/>
</include>
</if>
<if test="${condition}.method != null">
and test_case.method
<include refid="condition">
<property name="object" value="${condition}.method"/>
</include>
</if>
<if test="${condition}.creator != null">
and test_case.maintainer
<include refid="condition">
<property name="object" value="${condition}.creator"/>
</include>
</if>
</sql>
<select id="getReportMetric" parameterType="java.lang.String"
resultType="io.metersphere.track.dto.TestCaseReportStatusResultDTO">
@ -25,9 +119,20 @@
from test_plan_test_case
inner join test_case on test_plan_test_case.case_id = test_case.id
<where>
<choose>
<!--高级-->
<when test="request.combine != null">
<include refid="combine">
<property name="condition" value="request.combine"/>
</include>
</when>
<!--普通-->
<otherwise>
<if test="request.name != null">
and test_case.name like CONCAT('%', #{request.name},'%')
</if>
</otherwise>
</choose>
<if test="request.id != null">
and test_case.id = #{request.id}
</if>

View File

@ -33,4 +33,6 @@ public class QueryTestPlanCaseRequest extends TestPlanTestCase {
private String node;
private String method;
private Map<String, Object> combine;
}

View File

@ -2,19 +2,30 @@
<div class="card-container">
<el-card class="card-content" v-loading="result.loading">
<template v-slot:header>
<ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="initTableData" :show-create="false">
<ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="initTableData"
:show-create="false">
<template v-slot:title>
<node-breadcrumb class="table-title" :nodes="selectParentNodes" @refresh="refresh"/>
</template>
<template v-slot:button>
<ms-table-button :is-tester-permission="true" v-if="!showMyTestCase" icon="el-icon-s-custom" :content="$t('test_track.plan_view.my_case')" @click="searchMyTestCase"/>
<ms-table-button :is-tester-permission="true" v-if="showMyTestCase" icon="el-icon-files" :content="$t('test_track.plan_view.all_case')" @click="searchMyTestCase"/>
<ms-table-button :is-tester-permission="true" icon="el-icon-connection" :content="$t('test_track.plan_view.relevance_test_case')" @click="$emit('openTestCaseRelevanceDialog')"/>
<ms-table-button :is-tester-permission="true" icon="el-icon-unlock" :content="$t('test_track.plan_view.cancel_relevance')" @click="handleBatch('delete')"/>
<ms-table-button :is-tester-permission="true" icon="el-icon-edit-outline" :content="$t('test_track.plan_view.change_execution_results')" @click="handleBatch('status')"/>
<ms-table-button :is-tester-permission="true" icon="el-icon-user" :content="$t('test_track.plan_view.change_executor')" @click="handleBatch('executor')"/>
<ms-table-button :is-tester-permission="true" v-if="!testPlan.reportId" icon="el-icon-document" :content="$t('test_track.plan_view.create_report')" @click="openTestReport"/>
<ms-table-button :is-tester-permission="true" v-if="testPlan.reportId" icon="el-icon-document" :content="$t('test_track.plan_view.view_report')" @click="openReport"/>
<ms-table-button :is-tester-permission="true" v-if="!showMyTestCase" icon="el-icon-s-custom"
:content="$t('test_track.plan_view.my_case')" @click="searchMyTestCase"/>
<ms-table-button :is-tester-permission="true" v-if="showMyTestCase" icon="el-icon-files"
:content="$t('test_track.plan_view.all_case')" @click="searchMyTestCase"/>
<ms-table-button :is-tester-permission="true" icon="el-icon-connection"
:content="$t('test_track.plan_view.relevance_test_case')"
@click="$emit('openTestCaseRelevanceDialog')"/>
<ms-table-button :is-tester-permission="true" icon="el-icon-unlock"
:content="$t('test_track.plan_view.cancel_relevance')" @click="handleBatch('delete')"/>
<ms-table-button :is-tester-permission="true" icon="el-icon-edit-outline"
:content="$t('test_track.plan_view.change_execution_results')"
@click="handleBatch('status')"/>
<ms-table-button :is-tester-permission="true" icon="el-icon-user"
:content="$t('test_track.plan_view.change_executor')" @click="handleBatch('executor')"/>
<ms-table-button :is-tester-permission="true" v-if="!testPlan.reportId" icon="el-icon-document"
:content="$t('test_track.plan_view.create_report')" @click="openTestReport"/>
<ms-table-button :is-tester-permission="true" v-if="testPlan.reportId" icon="el-icon-document"
:content="$t('test_track.plan_view.view_report')" @click="openReport"/>
</template>
</ms-table-header>
</template>
@ -93,7 +104,7 @@
:label="$t('test_track.plan_view.execute_result')">
<template v-slot:default="scope">
<span @click.stop="clickt = 'stop'">
<el-dropdown class="test-case-status" @command="statusChange" >
<el-dropdown class="test-case-status" @command="statusChange">
<span class="el-dropdown-link">
<status-table-item :value="scope.row.status"/>
</span>
@ -101,10 +112,12 @@
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'Pass'}">
{{$t('test_track.plan_view.pass')}}
</el-dropdown-item>
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'Failure'}">
<el-dropdown-item :disabled="!isTestManagerOrTestUser"
:command="{id: scope.row.id, status: 'Failure'}">
{{$t('test_track.plan_view.failure')}}
</el-dropdown-item>
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'Blocking'}">
<el-dropdown-item :disabled="!isTestManagerOrTestUser"
:command="{id: scope.row.id, status: 'Blocking'}">
{{$t('test_track.plan_view.blocking')}}
</el-dropdown-item>
<el-dropdown-item :disabled="!isTestManagerOrTestUser" :command="{id: scope.row.id, status: 'Skip'}">
@ -128,8 +141,10 @@
<el-table-column
:label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator-button :is-tester-permission="true" :tip="$t('commons.edit')" icon="el-icon-edit" @exec="handleEdit(scope.row)" />
<ms-table-operator-button :is-tester-permission="true" :tip="$t('test_track.plan_view.cancel_relevance')" icon="el-icon-unlock" type="danger" @exec="handleDelete(scope.row)"/>
<ms-table-operator-button :is-tester-permission="true" :tip="$t('commons.edit')" icon="el-icon-edit"
@exec="handleEdit(scope.row)"/>
<ms-table-operator-button :is-tester-permission="true" :tip="$t('test_track.plan_view.cancel_relevance')"
icon="el-icon-unlock" type="danger" @exec="handleDelete(scope.row)"/>
</template>
</el-table-column>
</el-table>
@ -162,12 +177,7 @@
import NodeBreadcrumb from '../../../common/NodeBreadcrumb';
import {ROLE_TEST_MANAGER, ROLE_TEST_USER, TokenKey} from '../../../../../../common/js/constants';
import {
_filter,
_sort,
checkoutTestManagerOrTestUser,
hasRoles
} from '../../../../../../common/js/utils';
import {_filter, _sort, checkoutTestManagerOrTestUser, hasRoles} from '../../../../../../common/js/utils';
import PriorityTableItem from "../../../common/tableItems/planview/PriorityTableItem";
import StatusTableItem from "../../../common/tableItems/planview/StatusTableItem";
import TypeTableItem from "../../../common/tableItems/planview/TypeTableItem";
@ -176,6 +186,7 @@
import MsTableOperatorButton from "../../../../common/components/MsTableOperatorButton";
import TestReportTemplateList from "./TestReportTemplateList";
import TestCaseReportView from "./report/TestCaseReportView";
import {TEST_CASE_CONFIGS} from "../../../../common/components/search/search-components";
export default {
name: "TestPlanTestCaseList",
@ -188,12 +199,15 @@
TypeTableItem,
StatusTableItem,
PriorityTableItem, StatusEdit, ExecutorEdit, MsTipButton, MsTablePagination,
TestPlanTestCaseEdit, MsTableHeader, NodeBreadcrumb, MsTableButton},
TestPlanTestCaseEdit, MsTableHeader, NodeBreadcrumb, MsTableButton
},
data() {
return {
result: {},
deletePath: "/test/case/delete",
condition: {},
condition: {
components: TEST_CASE_CONFIGS
},
showMyTestCase: false,
tableData: [],
currentPage: 1,
@ -228,7 +242,7 @@
]
}
},
props:{
props: {
planId: {
type: String
},
@ -252,11 +266,19 @@
this.isTestManagerOrTestUser = checkoutTestManagerOrTestUser();
},
methods: {
initTableData() {
initTableData(combine) {
// combine
let condition = combine ? {combine: combine} : this.condition;
if (this.planId) {
this.condition.planId = this.planId;
this.condition.nodeIds = this.selectNodeIds;
this.result = this.$post(this.buildPagePath('/test/plan/case/list'), this.condition, response => {
// param.planId = this.planId;
condition.planId = this.planId;
}
if (this.selectNodeIds && this.selectNodeIds.length > 0) {
// param.nodeIds = this.selectNodeIds;
condition.nodeIds = this.selectNodeIds;
}
if (this.planId) {
this.result = this.$post(this.buildPagePath('/test/plan/case/list'), condition, response => {
let data = response.data;
this.total = data.itemCount;
this.tableData = data.listObject;
@ -269,7 +291,7 @@
this.$refs.testPlanTestCaseEdit.openTestCaseEdit(row);
},
refresh() {
this.condition = {};
this.condition = {components: TEST_CASE_CONFIGS};
this.selectIds.clear();
this.$emit('refresh');
},
@ -330,7 +352,7 @@
});
},
handleSelectAll(selection) {
if(selection.length > 0) {
if (selection.length > 0) {
this.tableData.forEach(item => {
this.selectIds.add(item.id);
});
@ -339,20 +361,20 @@
}
},
handleSelectionChange(selection, row) {
if(this.selectIds.has(row.id)){
if (this.selectIds.has(row.id)) {
this.selectIds.delete(row.id);
} else {
this.selectIds.add(row.id);
}
},
handleBatch(type){
handleBatch(type) {
if (this.selectIds.size < 1) {
this.$warning(this.$t('test_track.plan_view.select_manipulate'));
return;
}
if (type === 'executor'){
if (type === 'executor') {
this.$refs.executorEdit.openExecutorEdit();
} else if (type === 'status'){
} else if (type === 'status') {
this.$refs.statusEdit.openStatusEdit();
} else if (type === 'delete') {
this.handleDeleteBatch();
@ -372,7 +394,7 @@
this.$refs.testReporTtemplateList.open(this.planId);
},
statusChange(param) {
this.$post('/test/plan/case/edit' , param, () => {
this.$post('/test/plan/case/edit', param, () => {
for (let i = 0; i < this.tableData.length; i++) {
if (this.tableData[i].id == param.id) {
this.tableData[i].status = param.status;
@ -418,8 +440,8 @@
width: 240px;
}
.test-case-status,.el-table {
cursor:pointer;
.test-case-status, .el-table {
cursor: pointer;
}
</style>