<template>
|
<el-dialog
|
class="ztzf-data-cockpit-dialog"
|
append-to-body
|
v-model="visibleModel"
|
:title="dialogTitle"
|
:close-on-click-modal="false"
|
:destroy-on-close="true"
|
>
|
<div class="dialog-body">
|
<el-form ref="queryParamsRef" :model="searchParams" class="history-search">
|
<el-row :gutter="12">
|
<el-col :span="5">
|
<el-form-item label="关键字" prop="keyword">
|
<el-input v-model="searchParams.keyword" placeholder="名称/序列号" clearable @clear="handleSearch" />
|
</el-form-item>
|
</el-col>
|
<el-col :span="5">
|
<el-form-item label="日期" prop="dateRange">
|
<el-date-picker
|
v-model="searchParams.dateRange"
|
type="daterange"
|
range-separator="至"
|
start-placeholder="开始日期"
|
end-placeholder="结束日期"
|
value-format="YYYY/MM/DD"
|
@change="handleSearch"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="5">
|
<el-form-item label="区域" prop="area">
|
<el-tree-select
|
v-model="searchParams.area"
|
:data="areaTree"
|
:props="areaTreeProps"
|
node-key="value"
|
check-strictly
|
clearable
|
placeholder="请选择"
|
@change="handleSearch"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="5">
|
<el-form-item label="无人机类型" prop="droneType">
|
<el-select
|
v-model="searchParams.droneType"
|
placeholder="请选择"
|
clearable
|
@change="handleSearch"
|
>
|
<el-option v-for="item in droneTypeOptions" :key="item" :label="item" :value="item" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="4" class="history-search-actions">
|
<el-form-item>
|
<el-button @click="resetForm">重置</el-button>
|
<el-button type="primary" @click="handleSearch">查询</el-button>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
|
<el-table v-loading="loading" :data="pagedList" height="360" class="history-table">
|
<el-table-column type="index" width="60" label="序号" />
|
<el-table-column prop="droneName" label="无人机名称" min-width="120" />
|
<el-table-column prop="serialNumber" label="无人机序列号" min-width="140" />
|
<el-table-column prop="droneType" label="无人机类型" min-width="110" />
|
<el-table-column prop="area" label="区域" min-width="90" />
|
<el-table-column prop="dataSource" label="数据来源" min-width="110" />
|
<el-table-column prop="frequency" label="信号频段" min-width="100" />
|
<el-table-column prop="discoveredAt" label="发现时间" min-width="150" />
|
<el-table-column prop="stayTime" label="停留时间" min-width="110" />
|
<el-table-column prop="counterMethod" label="反制方式" min-width="110" />
|
</el-table>
|
|
<div class="history-pagination">
|
<el-pagination
|
v-model:current-page="searchParams.current"
|
v-model:page-size="searchParams.size"
|
:total="total"
|
/>
|
</div>
|
</div>
|
</el-dialog>
|
</template>
|
|
<script setup>
|
import { computed, ref } from 'vue'
|
|
const props = defineProps({
|
modelValue: {
|
type: Boolean,
|
default: false
|
},
|
device: {
|
type: Object,
|
default: () => null
|
}
|
})
|
|
const emit = defineEmits(['update:modelValue'])
|
|
const visibleModel = computed({
|
get: () => props.modelValue,
|
set: (val) => emit('update:modelValue', val)
|
})
|
|
const dialogTitle = computed(() => {
|
return `反制设备名称 ${props.device?.name || ''}`.trim()
|
})
|
|
const initSearchParams = () => ({
|
keyword: '',
|
dateRange: [],
|
area: '',
|
droneType: '',
|
current: 1,
|
size: 6
|
})
|
const searchParams = ref(initSearchParams())
|
const queryParamsRef = ref(null)
|
const loading = ref(false)
|
const areaTree = ref([
|
{
|
label: '古村区',
|
value: '古村区'
|
},
|
{
|
label: '新区',
|
value: '新区'
|
},
|
{
|
label: '产业园',
|
value: '产业园'
|
}
|
])
|
const areaTreeProps = {
|
label: 'label',
|
children: 'children'
|
}
|
|
const historyList = computed(() => {
|
const dataSource = props.device?.name || '侦测反制设备名称'
|
return [
|
{
|
id: 'his_001',
|
droneName: '无人机名称',
|
serialNumber: 'XLH789456',
|
droneType: '微型机',
|
area: '古村区',
|
dataSource,
|
frequency: '5800MHZ',
|
discoveredAt: '2025/12/26 12:15:26',
|
stayTime: '00:10:50',
|
counterMethod: '信号干扰'
|
},
|
{
|
id: 'his_002',
|
droneName: '无人机名称',
|
serialNumber: 'XLH789456',
|
droneType: '微型机',
|
area: '古村区',
|
dataSource,
|
frequency: '5800MHZ',
|
discoveredAt: '2025/12/26 12:18:06',
|
stayTime: '00:08:12',
|
counterMethod: '信号干扰'
|
},
|
{
|
id: 'his_003',
|
droneName: '无人机名称',
|
serialNumber: 'XLH789456',
|
droneType: '微型机',
|
area: '古村区',
|
dataSource,
|
frequency: '2400MHZ',
|
discoveredAt: '2025/12/26 12:22:31',
|
stayTime: '00:06:09',
|
counterMethod: '诱导驱离'
|
},
|
{
|
id: 'his_004',
|
droneName: '无人机名称',
|
serialNumber: 'XLH789456',
|
droneType: '微型机',
|
area: '古村区',
|
dataSource,
|
frequency: '2400MHZ',
|
discoveredAt: '2025/12/26 12:28:44',
|
stayTime: '00:12:03',
|
counterMethod: '诱导驱离'
|
},
|
{
|
id: 'his_005',
|
droneName: '无人机名称',
|
serialNumber: 'XLH789456',
|
droneType: '微型机',
|
area: '古村区',
|
dataSource,
|
frequency: '5800MHZ',
|
discoveredAt: '2025/12/26 12:32:10',
|
stayTime: '00:04:39',
|
counterMethod: '信号干扰'
|
},
|
{
|
id: 'his_006',
|
droneName: '无人机名称',
|
serialNumber: 'XLH789456',
|
droneType: '微型机',
|
area: '古村区',
|
dataSource,
|
frequency: '5800MHZ',
|
discoveredAt: '2025/12/26 12:36:42',
|
stayTime: '00:07:21',
|
counterMethod: '信号干扰'
|
}
|
]
|
})
|
|
const droneTypeOptions = computed(() => {
|
const types = historyList.value.map((item) => item.droneType).filter(Boolean)
|
return Array.from(new Set(types))
|
})
|
|
const filteredList = computed(() => {
|
const { keyword, dateRange, area, droneType } = searchParams.value
|
const [startDate, endDate] = dateRange || []
|
return historyList.value.filter((item) => {
|
const keywordMatch =
|
!keyword || item.droneName.includes(keyword) || item.serialNumber.includes(keyword)
|
const typeMatch = !droneType || item.droneType === droneType
|
const areaMatch = !area || item.area.includes(area)
|
const dateMatch =
|
!startDate || !endDate || isWithinDateRange(item.discoveredAt, startDate, endDate)
|
return keywordMatch && typeMatch && areaMatch && dateMatch
|
})
|
})
|
|
const total = computed(() => filteredList.value.length)
|
|
const pagedList = computed(() => {
|
const { current, size } = searchParams.value
|
const start = (current - 1) * size
|
return filteredList.value.slice(start, start + size)
|
})
|
|
function handleSearch() {
|
searchParams.value.current = 1
|
}
|
|
function resetForm() {
|
queryParamsRef.value?.resetFields()
|
searchParams.value.current = 1
|
}
|
|
function isWithinDateRange(value, start, end) {
|
const dateValue = new Date(value)
|
const startDate = new Date(`${start} 00:00:00`)
|
const endDate = new Date(`${end} 23:59:59`)
|
return dateValue >= startDate && dateValue <= endDate
|
}
|
|
</script>
|
|
<style lang="scss" scoped>
|
.dialog-body {
|
display: flex;
|
flex-direction: column;
|
gap: 16px;
|
color: #C3C3DD;
|
}
|
|
.history-search {
|
padding: 8px 12px 4px;
|
background: rgba(10, 14, 34, 0.6);
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
border-radius: 6px;
|
}
|
|
.history-search :deep(.el-date-editor),
|
.history-search :deep(.el-select),
|
.history-search :deep(.el-tree-select) {
|
width: 100%;
|
}
|
|
.history-search-actions :deep(.el-form-item__content) {
|
justify-content: flex-end;
|
gap: 8px;
|
}
|
|
.history-table {
|
margin-top: 8px;
|
--el-table-border-color: rgba(255, 255, 255, 0.08);
|
--el-table-header-bg-color: rgba(20, 24, 48, 0.9);
|
--el-table-row-hover-bg-color: rgba(255, 255, 255, 0.03);
|
--el-table-text-color: #C3C3DD;
|
--el-table-header-text-color: #FFFFFF;
|
}
|
|
.history-pagination {
|
display: flex;
|
justify-content: flex-end;
|
padding-top: 8px;
|
}
|
</style>
|