Files
kafka-console-ui/ui/src/views/message/SearchByTime.vue
2021-12-29 21:15:56 +08:00

335 lines
9.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="tab-content">
<a-spin :spinning="loading">
<div id="search-time-form-advanced-search">
<a-form
class="ant-advanced-search-form"
:form="form"
@submit="handleSearch"
>
<a-row :gutter="24">
<a-col :span="9">
<a-form-item label="topic">
<a-select
class="topic-select"
@change="handleTopicChange"
show-search
option-filter-prop="children"
v-decorator="[
'topic',
{
rules: [{ required: true, message: '请选择一个topic!' }],
},
]"
placeholder="请选择一个topic"
>
<a-select-option v-for="v in topicList" :key="v" :value="v">
{{ v }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="5">
<a-form-item label="分区">
<a-select
class="type-select"
show-search
option-filter-prop="children"
v-model="selectPartition"
placeholder="请选择一个分区"
>
<a-select-option v-for="v in partitions" :key="v" :value="v">
<span v-if="v == -1">全部</span> <span v-else>{{ v }}</span>
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="时间">
<a-range-picker
v-decorator="['time', rangeConfig]"
show-time
format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
<a-col :span="2" :style="{ textAlign: 'right' }">
<a-form-item>
<a-button type="primary" html-type="submit"> 搜索</a-button>
</a-form-item>
</a-col>
</a-row>
<hr class="hr" />
<a-row :gutter="24">
<a-col :span="5">
<a-form-item label="消息过滤">
<a-select
class="filter-select"
option-filter-prop="children"
v-decorator="['filter', { initialValue: 'none' }]"
@change="onFilterChange"
>
<a-select-option value="none"> 不启用过滤 </a-select-option>
<a-select-option value="body">
根据消息体过滤
</a-select-option>
<a-select-option value="header">
根据消息头过滤
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<div v-show="showBodyFilter">
<a-col :span="8">
<a-form-item label="消息内容">
<a-input
class="msg-body"
v-decorator="['value']"
placeholder="请输入消息内容"
/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="消息类型">
<a-select
v-decorator="['valueDeserializer', { initialValue: 'String' }]"
class="body-type"
>
<a-select-option
v-for="v in deserializerList"
:key="v"
:value="v"
>
{{ v }}
</a-select-option>
</a-select>
<span class="hint"
>String类型模糊匹配数字类型绝对匹配其它不支持</span
>
</a-form-item>
</a-col>
</div>
<div v-show="showHeaderFilter">
<a-col :span="5">
<a-form-item label="Key">
<a-input
v-decorator="['headerKey']"
placeholder="消息头的key"
/>
</a-form-item>
</a-col>
<a-col :span="11">
<a-form-item label="Value">
<a-input
v-decorator="['headerValue']"
placeholder="消息头对应key的value"
/>
<span class="hint"
>消息头的value不是字符串类型就不要输入用来过滤了</span
>
</a-form-item>
</a-col>
</div>
</a-row>
</a-form>
</div>
<p style="margin-top: 1%">
<strong
>检索条数:{{ data.realNum }},允许返回的最大条数:{{
data.maxNum
}}</strong
>
</p>
<MessageList :data="data.data"></MessageList>
</a-spin>
</div>
</template>
<script>
import request from "@/utils/request";
import { KafkaMessageApi, KafkaTopicApi } from "@/utils/api";
import notification from "ant-design-vue/lib/notification";
import MessageList from "@/views/message/MessageList";
export default {
name: "SearchByTime",
components: { MessageList },
props: {
topicList: {
type: Array,
},
},
data() {
return {
loading: false,
form: this.$form.createForm(this, { name: "message_search_time" }),
partitions: [],
selectPartition: undefined,
rangeConfig: {
rules: [{ type: "array", required: true, message: "请选择时间!" }],
},
data: defaultData,
deserializerList: [],
showBodyFilter: false,
showHeaderFilter: false,
};
},
methods: {
handleSearch(e) {
e.preventDefault();
this.form.validateFields((err, values) => {
if (!err) {
const data = Object.assign({}, values, {
partition: this.selectPartition,
});
data.startTime = values.time[0].valueOf();
data.endTime = values.time[1];
this.loading = true;
request({
url: KafkaMessageApi.searchByTime.url,
method: KafkaMessageApi.searchByTime.method,
data: data,
}).then((res) => {
this.loading = false;
if (res.code == 0) {
this.$message.success(res.msg);
this.data = res.data;
} else {
notification.error({
message: "error",
description: res.msg,
});
}
});
}
});
},
getPartitionInfo(topic) {
this.loading = true;
request({
url: KafkaTopicApi.getPartitionInfo.url + "?topic=" + topic,
method: KafkaTopicApi.getPartitionInfo.method,
}).then((res) => {
this.loading = false;
if (res.code != 0) {
notification.error({
message: "error",
description: res.msg,
});
} else {
this.partitions = res.data.map((v) => v.partition);
this.partitions.splice(0, 0, -1);
}
});
},
handleTopicChange(topic) {
this.selectPartition = -1;
this.getPartitionInfo(topic);
},
onFilterChange(e) {
switch (e) {
case "body":
this.showBodyFilter = true;
this.showHeaderFilter = false;
break;
case "header":
this.showHeaderFilter = true;
this.showBodyFilter = false;
break;
default:
this.showBodyFilter = false;
this.showHeaderFilter = false;
break;
}
},
getDeserializerList() {
request({
url: KafkaMessageApi.deserializerList.url,
method: KafkaMessageApi.deserializerList.method,
}).then((res) => {
if (res.code != 0) {
notification.error({
message: "error",
description: res.msg,
});
} else {
this.deserializerList = res.data;
}
});
},
},
created() {
this.getDeserializerList();
},
};
const defaultData = { realNum: 0, maxNum: 0 };
</script>
<style scoped>
.tab-content {
width: 100%;
height: 100%;
}
.ant-advanced-search-form {
padding: 24px;
background: #fbfbfb;
border: 1px solid #d9d9d9;
border-radius: 6px;
}
.ant-advanced-search-form .ant-form-item {
display: flex;
}
.ant-advanced-search-form .ant-form-item-control-wrapper {
flex: 1;
}
#components-form-topic-advanced-search .ant-form {
max-width: none;
margin-bottom: 1%;
}
#search-time-form-advanced-search .search-result-list {
margin-top: 16px;
border: 1px dashed #e9e9e9;
border-radius: 6px;
background-color: #fafafa;
min-height: 200px;
text-align: center;
padding-top: 80px;
}
.topic-select {
width: 400px !important;
}
.filter-select {
width: 160px !important;
}
.body-type {
width: 120px;
}
.msg-body {
width: 400px;
}
.type-select {
width: 150px !important;
}
.hint {
font-size: smaller;
color: green;
}
.ant-advanced-search-form {
padding-bottom: 0px;
}
.hr {
height: 1px;
border: none;
border-top: 1px dashed #0066cc;
}
</style>