From ebd0ec4f51288042b6fc5bf714b1febbb63cfacc Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Fri, 09 Jan 2026 18:03:49 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
applications/drone-command/src/views/dataCockpit/components/DeviceHistoryDialog.vue | 308 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 308 insertions(+), 0 deletions(-)
diff --git a/applications/drone-command/src/views/dataCockpit/components/DeviceHistoryDialog.vue b/applications/drone-command/src/views/dataCockpit/components/DeviceHistoryDialog.vue
new file mode 100644
index 0000000..c9b0954
--- /dev/null
+++ b/applications/drone-command/src/views/dataCockpit/components/DeviceHistoryDialog.vue
@@ -0,0 +1,308 @@
+<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>
--
Gitblit v1.9.3