高级查询控件

This commit is contained in:
q4speed 2020-07-10 16:43:43 +08:00
parent 5a377843d9
commit 37577b76b0
11 changed files with 227 additions and 73 deletions

View File

@ -4,7 +4,7 @@
<el-card class="table-card" v-loading="result.loading"> <el-card class="table-card" v-loading="result.loading">
<template v-slot:header> <template v-slot:header>
<ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="search" <ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="search"
:title="$t('api_report.title')" :title="$t('api_report.title')" :advanced="advanced"
:show-create="false"/> :show-create="false"/>
</template> </template>
<el-table :data="tableData" class="table-content" @sort-change="sort" <el-table :data="tableData" class="table-content" @sort-change="sort"
@ -14,13 +14,13 @@
<el-table-column prop="testName" :label="$t('api_report.test_name')" width="200" show-overflow-tooltip/> <el-table-column prop="testName" :label="$t('api_report.test_name')" width="200" show-overflow-tooltip/>
<el-table-column prop="projectName" :label="$t('load_test.project_name')" width="150" show-overflow-tooltip/> <el-table-column prop="projectName" :label="$t('load_test.project_name')" width="150" show-overflow-tooltip/>
<el-table-column prop="userName" :label="$t('api_test.creator')" width="150" show-overflow-tooltip/> <el-table-column prop="userName" :label="$t('api_test.creator')" width="150" show-overflow-tooltip/>
<el-table-column width="250" :label="$t('commons.create_time')" sortable <el-table-column prop="createTime" width="250" :label="$t('commons.create_time')" sortable>
prop="createTime">
<template v-slot:default="scope"> <template v-slot:default="scope">
<span>{{ scope.row.createTime | timestampFormatDate }}</span> <span>{{ scope.row.createTime | timestampFormatDate }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="triggerMode" width="150" :label="'触发方式'" column-key="triggerMode" :filters="triggerFilters"> <el-table-column prop="triggerMode" width="150" :label="$t('commons.trigger_mode.name')"
column-key="triggerMode" :filters="triggerFilters">
<template v-slot:default="scope"> <template v-slot:default="scope">
<report-trigger-mode-item :trigger-mode="scope.row.triggerMode"/> <report-trigger-mode-item :trigger-mode="scope.row.triggerMode"/>
</template> </template>
@ -34,8 +34,10 @@
</el-table-column> </el-table-column>
<el-table-column width="150" :label="$t('commons.operating')"> <el-table-column width="150" :label="$t('commons.operating')">
<template v-slot:default="scope"> <template v-slot:default="scope">
<ms-table-operator-button :tip="$t('api_report.detail')" icon="el-icon-s-data" @exec="handleView(scope.row)" type="primary"/> <ms-table-operator-button :tip="$t('api_report.detail')" icon="el-icon-s-data"
<ms-table-operator-button :is-tester-permission="true" :tip="$t('api_report.delete')" icon="el-icon-delete" @exec="handleDelete(scope.row)" type="danger"/> @exec="handleView(scope.row)" type="primary"/>
<ms-table-operator-button :is-tester-permission="true" :tip="$t('api_report.delete')"
icon="el-icon-delete" @exec="handleDelete(scope.row)" type="danger"/>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -55,16 +57,21 @@
import {_filter, _sort} from "../../../../common/js/utils"; import {_filter, _sort} from "../../../../common/js/utils";
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton"; import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
import ReportTriggerModeItem from "../../common/tableItem/ReportTriggerModeItem"; import ReportTriggerModeItem from "../../common/tableItem/ReportTriggerModeItem";
import {REPORT_CONFIGS} from "../../common/components/search/search-components";
export default { export default {
components: { components: {
ReportTriggerModeItem, ReportTriggerModeItem,
MsTableOperatorButton, MsTableOperatorButton,
MsApiReportStatus, MsMainContainer, MsContainer, MsTableHeader, MsTablePagination}, MsApiReportStatus, MsMainContainer, MsContainer, MsTableHeader, MsTablePagination
},
data() { data() {
return { return {
result: {}, result: {},
condition: {}, condition: {},
advanced: {
components: REPORT_CONFIGS
},
tableData: [], tableData: [],
multipleSelection: [], multipleSelection: [],
currentPage: 1, currentPage: 1,

View File

@ -4,7 +4,7 @@
<el-card class="table-card" v-loading="result.loading"> <el-card class="table-card" v-loading="result.loading">
<template v-slot:header> <template v-slot:header>
<ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="search" <ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="search"
:title="$t('commons.test')" :title="$t('commons.test')" :advanced="advanced"
@create="create" :createTip="$t('load_test.create')"/> @create="create" :createTip="$t('load_test.create')"/>
</template> </template>
<el-table :data="tableData" class="table-content" @sort-change="sort" @row-click="handleView" <el-table :data="tableData" class="table-content" @sort-change="sort" @row-click="handleView"
@ -54,14 +54,7 @@
import MsApiTestStatus from "./ApiTestStatus"; import MsApiTestStatus from "./ApiTestStatus";
import MsTableOperators from "../../common/components/MsTableOperators"; import MsTableOperators from "../../common/components/MsTableOperators";
import {_filter, _sort} from "../../../../common/js/utils"; import {_filter, _sort} from "../../../../common/js/utils";
import { import {TEST_CONFIGS} from "../../common/components/search/search-components";
TEST_NAME,
UPDATE_TIME,
PROJECT_NAME,
CREATE_TIME,
STATUS,
CREATOR,
} from "../../common/components/search/search-components";
export default { export default {
components: { components: {
@ -71,8 +64,9 @@
data() { data() {
return { return {
result: {}, result: {},
condition: { condition: {},
components: [TEST_NAME, UPDATE_TIME, PROJECT_NAME, CREATE_TIME, STATUS, CREATOR] advanced: {
components: TEST_CONFIGS
}, },
projectId: null, projectId: null,
tableData: [], tableData: [],

View File

@ -14,7 +14,7 @@
</span> </span>
<span> <span>
<ms-table-search-bar :condition.sync="condition" @change="search" class="search-bar"/> <ms-table-search-bar :condition.sync="condition" @change="search" class="search-bar"/>
<ms-table-adv-search-bar :condition.sync="condition" @search="search"/> <ms-table-adv-search-bar :condition="advanced" @search="search" v-if="advanced"/>
</span> </span>
</el-row> </el-row>
</div> </div>
@ -22,7 +22,7 @@
</template> </template>
<script> <script>
import MsTableSearchBar from './search/MsTableSearchBar'; import MsTableSearchBar from './MsTableSearchBar';
import MsTableButton from './MsTableButton'; import MsTableButton from './MsTableButton';
import MsTableAdvSearchBar from "./search/MsTableAdvSearchBar"; import MsTableAdvSearchBar from "./search/MsTableAdvSearchBar";
@ -43,6 +43,7 @@
condition: { condition: {
type: Object type: Object
}, },
advanced: Object,
createTip: { createTip: {
type: String, type: String,
default() { default() {

View File

@ -4,20 +4,18 @@
<el-dialog :title="$t('commons.adv_search.combine')" :visible.sync="visible" width="70%"> <el-dialog :title="$t('commons.adv_search.combine')" :visible.sync="visible" width="70%">
<div> <div>
<div class="search-label">{{$t('commons.adv_search.combine')}}: </div> <div class="search-label">{{$t('commons.adv_search.combine')}}: </div>
<el-select v-model="condition.logic" :placeholder="$t('commons.please_select')" size="small" <el-select v-model="logic" :placeholder="$t('commons.please_select')" size="small" class="search-combine">
class="search-combine"> <el-option v-for="op in options" :key="op.value" :label="$t(op.label)" :value="op.value"/>
<el-option :label="$t('commons.adv_search.and')" value="and"></el-option>
<el-option :label="$t('commons.adv_search.or')" value="or"></el-option>
</el-select> </el-select>
<div class="search-items"> <div class="search-items">
<component class="search-item" v-for="(component, index) in condition.components" :key="index" <component class="search-item" v-for="(component, index) in condition.components" :key="index"
:is="component.name" v-model="component.value" :component="component"/> :is="component.name" :component="component"/>
</div> </div>
</div> </div>
<template v-slot:footer> <template v-slot:footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button @click="visible = false">{{$t('commons.cancel')}}</el-button> <el-button @click="visible = false">{{$t('commons.cancel')}}</el-button>
<el-button type="primary" @click="search">{{$t('commons.search')}}</el-button> <el-button type="primary" @click="search">{{$t('commons.adv_search.search')}}</el-button>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
@ -25,7 +23,7 @@
</template> </template>
<script> <script>
import components from "./search-components"; import {default as components, LOGIC} from "./search-components";
export default { export default {
components: {...components}, components: {...components},
@ -36,32 +34,38 @@
data() { data() {
return { return {
visible: false, visible: false,
operator: "" options: [LOGIC.AND, LOGIC.OR],
logic: this.condition.logic || LOGIC.AND.value
} }
}, },
methods: { methods: {
search() { search() {
let condition = { let condition = {
logic: this.condition.logic logic: this.logic
} }
this.condition.components.forEach(component => { this.condition.components.forEach(component => {
if (component.value !== undefined && component.value !== null) { if (Array.isArray(component.value)) {
condition[component.key] = { if (component.value.length > 0) {
operator: component.operator, condition[component.key] = {
value: component.value operator: component.operator,
value: component.value
}
}
} else {
if (component.value !== undefined && component.value !== null) {
condition[component.key] = {
operator: component.operator,
value: component.value
}
} }
} }
}); });
this.$emit('search', condition); this.$emit('search', condition);
}, },
open() { open() {
this.visible = true; this.visible = true;
} }
},
created() {
if (this.condition.logic === undefined) {
this.condition.logic = 'and';
}
} }
} }
</script> </script>

View File

@ -3,11 +3,11 @@
<template v-slot="scope"> <template v-slot="scope">
<el-date-picker <el-date-picker
v-model="scope.component.value" v-bind="scope.component.props" v-model="scope.component.value" v-bind="scope.component.props"
:placeholder="$t('commons.select_date')" size="small" :placeholder="$t('commons.date.select_date')" size="small"
:type="type" value-format="timestamp" :type="type" :key="type" value-format="timestamp"
:range-separator="$t('commons.range_separator')" :range-separator="$t('commons.date.range_separator')"
:start-placeholder="$t('commons.start_date')" :start-placeholder="$t('commons.date.start_date')"
:end-placeholder="$t('commons.end_date')"> :end-placeholder="$t('commons.date.end_date')">
</el-date-picker> </el-date-picker>
</template> </template>
</ms-table-search-component> </ms-table-search-component>
@ -22,12 +22,23 @@
name: "MsTableSearchDatePicker", name: "MsTableSearchDatePicker",
components: {MsTableSearchComponent}, components: {MsTableSearchComponent},
props: ['component'], props: ['component'],
computed: { data() {
type() { return {
if (this.component.operator === OPERATORS.BETWEEN.value) { type: "daterange"
return "daterange"; }
},
methods: {
change(value) {
if (value === OPERATORS.BETWEEN.value) {
if (!Array.isArray(this.component.value)) {
this.component.value = [];
}
this.type = "daterange";
} else { } else {
return "date"; if (Array.isArray(this.component.value)) {
this.component.value = "";
}
this.type = "date";
} }
} }
} }

View File

@ -1,13 +1,12 @@
<template> <template>
<ms-table-search-component v-model="component.operator" :component="component"> <ms-table-search-component v-model="component.operator" :component="component" @change="change">
<template v-slot="scope"> <template v-slot="scope">
<el-date-picker <el-date-picker v-model="scope.component.value" v-bind="scope.component.props"
v-model="scope.component.value" v-bind="scope.component.props" :placeholder="$t('commons.date.select_date_time')" size="small"
:placeholder="$t('commons.select_date_time')" size="small" :type="type" :key="type" value-format="timestamp"
:type="type" value-format="timestamp" :range-separator="$t('commons.date.range_separator')"
:range-separator="$t('commons.range_separator')" :start-placeholder="$t('commons.date.start_date_time')"
:start-placeholder="$t('commons.start_date_time')" :end-placeholder="$t('commons.date.end_date_time')">
:end-placeholder="$t('commons.end_date_time')">
</el-date-picker> </el-date-picker>
</template> </template>
</ms-table-search-component> </ms-table-search-component>
@ -22,12 +21,23 @@
name: "MsTableSearchDateTimePicker", name: "MsTableSearchDateTimePicker",
components: {MsTableSearchComponent}, components: {MsTableSearchComponent},
props: ['component'], props: ['component'],
computed: { data() {
type() { return {
if (this.component.operator === OPERATORS.BETWEEN.value) { type: "datetimerange"
return "datetimerange"; }
},
methods: {
change(value) {
if (value === OPERATORS.BETWEEN.value) {
if (!Array.isArray(this.component.value)) {
this.component.value = [];
}
this.type = "datetimerange";
} else { } else {
return "datetime"; if (Array.isArray(this.component.value)) {
this.component.value = "";
}
this.type = "datetime";
} }
} }
} }

View File

@ -7,6 +7,17 @@ export default {
MsTableSearchInput, MsTableSearchDatePicker, MsTableSearchDateTimePicker, MsTableSearchSelect MsTableSearchInput, MsTableSearchDatePicker, MsTableSearchDateTimePicker, MsTableSearchSelect
} }
export const LOGIC = {
AND: {
label: "commons.adv_search.and",
value: "and"
},
OR: {
label: "commons.adv_search.or",
value: "or"
},
}
export const OPERATORS = { export const OPERATORS = {
LIKE: { LIKE: {
label: "commons.adv_search.operators.like", label: "commons.adv_search.operators.like",
@ -24,14 +35,6 @@ export const OPERATORS = {
label: "commons.adv_search.operators.not_in", label: "commons.adv_search.operators.not_in",
value: "not in" value: "not in"
}, },
IS: {
label: "commons.adv_search.operators.is",
value: "is"
},
NOT_IS: {
label: "commons.adv_search.operators.not_is",
value: "not is"
},
GT: { GT: {
label: "commons.adv_search.operators.gt", label: "commons.adv_search.operators.gt",
value: ">" value: ">"
@ -107,7 +110,7 @@ export const CREATOR = {
key: "creator", key: "creator",
name: 'MsTableSearchSelect', name: 'MsTableSearchSelect',
labelI18n: 'api_test.creator', labelI18n: 'api_test.creator',
operators: [OPERATORS.IN, OPERATORS.NOT_IN, OPERATORS.IS, OPERATORS.NOT_IS, OPERATORS.CURRENT_USER], operators: [OPERATORS.IN, OPERATORS.NOT_IN, OPERATORS.CURRENT_USER],
options: { options: {
url: "/user/list", url: "/user/list",
label: "name", label: "name",
@ -123,3 +126,22 @@ export const CREATOR = {
return operator !== OPERATORS.CURRENT_USER.value; return operator !== OPERATORS.CURRENT_USER.value;
} }
} }
export const TRIGGER_MODE = {
key: "triggerMode",
name: 'MsTableSearchSelect',
labelI18n: 'commons.trigger_mode.name',
operators: [OPERATORS.IN, OPERATORS.NOT_IN],
options: [
{label: "commons.trigger_mode.manual", value: "MANUAL"},
{label: "commons.trigger_mode.schedule", value: "SCHEDULE"},
{label: "commons.trigger_mode.api", value: "API"}
],
props: {
multiple: true
}
}
export const TEST_CONFIGS = [TEST_NAME, UPDATE_TIME, PROJECT_NAME, CREATE_TIME, STATUS, CREATOR]
export const REPORT_CONFIGS = [TEST_NAME, UPDATE_TIME, PROJECT_NAME, CREATE_TIME, STATUS, CREATOR, TRIGGER_MODE]

View File

@ -102,7 +102,42 @@ export default {
'login_username': 'ID or email', 'login_username': 'ID or email',
'input_login_username': 'Please input the user ID or email', 'input_login_username': 'Please input the user ID or email',
'input_name': 'Please enter name', 'input_name': 'Please enter name',
'formatErr': 'Format Error' 'formatErr': 'Format Error',
date: {
select_date: 'Select date',
start_date: 'Start date',
end_date: 'End date',
select_date_time: 'Select date and time',
start_date_time: 'Start date and time',
end_date_time: 'End date time',
range_separator: "To",
},
trigger_mode: {
name: "Trigger Mode",
manual: "Manual",
schedule: "Scheduled Task",
api: "API call"
},
adv_search: {
title: 'Advanced Search',
combine: 'Combined query',
search: "Query",
and: 'All',
or: 'any one',
operators: {
like: "Contains",
not_like: "Not included",
in: "Belong to",
not_in: "Not belonging",
gt: "Greater than",
ge: "Greater than or equal to",
lt: "Less than",
le: "Less than or equal to",
equals: "Equal",
between: "Between",
current_user: "Current user"
}
}
}, },
workspace: { workspace: {
'create': 'Create Workspace', 'create': 'Create Workspace',

View File

@ -102,7 +102,42 @@ export default {
'login_username': 'ID 或 邮箱', 'login_username': 'ID 或 邮箱',
'input_login_username': '请输入用户 ID 或 邮箱', 'input_login_username': '请输入用户 ID 或 邮箱',
'input_name': '请输入名称', 'input_name': '请输入名称',
'formatErr': '格式错误' 'formatErr': '格式错误',
date: {
select_date: '选择日期',
start_date: '开始日期',
end_date: '结束日期',
select_date_time: '选择日期时间',
start_date_time: '开始日期时间',
end_date_time: '结束日期时间',
range_separator: "至",
},
trigger_mode: {
name: "触发方式",
manual: "手动触发",
schedule: "定时任务",
api: "API调用"
},
adv_search: {
title: '高级搜索',
combine: '组合查询',
search: "查询",
and: '所有',
or: '任意一个',
operators: {
like: "包含",
not_like: "不包含",
in: "属于",
not_in: "不属于",
gt: "大于",
ge: "大于等于",
lt: "小于",
le: "小于等于",
equals: "等于",
between: "之间",
current_user: "是当前登录用户"
}
}
}, },
workspace: { workspace: {
'create': '创建工作空间', 'create': '创建工作空间',

View File

@ -100,7 +100,42 @@ export default {
'incorrect_input': '輸入內容不正確', 'incorrect_input': '輸入內容不正確',
'delete_confirm': '請輸入以下內容,確認刪除:', 'delete_confirm': '請輸入以下內容,確認刪除:',
'input_name': '請輸入名稱', 'input_name': '請輸入名稱',
'formatErr': '格式錯誤' 'formatErr': '格式錯誤',
date: {
select_date: '選擇日期',
start_date: '開始日期',
end_date: '結束日期',
select_date_time: '選擇日期時間',
start_date_time: '開始日期時間',
end_date_time: '結束日期時間',
range_separator: "至",
},
trigger_mode: {
name: "觸發方式",
manual: "手動觸發",
schedule: "定時任務",
api: "API調用"
},
adv_search: {
title: '高級搜索',
combine: '組合查詢',
search: "查詢",
and: '所有',
or: '任意一個',
operators: {
like: "包含",
not_like: "不包含",
in: "屬於",
not_in: "不屬於",
gt: "大於",
ge: "大於等於",
lt: "小於",
le: "小於等於",
equals: "等於",
between: "之間",
current_user: "是當前登錄用戶"
}
}
}, },
workspace: { workspace: {
'create': '創建工作空間', 'create': '創建工作空間',