refactor(高级搜索): 优化根据所属模块搜索
This commit is contained in:
parent
cabd97b96f
commit
3eea5fbd4c
|
@ -208,6 +208,12 @@
|
||||||
<property name="object" value="${condition}.module"/>
|
<property name="object" value="${condition}.module"/>
|
||||||
</include>
|
</include>
|
||||||
</if>
|
</if>
|
||||||
|
<if test="${condition}.moduleIds != null">
|
||||||
|
and api_definition.module_id
|
||||||
|
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
|
||||||
|
<property name="object" value="${condition}.moduleIds"/>
|
||||||
|
</include>
|
||||||
|
</if>
|
||||||
<if test="${condition}.caseCount != null">
|
<if test="${condition}.caseCount != null">
|
||||||
and api_definition.case_total
|
and api_definition.case_total
|
||||||
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
|
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
|
||||||
|
|
|
@ -162,6 +162,12 @@
|
||||||
<property name="object" value="${condition}.module"/>
|
<property name="object" value="${condition}.module"/>
|
||||||
</include>
|
</include>
|
||||||
</if>
|
</if>
|
||||||
|
<if test="${condition}.moduleIds != null">
|
||||||
|
and api_scenario.api_scenario_module_id
|
||||||
|
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
|
||||||
|
<property name="object" value="${condition}.moduleIds"/>
|
||||||
|
</include>
|
||||||
|
</if>
|
||||||
<if test="${condition}.stepCount != null">
|
<if test="${condition}.stepCount != null">
|
||||||
and api_scenario.step_total
|
and api_scenario.step_total
|
||||||
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
|
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
|
||||||
|
|
|
@ -34,6 +34,12 @@
|
||||||
<property name="object" value="${condition}.module"/>
|
<property name="object" value="${condition}.module"/>
|
||||||
</include>
|
</include>
|
||||||
</if>
|
</if>
|
||||||
|
<if test="${condition}.moduleIds != null">
|
||||||
|
and test_case.node_id
|
||||||
|
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
|
||||||
|
<property name="object" value="${condition}.moduleIds"/>
|
||||||
|
</include>
|
||||||
|
</if>
|
||||||
<if test="${condition}.priority != null">
|
<if test="${condition}.priority != null">
|
||||||
and test_case.priority
|
and test_case.priority
|
||||||
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
|
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.condition">
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<span>
|
<span>
|
||||||
<span>
|
<span>
|
||||||
<ms-search
|
<ms-search
|
||||||
|
v-if="visibleSearch"
|
||||||
:condition.sync="condition"
|
:condition.sync="condition"
|
||||||
:base-search-tip="$t('commons.search_by_id_name_tag_path')"
|
:base-search-tip="$t('commons.search_by_id_name_tag_path')"
|
||||||
:base-search-width="260"
|
:base-search-width="260"
|
||||||
|
@ -431,6 +432,7 @@ export default {
|
||||||
projectName: "",
|
projectName: "",
|
||||||
versionEnable: false,
|
versionEnable: false,
|
||||||
isFirstInitTable: true,
|
isFirstInitTable: true,
|
||||||
|
visibleSearch: true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -517,6 +519,7 @@ export default {
|
||||||
this.editApi(response.data);
|
this.editApi(response.data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.setAdvSearchParam();
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
selectNodeIds() {
|
selectNodeIds() {
|
||||||
|
@ -535,6 +538,9 @@ export default {
|
||||||
initCondition(this.condition, false);
|
initCondition(this.condition, false);
|
||||||
this.closeCaseModel();
|
this.closeCaseModel();
|
||||||
this.initTable(true);
|
this.initTable(true);
|
||||||
|
this.visibleSearch = false;
|
||||||
|
this.$nextTick(() => (this.visibleSearch = true));
|
||||||
|
this.setAdvSearchParam();
|
||||||
},
|
},
|
||||||
currentVersion() {
|
currentVersion() {
|
||||||
this.condition.versionId = this.currentVersion;
|
this.condition.versionId = this.currentVersion;
|
||||||
|
@ -557,6 +563,12 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
setAdvSearchParam() {
|
||||||
|
let comp = this.condition.components.find(c => c.key === 'moduleIds');
|
||||||
|
if (comp) {
|
||||||
|
comp.options.params = {protocol: this.currentProtocol};
|
||||||
|
}
|
||||||
|
},
|
||||||
getProtocolFilter() {
|
getProtocolFilter() {
|
||||||
this.methodFilters = getProtocolFilter(this.currentProtocol);
|
this.methodFilters = getProtocolFilter(this.currentProtocol);
|
||||||
},
|
},
|
||||||
|
|
|
@ -172,8 +172,15 @@ export default {
|
||||||
if (!this.isInit) {
|
if (!this.isInit) {
|
||||||
this.isInit = true;
|
this.isInit = true;
|
||||||
this.init();
|
this.init();
|
||||||
|
} else {
|
||||||
|
this.refreshComponentOption();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
refreshComponentOption() {
|
||||||
|
// 当前已存在的搜索子组件中是否有需要进行刷新数据选项的
|
||||||
|
let comps = this.optional.components.filter(cp => cp.init && cp.init instanceof Function);
|
||||||
|
comps.forEach(comp => comp.init());
|
||||||
|
},
|
||||||
addFilter() {
|
addFilter() {
|
||||||
const index = _findIndexByKey(this.optional.components, this.nullFilterKey);
|
const index = _findIndexByKey(this.optional.components, this.nullFilterKey);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
|
|
|
@ -0,0 +1,191 @@
|
||||||
|
<template>
|
||||||
|
<ms-table-search-component
|
||||||
|
v-model="component.operator.value"
|
||||||
|
:component="component"
|
||||||
|
v-on="$listeners"
|
||||||
|
v-bind="$attrs">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-select
|
||||||
|
v-loading="result.loading"
|
||||||
|
v-model="scope.component.value"
|
||||||
|
:placeholder="$t('commons.please_select')"
|
||||||
|
:popper-append-to-body="false"
|
||||||
|
@remove-tag="removeTreeTag"
|
||||||
|
@change="changeTreeTag"
|
||||||
|
class="search-select"
|
||||||
|
size="small"
|
||||||
|
collapse-tags
|
||||||
|
multiple>
|
||||||
|
<div class="search-div">
|
||||||
|
<el-option
|
||||||
|
v-for="item in treeOptions"
|
||||||
|
class="search-select-option"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
:key="item.id">
|
||||||
|
</el-option>
|
||||||
|
<el-input
|
||||||
|
size="small"
|
||||||
|
class="search-input"
|
||||||
|
:placeholder="$t('api_test.request.parameters_mock_filter_tips')"
|
||||||
|
v-model="filterText">
|
||||||
|
<i slot="prefix" class="el-input__icon el-icon-search"></i>
|
||||||
|
</el-input>
|
||||||
|
<el-tree
|
||||||
|
:data="treeNodes"
|
||||||
|
:filter-node-method="filterNode"
|
||||||
|
@check="handleCheckChange"
|
||||||
|
default-expand-all
|
||||||
|
show-checkbox
|
||||||
|
node-key="id"
|
||||||
|
class="search-tree"
|
||||||
|
ref="tree">
|
||||||
|
</el-tree>
|
||||||
|
</div>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
</ms-table-search-component>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MsTableSearchComponent from "@/business/components/common/components/search/MsTableSearchComponet";
|
||||||
|
import MsNodeTree from "@/business/components/track/common/NodeTree";
|
||||||
|
import {cloneDeep} from "lodash";
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MsTableSearchNodeTree",
|
||||||
|
components: {
|
||||||
|
MsTableSearchComponent,
|
||||||
|
MsNodeTree
|
||||||
|
},
|
||||||
|
props: ['component'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
treeOptions: [],
|
||||||
|
result: {},
|
||||||
|
treeNodes: [],
|
||||||
|
filterText: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
filterText(val) {
|
||||||
|
this.$refs.tree.filter(val);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.init();
|
||||||
|
// 高级搜索框再次打开时调用 component.init() 函数
|
||||||
|
this.component.init = this.reload;
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
this.treeOptions = [];
|
||||||
|
let options = cloneDeep(this.component.options);
|
||||||
|
let {url, params, type} = options;
|
||||||
|
if (!url) return;
|
||||||
|
if (type === "POST") {
|
||||||
|
this.result = this.$post(url, params || {}, response => {
|
||||||
|
this.handleTreeNodes(response.data);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (type === "GET") {
|
||||||
|
this.result = this.$get(this.handleGETUrl(url, params), response => {
|
||||||
|
this.handleTreeNodes(response.data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reload() {
|
||||||
|
// 数据可能变更,刷新数据
|
||||||
|
this.init();
|
||||||
|
// 刷新选中状态
|
||||||
|
this.resetChecked();
|
||||||
|
},
|
||||||
|
resetChecked() {
|
||||||
|
if (this.component.value && this.component.value instanceof Array) {
|
||||||
|
for (let i = this.component.value.length - 1; i >= 0; i--) {
|
||||||
|
let node = this.$refs.tree.getNode(this.component.value[i]);
|
||||||
|
if (!node) {
|
||||||
|
this.component.value.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.changeTreeTag();
|
||||||
|
},
|
||||||
|
handleGETUrl(url, params) {
|
||||||
|
if (!params) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
for (let p in params) {
|
||||||
|
if (params.hasOwnProperty(p) && params[p]) {
|
||||||
|
url = url + "/" + params[p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
},
|
||||||
|
handleTreeNodes(data) {
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.treeNodes = data;
|
||||||
|
this.treeNodes.forEach(node => {
|
||||||
|
node.name = node.name === '未规划用例' ? this.$t('api_test.unplanned_case') : node.name;
|
||||||
|
this.buildTree(node);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
buildTree(node) {
|
||||||
|
this.treeOptions.push(node);
|
||||||
|
if (node.children) {
|
||||||
|
for (let i = 0; i < node.children.length; i++) {
|
||||||
|
this.buildTree(node.children[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleCheckChange(data, curData) {
|
||||||
|
const {checkedKeys} = curData;
|
||||||
|
this.component.value = checkedKeys;
|
||||||
|
},
|
||||||
|
changeTreeTag() {
|
||||||
|
this.$refs.tree.setCheckedKeys(this.component.value);
|
||||||
|
},
|
||||||
|
removeTreeTag(data) {
|
||||||
|
this.$refs.tree.setChecked(data, false, false);
|
||||||
|
},
|
||||||
|
filterNode(value, data) {
|
||||||
|
if (!value) return true;
|
||||||
|
return data.label.indexOf(value) !== -1;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.search-select {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-div {
|
||||||
|
max-height: 700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input {
|
||||||
|
padding: 0;
|
||||||
|
margin-top: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-tree {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-select-option {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input >>> .el-input__inner {
|
||||||
|
border-radius: 2px;
|
||||||
|
border-color: #e1dee5;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -5,6 +5,7 @@ import MsTableSearchSelect from "./MsTableSearchSelect";
|
||||||
import MsTableSearchInputNumber from "@/business/components/common/components/search/MsTableSearchInputNumber";
|
import MsTableSearchInputNumber from "@/business/components/common/components/search/MsTableSearchInputNumber";
|
||||||
import {getCurrentProjectID} from "@/common/js/utils";
|
import {getCurrentProjectID} from "@/common/js/utils";
|
||||||
import MsTableSearchMix from "@/business/components/common/components/search/MsTableSearchMix";
|
import MsTableSearchMix from "@/business/components/common/components/search/MsTableSearchMix";
|
||||||
|
import MsTableSearchNodeTree from "@/business/components/common/components/search/MsTableSearchNodeTree";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
MsTableSearchInput,
|
MsTableSearchInput,
|
||||||
|
@ -12,7 +13,8 @@ export default {
|
||||||
MsTableSearchDateTimePicker,
|
MsTableSearchDateTimePicker,
|
||||||
MsTableSearchSelect,
|
MsTableSearchSelect,
|
||||||
MsTableSearchInputNumber,
|
MsTableSearchInputNumber,
|
||||||
MsTableSearchMix
|
MsTableSearchMix,
|
||||||
|
MsTableSearchNodeTree
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OPERATORS = {
|
export const OPERATORS = {
|
||||||
|
@ -665,6 +667,44 @@ export const ID = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _getModuleTree(options) {
|
||||||
|
return {
|
||||||
|
key: "moduleIds",
|
||||||
|
name: 'MsTableSearchNodeTree',
|
||||||
|
label: "test_track.case.module",
|
||||||
|
operator: {
|
||||||
|
value: OPERATORS.IN.value,
|
||||||
|
options: [OPERATORS.IN, OPERATORS.NOT_IN]
|
||||||
|
},
|
||||||
|
options: options,
|
||||||
|
init: undefined // 高级搜索框非首次打开时会执行该函数,在组件首次created时给其赋值
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TEST_CASE_MODULE_TREE = _getModuleTree({
|
||||||
|
url: "/case/node/list/" + getCurrentProjectID(),
|
||||||
|
type: "POST",
|
||||||
|
params: {} // 赋值时注意顺序
|
||||||
|
})
|
||||||
|
|
||||||
|
export const API_MODULE_TREE = _getModuleTree({
|
||||||
|
url: "/api/module/list/" + getCurrentProjectID(),
|
||||||
|
type: "GET",
|
||||||
|
params: {}
|
||||||
|
})
|
||||||
|
|
||||||
|
export const SCENARIO_MODULE_TREE = _getModuleTree({
|
||||||
|
url: "/api/automation/module/list/" + getCurrentProjectID(),
|
||||||
|
type: "GET",
|
||||||
|
params: {}
|
||||||
|
})
|
||||||
|
|
||||||
|
export const UI_MODULE_TREE = _getModuleTree({
|
||||||
|
url: "/ui/scenario/module/list/" + getCurrentProjectID(),
|
||||||
|
type: "GET",
|
||||||
|
params: {}
|
||||||
|
})
|
||||||
|
|
||||||
export const TEST_CONFIGS = [ID, NAME, UPDATE_TIME, CREATE_TIME, STATUS, CREATOR, FOLLOW_PEOPLE];
|
export const TEST_CONFIGS = [ID, NAME, UPDATE_TIME, CREATE_TIME, STATUS, CREATOR, FOLLOW_PEOPLE];
|
||||||
|
|
||||||
export const PROJECT_CONFIGS = [NAME, UPDATE_TIME, CREATE_TIME, CREATOR];
|
export const PROJECT_CONFIGS = [NAME, UPDATE_TIME, CREATE_TIME, CREATOR];
|
||||||
|
@ -673,21 +713,21 @@ export const REPORT_CONFIGS = [NAME, TEST_NAME, CREATE_TIME, STATUS, CREATOR, TR
|
||||||
|
|
||||||
export const REPORT_CASE_CONFIGS = [NAME, CREATE_TIME, STATUS, CREATOR, TRIGGER_MODE];
|
export const REPORT_CASE_CONFIGS = [NAME, CREATE_TIME, STATUS, CREATOR, TRIGGER_MODE];
|
||||||
|
|
||||||
export const UI_REPORT_CONFIGS = [NAME, TEST_NAME, CREATE_TIME, UI_REPORT_STATUS, CREATOR, TRIGGER_MODE];
|
export const UI_REPORT_CONFIGS = [NAME, TEST_NAME, CREATE_TIME, UI_REPORT_STATUS, CREATOR, TRIGGER_MODE, UI_MODULE_TREE];
|
||||||
|
|
||||||
// 测试跟踪-测试用例 列表
|
// 测试跟踪-测试用例 列表
|
||||||
export const TEST_CASE_CONFIGS = [ID, NAME, TAGS, MODULE, CREATE_TIME, UPDATE_TIME, CREATOR, CASE_REVIEW_STATUS, FOLLOW_PEOPLE, CASE_DEMAND];
|
export const TEST_CASE_CONFIGS = [ID, NAME, TAGS, TEST_CASE_MODULE_TREE, CREATE_TIME, UPDATE_TIME, CREATOR, CASE_REVIEW_STATUS, FOLLOW_PEOPLE, CASE_DEMAND];
|
||||||
|
|
||||||
export const TEST_PLAN_CONFIGS = [NAME, UPDATE_TIME, CREATE_TIME, PRINCIPAL, TEST_PLAN_STATUS, STAGE, TAGS, FOLLOW_PEOPLE, ACTUAL_START_TIME, ACTUAL_END_TIME, PLAN_START_TIME, PLAN_END_TIME];
|
export const TEST_PLAN_CONFIGS = [NAME, UPDATE_TIME, CREATE_TIME, PRINCIPAL, TEST_PLAN_STATUS, STAGE, TAGS, FOLLOW_PEOPLE, ACTUAL_START_TIME, ACTUAL_END_TIME, PLAN_START_TIME, PLAN_END_TIME];
|
||||||
|
|
||||||
// 测试跟踪 测试评审列表
|
// 测试跟踪 测试评审列表
|
||||||
export const TEST_REVIEW = [NAME, CREATOR, TAGS, TEST_PLAN_STATUS, FOLLOW_PEOPLE, CREATE_TIME, UPDATE_TIME, END_TIME];
|
export const TEST_REVIEW = [NAME, CREATOR, TAGS, TEST_PLAN_STATUS, FOLLOW_PEOPLE, CREATE_TIME, UPDATE_TIME, END_TIME];
|
||||||
|
|
||||||
export const API_DEFINITION_CONFIGS = [ID, NAME, API_METHOD, API_PATH, API_STATUS, TAGS, UPDATE_TIME, CREATE_TIME, API_PRINCIPAL, ISREFERENCE, MODULE, FOLLOW_PEOPLE, CASE_COUNT];
|
export const API_DEFINITION_CONFIGS = [ID, NAME, API_METHOD, API_PATH, API_STATUS, TAGS, UPDATE_TIME, CREATE_TIME, API_PRINCIPAL, ISREFERENCE, API_MODULE_TREE, FOLLOW_PEOPLE, CASE_COUNT];
|
||||||
|
|
||||||
export const API_CASE_CONFIGS = [ID, NAME, PRIORITY, TAGS, API_CASE_RESULT, UPDATE_TIME, CREATE_TIME, CREATOR, ISREFERENCE, FOLLOW_PEOPLE, API_PATH];
|
export const API_CASE_CONFIGS = [ID, NAME, PRIORITY, TAGS, API_CASE_RESULT, UPDATE_TIME, CREATE_TIME, CREATOR, ISREFERENCE, FOLLOW_PEOPLE, API_PATH];
|
||||||
|
|
||||||
export const API_SCENARIO_CONFIGS = [ID, NAME, PRIORITY, TAGS, API_SCENARIO_RESULT, UPDATE_TIME, CREATE_TIME, CREATOR, FOLLOW_PEOPLE, STEP_COUNT, MODULE, API_STATUS];
|
export const API_SCENARIO_CONFIGS = [ID, NAME, PRIORITY, TAGS, API_SCENARIO_RESULT, UPDATE_TIME, CREATE_TIME, CREATOR, FOLLOW_PEOPLE, STEP_COUNT, SCENARIO_MODULE_TREE, API_STATUS];
|
||||||
|
|
||||||
export const TEST_PLAN_REPORT_CONFIGS = [NAME, TEST_PLAN_NAME, CREATOR, CREATE_TIME, TEST_PLAN_TRIGGER_MODE, TEST_PLAN_REPORT_STATUS];
|
export const TEST_PLAN_REPORT_CONFIGS = [NAME, TEST_PLAN_NAME, CREATOR, CREATE_TIME, TEST_PLAN_TRIGGER_MODE, TEST_PLAN_REPORT_STATUS];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue