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

This commit is contained in:
Captain.B 2020-07-21 14:53:42 +08:00
parent f29dfbf018
commit 9a5c02827b
6 changed files with 217 additions and 16 deletions

View File

@ -142,9 +142,20 @@
<select id="list" resultType="io.metersphere.track.dto.TestCaseDTO"> <select id="list" resultType="io.metersphere.track.dto.TestCaseDTO">
select test_case.* from test_case select test_case.* from test_case
<where> <where>
<if test="request.name != null"> <choose>
and test_case.name like CONCAT('%', #{request.name},'%') <!--高级-->
</if> <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.nodeIds != null and request.nodeIds.size() > 0"> <if test="request.nodeIds != null and request.nodeIds.size() > 0">
and test_case.node_id in and test_case.node_id in
<foreach collection="request.nodeIds" item="nodeId" separator="," open="(" close=")"> <foreach collection="request.nodeIds" item="nodeId" separator="," open="(" close=")">

View File

@ -6,15 +6,114 @@
extends="io.metersphere.base.mapper.TestPlanMapper.BaseResultMap"> extends="io.metersphere.base.mapper.TestPlanMapper.BaseResultMap">
<result column="project_name" property="projectName"/> <result column="project_name" property="projectName"/>
</resultMap> </resultMap>
<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_plan.name
<include refid="condition">
<property name="object" value="${condition}.name"/>
</include>
</if>
<if test="${condition}.projectName != null">
and project.name
<include refid="condition">
<property name="object" value="${condition}.projectName"/>
</include>
</if>
<if test="${condition}.principal != null">
and test_plan.principal
<include refid="condition">
<property name="object" value="${condition}.principal"/>
</include>
</if>
<if test="${condition}.createTime != null">
and test_plan.create_time
<include refid="condition">
<property name="object" value="${condition}.createTime"/>
</include>
</if>
<if test="${condition}.status != null">
and test_plan.status
<include refid="condition">
<property name="object" value="${condition}.status"/>
</include>
</if>
<if test="${condition}.updateTime != null">
and test_plan.update_time
<include refid="condition">
<property name="object" value="${condition}.updateTime"/>
</include>
</if>
<if test="${condition}.stage != null">
and test_plan.stage
<include refid="condition">
<property name="object" value="${condition}.stage"/>
</include>
</if>
</sql>
<select id="list" resultMap="BaseResultMap" parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest"> <select id="list" resultMap="BaseResultMap" parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
select test_plan.*, project.name as project_name select test_plan.*, project.name as project_name
from test_plan from test_plan
left join project on test_plan.project_id = project.id left join project on test_plan.project_id = project.id
<where> <where>
<if test="request.name != null"> <choose>
and test_plan.name like CONCAT('%', #{request.name},'%') <!--高级-->
</if> <when test="request.combine != null">
<include refid="combine">
<property name="condition" value="request.combine"/>
</include>
</when>
<!--普通-->
<otherwise>
<if test="request.name != null">
and test_plan.name like CONCAT('%', #{request.name},'%')
</if>
</otherwise>
</choose>
<if test="request.workspaceId != null"> <if test="request.workspaceId != null">
AND project.workspace_id = #{request.workspaceId} AND project.workspace_id = #{request.workspaceId}
</if> </if>

View File

@ -19,4 +19,6 @@ public class QueryTestPlanRequest extends TestPlan {
private List<OrderRequest> orders; private List<OrderRequest> orders;
private Map<String, List<String>> filters; private Map<String, List<String>> filters;
private Map<String, Object> combine;
} }

View File

@ -220,8 +220,72 @@ export const MODULE = {
}, },
} }
export const PRINCIPAL = {
key: "principal",
name: 'MsTableSearchSelect',
label: 'test_track.plan.plan_principal',
operator: {
options: [OPERATORS.IN, OPERATORS.NOT_IN, OPERATORS.CURRENT_USER],
change: function (component, value) { // 运算符change事件
if (value === OPERATORS.CURRENT_USER.value) {
component.value = value;
}
}
},
options: { // 异步获取候选项
url: "/user/list",
labelKey: "name",
valueKey: "id",
showLabel: option => {
return option.label + "(" + option.value + ")";
}
},
props: {
multiple: true
},
isShow: operator => {
return operator !== OPERATORS.CURRENT_USER.value;
}
};
export const STAGE = {
key: "stage",
name: 'MsTableSearchSelect',
label: "test_track.plan.plan_stage",
operator: {
options: [OPERATORS.IN, OPERATORS.NOT_IN]
},
options: [
{label: 'test_track.plan.smoke_test', value: 'smoke'},
{label: 'test_track.plan.regression_test', value: 'regression'},
{label: 'test_track.plan.system_test', value: 'system'}
],
props: {
multiple: true
}
};
export const TEST_PLAN_STATUS = {
key: "status",
name: 'MsTableSearchSelect',
label: "test_track.plan.plan_status",
operator: {
options: [OPERATORS.IN, OPERATORS.NOT_IN]
},
options: [
{label: 'test_track.plan.plan_status_prepare', value: 'Prepare'},
{label: 'test_track.plan.plan_status_running', value: 'Underway'},
{label: 'test_track.plan.plan_status_completed', value: 'Completed'}
],
props: {
multiple: true
}
};
export const TEST_CONFIGS = [NAME, UPDATE_TIME, PROJECT_NAME, CREATE_TIME, STATUS, CREATOR]; export const TEST_CONFIGS = [NAME, UPDATE_TIME, PROJECT_NAME, CREATE_TIME, STATUS, CREATOR];
export const REPORT_CONFIGS = [NAME, TEST_NAME, PROJECT_NAME, CREATE_TIME, STATUS, CREATOR, TRIGGER_MODE]; export const REPORT_CONFIGS = [NAME, TEST_NAME, PROJECT_NAME, CREATE_TIME, STATUS, CREATOR, TRIGGER_MODE];
export const TEST_CASE_CONFIGS = [NAME, MODULE, PRIORITY, CREATE_TIME, TYPE, UPDATE_TIME, METHOD, CREATOR]; export const TEST_CASE_CONFIGS = [NAME, MODULE, PRIORITY, CREATE_TIME, TYPE, UPDATE_TIME, METHOD, CREATOR];
export const TEST_PLAN_CONFIGS = [NAME, UPDATE_TIME, PROJECT_NAME, CREATE_TIME, PRINCIPAL, TEST_PLAN_STATUS, STAGE];

View File

@ -130,7 +130,8 @@
import MsTableOperator from "../../../common/components/MsTableOperator"; import MsTableOperator from "../../../common/components/MsTableOperator";
import MsTableOperatorButton from "../../../common/components/MsTableOperatorButton"; import MsTableOperatorButton from "../../../common/components/MsTableOperatorButton";
import MsTableButton from "../../../common/components/MsTableButton"; import MsTableButton from "../../../common/components/MsTableButton";
import {_filter, _sort, downloadFile, humpToLine} from "../../../../../common/js/utils"; import {_filter, _sort} from "../../../../../common/js/utils";
import {TEST_CASE_CONFIGS} from "../../../common/components/search/search-components";
export default { export default {
name: "TestCaseList", name: "TestCaseList",
@ -147,7 +148,9 @@
return { return {
result: {}, result: {},
deletePath: "/test/case/delete", deletePath: "/test/case/delete",
condition: {}, condition: {
components: TEST_CASE_CONFIGS
},
tableData: [], tableData: [],
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
@ -193,11 +196,20 @@
} }
}, },
methods: { methods: {
initTableData() { initTableData(combine) {
this.condition.nodeIds = this.selectNodeIds; // combine
let condition = combine ? {combine: combine} : this.condition;
if (this.planId) {
// 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.currentProject) { if (this.currentProject) {
this.condition.projectId = this.currentProject.id; condition.projectId = this.currentProject.id;
this.result = this.$post(this.buildPagePath('/test/case/list'), this.condition, response => { this.result = this.$post(this.buildPagePath('/test/case/list'), condition, response => {
let data = response.data; let data = response.data;
this.total = data.itemCount; this.total = data.itemCount;
this.tableData = data.listObject; this.tableData = data.listObject;
@ -252,7 +264,7 @@
}); });
}, },
refresh() { refresh() {
this.condition = {}; this.condition = {components: TEST_CASE_CONFIGS};
this.selectIds.clear(); this.selectIds.clear();
this.$emit('refresh'); this.$emit('refresh');
}, },

View File

@ -118,6 +118,7 @@
import TestReportTemplateList from "../view/comonents/TestReportTemplateList"; import TestReportTemplateList from "../view/comonents/TestReportTemplateList";
import TestCaseReportView from "../view/comonents/report/TestCaseReportView"; import TestCaseReportView from "../view/comonents/report/TestCaseReportView";
import MsDeleteConfirm from "../../../common/components/MsDeleteConfirm"; import MsDeleteConfirm from "../../../common/components/MsDeleteConfirm";
import {TEST_PLAN_CONFIGS} from "../../../common/components/search/search-components";
export default { export default {
name: "TestPlanList", name: "TestPlanList",
@ -133,7 +134,9 @@
result: {}, result: {},
queryPath: "/test/plan/list", queryPath: "/test/plan/list",
deletePath: "/test/plan/delete", deletePath: "/test/plan/delete",
condition: {}, condition: {
components: TEST_PLAN_CONFIGS
},
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
isTestManagerOrTestUser: false, isTestManagerOrTestUser: false,
@ -164,8 +167,18 @@
this.initTableData(); this.initTableData();
}, },
methods: { methods: {
initTableData() { initTableData(combine) {
this.result = this.$post(this.buildPagePath(this.queryPath), this.condition, response => { // combine
let condition = combine ? {combine: combine} : this.condition;
if (this.planId) {
// param.planId = this.planId;
condition.planId = this.planId;
}
if (this.selectNodeIds && this.selectNodeIds.length > 0) {
// param.nodeIds = this.selectNodeIds;
condition.nodeIds = this.selectNodeIds;
}
this.result = this.$post(this.buildPagePath(this.queryPath), condition, response => {
let data = response.data; let data = response.data;
this.total = data.itemCount; this.total = data.itemCount;
this.tableData = data.listObject; this.tableData = data.listObject;