From 46f71f1985eabbf84926d6416659370f1e8c8c3e Mon Sep 17 00:00:00 2001
From: 张含笑 <zhx18749296735@163.com>
Date: Wed, 14 Jan 2026 11:39:14 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 applications/drone-command/src/views/areaManage/precinctInfo/index.vue                           |   93 
 applications/drone-command/src/views/basicManage/maintainRecord/index.vue                        |  167 +-
 applications/drone-command/src/styles/common/cockpit.scss                                        |  488 ++++++---
 applications/drone-command/src/views/areaManage/areaStatistics/index.vue                         |  143 +-
 applications/drone-command/src/views/areaManage/sceneConfig/index.vue                            |  152 +-
 applications/drone-command/src/views/dataCockpit/index.vue                                       |    8 
 applications/drone-command/src/views/detectionCountermeasure/components/DetectionRangeDialog.vue |  348 +++++++
 applications/drone-command/src/components/basic-container/main.vue                               |   19 
 packages/utils/date/index.js                                                                     |   15 
 applications/drone-command/src/views/areaManage/partition/index.vue                              |  155 +-
 applications/drone-command/src/views/basicManage/deviceScrap/index.vue                           |  154 +-
 applications/drone-command/src/components/map-container/device-map-container.vue                 |  178 +-
 applications/drone-command/src/views/api.txt                                                     |  329 +++++-
 applications/drone-command/src/views/basicManage/deviceStock/index.vue                           |  206 ++--
 applications/drone-command/env/.env.development                                                  |    4 
 applications/drone-command/src/views/areaManage/defenseZone/index.vue                            |   94 
 applications/drone-command/src/views/dataCockpit/components/DeviceHistoryDialog.vue              |   32 
 applications/drone-command/src/views/detectionCountermeasure/detectionRange.vue                  |  190 +++
 applications/drone-command/src/api/detectionCountermeasure/detectionRange/index.js               |   55 +
 19 files changed, 1,881 insertions(+), 949 deletions(-)

diff --git a/applications/drone-command/env/.env.development b/applications/drone-command/env/.env.development
index 4b360d8..73ebb7a 100644
--- a/applications/drone-command/env/.env.development
+++ b/applications/drone-command/env/.env.development
@@ -2,7 +2,7 @@
  # @Author       : yuan
  # @Date         : 2026-01-07 14:58:30
  # @LastEditors  : yuan
- # @LastEditTime : 2026-01-08 15:14:52
+ # @LastEditTime : 2026-01-13 16:28:33
  # @FilePath     : \applications\drone-command\env\.env.development
  # @Description  : 
  # Copyright 2026 OBKoro1, All Rights Reserved. 
@@ -16,7 +16,7 @@
 
 #开发环境代理地址(推荐本地新建文件 .env.development.local 来进行覆盖)
 # VITE_APP_URL = https://wrj.shuixiongit.com/api
-VITE_APP_URL= http://192.168.1.33
+VITE_APP_URL= http://192.168.1.168
 
 #新大屏地址
 VITE_APP_DASHBOARD_URL = 'https://wrj.shuixiongit.com/command-center-dashboard/'
diff --git a/applications/drone-command/src/api/detectionCountermeasure/detectionRange/index.js b/applications/drone-command/src/api/detectionCountermeasure/detectionRange/index.js
new file mode 100644
index 0000000..dbe0fc0
--- /dev/null
+++ b/applications/drone-command/src/api/detectionCountermeasure/detectionRange/index.js
@@ -0,0 +1,55 @@
+import request from '@/axios'
+
+// 查
+export const detectionRangePageApi = params => {
+	return request({
+		url: `/drone-fw/device/fwDevice/page`,
+		method: 'get',
+		params,
+	})
+}
+
+// 增
+export const detectionRangeAddApi = data => {
+	return request({
+		url: `/drone-fw/device/fwDevice/submit`,
+		method: 'post',
+		data,
+	})
+}
+
+// 改
+export const detectionRangeEditApi = data => {
+	return request({
+		url: `/drone-fw/device/fwDevice/submit`,
+		method: 'post',
+		data,
+	})
+}
+
+// 新增或修改
+export const detectionRangeSubmitApi = data => {
+	return request({
+		url: `/drone-fw/device/fwDevice/submit`,
+		method: 'post',
+		data,
+	})
+}
+
+// 删
+export const detectionRangeRemoveApi = params => {
+	return request({
+		url: `/drone-fw/device/fwDevice/remove`,
+		method: 'post',
+		params,
+	})
+}
+
+// 详情
+export const detectionRangeDetailApi = params => {
+	return request({
+		url: `/drone-fw/device/fwDevice/detail`,
+		method: 'get',
+		params,
+	})
+}
diff --git a/applications/drone-command/src/components/basic-container/main.vue b/applications/drone-command/src/components/basic-container/main.vue
index 43459d6..735b458 100644
--- a/applications/drone-command/src/components/basic-container/main.vue
+++ b/applications/drone-command/src/components/basic-container/main.vue
@@ -2,7 +2,7 @@
  * @Author       : yuan
  * @Date         : 2025-06-14 15:19:16
  * @LastEditors  : yuan
- * @LastEditTime : 2026-01-07 16:26:20
+ * @LastEditTime : 2026-01-14 10:10:35
  * @FilePath     : \applications\drone-command\src\components\basic-container\main.vue
  * @Description  : 
  * Copyright 2025 OBKoro1, All Rights Reserved. 
@@ -50,25 +50,26 @@
   height: 0;
   flex: 1;
 
-  padding: 30px;
+  padding: 6px 30px;
   // box-sizing: border-box;
   // height: 100%;
 
   .basic-container__card {
+    display: flex;
+    flex-direction: column;
     height: 100% !important;
     overflow: hidden;
+    background: transparent;
 
-    .el-card__body {
+    ::v-deep(.el-card__body) {
+      padding: 0 !important;
+      height: 0 !important;
+      flex: 1 !important;
       display: flex;
       flex-direction: column;
-      height: 100% !important;
+      
       overflow: hidden;
       box-sizing: border-box;
-
-      &>div {
-        height: 0;
-        flex: 1;
-      }
     }
   }
 
diff --git a/applications/drone-command/src/views/dataCockpit/components/MapContainer.vue b/applications/drone-command/src/components/map-container/device-map-container.vue
similarity index 83%
rename from applications/drone-command/src/views/dataCockpit/components/MapContainer.vue
rename to applications/drone-command/src/components/map-container/device-map-container.vue
index 4576555..888edaf 100644
--- a/applications/drone-command/src/views/dataCockpit/components/MapContainer.vue
+++ b/applications/drone-command/src/components/map-container/device-map-container.vue
@@ -1,16 +1,22 @@
 <template>
-	<div class="ztzf-cesium map-container" id="cesium"></div>
-	<div class="layer-control-root" :class="{ collapsed: props.leftCollapsed }">
+	<div class="ztzf-cesium map-container" :id="props.containerId"></div>
+	<div v-if="props.showLayerControl" class="layer-control-root" :class="{ collapsed: props.leftCollapsed }">
 		<div class="layer-control-wrap" ref="layerWrapRef">
 			<div class="layer-control" @click="toggleLayerPanel">
-				<img :src="layerControlIcon" alt="图层控制">
+				<img :src="layerControlIcon" alt="图层控制" />
 			</div>
 			<div v-if="showLayerPanel" class="layer-panel">
 				<div class="panel-title">图层管理</div>
 
 				<div class="panel-content">
-					<el-tree :data="layerTree" show-checkbox default-expand-all node-key="key" :props="layerTreeProps"
-						:default-checked-keys="defaultCheckedKeys" />
+					<el-tree
+						:data="layerTree"
+						show-checkbox
+						default-expand-all
+						node-key="key"
+						:props="layerTreeProps"
+						:default-checked-keys="defaultCheckedKeys"
+					/>
 				</div>
 			</div>
 		</div>
@@ -26,12 +32,20 @@
 const props = defineProps({
 	onlineDevices: {
 		type: Array,
-		default: () => []
+		default: () => [],
 	},
 	leftCollapsed: {
 		type: Boolean,
-		default: false
-	}
+		default: false,
+	},
+	containerId: {
+		type: String,
+		default: 'device-map-container',
+	},
+	showLayerControl: {
+		type: Boolean,
+		default: true,
+	},
 })
 
 let viewInstance = null
@@ -41,7 +55,7 @@
 const layerWrapRef = ref(null)
 const layerTreeProps = {
 	label: 'label',
-	children: 'children'
+	children: 'children',
 }
 const defaultCheckedKeys = ['global', 'city-base']
 const layerTree = ref([
@@ -50,8 +64,8 @@
 		label: '地理信息图层',
 		children: [
 			{ key: 'global', label: '全球地形' },
-			{ key: 'admin', label: '行政区划' }
-		]
+			{ key: 'admin', label: '行政区划' },
+		],
 	},
 	{
 		key: 'city',
@@ -60,20 +74,20 @@
 			{ key: 'city-base', label: '皖山白模' },
 			{ key: 'city-grid', label: '皖山白模光栅网格' },
 			{ key: 'city-tilt', label: '皖山倾斜摄影' },
-			{ key: 'city-tilt-grid', label: '皖山倾斜摄影网格' }
-		]
+			{ key: 'city-tilt-grid', label: '皖山倾斜摄影网格' },
+		],
 	},
 	{
 		key: 'sky',
 		label: '空域要素图层',
 		children: [
 			{ key: 'airspace', label: '空域边界' },
-			{ key: 'route', label: '飞行航路' }
-		]
-	}
+			{ key: 'route', label: '飞行航路' },
+		],
+	},
 ])
 
-const getDevicePosition = (item) => {
+const getDevicePosition = item => {
 	const longitudeRaw = item.longitude ?? item.lng ?? item.lon
 	const latitudeRaw = item.latitude ?? item.lat
 	if (longitudeRaw == null || latitudeRaw == null) return null
@@ -85,7 +99,7 @@
 
 const clearDeviceEntities = () => {
 	if (!viewer) return
-	deviceEntityIds.forEach((id) => {
+	deviceEntityIds.forEach(id => {
 		viewer.entities.removeById(id)
 	})
 	deviceEntityIds.clear()
@@ -94,7 +108,7 @@
 const RING_STYLES = [
 	{ inner: 0, outer: 5000, gradient: ['#FF361C', '#360B00'] },
 	{ inner: 5000, outer: 8000, gradient: ['#FFC609', '#583300'] },
-	{ inner: 8000, outer: 10000, gradient: ['#2AEDBF', '#012B11'] }
+	{ inner: 8000, outer: 10000, gradient: ['#2AEDBF', '#012B11'] },
 ]
 
 const MATERIAL_TYPE = 'RadialGradientMaterial'
@@ -108,7 +122,7 @@
 			type: MATERIAL_TYPE,
 			uniforms: {
 				color1: new Cesium.Color(1.0, 1.0, 1.0, 1.0),
-				color2: new Cesium.Color(0.0, 0.0, 0.0, 1.0)
+				color2: new Cesium.Color(0.0, 0.0, 0.0, 1.0),
 			},
 			source: `
 				czm_material czm_getMaterial(czm_materialInput materialInput) {
@@ -120,45 +134,10 @@
 					material.alpha = color.a;
 					return material;
 				}
-			`
+			`,
 		},
-		translucent: () => true
+		translucent: () => true,
 	})
-}
-
-class RadialGradientMaterialProperty {
-	constructor(color1, color2) {
-		this._definitionChanged = new Cesium.Event()
-		this.color1 = color1
-		this.color2 = color2
-	}
-
-	get isConstant () {
-		return true
-	}
-
-	get definitionChanged () {
-		return this._definitionChanged
-	}
-
-	getType () {
-		return MATERIAL_TYPE
-	}
-
-	getValue (time, result) {
-		const target = result || {}
-		target.color1 = this.color1
-		target.color2 = this.color2
-		return target
-	}
-
-	equals (other) {
-		return (
-			other instanceof RadialGradientMaterialProperty &&
-			Cesium.Color.equals(this.color1, other.color1) &&
-			Cesium.Color.equals(this.color2, other.color2)
-		)
-	}
 }
 
 const buildCirclePositions = (center, radiusMeters, steps = 64) => {
@@ -194,17 +173,49 @@
 			id: entityId,
 			polygon: {
 				hierarchy: new Cesium.PolygonHierarchy(outerPositions, holes),
-				material
-			}
+				material,
+			},
 		})
 	})
 }
 
-const renderDeviceEntities = (devices) => {
-	console.log(devices, 'devices')
+class RadialGradientMaterialProperty {
+	constructor(color1, color2) {
+		this._definitionChanged = new Cesium.Event()
+		this.color1 = color1
+		this.color2 = color2
+	}
 
+	get isConstant() {
+		return true
+	}
+
+	get definitionChanged() {
+		return this._definitionChanged
+	}
+
+	getType() {
+		return MATERIAL_TYPE
+	}
+
+	getValue(time, result) {
+		const target = result || {}
+		target.color1 = this.color1
+		target.color2 = this.color2
+		return target
+	}
+
+	equals(other) {
+		return (
+			other instanceof RadialGradientMaterialProperty &&
+			Cesium.Color.equals(this.color1, other.color1) &&
+			Cesium.Color.equals(this.color2, other.color2)
+		)
+	}
+}
+
+const renderDeviceEntities = devices => {
 	if (!viewer) return
-
 	clearDeviceEntities()
 	devices.forEach((item, index) => {
 		const position = getDevicePosition(item)
@@ -218,15 +229,15 @@
 			billboard: {
 				image: equipmentIcon,
 				width: 40.34,
-				height: 40.34
-			}
+				height: 40.34,
+			},
 		})
 	})
 }
 
 watch(
 	() => props.onlineDevices,
-	(devices) => {
+	devices => {
 		renderDeviceEntities(devices || [])
 	},
 	{ deep: true }
@@ -234,16 +245,17 @@
 
 watch(
 	() => props.leftCollapsed,
-	(isCollapsed) => {
+	isCollapsed => {
 		if (isCollapsed) showLayerPanel.value = false
 	}
 )
 
 const toggleLayerPanel = () => {
+	if (!props.showLayerControl) return
 	showLayerPanel.value = !showLayerPanel.value
 }
 
-const handleClickOutside = (event) => {
+const handleClickOutside = event => {
 	if (!showLayerPanel.value) return
 	const target = event.target
 	if (layerWrapRef.value?.contains(target)) return
@@ -253,11 +265,11 @@
 onMounted(() => {
 	document.addEventListener('click', handleClickOutside)
 	viewInstance = new PublicCesium({
-		dom: 'cesium',
+		dom: props.containerId,
 		flatMode: false,
 		terrain: false,
 		layerMode: 4,
-		contour: false
+		contour: false,
 	})
 
 	viewer = viewInstance.getViewer()
@@ -331,17 +343,14 @@
 	.panel-title {
 		padding: 0 16px;
 		line-height: 42px;
-
-		font-family: Open Sans, Open Sans;
+		font-family: 'Open Sans', Open Sans;
 		font-weight: 400;
 		font-size: 12px;
-		color: #FFFFFF;
+		color: #ffffff;
 		text-align: left;
 		font-style: normal;
 		text-transform: none;
-
-		border-bottom: 1px solid rgba(70,70,100,0.5);
-
+		border-bottom: 1px solid rgba(70, 70, 100, 0.5);
 		box-sizing: border-box;
 	}
 
@@ -354,7 +363,7 @@
 
 	::v-deep(.el-tree) {
 		background: transparent;
-		color: #C3C3DD;
+		color: #c3c3dd;
 		font-size: 12px;
 
 		.el-tree-node {
@@ -365,7 +374,7 @@
 				align-items: center;
 				height: 40px !important;
 				line-height: 40px !important;
-				border-bottom: 1px solid rgba(70,70,100,0.5);
+				border-bottom: 1px solid rgba(70, 70, 100, 0.5);
 				box-sizing: border-box;
 			}
 
@@ -375,14 +384,11 @@
 				}
 			}
 		}
-
 	}
 }
 
-
-
 .layer-panel :deep(.el-tree-node__label) {
-	color: #C3C3DD;
+	color: #c3c3dd;
 }
 
 .layer-panel :deep(.el-tree-node__expand-icon) {
@@ -412,20 +418,20 @@
 
 .layer-panel :deep(.el-tree-node.is-current > .el-tree-node__content) {
 	background: transparent !important;
-	color: #FFFFFF;
+	color: #ffffff;
 }
 
 .layer-panel :deep(.el-tree-node.is-current > .el-tree-node__content .el-tree-node__label) {
-	color: #FFFFFF;
+	color: #ffffff;
 }
 
 .layer-panel :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
-	background-color: #023AFF;
-	border-color: #023AFF;
+	background-color: #023aff;
+	border-color: #023aff;
 }
 
 .layer-panel :deep(.el-checkbox__inner) {
 	background-color: transparent;
-	border-color: #A1A3D4;
+	border-color: #a1a3d4;
 }
 </style>
diff --git a/applications/drone-command/src/styles/common/cockpit.scss b/applications/drone-command/src/styles/common/cockpit.scss
index 9bf2d0c..563d248 100644
--- a/applications/drone-command/src/styles/common/cockpit.scss
+++ b/applications/drone-command/src/styles/common/cockpit.scss
@@ -449,212 +449,382 @@
         }
     }
 
-    .history-search {
-        .el-form-item__label {
-            font-family: Source Han Sans CN, Source Han Sans CN;
-            font-weight: 500;
-            font-size: 14px;
-            color: #C5C9D6;
-            font-style: normal;
-            text-transform: none;
-        }
+    .el-dialog__body {
+        height: 0;
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+    }
+}
 
-        .ztzf-data-cockpit-search-input {
-            .el-input__wrapper {
-                background: #2E2E48;
-            }
+.ztzf-dialog-history-search {
+    .el-form-item__label {
+        font-family: Source Han Sans CN, Source Han Sans CN;
+        font-weight: 500;
+        font-size: 14px;
+        color: #C5C9D6;
+        font-style: normal;
+        text-transform: none;
+    }
 
-            &.is-disabled {
-                .el-input__wrapper {
-                    background-color: #2E2E48;
-                }
-            }
-        }
-
-        .ztzf-data-cockpit-date-picker {
+    .ztzf-data-cockpit-search-input {
+        .el-input__wrapper {
             background: #2E2E48;
         }
 
-        .ztzf-data-cockpit-date-picker-popper {
-            background: #2E2E48 !important;
+        &.is-disabled {
+            .el-input__wrapper {
+                background-color: #2E2E48;
+            }
+        }
+    }
 
-            .el-picker-panel {
-                .el-picker-panel__body-wrapper {
-                    .el-picker-panel__body {
-                        background: #2E2E48 !important;
+    .ztzf-data-cockpit-date-picker {
+        background: #2E2E48;
+    }
 
-                        .el-date-picker__time-header {
+    .ztzf-data-cockpit-date-picker-popper {
+        background: #2E2E48 !important;
 
-                            .el-date-picker__editor-wrap {
-                                .el-time-panel {
+        .el-picker-panel {
+            .el-picker-panel__body-wrapper {
+                .el-picker-panel__body {
+                    background: #2E2E48 !important;
+
+                    .el-date-picker__time-header {
+
+                        .el-date-picker__editor-wrap {
+                            .el-time-panel {
+                                background: #2E2E48 !important;
+
+                                // 将 time-picker-popper 的样式移到这里
+                                .el-time-panel__header {
                                     background: #2E2E48 !important;
-
-                                    // 将 time-picker-popper 的样式移到这里
-                                    .el-time-panel__header {
-                                        background: #2E2E48 !important;
-                                    }
                                 }
                             }
                         }
                     }
                 }
             }
-
-            .el-popper__arrow {
-                &::before {
-                    background: #2E2E48 !important;
-                    border: 1px solid #2E2E48 !important;
-                    box-sizing: border-box;
-                }
-            }
         }
 
-        .history-search-actions {
-            .el-button {
-                width: 96px;
-                background: transparent !important;
-                border-radius: 4px 4px 4px 4px;
-                border: 1px solid rgba(255, 255, 255, 0.3);
-
-                .el-icon {
-                    font-size: 16px;
-                    color: #fff;
-                }
+        .el-popper__arrow {
+            &::before {
+                background: #2E2E48 !important;
+                border: 1px solid #2E2E48 !important;
+                box-sizing: border-box;
             }
         }
     }
 
-    .el-dialog__body {
+    .history-search-actions {
+        .el-button {
+            width: 96px;
+            background: transparent !important;
+            border-radius: 4px 4px 4px 4px;
+            border: 1px solid rgba(255, 255, 255, 0.3);
+
+            .el-icon {
+                font-size: 16px;
+                color: #fff;
+            }
+        }
+    }
+}
+
+.ztzf-page-history-search {
+    .el-form-item__label {
+        font-family: Source Han Sans CN, Source Han Sans CN;
+        font-weight: 500;
+        font-size: 14px;
+        color: #C5C9D6;
+        font-style: normal;
+        text-transform: none;
+    }
+
+    .ztzf-data-cockpit-select {
+        .el-select__wrapper {
+            background: #1C1C31;
+        }
+    }
+
+    .ztzf-data-cockpit-search-input {
+        .el-input__wrapper {
+            background: #1C1C31;
+        }
+
+        &.is-disabled {
+            .el-input__wrapper {
+                background-color: #1C1C31;
+            }
+        }
+    }
+
+    .ztzf-data-cockpit-date-picker {
+        background: #1C1C31;
+    }
+
+    .ztzf-data-cockpit-date-picker-popper {
+        background: #1C1C31 !important;
+
+        .el-picker-panel {
+            .el-picker-panel__body-wrapper {
+                .el-picker-panel__body {
+                    background: #1C1C31 !important;
+
+                    .el-date-picker__time-header {
+
+                        .el-date-picker__editor-wrap {
+                            .el-time-panel {
+                                background: #1C1C31 !important;
+
+                                // 将 time-picker-popper 的样式移到这里
+                                .el-time-panel__header {
+                                    background: #1C1C31 !important;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        .el-popper__arrow {
+            &::before {
+                background: #1C1C31 !important;
+                border: 1px solid #1C1C31 !important;
+                box-sizing: border-box;
+            }
+        }
+    }
+
+    .history-search-actions {
+        .el-button {
+            width: 96px;
+            background: transparent !important;
+            border-radius: 4px 4px 4px 4px;
+            border: 1px solid rgba(255, 255, 255, 0.3);
+
+            .el-icon {
+                font-size: 16px;
+                color: #fff;
+            }
+        }
+
+        .search-btn {
+            background: #1C1C31 !important;
+            border: 1px solid rgba(227, 227, 236, 0.3) !important;
+        }
+    }
+}
+
+.ztzf-dialog-history-search,
+.ztzf-page-history-search {
+    display: flex;
+
+    .el-form-item {
+        margin-left: 30px;
+        margin-bottom: 0;
+
+        &:first-child {
+            margin-left: 0;
+        }
+    }
+
+    .el-form-item__label {
+        margin-right: 12px;
+        height: 40px;
+        line-height: 40px;
+    }
+
+    .el-input {
+        width: 200px;
+        height: 40px;
+    }
+
+    .el-select {
+        .el-select__wrapper {
+            width: 200px;
+            height: 40px;
+        }
+    }
+
+    .el-date-editor {
+        width: 240px;
+        height: 40px;
+    }
+
+    .el-button {
+        width: 96px;
+        height: 40px;
+    }
+}
+
+.ztzf-table-toolbar {
+    margin-top: 30px;
+
+    .el-button {
+        min-width: 88px;
+    }
+}
+
+.ztzf-table-container {
+    margin-top: 20px;
+
+    height: 0;
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+
+    .ztzf-table-content {
         height: 0;
         flex: 1;
         display: flex;
         flex-direction: column;
 
-        .table-container {
+        .ztzf-data-cockpit-table {
             height: 0;
             flex: 1;
-            display: flex;
-            flex-direction: column;
+            background: transparent !important;
 
-            .table-content {
+            .el-table--border .el-table__inner-wrapper:after,
+            .el-table--border:after,
+            .el-table--border:before,
+            .el-table__inner-wrapper:before {
                 height: 0;
-                flex: 1;
-                display: flex;
-                flex-direction: column;
-
-                .ztzf-data-cockpit-table {
-                    height: 0;
-                    flex: 1;
-                    background: transparent !important;
-
-					.el-table--border .el-table__inner-wrapper:after, .el-table--border:after, .el-table--border:before, .el-table__inner-wrapper:before {
-						height: 0;
-					}
-
-                    tr {
-                        background: transparent !important;
-                    }
-
-                    th.el-table__cell {
-						border-bottom: 1px solid #323241;
-                        background: transparent !important;
-
-                        .cell {
-                            font-family: Source Han Sans CN, Source Han Sans CN;
-                            font-weight: 500;
-                            font-size: 14px;
-                            color: #FFFFFF;
-                            line-height: 22px;
-                            font-style: normal;
-                            text-transform: none;
-                        }
-                    }
-
-                    td.el-table__cell {
-						border-bottom: 1px solid #323241;
-                        background: transparent !important;
-
-                        .cell {
-                            font-family: Source Han Sans CN, Source Han Sans CN;
-                            font-weight: 400;
-                            font-size: 14px;
-                            color: #9E9EBA;
-                            line-height: 18px;
-                            font-style: normal;
-                            text-transform: none;
-                        }
-                    }
-                }
             }
 
-            .table-pagination {
-                padding-top: 30px;
-                padding-bottom: 10px;
-                display: flex;
-                justify-content: flex-end;
+            tr {
+                background: transparent !important;
+            }
 
-                .el-pagination__total {
+            th.el-table__cell {
+                height: 40px;
+                border-bottom: 1px solid #323241;
+                background: transparent !important;
+
+                .cell {
+                    padding: 0;
+                    padding-left: 16px;
                     font-family: Source Han Sans CN, Source Han Sans CN;
-                    font-weight: 400;
+                    font-weight: 500;
                     font-size: 14px;
-                    color: #9E9EBA;
+                    color: #FFFFFF;
+                    line-height: 22px;
                     font-style: normal;
                     text-transform: none;
                 }
+            }
 
-                .btn-prev,
-                .btn-next {
-                    background: transparent !important;
+            td.el-table__cell {
+                padding: 9px 0;
+                height: 56px;
+                border-bottom: 1px solid #323241;
+                background: transparent !important;
 
-                    .el-icon {
-                        color: #C9CDD4;
-                    }
+                .cell {
+                    padding: 0;
+                    padding-left: 16px;
+                    font-family: Source Han Sans CN, Source Han Sans CN;
+                    font-weight: 400;
+                    font-size: 14px;
+                    color: #D2D2E7;
+                    line-height: 18px;
+                    font-style: normal;
+                    text-transform: none;
                 }
+            }
 
-                .el-pager {
-                    li {
-                        margin-left: 8px;
-                        font-family: Nunito Sans, Nunito Sans;
-                        font-weight: 600;
-                        font-size: 14px;
-                        color: #9E9EBA;
-                        font-style: normal;
-                        text-transform: none;
-                        background: transparent;
+            td.operation-btns .cell {
+                display: flex;
+                flex-wrap: nowrap;
+                gap: 12px;
+                /* 按钮间距(推荐) */
+                white-space: nowrap;
+                /* 双保险 */
 
-                        &:first-child {
-                            margin-left: 0;
-                        }
+                a {
+                    min-width: 28px;
+                    color: #6A89FF;
 
-                        &.is-active {
-                            font-family: Nunito Sans, Nunito Sans;
-                            font-weight: 600;
-                            font-size: 14px;
-                            color: #477EFF;
-                            font-style: normal;
-                            text-transform: none;
-                            background: rgba(71, 126, 255, 0.16);
-                        }
-                    }
-                }
-
-                .el-select {
-                    .el-select__wrapper {
-						.el-select__placeholder {
-							font-family: Source Han Sans CN, Source Han Sans CN;
-							font-weight: 400;
-							font-size: 14px;
-							color: #9E9EBA;
-							font-style: normal;
-							text-transform: none;
-						}
-
-                        background: #1C1C31;
-                        border: none;
-                        box-shadow: none;
+                    &:last-child {
+                        margin-right: 0;
                     }
                 }
             }
         }
     }
+
+    .ztzf-table-content-bg {
+        background: #1A1A2A;
+    }
+}
+
+.ztzf-table-pagination {
+    padding-top: 30px;
+    padding-bottom: 10px;
+    display: flex;
+    justify-content: flex-end;
+
+    .el-pagination__total {
+        font-family: Source Han Sans CN, Source Han Sans CN;
+        font-weight: 400;
+        font-size: 14px;
+        color: #9E9EBA;
+        font-style: normal;
+        text-transform: none;
+    }
+
+    .btn-prev,
+    .btn-next {
+        background: transparent !important;
+
+        .el-icon {
+            color: #C9CDD4;
+        }
+    }
+
+    .el-pager {
+        li {
+            margin-left: 8px;
+            font-family: Nunito Sans, Nunito Sans;
+            font-weight: 600;
+            font-size: 14px;
+            color: #9E9EBA;
+            font-style: normal;
+            text-transform: none;
+            background: transparent;
+
+            &:first-child {
+                margin-left: 0;
+            }
+
+            &.is-active {
+                font-family: Nunito Sans, Nunito Sans;
+                font-weight: 600;
+                font-size: 14px;
+                color: #477EFF;
+                font-style: normal;
+                text-transform: none;
+                background: rgba(71, 126, 255, 0.16);
+            }
+        }
+    }
+
+    .el-select {
+        .el-select__wrapper {
+            .el-select__placeholder {
+                font-family: Source Han Sans CN, Source Han Sans CN;
+                font-weight: 400;
+                font-size: 14px;
+                color: #9E9EBA;
+                font-style: normal;
+                text-transform: none;
+            }
+
+            background: #1C1C31;
+            border: none;
+            box-shadow: none;
+        }
+    }
 }
\ No newline at end of file
diff --git a/applications/drone-command/src/views/api.txt b/applications/drone-command/src/views/api.txt
index 1decdbe..716ca76 100644
--- a/applications/drone-command/src/views/api.txt
+++ b/applications/drone-command/src/views/api.txt
@@ -1,9 +1,9 @@
 
 
-## 历史告警-实时告警
+## 分页
 
 
-**接口地址**:`/cockpit/dataCockpit/alarmLog`
+**接口地址**:`/device/fwDevice/page`
 
 
 **请求方式**:`GET`
@@ -15,7 +15,7 @@
 **响应数据类型**:`*/*`
 
 
-**接口描述**:<p>传入fwDroneAlarmRecord</p>
+**接口描述**:<p>传入fwDevice</p>
 
 
 
@@ -27,31 +27,12 @@
 
 | 参数名称 | 参数说明 | 请求类型    | 是否必须 | 数据类型 | schema |
 | -------- | -------- | ----- | -------- | -------- | ------ |
-|alarmTime|告警时间|query|false|string(date-time)||
-|alarmType|告警类型:1.实时告警/2.历史告警|query|false|string||
-|areaCode|区域编码|query|false|string||
-|areaDivideId|区域id ja_fw_area_divide|query|false|string||
-|areaName|区域名称|query|false|string||
-|counterWay|反制方式:1.信号干扰/2.诱导驱离/无|query|false|string||
+|belongDept|所属部门|query|false|integer(int64)||
 |current|当前页|query|false|integer(int32)||
-|defenseSceneId|场景id ja_fw_defense_scene.id|query|false|string||
-|deviceId|反无设备ID(关联ja_fw_device.id)|query|false|integer(int64)||
-|deviceType|设备类型|query|false|string||
-|droneName|无人机名称|query|false|string||
-|droneSerialNo|无人机序列号|query|false|string||
-|droneType|无人机类型(1.微型机/2.植保机...)|query|false|string||
-|endTime|结束时间|query|false|string||
-|flightHeightM|飞行高度(m)|query|false|integer(int32)||
-|flightSpeedMs|飞行速度(m/s)|query|false|number||
-|flightStatus|飞行状态:1.侦测中/2.反制中|query|false|string||
-|id|主键id|query|false|integer(int64)||
-|latitude|当前纬度|query|false|number(double)||
-|longitude|当前经度|query|false|number(double)||
-|signalFreqMhz|信号频段(MHz)|query|false|integer(int32)||
+|deviceName|设备名称|query|false|string||
+|deviceType|设备类型(察打一体/便捷侦测箱/反制枪)|query|false|string||
+|effectiveRangeKmIsNotNull|有效范围是否为空:0-不处理 1-不为空 2-为空|query|false|integer(int32)||
 |size|每页的数量|query|false|integer(int32)||
-|startTime|开始时间|query|false|string||
-|stayDuration|停留时长 (秒) |query|false|string||
-|triggerReason|触发原因|query|false|string||
 
 
 **响应状态**:
@@ -59,7 +40,7 @@
 
 | 状态码 | 说明 | schema |
 | -------- | -------- | ----- | 
-|200|OK|R«IPage«FwDroneAlarmRecordVO»»|
+|200|OK|R«IPage«FwDeviceVO»»|
 |401|Unauthorized||
 |403|Forbidden||
 |404|Not Found||
@@ -71,31 +52,32 @@
 | 参数名称 | 参数说明 | 类型 | schema |
 | -------- | -------- | ----- |----- | 
 |code|状态码|integer(int32)|integer(int32)|
-|data|承载数据|IPage«FwDroneAlarmRecordVO»|IPage«FwDroneAlarmRecordVO»|
+|data|承载数据|IPage«FwDeviceVO»|IPage«FwDeviceVO»|
 |&emsp;&emsp;current||integer(int64)||
 |&emsp;&emsp;pages||integer(int64)||
-|&emsp;&emsp;records||array|FwDroneAlarmRecordVO|
-|&emsp;&emsp;&emsp;&emsp;alarmTime|告警时间|string||
-|&emsp;&emsp;&emsp;&emsp;alarmType|告警类型:1.实时告警/2.历史告警|string||
-|&emsp;&emsp;&emsp;&emsp;areaCode|区域编码|string||
-|&emsp;&emsp;&emsp;&emsp;areaName|区域名称|string||
-|&emsp;&emsp;&emsp;&emsp;counterWay|反制方式:1.信号干扰/2.诱导驱离/3.无|string||
-|&emsp;&emsp;&emsp;&emsp;deviceId|反无设备ID(关联ja_fw_device.id)|integer||
-|&emsp;&emsp;&emsp;&emsp;deviceModel|设备型号|string||
+|&emsp;&emsp;records||array|FwDeviceVO|
+|&emsp;&emsp;&emsp;&emsp;azimuth|方位角 0-360°|integer||
+|&emsp;&emsp;&emsp;&emsp;batteryPct|电量百分比 0-100|integer||
+|&emsp;&emsp;&emsp;&emsp;belongDept|所属部门id|integer||
+|&emsp;&emsp;&emsp;&emsp;belongDeptName|所属部门名称|string||
+|&emsp;&emsp;&emsp;&emsp;charger|负责人|string||
+|&emsp;&emsp;&emsp;&emsp;contactPhone|联系电话|string||
+|&emsp;&emsp;&emsp;&emsp;createTime|创建时间|string||
+|&emsp;&emsp;&emsp;&emsp;detectTargetCnt|侦测目标数量|integer||
+|&emsp;&emsp;&emsp;&emsp;deviceAtt|设备属性(无线电/光电/雷达)|string||
+|&emsp;&emsp;&emsp;&emsp;deviceModel|型号|string||
 |&emsp;&emsp;&emsp;&emsp;deviceName|设备名称|string||
-|&emsp;&emsp;&emsp;&emsp;deviceType|设备类型(1.便捷侦测箱/2.反制枪/3.察打一体)|string||
-|&emsp;&emsp;&emsp;&emsp;droneName|无人机名称|string||
-|&emsp;&emsp;&emsp;&emsp;droneSerialNo|无人机序列号|string||
-|&emsp;&emsp;&emsp;&emsp;droneType|无人机类型(1.微型机/2.植保机...)|string||
-|&emsp;&emsp;&emsp;&emsp;flightHeightM|飞行高度(m)|integer||
-|&emsp;&emsp;&emsp;&emsp;flightSpeedMs|飞行速度(m/s)|number||
-|&emsp;&emsp;&emsp;&emsp;flightStatus|飞行状态:1.侦测中/2.反制中|string||
-|&emsp;&emsp;&emsp;&emsp;id|主键id|integer||
-|&emsp;&emsp;&emsp;&emsp;latitude|当前纬度|number||
-|&emsp;&emsp;&emsp;&emsp;longitude|当前经度|number||
-|&emsp;&emsp;&emsp;&emsp;signalFreqMhz|信号频段(MHz)|integer||
-|&emsp;&emsp;&emsp;&emsp;stayDuration|停留时长(秒)|string||
-|&emsp;&emsp;&emsp;&emsp;triggerReason|触发原因|string||
+|&emsp;&emsp;&emsp;&emsp;deviceSpecification|规格|string||
+|&emsp;&emsp;&emsp;&emsp;deviceType|设备类型(察打一体/便捷侦测箱/反制枪)|string||
+|&emsp;&emsp;&emsp;&emsp;effectiveRangeKm|有效范围 km|number||
+|&emsp;&emsp;&emsp;&emsp;elevation|俯仰角 -90-+90°|integer||
+|&emsp;&emsp;&emsp;&emsp;id|主键|integer||
+|&emsp;&emsp;&emsp;&emsp;manufacturer|生产厂商|string||
+|&emsp;&emsp;&emsp;&emsp;purpose|用途|string||
+|&emsp;&emsp;&emsp;&emsp;remark|备注|string||
+|&emsp;&emsp;&emsp;&emsp;source|来源|string||
+|&emsp;&emsp;&emsp;&emsp;status|运行状态(0:在线/1:离线/2:故障/3:报废)|integer||
+|&emsp;&emsp;&emsp;&emsp;workMode|工作模式:1.侦测中/2.信号干扰中/3.诱导驱离中/4.待机|string||
 |&emsp;&emsp;size||integer(int64)||
 |&emsp;&emsp;total||integer(int64)||
 |msg|返回消息|string||
@@ -111,27 +93,28 @@
 		"pages": 0,
 		"records": [
 			{
-				"alarmTime": "",
-				"alarmType": "",
-				"areaCode": "",
-				"areaName": "",
-				"counterWay": "",
-				"deviceId": 0,
+				"azimuth": 0,
+				"batteryPct": 0,
+				"belongDept": 0,
+				"belongDeptName": "",
+				"charger": "",
+				"contactPhone": "",
+				"createTime": "",
+				"detectTargetCnt": 0,
+				"deviceAtt": "",
 				"deviceModel": "",
 				"deviceName": "",
+				"deviceSpecification": "",
 				"deviceType": "",
-				"droneName": "",
-				"droneSerialNo": "",
-				"droneType": "",
-				"flightHeightM": 0,
-				"flightSpeedMs": 0,
-				"flightStatus": "",
+				"effectiveRangeKm": 0,
+				"elevation": 0,
 				"id": 0,
-				"latitude": 0,
-				"longitude": 0,
-				"signalFreqMhz": 0,
-				"stayDuration": "",
-				"triggerReason": ""
+				"manufacturer": "",
+				"purpose": "",
+				"remark": "",
+				"source": "",
+				"status": 0,
+				"workMode": ""
 			}
 		],
 		"size": 0,
@@ -140,4 +123,218 @@
 	"msg": "",
 	"success": true
 }
+```
+
+
+
+
+## 详情
+
+
+**接口地址**:`/device/fwDevice/detail`
+
+
+**请求方式**:`GET`
+
+
+**请求数据类型**:`application/x-www-form-urlencoded`
+
+
+**响应数据类型**:`*/*`
+
+
+**接口描述**:<p>传入fwDevice</p>
+
+
+
+**请求参数**:
+
+
+**请求参数**:
+
+
+| 参数名称 | 参数说明 | 请求类型    | 是否必须 | 数据类型 | schema |
+| -------- | -------- | ----- | -------- | -------- | ------ |
+|id|主键|query|true|integer(int64)||
+
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| -------- | -------- | ----- | 
+|200|OK|R«FwDeviceVO»|
+|401|Unauthorized||
+|403|Forbidden||
+|404|Not Found||
+
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| -------- | -------- | ----- |----- | 
+|code|状态码|integer(int32)|integer(int32)|
+|data|承载数据|FwDeviceVO|FwDeviceVO|
+|&emsp;&emsp;azimuth|方位角 0-360°|integer(int32)||
+|&emsp;&emsp;batteryPct|电量百分比 0-100|integer(int32)||
+|&emsp;&emsp;belongDept|所属部门id|integer(int64)||
+|&emsp;&emsp;belongDeptName|所属部门名称|string||
+|&emsp;&emsp;charger|负责人|string||
+|&emsp;&emsp;contactPhone|联系电话|string||
+|&emsp;&emsp;createTime|创建时间|string(date-time)||
+|&emsp;&emsp;detectTargetCnt|侦测目标数量|integer(int32)||
+|&emsp;&emsp;deviceAtt|设备属性(无线电/光电/雷达)|string||
+|&emsp;&emsp;deviceModel|型号|string||
+|&emsp;&emsp;deviceName|设备名称|string||
+|&emsp;&emsp;deviceSpecification|规格|string||
+|&emsp;&emsp;deviceType|设备类型(察打一体/便捷侦测箱/反制枪)|string||
+|&emsp;&emsp;effectiveRangeKm|有效范围 km|number||
+|&emsp;&emsp;elevation|俯仰角 -90-+90°|integer(int32)||
+|&emsp;&emsp;id|主键|integer(int64)||
+|&emsp;&emsp;manufacturer|生产厂商|string||
+|&emsp;&emsp;purpose|用途|string||
+|&emsp;&emsp;remark|备注|string||
+|&emsp;&emsp;source|来源|string||
+|&emsp;&emsp;status|运行状态(0:在线/1:离线/2:故障/3:报废)|integer(int32)||
+|&emsp;&emsp;workMode|工作模式:1.侦测中/2.信号干扰中/3.诱导驱离中/4.待机|string||
+|msg|返回消息|string||
+|success|是否成功|boolean||
+
+
+**响应示例**:
+```javascript
+{
+	"code": 0,
+	"data": {
+		"azimuth": 0,
+		"batteryPct": 0,
+		"belongDept": 0,
+		"belongDeptName": "",
+		"charger": "",
+		"contactPhone": "",
+		"createTime": "",
+		"detectTargetCnt": 0,
+		"deviceAtt": "",
+		"deviceModel": "",
+		"deviceName": "",
+		"deviceSpecification": "",
+		"deviceType": "",
+		"effectiveRangeKm": 0,
+		"elevation": 0,
+		"id": 0,
+		"manufacturer": "",
+		"purpose": "",
+		"remark": "",
+		"source": "",
+		"status": 0,
+		"workMode": ""
+	},
+	"msg": "",
+	"success": true
+}
+```
+
+
+
+## 新增或修改
+
+
+**接口地址**:`/device/fwDevice/submit`
+
+
+**请求方式**:`POST`
+
+
+**请求数据类型**:`application/json`
+
+
+**响应数据类型**:`*/*`
+
+
+**接口描述**:<p>传入fwDevice</p>
+
+
+
+**请求示例**:
+
+
+```javascript
+{
+  "belongDept": 0,
+  "charger": "",
+  "contactPhone": "",
+  "deviceAtt": "",
+  "deviceModel": "",
+  "deviceName": "",
+  "deviceSpecification": "",
+  "deviceStatusList": [],
+  "deviceType": "",
+  "effectiveRangeKm": 0,
+  "effectiveRangeKmIsNotNull": 0,
+  "id": 0,
+  "manufacturer": "",
+  "purpose": "",
+  "source": ""
+}
+```
+
+
+**请求参数**:
+
+
+**请求参数**:
+
+
+| 参数名称 | 参数说明 | 请求类型    | 是否必须 | 数据类型 | schema |
+| -------- | -------- | ----- | -------- | -------- | ------ |
+|fwDevice|fwDevice|body|true|FwDeviceDTO|FwDeviceDTO|
+|&emsp;&emsp;belongDept|所属部门||false|integer(int64)||
+|&emsp;&emsp;charger|负责人||false|string||
+|&emsp;&emsp;contactPhone|联系电话||false|string||
+|&emsp;&emsp;deviceAtt|设备属性(无线电/光电/雷达)||false|string||
+|&emsp;&emsp;deviceModel|型号||false|string||
+|&emsp;&emsp;deviceName|设备名称||true|string||
+|&emsp;&emsp;deviceSpecification|规格||false|string||
+|&emsp;&emsp;deviceStatusList|设备状态,多个状态用逗号隔开||false|array|string|
+|&emsp;&emsp;deviceType|设备类型(察打一体/便捷侦测箱/反制枪)||false|string||
+|&emsp;&emsp;effectiveRangeKm|有效范围 km||false|number||
+|&emsp;&emsp;effectiveRangeKmIsNotNull|是否有范围 0不过滤 1有 2没有||false|integer(int32)||
+|&emsp;&emsp;id|主键||false|integer(int64)||
+|&emsp;&emsp;manufacturer|生产厂商||false|string||
+|&emsp;&emsp;purpose|用途||false|string||
+|&emsp;&emsp;source|来源||false|string||
+
+
+**响应状态**:
+
+
+| 状态码 | 说明 | schema |
+| -------- | -------- | ----- | 
+|200|OK|R|
+|201|Created||
+|401|Unauthorized||
+|403|Forbidden||
+|404|Not Found||
+
+
+**响应参数**:
+
+
+| 参数名称 | 参数说明 | 类型 | schema |
+| -------- | -------- | ----- |----- | 
+|code|状态码|integer(int32)|integer(int32)|
+|data|承载数据|object||
+|msg|返回消息|string||
+|success|是否成功|boolean||
+
+
+**响应示例**:
+```javascript
+{
+	"code": 0,
+	"data": {},
+	"msg": "",
+	"success": true
+}
 ```
\ No newline at end of file
diff --git a/applications/drone-command/src/views/areaManage/areaStatistics/index.vue b/applications/drone-command/src/views/areaManage/areaStatistics/index.vue
index 5448069..bc667e2 100644
--- a/applications/drone-command/src/views/areaManage/areaStatistics/index.vue
+++ b/applications/drone-command/src/views/areaManage/areaStatistics/index.vue
@@ -1,82 +1,75 @@
 <template>
 	<basic-container>
-		<el-form ref="queryParamsRef" :model="searchParams">
-			<el-row :gutter="16">
-				<el-col :span="4">
-					<el-form-item label="区域名称" prop="areaName">
-						<el-input v-model="searchParams.areaName" placeholder="请输入" clearable @clear="handleSearch" />
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<el-form-item label="区域类型" prop="areaType">
-						<el-select v-model="searchParams.areaType" placeholder="请选择" clearable @change="handleSearch">
-							<el-option
-								v-for="item in dictObj.areaType"
-								:key="item.dictKey"
-								:label="item.dictValue"
-								:value="item.dictKey"
-							/>
-						</el-select>
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<el-form-item label="场景类型" prop="sceneType">
-						<el-select v-model="searchParams.sceneType" placeholder="请选择" clearable @change="handleSearch">
-							<el-option
-								v-for="item in dictObj.sceneType"
-								:key="item.dictKey"
-								:label="item.dictValue"
-								:value="item.dictKey"
-							/>
-						</el-select>
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<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 ref="queryParamsRef" :model="searchParams" class="ztzf-page-history-search">
+			<el-form-item label="区域名称" prop="areaName">
+				<el-input class="ztzf-data-cockpit-search-input" v-model="searchParams.areaName" placeholder="请输入"
+					clearable @clear="handleSearch" />
+			</el-form-item>
+
+			<el-form-item label="区域类型" prop="areaType">
+				<el-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-select-popper"
+					v-model="searchParams.areaType" placeholder="请选择" clearable @change="handleSearch">
+					<el-option v-for="item in dictObj.areaType" :key="item.dictKey" :label="item.dictValue"
+						:value="item.dictKey" />
+				</el-select>
+			</el-form-item>
+
+			<el-form-item label="场景类型" prop="sceneType">
+				<el-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-select-popper"
+					v-model="searchParams.sceneType" placeholder="请选择" clearable @change="handleSearch">
+					<el-option v-for="item in dictObj.sceneType" :key="item.dictKey" :label="item.dictValue"
+						:value="item.dictKey" />
+				</el-select>
+			</el-form-item>
+
+			<el-form-item class="history-search-actions">
+				<el-button :icon="RefreshRight" @click="resetForm"></el-button>
+				<el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+			</el-form-item>
 		</el-form>
-		<el-table v-loading="loading" :data="list">
-			<el-table-column type="index" width="60" label="序号" />
-			<el-table-column prop="areaName" label="区域名称" />
-			<el-table-column prop="areaType" label="区域类型">
-				<template v-slot="{ row }">
-					{{ getDictLabel(row.areaType, dictObj.areaType) }}
-				</template>
-			</el-table-column>
-			<el-table-column prop="sceneName" label="关联场景" />
-			<el-table-column prop="sceneType" label="场景类型">
-				<template v-slot="{ row }">
-					{{ getDictLabel(row.sceneType, dictObj.sceneType) }}
-				</template>
-			</el-table-column>
-			<el-table-column prop="deviceCount" label="设备数量" />
-			<el-table-column prop="alarmCount" label="告警次数" />
-			<el-table-column prop="counterCount" label="侦测反制次数" />
-			<el-table-column prop="counterSuccessCount" label="反制成功次数" />
-			<el-table-column prop="controlEffect" label="管控效果" />
-			<el-table-column label="操作">
-				<template v-slot="{ row }">
-					<el-link @click="openForm(row)" type="primary">查看</el-link>
-				</template>
-			</el-table-column>
-		</el-table>
-		<div>
-			<el-pagination
-				v-model:current-page="searchParams.current"
-				v-model:page-size="searchParams.size"
-				:total="total"
-				@change="getList"
-			/>
+
+		<div class="ztzf-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
+			<div class="ztzf-table-content ztzf-table-content-bg">
+				<el-table class="ztzf-data-cockpit-table" :data="list">
+					<el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
+					<el-table-column prop="areaName" show-overflow-tooltip width="150" label="区域名称" />
+					<el-table-column prop="areaType" show-overflow-tooltip width="130" label="区域类型">
+						<template v-slot="{ row }">
+							{{ getDictLabel(row.areaType, dictObj.areaType) }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="sceneName" show-overflow-tooltip width="150" label="关联场景" />
+					<el-table-column prop="sceneType" show-overflow-tooltip width="130" label="场景类型">
+						<template v-slot="{ row }">
+							{{ getDictLabel(row.sceneType, dictObj.sceneType) }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="deviceCount" show-overflow-tooltip width="110" label="设备数量" />
+					<el-table-column prop="alarmCount" show-overflow-tooltip width="110" label="告警次数" />
+					<el-table-column prop="counterCount" show-overflow-tooltip width="120" label="侦测反制次数" />
+					<el-table-column prop="counterSuccessCount" show-overflow-tooltip width="130" label="反制成功次数" />
+					<el-table-column prop="controlEffect" show-overflow-tooltip width="110" label="管控效果" />
+					<el-table-column label="操作" class-name="operation-btns">
+						<template v-slot="{ row }">
+							<el-link @click="openForm(row)">查看</el-link>
+						</template>
+					</el-table-column>
+				</el-table>
+			</div>
+
+			<div class="ztzf-table-pagination">
+				<el-pagination popper-class="ztzf-data-cockpit-select-popper"
+					v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
+					layout="total, prev, pager, next, sizes" :total="total" @change="getList" />
+			</div>
 		</div>
+
 		<FormDiaLog v-if="dialogVisible" v-model="dialogVisible" ref="dialogRef" />
 	</basic-container>
 </template>
 
 <script setup>
+import { Search, RefreshRight } from '@element-plus/icons-vue'
 import { nextTick, onMounted, ref } from 'vue'
 import { fwAreaDivideStatisticsPageApi } from './areaStatisticsApi'
 import FormDiaLog from './FormDiaLog.vue'
@@ -107,7 +100,7 @@
 provide('dictObj', dictObj)
 
 // 获取列表
-async function getList() {
+async function getList () {
 	loading.value = true
 	try {
 		const res = await fwAreaDivideStatisticsPageApi(searchParams.value)
@@ -119,27 +112,27 @@
 }
 
 // 查询
-function handleSearch() {
+function handleSearch () {
 	searchParams.value.current = 1
 	getList()
 }
 
 // 重置查询
-function resetForm() {
+function resetForm () {
 	queryParamsRef.value?.resetFields()
 	searchParams.value.current = 1
 	getList()
 }
 
 // 获取字典
-function getDictList() {
+function getDictList () {
 	getDictionaryByCode('areaType,sceneType').then(res => {
 		dictObj.value = res.data.data
 	})
 }
 
 // 打开查看弹框
-function openForm(row) {
+function openForm (row) {
 	dialogVisible.value = true
 	nextTick(() => {
 		dialogRef.value?.open({ mode: 'view', row })
diff --git a/applications/drone-command/src/views/areaManage/defenseZone/index.vue b/applications/drone-command/src/views/areaManage/defenseZone/index.vue
index 4ef83fc..b1951c3 100644
--- a/applications/drone-command/src/views/areaManage/defenseZone/index.vue
+++ b/applications/drone-command/src/views/areaManage/defenseZone/index.vue
@@ -1,47 +1,47 @@
 <template>
 	<basic-container>
-		<el-form ref="queryParamsRef" :model="searchParams">
-			<el-row :gutter="16">
-				<el-col :span="4">
-					<el-form-item label="防区名称" prop="zoneName">
-						<el-input v-model="searchParams.zoneName" placeholder="请输入" clearable @clear="handleSearch" />
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<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 ref="queryParamsRef" :model="searchParams" class="ztzf-page-history-search">
+			<el-form-item label="防区名称" prop="zoneName">
+				<el-input class="ztzf-data-cockpit-search-input" v-model="searchParams.zoneName" placeholder="请输入"
+					clearable @clear="handleSearch" />
+			</el-form-item>
+
+			<el-form-item class="history-search-actions">
+				<el-button :icon="RefreshRight" @click="resetForm"></el-button>
+				<el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+			</el-form-item>
 		</el-form>
-		<div>
-			<el-button type="primary" @click="openForm('add')">新增</el-button>
+
+		<div class="ztzf-table-toolbar">
+			<el-button :icon="Plus" color="#284FE3" type="primary" @click="openForm('add')">新增</el-button>
 			<el-button type="danger" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button>
 		</div>
-		<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
-			<el-table-column type="selection" width="55" />
-			<el-table-column type="index" width="60" label="序号" />
-			<el-table-column prop="zoneName" label="防区名称" />
-			<el-table-column prop="zoneArea" label="防区面积(k㎡)" />
-			<el-table-column prop="sceneCount" label="场景数量" />
-			<el-table-column prop="areaCount" label="区域数量" />
-			<el-table-column prop="deviceCount" label="设备数量" />
-			<el-table-column label="操作">
-				<template v-slot="{ row }">
-					<el-link @click="openForm('view', row)" type="primary">查看</el-link>
-					<el-link @click="openForm('edit', row)" type="warning">编辑</el-link>
-					<el-link @click="handleDelete(row)" type="danger">删除</el-link>
-				</template>
-			</el-table-column>
-		</el-table>
-		<div>
-			<el-pagination
-				v-model:current-page="searchParams.current"
-				v-model:page-size="searchParams.size"
-				:total="total"
-				@change="getList"
-			/>
+
+		<div class="ztzf-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
+			<div class="ztzf-table-content ztzf-table-content-bg">
+				<el-table class="ztzf-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
+					<el-table-column type="selection" width="46" />
+					<el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
+					<el-table-column prop="zoneName" show-overflow-tooltip width="150" label="防区名称" />
+					<el-table-column prop="zoneArea" show-overflow-tooltip width="130" label="防区面积(k㎡)" />
+					<el-table-column prop="sceneCount" show-overflow-tooltip width="120" label="场景数量" />
+					<el-table-column prop="areaCount" show-overflow-tooltip width="120" label="区域数量" />
+					<el-table-column prop="deviceCount" show-overflow-tooltip width="120" label="设备数量" />
+					<el-table-column label="操作" class-name="operation-btns">
+						<template v-slot="{ row }">
+							<el-link @click="openForm('view', row)">查看</el-link>
+							<el-link @click="openForm('edit', row)">编辑</el-link>
+							<el-link @click="handleDelete(row)">删除</el-link>
+						</template>
+					</el-table-column>
+				</el-table>
+			</div>
+
+			<div class="ztzf-table-pagination">
+				<el-pagination popper-class="ztzf-data-cockpit-select-popper"
+					v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
+					layout="total, prev, pager, next, sizes" :total="total" @change="getList" />
+			</div>
 		</div>
 
 		<FormDiaLog v-if="dialogVisible" v-model="dialogVisible" ref="dialogRef" @success="getList" />
@@ -49,6 +49,7 @@
 </template>
 
 <script setup>
+import { Search, RefreshRight, Plus } from '@element-plus/icons-vue'
 import { nextTick, onMounted, provide, ref } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { fwDefenseZonePageApi, fwDefenseZoneRemoveApi } from './defenseZoneApi'
@@ -73,7 +74,7 @@
 const dialogVisible = ref(false)
 
 // 获取列表
-async function getList() {
+async function getList () {
 	loading.value = true
 	try {
 		const res = await fwDefenseZonePageApi(searchParams.value)
@@ -85,20 +86,20 @@
 }
 
 // 查询
-function handleSearch() {
+function handleSearch () {
 	searchParams.value.current = 1
 	getList()
 }
 
 // 重置查询
-function resetForm() {
+function resetForm () {
 	queryParamsRef.value?.resetFields()
 	searchParams.value.current = 1
 	getList()
 }
 
 // 删除
-async function handleDelete(row) {
+async function handleDelete (row) {
 	const tips = row ? '该条' : '选中的项'
 	await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', { type: 'warning' })
 	const ids = row ? row.id : selectedIds.value.join(',')
@@ -109,7 +110,7 @@
 }
 
 // 勾选值设置
-function handleSelectionChange(rows) {
+function handleSelectionChange (rows) {
 	selectedIds.value = rows.map(item => item.id)
 }
 
@@ -120,21 +121,20 @@
 provide('dictObj', dictObj)
 
 // 获取字典
-function getDictList() {
+function getDictList () {
 	getDictionaryByCode('areaType,sceneType').then(res => {
 		dictObj.value = res.data.data
 	})
 }
 
 // 新增/编辑/查看 弹框
-function openForm(mode, row) {
+function openForm (mode, row) {
 	dialogVisible.value = true
 	nextTick(() => {
 		dialogRef.value?.open({ mode, row })
 	})
 }
 
-// 初始化加载
 onMounted(() => {
 	getList()
 	getDictList()
diff --git a/applications/drone-command/src/views/areaManage/partition/index.vue b/applications/drone-command/src/views/areaManage/partition/index.vue
index 820a8a3..0665089 100644
--- a/applications/drone-command/src/views/areaManage/partition/index.vue
+++ b/applications/drone-command/src/views/areaManage/partition/index.vue
@@ -1,79 +1,75 @@
 <template>
 	<basic-container>
-		<el-form ref="queryParamsRef" :model="searchParams">
-			<el-row :gutter="16">
-				<el-col :span="4">
-					<el-form-item label="区域名称" prop="areaName">
-						<el-input v-model="searchParams.areaName" placeholder="请输入" clearable @clear="handleSearch" />
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<el-form-item label="区域类型" prop="areaType">
-						<el-select v-model="searchParams.areaType" placeholder="请选择" clearable @change="handleSearch">
-							<el-option
-								v-for="item in dictObj.areaType"
-								:key="item.dictKey"
-								:label="item.dictValue"
-								:value="item.dictKey"
-							/>
-						</el-select>
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<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 ref="queryParamsRef" :model="searchParams" class="ztzf-page-history-search">
+			<el-form-item label="区域名称" prop="areaName">
+				<el-input class="ztzf-data-cockpit-search-input" v-model="searchParams.areaName" placeholder="请输入"
+					clearable @clear="handleSearch" />
+			</el-form-item>
+
+			<el-form-item label="区域类型" prop="areaType">
+				<el-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-select-popper"
+					v-model="searchParams.areaType" placeholder="请选择" clearable @change="handleSearch">
+					<el-option v-for="item in dictObj.areaType" :key="item.dictKey" :label="item.dictValue"
+						:value="item.dictKey" />
+				</el-select>
+			</el-form-item>
+
+			<el-form-item class="history-search-actions">
+				<el-button :icon="RefreshRight" @click="resetForm"></el-button>
+				<el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+			</el-form-item>
 		</el-form>
-		<div>
-			<el-button type="primary" @click="openForm('add')">新增</el-button>
+
+		<div class="ztzf-table-toolbar">
+			<el-button :icon="Plus" color="#284FE3" type="primary" @click="openForm('add')">新增</el-button>
 			<el-button type="danger" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button>
 		</div>
-		<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
-			<el-table-column type="selection" width="55" />
-			<el-table-column type="index" width="60" label="序号" />
-			<el-table-column prop="areaName" label="区域名称" />
-			<el-table-column label="区域位置">
-				<template v-slot="{ row }">
-					{{ formatLocation(row) }}
-				</template>
-			</el-table-column>
-			<el-table-column prop="areaSize" label="区域面积(k㎡)" />
-			<el-table-column prop="areaType" label="区域类型">
-				<template v-slot="{ row }">
-					{{ getDictLabel(row.areaType, dictObj.areaType) }}
-				</template>
-			</el-table-column>
-			<el-table-column prop="triggerCondition" label="触发条件" />
-			<el-table-column prop="responseMechanism" label="响应机制" />
-			<el-table-column prop="controlLevel" label="管控级别">
-				<template v-slot="{ row }">
-					{{ getDictLabel(row.controlLevel, dictObj.controlLevel) }}
-				</template>
-			</el-table-column>
-			<el-table-column prop="policeStationName" label="关联派出所" />
-			<el-table-column label="可飞行时间段">
-				<template v-slot="{ row }">
-					{{ formatFlyDate(row) }}
-				</template>
-			</el-table-column>
-			<el-table-column label="操作">
-				<template v-slot="{ row }">
-					<el-link @click="openForm('view', row)" type="primary">查看</el-link>
-					<el-link @click="openForm('edit', row)" type="warning">编辑</el-link>
-					<el-link @click="handleDelete(row)" type="danger">删除</el-link>
-				</template>
-			</el-table-column>
-		</el-table>
-		<div>
-			<el-pagination
-				v-model:current-page="searchParams.current"
-				v-model:page-size="searchParams.size"
-				:total="total"
-				@change="getList"
-			/>
+
+		<div class="ztzf-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
+			<div class="ztzf-table-content ztzf-table-content-bg">
+				<el-table class="ztzf-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
+					<el-table-column type="selection" width="46" />
+					<el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
+					<el-table-column prop="areaName" show-overflow-tooltip width="150" label="区域名称" />
+					<el-table-column show-overflow-tooltip width="160" label="区域位置">
+						<template v-slot="{ row }">
+							{{ formatLocation(row) }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="areaSize" show-overflow-tooltip width="130" label="区域面积(k㎡)" />
+					<el-table-column prop="areaType" show-overflow-tooltip width="120" label="区域类型">
+						<template v-slot="{ row }">
+							{{ getDictLabel(row.areaType, dictObj.areaType) }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="triggerCondition" show-overflow-tooltip width="130" label="触发条件" />
+					<el-table-column prop="responseMechanism" show-overflow-tooltip width="130" label="响应机制" />
+					<el-table-column prop="controlLevel" show-overflow-tooltip width="120" label="管控级别">
+						<template v-slot="{ row }">
+							{{ getDictLabel(row.controlLevel, dictObj.controlLevel) }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="policeStationName" show-overflow-tooltip width="140" label="关联派出所" />
+					<el-table-column show-overflow-tooltip width="160" label="可飞行时间段">
+						<template v-slot="{ row }">
+							{{ formatFlyDate(row) }}
+						</template>
+					</el-table-column>
+					<el-table-column label="操作" class-name="operation-btns">
+						<template v-slot="{ row }">
+							<el-link @click="openForm('view', row)">查看</el-link>
+							<el-link @click="openForm('edit', row)">编辑</el-link>
+							<el-link @click="handleDelete(row)">删除</el-link>
+						</template>
+					</el-table-column>
+				</el-table>
+			</div>
+
+			<div class="ztzf-table-pagination">
+				<el-pagination popper-class="ztzf-data-cockpit-select-popper"
+					v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
+					layout="total, prev, pager, next, sizes" :total="total" @change="getList" />
+			</div>
 		</div>
 
 		<FormDiaLog v-if="dialogVisible" v-model="dialogVisible" ref="dialogRef" @success="getList" />
@@ -81,6 +77,7 @@
 </template>
 
 <script setup>
+import { Search, RefreshRight, Plus } from '@element-plus/icons-vue'
 import { nextTick, onMounted, ref } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { fwAreaDividePageApi, fwAreaDivideRemoveApi } from './partitionApi'
@@ -105,7 +102,7 @@
 const dialogVisible = ref(false)
 
 // 获取列表
-async function getList() {
+async function getList () {
 	loading.value = true
 	try {
 		const res = await fwAreaDividePageApi(searchParams.value)
@@ -117,20 +114,20 @@
 }
 
 // 查询
-function handleSearch() {
+function handleSearch () {
 	searchParams.value.current = 1
 	getList()
 }
 
 // 重置查询
-function resetForm() {
+function resetForm () {
 	queryParamsRef.value?.resetFields()
 	searchParams.value.current = 1
 	getList()
 }
 
 // 删除
-async function handleDelete(row) {
+async function handleDelete (row) {
 	const tips = row ? '该条' : '选中的项'
 	await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', { type: 'warning' })
 	const ids = row ? row.id : selectedIds.value.join(',')
@@ -141,16 +138,16 @@
 }
 
 // 勾选值设置
-function handleSelectionChange(rows) {
+function handleSelectionChange (rows) {
 	selectedIds.value = rows.map(item => item.id)
 }
 
-function formatLocation(row) {
+function formatLocation (row) {
 	if (row?.longitude == null || row?.latitude == null) return ''
 	return `${row.longitude}, ${row.latitude}`
 }
 
-function formatFlyDate(row) {
+function formatFlyDate (row) {
 	if (!row?.flyDateStart && !row?.flyDateEnd) return ''
 	return `${row.flyDateStart || '-'} ~ ${row.flyDateEnd || '-'}`
 }
@@ -170,7 +167,7 @@
 }
 
 // 新增/编辑/查看 弹框
-function openForm(mode, row) {
+function openForm (mode, row) {
 	dialogVisible.value = true
 	nextTick(() => {
 		dialogRef.value?.open({ mode, row })
diff --git a/applications/drone-command/src/views/areaManage/precinctInfo/index.vue b/applications/drone-command/src/views/areaManage/precinctInfo/index.vue
index 526806d..7ba96d7 100644
--- a/applications/drone-command/src/views/areaManage/precinctInfo/index.vue
+++ b/applications/drone-command/src/views/areaManage/precinctInfo/index.vue
@@ -1,47 +1,47 @@
 <template>
 	<basic-container>
-		<el-form ref="queryParamsRef" :model="searchParams">
-			<el-row :gutter="16">
-				<el-col :span="4">
-					<el-form-item label="派出所名称" prop="stationName">
-						<el-input v-model="searchParams.stationName" placeholder="请输入" clearable @clear="handleSearch" />
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<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 ref="queryParamsRef" :model="searchParams" class="ztzf-page-history-search">
+			<el-form-item label="派出所名称" prop="stationName">
+				<el-input class="ztzf-data-cockpit-search-input" v-model="searchParams.stationName" placeholder="请输入"
+					clearable @clear="handleSearch" />
+			</el-form-item>
+
+			<el-form-item class="history-search-actions">
+				<el-button :icon="RefreshRight" @click="resetForm"></el-button>
+				<el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+			</el-form-item>
 		</el-form>
-		<div>
-			<el-button type="primary" @click="openForm('add')">新增</el-button>
+
+		<div class="ztzf-table-toolbar">
+			<el-button :icon="Plus" color="#284FE3" type="primary" @click="openForm('add')">新增</el-button>
 			<el-button type="danger" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button>
 		</div>
-		<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
-			<el-table-column type="selection" width="55" />
-			<el-table-column type="index" width="60" label="序号" />
-			<el-table-column prop="stationName" label="派出所名称" />
-			<el-table-column prop="address" label="位置" />
-			<el-table-column prop="longitude" label="经度" />
-			<el-table-column prop="latitude" label="纬度" />
-			<el-table-column prop="contactPerson" label="联系人" />
-			<el-table-column prop="contactPhone" label="联系方式" />
-			<el-table-column label="操作">
-				<template v-slot="{ row }">
-					<el-link @click="openForm('edit', row)" type="warning">编辑</el-link>
-					<el-link @click="handleDelete(row)" type="danger">删除</el-link>
-				</template>
-			</el-table-column>
-		</el-table>
-		<div>
-			<el-pagination
-				v-model:current-page="searchParams.current"
-				v-model:page-size="searchParams.size"
-				:total="total"
-				@change="getList"
-			/>
+
+		<div class="ztzf-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
+			<div class="ztzf-table-content ztzf-table-content-bg">
+				<el-table class="ztzf-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
+					<el-table-column type="selection" width="46" />
+					<el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
+					<el-table-column prop="stationName" show-overflow-tooltip width="160" label="派出所名称" />
+					<el-table-column prop="address" show-overflow-tooltip width="200" label="位置" />
+					<el-table-column prop="longitude" show-overflow-tooltip width="120" label="经度" />
+					<el-table-column prop="latitude" show-overflow-tooltip width="120" label="纬度" />
+					<el-table-column prop="contactPerson" show-overflow-tooltip width="120" label="联系人" />
+					<el-table-column prop="contactPhone" show-overflow-tooltip width="140" label="联系方式" />
+					<el-table-column label="操作" class-name="operation-btns">
+						<template v-slot="{ row }">
+							<el-link @click="openForm('edit', row)">编辑</el-link>
+							<el-link @click="handleDelete(row)">删除</el-link>
+						</template>
+					</el-table-column>
+				</el-table>
+			</div>
+
+			<div class="ztzf-table-pagination">
+				<el-pagination popper-class="ztzf-data-cockpit-select-popper"
+					v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
+					layout="total, prev, pager, next, sizes" :total="total" @change="getList" />
+			</div>
 		</div>
 
 		<FormDiaLog ref="dialogRef" @success="getList" v-if="dialogVisible" v-model="dialogVisible" />
@@ -49,7 +49,8 @@
 </template>
 
 <script setup>
-import { onMounted, ref } from 'vue'
+import { Search, RefreshRight, Plus } from '@element-plus/icons-vue'
+import { nextTick, onMounted, ref } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { fwPoliceStationPageApi, fwPoliceStationRemoveApi } from './precinctInfoApi'
 import FormDiaLog from './FormDiaLog.vue'
@@ -69,7 +70,7 @@
 const dialogVisible = ref(false)
 
 // 获取列表
-async function getList() {
+async function getList () {
 	loading.value = true
 	try {
 		const res = await fwPoliceStationPageApi(searchParams.value)
@@ -81,20 +82,20 @@
 }
 
 // 查询
-function handleSearch() {
+function handleSearch () {
 	searchParams.value.current = 1
 	getList()
 }
 
 // 重置查询
-function resetForm() {
+function resetForm () {
 	queryParamsRef.value?.resetFields()
 	searchParams.value.current = 1
 	getList()
 }
 
 // 删除
-async function handleDelete(row) {
+async function handleDelete (row) {
 	const tips = row ? '该条' : '选中的项'
 	await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', { type: 'warning' })
 	const ids = row ? row.id : selectedIds.value.join(',')
@@ -105,12 +106,12 @@
 }
 
 // 勾选值设置
-function handleSelectionChange(rows) {
+function handleSelectionChange (rows) {
 	selectedIds.value = rows.map(item => item.id)
 }
 
 // 新增
-function openForm(mode, row) {
+function openForm (mode, row) {
 	dialogVisible.value = true
 	nextTick(() => {
 		dialogRef.value?.open({ mode, row })
diff --git a/applications/drone-command/src/views/areaManage/sceneConfig/index.vue b/applications/drone-command/src/views/areaManage/sceneConfig/index.vue
index 92be17e..23fcc99 100644
--- a/applications/drone-command/src/views/areaManage/sceneConfig/index.vue
+++ b/applications/drone-command/src/views/areaManage/sceneConfig/index.vue
@@ -1,77 +1,74 @@
 <template>
 	<basic-container>
-		<el-form ref="queryParamsRef" :model="searchParams">
-			<el-row :gutter="16">
-				<el-col :span="4">
-					<el-form-item label="场景名称" prop="sceneName">
-						<el-input v-model="searchParams.sceneName" placeholder="请输入" clearable @clear="handleSearch" />
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<el-form-item label="场景类型" prop="sceneType">
-						<el-select v-model="searchParams.sceneType" placeholder="请选择" clearable @change="handleSearch">
-							<el-option
-								v-for="item in dictObj.sceneType"
-								:key="item.dictKey"
-								:label="item.dictValue"
-								:value="item.dictKey"
-							/>
-						</el-select>
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<el-form-item label="场景状态" prop="status">
-						<el-select v-model="searchParams.status" placeholder="请选择" clearable @change="handleSearch">
-							<el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
-						</el-select>
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<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 ref="queryParamsRef" :model="searchParams" class="ztzf-page-history-search">
+			<el-form-item label="场景名称" prop="sceneName">
+				<el-input class="ztzf-data-cockpit-search-input" v-model="searchParams.sceneName" placeholder="请输入"
+					clearable @clear="handleSearch" />
+			</el-form-item>
+
+			<el-form-item label="场景类型" prop="sceneType">
+				<el-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-select-popper"
+					v-model="searchParams.sceneType" placeholder="请选择" clearable @change="handleSearch">
+					<el-option v-for="item in dictObj.sceneType" :key="item.dictKey" :label="item.dictValue"
+						:value="item.dictKey" />
+				</el-select>
+			</el-form-item>
+
+			<el-form-item label="场景状态" prop="status">
+				<el-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-select-popper"
+					v-model="searchParams.status" placeholder="请选择" clearable @change="handleSearch">
+					<el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
+				</el-select>
+			</el-form-item>
+
+			<el-form-item class="history-search-actions">
+				<el-button :icon="RefreshRight" @click="resetForm"></el-button>
+				<el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+			</el-form-item>
 		</el-form>
-		<div>
-			<el-button type="primary" @click="openForm('add')">新增</el-button>
+
+		<div class="ztzf-table-toolbar">
+			<el-button :icon="Plus" color="#284FE3" type="primary" @click="openForm('add')">新增</el-button>
 			<el-button type="danger" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button>
 		</div>
-		<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
-			<el-table-column type="selection" width="55" />
-			<el-table-column type="index" width="60" label="序号" />
-			<el-table-column prop="sceneName" label="场景名称" />
-			<el-table-column prop="sceneType" label="场景类型">
-				<template v-slot="{ row }">
-					{{ getDictLabel(row.sceneType, dictObj.sceneType) }}
-				</template>
-			</el-table-column>
-			<el-table-column label="指挥点位置">
-				<template v-slot="{ row }">
-					{{ formatLocation(row) }}
-				</template>
-			</el-table-column>
-			<el-table-column prop="defenseLeader" label="防控负责人" />
-			<el-table-column prop="leaderPhone" label="防控负责人电话" />
-			<el-table-column prop="areaCount" label="区域数量" />
-			<el-table-column prop="counterDeviceCount" label="反制设备数量" />
-			<el-table-column prop="detectDeviceCount" label="探测设备数量" />
-			<el-table-column label="操作">
-				<template v-slot="{ row }">
-					<el-link @click="openForm('view', row)" type="primary">查看</el-link>
-					<el-link @click="openForm('edit', row)" type="warning">编辑</el-link>
-					<el-link @click="handleDelete(row)" type="danger">删除</el-link>
-				</template>
-			</el-table-column>
-		</el-table>
-		<div>
-			<el-pagination
-				v-model:current-page="searchParams.current"
-				v-model:page-size="searchParams.size"
-				:total="total"
-				@change="getList"
-			/>
+
+		<div class="ztzf-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
+			<div class="ztzf-table-content ztzf-table-content-bg">
+				<el-table class="ztzf-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
+					<el-table-column type="selection" width="46" />
+					<el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
+				
+					<el-table-column prop="sceneName" show-overflow-tooltip width="130" label="场景名称" />
+					<el-table-column prop="sceneType" show-overflow-tooltip width="120" label="场景类型">
+						<template v-slot="{ row }">
+							{{ getDictLabel(row.sceneType, dictObj.sceneType) }}
+						</template>
+					</el-table-column>
+					<el-table-column show-overflow-tooltip width="150" label="指挥点位置">
+						<template v-slot="{ row }">
+							{{ formatLocation(row) }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="defenseLeader" show-overflow-tooltip width="120" label="防控负责人" />
+					<el-table-column prop="leaderPhone" show-overflow-tooltip width="140" label="防控负责人电话" />
+					<el-table-column prop="areaCount" show-overflow-tooltip width="110" label="区域数量" />
+					<el-table-column prop="counterDeviceCount" show-overflow-tooltip width="120" label="反制设备数量" />
+					<el-table-column prop="detectDeviceCount" show-overflow-tooltip width="120" label="探测设备数量" />
+					<el-table-column label="操作" class-name="operation-btns">
+						<template v-slot="{ row }">
+							<el-link @click="openForm('view', row)">查看</el-link>
+							<el-link @click="openForm('edit', row)">编辑</el-link>
+							<el-link @click="handleDelete(row)">删除</el-link>
+						</template>
+					</el-table-column>
+				</el-table>
+			</div>
+
+			<div class="ztzf-table-pagination">
+				<el-pagination popper-class="ztzf-data-cockpit-select-popper"
+					v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
+					layout="total, prev, pager, next, sizes" :total="total" @change="getList" />
+			</div>
 		</div>
 
 		<FormDiaLog v-if="dialogVisible" v-model="dialogVisible" ref="dialogRef" @success="getList" />
@@ -79,6 +76,7 @@
 </template>
 
 <script setup>
+import { Search, RefreshRight, Plus } from '@element-plus/icons-vue'
 import { nextTick, onMounted, provide, ref } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { fwDefenseScenePageApi, fwDefenseSceneRemoveApi } from './sceneConfigApi'
@@ -109,7 +107,7 @@
 ])
 
 // 获取列表
-async function getList() {
+async function getList () {
 	loading.value = true
 	try {
 		const res = await fwDefenseScenePageApi(searchParams.value)
@@ -121,20 +119,20 @@
 }
 
 // 查询
-function handleSearch() {
+function handleSearch () {
 	searchParams.value.current = 1
 	getList()
 }
 
 // 重置查询
-function resetForm() {
+function resetForm () {
 	queryParamsRef.value?.resetFields()
 	searchParams.value.current = 1
 	getList()
 }
 
 // 删除
-async function handleDelete(row) {
+async function handleDelete (row) {
 	const tips = row ? '该条' : '选中的项'
 	await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', { type: 'warning' })
 	const ids = row ? row.id : selectedIds.value.join(',')
@@ -145,11 +143,11 @@
 }
 
 // 勾选值设置
-function handleSelectionChange(rows) {
+function handleSelectionChange (rows) {
 	selectedIds.value = rows.map(item => item.id)
 }
 
-function formatLocation(row) {
+function formatLocation (row) {
 	if (row?.longitude == null || row?.latitude == null) return ''
 	return `${_.round(row.longitude, 6)}, ${_.round(row.latitude, 6)}`
 }
@@ -162,14 +160,14 @@
 provide('dictObj', dictObj)
 
 // 获取字典
-function getDictList() {
+function getDictList () {
 	getDictionaryByCode('sceneType,deviceMode,areaType').then(res => {
 		dictObj.value = res.data.data
 	})
 }
 
 // 新增/编辑/查看 弹框
-function openForm(mode, row) {
+function openForm (mode, row) {
 	dialogVisible.value = true
 	nextTick(() => {
 		dialogRef.value?.open({ mode, row })
diff --git a/applications/drone-command/src/views/basicManage/deviceScrap/index.vue b/applications/drone-command/src/views/basicManage/deviceScrap/index.vue
index a3642a8..0032104 100644
--- a/applications/drone-command/src/views/basicManage/deviceScrap/index.vue
+++ b/applications/drone-command/src/views/basicManage/deviceScrap/index.vue
@@ -1,82 +1,72 @@
 <template>
 	<basic-container>
-		<el-form ref="queryParamsRef" :model="searchParams">
-			<el-row :gutter="16">
-				<el-col :span="4">
-					<el-form-item label="设备名称" prop="deviceName">
-						<el-input v-model="searchParams.deviceName" placeholder="请输入" clearable @clear="handleSearch" />
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<el-form-item label="设备类型" prop="deviceType">
-						<el-select v-model="searchParams.deviceType" placeholder="请选择" clearable @change="handleSearch">
-							<el-option
-								v-for="item in dictObj.deviceType"
-								:key="item.dictKey"
-								:label="item.dictValue"
-								:value="item.dictKey"
-							/>
-						</el-select>
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<el-form-item label="所属部门" prop="belongDept">
-						<el-tree-select
-							v-model="searchParams.belongDept"
-							:data="deptTree"
-							:props="treeProps"
-							node-key="id"
-							check-strictly
-							clearable
-							@change="handleSearch"
-						/>
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<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 ref="queryParamsRef" :model="searchParams" class="ztzf-page-history-search">
+			<el-form-item label="名称" prop="deviceName">
+				<el-input class="ztzf-data-cockpit-search-input" v-model="searchParams.deviceName" placeholder="请输入"
+					clearable @clear="handleSearch" />
+			</el-form-item>
+
+			<el-form-item label="类型" prop="deviceType">
+				<el-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-select-popper"
+					v-model="searchParams.deviceType" placeholder="请选择" clearable @change="handleSearch">
+					<el-option v-for="item in dictObj.deviceType" :key="item.dictKey" :label="item.dictValue"
+						:value="item.dictKey" />
+				</el-select>
+			</el-form-item>
+
+			<el-form-item label="部门" prop="belongDept">
+				<el-tree-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-tree-select-popper"
+					v-model="searchParams.belongDept" :data="deptTree" :props="treeProps" node-key="id" check-strictly
+					clearable @change="handleSearch" />
+			</el-form-item>
+
+			<el-form-item class="history-search-actions">
+				<el-button :icon="RefreshRight" @click="resetForm"></el-button>
+				<el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+			</el-form-item>
 		</el-form>
-		<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
-			<el-table-column type="selection" width="55" />
-			<el-table-column type="index" width="60" label="序号" />
-			<el-table-column prop="deviceName" label="设备名称" />
-			<el-table-column prop="deviceType" label="设备类型">
-				<template v-slot="{ row }">
-					{{ getDictLabel(row.deviceType, dictObj.deviceType) }}
-				</template>
-			</el-table-column>
-			<el-table-column prop="deviceModel" label="型号" />
-			<el-table-column prop="manufacturer" label="生产厂商" />
-			<el-table-column prop="createTime" label="入库时间" />
-			<el-table-column prop="source" label="来源" />
-			<el-table-column prop="charger" label="负责人" />
-			<el-table-column prop="scrapTime" label="报废时间" />
-			<el-table-column prop="scrapReason" label="报废原因" />
-			<el-table-column prop="disposeWay" label="处置方式" />
-			<el-table-column prop="maintainReminder" label="维护提醒" />
-			<el-table-column label="操作">
-				<template v-slot="{ row }">
-					<el-link @click="handleView(row)" type="primary">查看</el-link>
-				</template>
-			</el-table-column>
-		</el-table>
-		<div>
-			<el-pagination
-				v-model:current-page="searchParams.current"
-				v-model:page-size="searchParams.size"
-				:total="total"
-				@change="getList"
-			/>
+
+		<div class="ztzf-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
+			<div class="ztzf-table-content ztzf-table-content-bg">
+				<el-table class="ztzf-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
+					<el-table-column type="selection" width="46" />
+					<el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
+					<el-table-column prop="deviceName" show-overflow-tooltip width="130" label="设备名称" />
+					<el-table-column prop="deviceType" show-overflow-tooltip width="130" label="设备类型">
+						<template v-slot="{ row }">
+							{{ getDictLabel(row.deviceType, dictObj.deviceType) }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="deviceModel" show-overflow-tooltip width="98" label="型号" />
+					<el-table-column prop="manufacturer" show-overflow-tooltip width="130" label="生产厂商" />
+					<el-table-column prop="createTime" show-overflow-tooltip width="96" label="入库时间" />
+					<el-table-column prop="source" show-overflow-tooltip width="112" label="来源" />
+					<el-table-column prop="charger" show-overflow-tooltip width="100" label="负责人" />
+					<el-table-column prop="scrapTime" show-overflow-tooltip width="96" label="报废时间" />
+					<el-table-column prop="scrapReason" show-overflow-tooltip width="136" label="报废原因" />
+					<el-table-column prop="disposeWay" show-overflow-tooltip width="116" label="处置方式" />
+					<el-table-column prop="maintainReminder" show-overflow-tooltip width="116" label="维护提醒" />
+					<el-table-column label="操作" class-name="operation-btns">
+						<template v-slot="{ row }">
+							<el-link @click="handleView(row)">查看</el-link>
+						</template>
+					</el-table-column>
+				</el-table>
+			</div>
+
+			<div class="ztzf-table-pagination">
+				<el-pagination popper-class="ztzf-data-cockpit-select-popper"
+					v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
+					layout="total, prev, pager, next, sizes" :total="total" @change="getList" />
+			</div>
 		</div>
+
 		<FormDiaLog ref="dialogRef" @success="getList" />
 		<MaintenanceDiaLog ref="maintenanceDialogRef" @success="getList" />
 	</basic-container>
 </template>
 <script setup>
+import { Search, RefreshRight } from '@element-plus/icons-vue'
 import { onMounted, ref } from 'vue'
 import { getDictionaryByCode } from '@/api/system/dictbiz'
 import { getDeptTree } from '@/api/system/dept'
@@ -101,11 +91,11 @@
 const dialogRef = ref(null) // 弹框实例
 const maintenanceDialogRef = ref(null) // 弹框实例
 const dictObj = ref({
-	deviceType: [], //设备类型
-	deviceAtt: [], //设备属性
+	deviceType: [], // 设备类型
+	deviceAtt: [], // 设备属性
 })
 provide('dictObj', dictObj)
-const deptTree = ref([]) //部门树
+const deptTree = ref([]) // 部门树
 const treeProps = {
 	label: 'name',
 	children: 'children',
@@ -118,7 +108,7 @@
 provide('planCycleOptions', planCycleOptions)
 
 // 获取列表
-async function getList() {
+async function getList () {
 	loading.value = true
 	try {
 		const res = await fwDeviceScrapPageApi(searchParams.value)
@@ -130,48 +120,48 @@
 }
 
 // 查询
-function handleSearch() {
+function handleSearch () {
 	searchParams.value.current = 1
 	getList()
 }
 
 // 重置查询
-function resetForm() {
+function resetForm () {
 	queryParamsRef.value?.resetFields()
 	searchParams.value.current = 1
 	getList()
 }
 
 // 查看
-function handleView(row) {
+function handleView (row) {
 	dialogRef.value?.open({ mode: 'view', row: { ...row } })
 }
 
 // 勾选值设置
-function handleSelectionChange(rows) {
+function handleSelectionChange (rows) {
 	selectedIds.value = rows.map(item => item.id)
 }
 
 // 获取字典
-function getDictList() {
+function getDictList () {
 	getDictionaryByCode('deviceType,deviceAtt').then(res => {
 		dictObj.value = res.data.data
 	})
 }
 
 // 获取部门树
-function getDeptTreeFun() {
+function getDeptTreeFun () {
 	getDeptTree().then(res => {
 		deptTree.value = res.data.data
 	})
 }
 
 // 新增
-function handleAdd() {
+function handleAdd () {
 	dialogRef.value?.open({ mode: 'add' })
 }
 
-function getPlanCycleLabel(row) {
+function getPlanCycleLabel (row) {
 	const item = planCycleOptions.find(option => option.value === row.planCycleType)
 	return item?.label + '-' + row.planCycleValue.join(',')
 }
diff --git a/applications/drone-command/src/views/basicManage/deviceStock/index.vue b/applications/drone-command/src/views/basicManage/deviceStock/index.vue
index e3c5c44..b504d5c 100644
--- a/applications/drone-command/src/views/basicManage/deviceStock/index.vue
+++ b/applications/drone-command/src/views/basicManage/deviceStock/index.vue
@@ -1,104 +1,89 @@
 <template>
 	<basic-container>
-		<el-form ref="queryParamsRef" :model="searchParams">
-			<el-row :gutter="16">
-				<el-col :span="4">
-					<el-form-item label="名称" prop="deviceName">
-						<el-input v-model="searchParams.deviceName" placeholder="请输入" clearable @clear="handleSearch" />
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<el-form-item label="类型" prop="deviceType">
-						<el-select v-model="searchParams.deviceType" placeholder="请选择" clearable @change="handleSearch">
-							<el-option
-								v-for="item in dictObj.deviceType"
-								:key="item.dictKey"
-								:label="item.dictValue"
-								:value="item.dictKey"
-							/>
-						</el-select>
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<el-form-item label="部门" prop="belongDept">
-						<el-tree-select
-							v-model="searchParams.belongDept"
-							:data="deptTree"
-							:props="treeProps"
-							node-key="id"
-							check-strictly
-							clearable
-							@change="handleSearch"
-						/>
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<el-form-item label="时间">
-						<el-date-picker
-							popper-class="ztzf-date-picker-popper"
-							class="ztzf-date-picker"
-							v-model="dateRange"
-							type="daterange"
-							range-separator="至"
-							start-placeholder="开始日期"
-							end-placeholder="结束日期"
-							value-format="YYYY-MM-DD HH:mm:ss"
-							@change="handleSearch"
-						/>
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<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 ref="queryParamsRef" :model="searchParams" class="ztzf-page-history-search">
+			<el-form-item label="名称" prop="deviceName">
+				<el-input class="ztzf-data-cockpit-search-input" v-model="searchParams.deviceName" placeholder="请输入"
+					clearable @clear="handleSearch" />
+			</el-form-item>
+
+			<el-form-item label="类型" prop="deviceType">
+				<el-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-select-popper"
+					v-model="searchParams.deviceType" placeholder="请选择" clearable @change="handleSearch">
+					<el-option v-for="item in dictObj.deviceType" :key="item.dictKey" :label="item.dictValue"
+						:value="item.dictKey" />
+				</el-select>
+			</el-form-item>
+
+			<el-form-item label="部门" prop="belongDept">
+				<el-tree-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-tree-select-popper"
+					v-model="searchParams.belongDept" :data="deptTree" :props="treeProps" node-key="id" check-strictly
+					clearable @change="handleSearch" />
+			</el-form-item>
+
+			<el-form-item label="时间">
+				<el-date-picker popper-class="ztzf-data-cockpit-date-picker-popper"
+					class="ztzf-data-cockpit-date-picker" v-model="dateRange" type="daterange" range-separator="至"
+					start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD HH:mm:ss"
+					@change="handleSearch" />
+			</el-form-item>
+
+			<el-form-item class="history-search-actions">
+				<el-button :icon="RefreshRight" @click="resetForm"></el-button>
+				<el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+			</el-form-item>
 		</el-form>
-		<div>
-			<el-button type="primary" @click="handleAdd">新增</el-button>
-			<el-button type="primary" @click="exportFile" :loading="exportLoading">导出</el-button>
+
+		<div class="ztzf-table-toolbar">
+			<el-button :icon="Plus" color="#284FE3" type="primary" @click="handleAdd">新增</el-button>
+			<el-button :icon="Download" type="primary" @click="exportFile" :loading="exportLoading">导出</el-button>
 			<!--			<el-button type="danger" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button>-->
 		</div>
-		<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
-			<el-table-column type="selection" width="55" />
-			<el-table-column type="index" width="60" label="序号" />
-			<el-table-column prop="deviceName" label="设备名称" />
-			<el-table-column prop="deviceType" label="类型">
-				<template v-slot="{ row }">
-					{{ getDictLabel(row.deviceType, dictObj.deviceType) }}
-				</template>
-			</el-table-column>
-			<el-table-column prop="deviceModel" label="型号" />
-			<el-table-column prop="deviceSpecification" label="规格" />
-			<el-table-column prop="manufacturer" label="生产厂商" />
-			<el-table-column prop="createTime" label="入库时间" />
-			<el-table-column prop="source" label="来源" />
-			<el-table-column prop="purpose" label="用途" />
-			<el-table-column prop="belongDeptName" label="所属部门" />
-			<el-table-column prop="charger" label="负责人" />
-			<el-table-column prop="yxzt" label="运行状态">
-				<template v-slot="{ row }">
-					{{ DEVICE_STATUS[row.status] || '-' }}
-				</template>
-			</el-table-column>
-			<el-table-column label="操作">
-				<template v-slot="{ row }">
-					<el-link @click="handleView(row)" type="primary">查看</el-link>
-					<el-link @click="handleEdit(row)" type="warning">编辑</el-link>
-					<el-link @click="outbound(row)" type="warning">出库</el-link>
-					<el-link @click="scrap(row)" type="warning" v-if="row.status !== 3">报废</el-link>
-					<!--					<el-link @click="handleDelete(row)" type="danger">删除</el-link>-->
-				</template>
-			</el-table-column>
-		</el-table>
-		<div>
-			<el-pagination
-				v-model:current-page="searchParams.current"
-				v-model:page-size="searchParams.size"
-				:total="total"
-				@change="getList"
-			/>
+
+		<div class="ztzf-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
+			<div class="ztzf-table-content ztzf-table-content-bg">
+				<el-table class="ztzf-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
+					<el-table-column type="selection" width="46" />
+					<el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
+					<el-table-column prop="deviceName" show-overflow-tooltip width="130" label="设备名称" />
+					<el-table-column prop="deviceType" show-overflow-tooltip width="130" label="类型">
+						<template v-slot="{ row }">
+							{{ getDictLabel(row.deviceType, dictObj.deviceType) }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="deviceModel" show-overflow-tooltip width="98" label="型号" />
+					<el-table-column prop="deviceSpecification" show-overflow-tooltip width="112" label="规格" />
+					<el-table-column prop="manufacturer" show-overflow-tooltip width="130" label="生产厂商" />
+					<el-table-column prop="createTime" show-overflow-tooltip width="96" label="入库时间">
+						<template v-slot="{ row }">
+							{{ formatDateToSlash(row.createTime) }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="source" show-overflow-tooltip width="112" label="来源" />
+					<el-table-column prop="purpose" show-overflow-tooltip width="206" label="用途" />
+					<el-table-column prop="belongDeptName" show-overflow-tooltip width="124" label="所属部门" />
+					<el-table-column prop="charger" show-overflow-tooltip width="100" label="负责人" />
+					<el-table-column prop="yxzt" show-overflow-tooltip width="116" label="运行状态">
+						<template v-slot="{ row }">
+							{{ DEVICE_STATUS[row.status] || '-' }}
+						</template>
+					</el-table-column>
+					<el-table-column label="操作" class-name="operation-btns">
+						<template v-slot="{ row }">
+							<el-link @click="handleView(row)">查看</el-link>
+							<el-link @click="handleEdit(row)">编辑</el-link>
+							<el-link @click="outbound(row)">出库</el-link>
+							<el-link @click="scrap(row)" v-if="row.status !== 3">报废</el-link>
+							<!--					<el-link @click="handleDelete(row)" type="danger">删除</el-link>-->
+						</template>
+					</el-table-column>
+				</el-table>
+			</div>
+
+			<div class="ztzf-table-pagination">
+				<el-pagination popper-class="ztzf-data-cockpit-select-popper"
+					v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
+					layout="total, prev, pager, next, sizes" :total="total" @change="getList" />
+			</div>
 		</div>
 
 		<FormDiaLog ref="dialogRef" @success="getList" />
@@ -108,13 +93,14 @@
 </template>
 
 <script setup>
+import { Search, RefreshRight, Plus, Download } from '@element-plus/icons-vue'
 import { onMounted, ref } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { exportFwDeviceApi, fwDevicePageApi, fwDeviceRemoveApi } from '@/views/basicManage/deviceStock/fwDevice'
 import FormDiaLog from './FormDiaLog.vue'
 import { getDictionaryByCode } from '@/api/system/dictbiz'
 import { getDeptTree } from '@/api/system/dept'
-import { blobDownload, dateRangeFormat, getDictLabel } from '@ztzf/utils'
+import { blobDownload, dateRangeFormat, getDictLabel, formatDateToSlash } from '@ztzf/utils'
 import { DEVICE_STATUS } from '@ztzf/constants'
 import DeviceTrackDiaLog from '@/views/basicManage/deviceStock/DeviceTrackDiaLog.vue'
 import DeviceScrapDiaLog from '@/views/basicManage/deviceStock/DeviceScrapDiaLog.vue'
@@ -150,7 +136,7 @@
 provide('deptTree', deptTree)
 
 // 获取列表
-async function getList() {
+async function getList () {
 	const range = dateRangeFormat(dateRange.value)
 	loading.value = true
 	try {
@@ -164,13 +150,13 @@
 }
 
 // 查询
-function handleSearch() {
+function handleSearch () {
 	searchParams.value.current = 1
 	getList()
 }
 
 // 重置查询
-function resetForm() {
+function resetForm () {
 	dateRange.value = []
 	queryParamsRef.value?.resetFields()
 	searchParams.value.current = 1
@@ -178,25 +164,25 @@
 }
 
 // 查看
-function handleView(row) {
+function handleView (row) {
 	dialogRef.value?.open({ mode: 'view', row: { ...row } })
 }
 
 // 编辑
-function handleEdit(row) {
+function handleEdit (row) {
 	dialogRef.value?.open({ mode: 'edit', row: { ...row } })
 }
 
-function outbound(row) {
+function outbound (row) {
 	outboundDialogRef.value?.open({ mode: 'edit', row: { ...row } })
 }
 
-function scrap(row) {
+function scrap (row) {
 	scrapDialogRef.value?.open({ mode: 'edit', row: { ...row } })
 }
 
 // 删除
-async function handleDelete(row) {
+async function handleDelete (row) {
 	const tips = row ? '该条' : '选中的项'
 	await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', { type: 'warning' })
 	const ids = row ? row.id : selectedIds.value.join(',')
@@ -207,11 +193,11 @@
 }
 
 // 勾选值设置
-function handleSelectionChange(rows) {
+function handleSelectionChange (rows) {
 	selectedIds.value = rows.map(item => item.id)
 }
 
-function exportFile() {
+function exportFile () {
 	exportLoading.value = true
 	exportFwDeviceApi()
 		.then(res => {
@@ -223,21 +209,21 @@
 }
 
 // 获取字典
-function getDictList() {
+function getDictList () {
 	getDictionaryByCode('deviceType,deviceAtt').then(res => {
 		dictObj.value = res.data.data
 	})
 }
 
 // 获取部门树
-function getDeptTreeFun() {
+function getDeptTreeFun () {
 	getDeptTree().then(res => {
 		deptTree.value = res.data.data
 	})
 }
 
 // 新增
-function handleAdd() {
+function handleAdd () {
 	dialogRef.value?.open({ mode: 'add' })
 }
 
diff --git a/applications/drone-command/src/views/basicManage/maintainRecord/index.vue b/applications/drone-command/src/views/basicManage/maintainRecord/index.vue
index 3441515..562c968 100644
--- a/applications/drone-command/src/views/basicManage/maintainRecord/index.vue
+++ b/applications/drone-command/src/views/basicManage/maintainRecord/index.vue
@@ -1,88 +1,79 @@
 <template>
 	<basic-container>
-		<el-form ref="queryParamsRef" :model="searchParams">
-			<el-row :gutter="16">
-				<el-col :span="4">
-					<el-form-item label="设备名称" prop="deviceName">
-						<el-input v-model="searchParams.deviceName" placeholder="请输入" clearable @clear="handleSearch" />
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<el-form-item label="设备类型" prop="deviceType">
-						<el-select v-model="searchParams.deviceType" placeholder="请选择" clearable @change="handleSearch">
-							<el-option
-								v-for="item in dictObj.deviceType"
-								:key="item.dictKey"
-								:label="item.dictValue"
-								:value="item.dictKey"
-							/>
-						</el-select>
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<el-form-item label="所属部门" prop="belongDept">
-						<el-tree-select
-							v-model="searchParams.belongDept"
-							:data="deptTree"
-							:props="treeProps"
-							node-key="id"
-							check-strictly
-							clearable
-							@change="handleSearch"
-						/>
-					</el-form-item>
-				</el-col>
-				<el-col :span="4">
-					<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 ref="queryParamsRef" :model="searchParams" class="ztzf-page-history-search">
+			<el-form-item label="名称" prop="deviceName">
+				<el-input class="ztzf-data-cockpit-search-input" v-model="searchParams.deviceName" placeholder="请输入"
+					clearable @clear="handleSearch" />
+			</el-form-item>
+
+			<el-form-item label="类型" prop="deviceType">
+				<el-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-select-popper"
+					v-model="searchParams.deviceType" placeholder="请选择" clearable @change="handleSearch">
+					<el-option v-for="item in dictObj.deviceType" :key="item.dictKey" :label="item.dictValue"
+						:value="item.dictKey" />
+				</el-select>
+			</el-form-item>
+
+			<el-form-item label="部门" prop="belongDept">
+				<el-tree-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-tree-select-popper"
+					v-model="searchParams.belongDept" :data="deptTree" :props="treeProps" node-key="id" check-strictly
+					clearable @change="handleSearch" />
+			</el-form-item>
+
+			<el-form-item class="history-search-actions">
+				<el-button :icon="RefreshRight" @click="resetForm"></el-button>
+				<el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+			</el-form-item>
 		</el-form>
-		<div>
-			<el-button type="primary" @click="handleAdd">维护计划</el-button>
+
+		<div class="ztzf-table-toolbar">
+			<el-button :icon="Plus" color="#284FE3" type="primary" @click="handleAdd">维护计划</el-button>
 			<el-button type="danger" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button>
 		</div>
-		<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
-			<el-table-column type="selection" width="55" />
-			<el-table-column type="index" width="60" label="序号" />
-			<el-table-column prop="deviceName" label="设备名称" />
-			<el-table-column prop="deviceType" label="设备类型">
-				<template v-slot="{ row }">
-					{{ getDictLabel(row.deviceType, dictObj.deviceType) }}
-				</template>
-			</el-table-column>
-			<el-table-column prop="deviceModel" label="型号" />
-			<el-table-column prop="manufacturer" label="生产厂商" />
-			<el-table-column prop="charger" label="负责人" />
-			<el-table-column prop="maintainReminder" label="维护提醒" />
-			<el-table-column prop="planCycleType" label="维护计划">
-				<template v-slot="{ row }">
-					{{ getPlanCycleLabel(row) }}
-				</template>
-			</el-table-column>
-			<el-table-column label="操作">
-				<template v-slot="{ row }">
-					<el-link @click="handleView(row)" type="primary">查看</el-link>
-					<el-link @click="maintenance(row)" type="warning">维护</el-link>
-					<el-link @click="handleDelete(row)" type="danger">删除</el-link>
-				</template>
-			</el-table-column>
-		</el-table>
-		<div>
-			<el-pagination
-				v-model:current-page="searchParams.current"
-				v-model:page-size="searchParams.size"
-				:total="total"
-				@change="getList"
-			/>
+
+		<div class="ztzf-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
+			<div class="ztzf-table-content ztzf-table-content-bg">
+				<el-table class="ztzf-data-cockpit-table" :data="list" @selection-change="handleSelectionChange">
+					<el-table-column type="selection" width="46" />
+					<el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
+					<el-table-column prop="deviceName" show-overflow-tooltip width="130" label="设备名称" />
+					<el-table-column prop="deviceType" show-overflow-tooltip width="130" label="设备类型">
+						<template v-slot="{ row }">
+							{{ getDictLabel(row.deviceType, dictObj.deviceType) }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="deviceModel" show-overflow-tooltip width="98" label="型号" />
+					<el-table-column prop="manufacturer" show-overflow-tooltip width="130" label="生产厂商" />
+					<el-table-column prop="charger" show-overflow-tooltip width="100" label="负责人" />
+					<el-table-column prop="maintainReminder" show-overflow-tooltip width="116" label="维护提醒" />
+					<el-table-column prop="planCycleType" show-overflow-tooltip width="160" label="维护计划">
+						<template v-slot="{ row }">
+							{{ getPlanCycleLabel(row) }}
+						</template>
+					</el-table-column>
+					<el-table-column label="操作" class-name="operation-btns">
+						<template v-slot="{ row }">
+							<el-link @click="handleView(row)">查看</el-link>
+							<el-link @click="maintenance(row)">维护</el-link>
+							<el-link @click="handleDelete(row)">删除</el-link>
+						</template>
+					</el-table-column>
+				</el-table>
+			</div>
+
+			<div class="ztzf-table-pagination">
+				<el-pagination popper-class="ztzf-data-cockpit-select-popper"
+					v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
+					layout="total, prev, pager, next, sizes" :total="total" @change="getList" />
+			</div>
 		</div>
+
 		<FormDiaLog ref="dialogRef" @success="getList" />
 		<MaintenanceDiaLog ref="maintenanceDialogRef" @success="getList" />
 	</basic-container>
 </template>
 <script setup>
+import { Search, RefreshRight, Plus } from '@element-plus/icons-vue'
 import { onMounted, ref } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { getDictionaryByCode } from '@/api/system/dictbiz'
@@ -111,11 +102,11 @@
 const dialogRef = ref(null) // 弹框实例
 const maintenanceDialogRef = ref(null) // 弹框实例
 const dictObj = ref({
-	deviceType: [], //设备类型
-	deviceAtt: [], //设备属性
+	deviceType: [], // 设备类型
+	deviceAtt: [], // 设备属性
 })
 provide('dictObj', dictObj)
-const deptTree = ref([]) //部门树
+const deptTree = ref([]) // 部门树
 const treeProps = {
 	label: 'name',
 	children: 'children',
@@ -128,7 +119,7 @@
 provide('planCycleOptions', planCycleOptions)
 
 // 获取列表
-async function getList() {
+async function getList () {
 	loading.value = true
 	try {
 		const res = await fwDeviceMaintainPlanPageApi(searchParams.value)
@@ -140,30 +131,30 @@
 }
 
 // 查询
-function handleSearch() {
+function handleSearch () {
 	searchParams.value.current = 1
 	getList()
 }
 
 // 重置查询
-function resetForm() {
+function resetForm () {
 	queryParamsRef.value?.resetFields()
 	searchParams.value.current = 1
 	getList()
 }
 
 // 查看
-function handleView(row) {
+function handleView (row) {
 	dialogRef.value?.open({ mode: 'view', row: { ...row } })
 }
 
 // 维护
-function maintenance(row) {
+function maintenance (row) {
 	maintenanceDialogRef.value?.open({ mode: 'edit', row: { ...row } })
 }
 
 // 删除
-async function handleDelete(row) {
+async function handleDelete (row) {
 	const tips = row ? '该条' : '选中的项'
 	await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', { type: 'warning' })
 	const ids = row ? row.id : selectedIds.value.join(',')
@@ -174,30 +165,30 @@
 }
 
 // 勾选值设置
-function handleSelectionChange(rows) {
+function handleSelectionChange (rows) {
 	selectedIds.value = rows.map(item => item.id)
 }
 
 // 获取字典
-function getDictList() {
+function getDictList () {
 	getDictionaryByCode('deviceType,deviceAtt').then(res => {
 		dictObj.value = res.data.data
 	})
 }
 
 // 获取部门树
-function getDeptTreeFun() {
+function getDeptTreeFun () {
 	getDeptTree().then(res => {
 		deptTree.value = res.data.data
 	})
 }
 
 // 新增
-function handleAdd() {
+function handleAdd () {
 	dialogRef.value?.open({ mode: 'add' })
 }
 
-function getPlanCycleLabel(row) {
+function getPlanCycleLabel (row) {
 	const item = planCycleOptions.find(option => option.value === row.planCycleType)
 	return item?.label + '-' + row.planCycleValue.join(',')
 }
diff --git a/applications/drone-command/src/views/dataCockpit/components/DeviceHistoryDialog.vue b/applications/drone-command/src/views/dataCockpit/components/DeviceHistoryDialog.vue
index 1ac9a90..836cb79 100644
--- a/applications/drone-command/src/views/dataCockpit/components/DeviceHistoryDialog.vue
+++ b/applications/drone-command/src/views/dataCockpit/components/DeviceHistoryDialog.vue
@@ -1,7 +1,7 @@
 <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">
-		<el-form ref="queryParamsRef" :model="searchParams" class="history-search">
+		<el-form ref="queryParamsRef" :model="searchParams" class="ztzf-dialog-history-search">
 			<el-row :gutter="12">
 				<el-col :span="4">
 					<el-form-item label="关键字" prop="keyword">
@@ -19,8 +19,9 @@
 				</el-col>
 				<el-col :span="4">
 					<el-form-item label="区域" prop="area">
-						<el-tree-select  class="ztzf-data-cockpit-select" popper-class="ztzf-tree-cockpit-select-popper" v-model="searchParams.area" :data="areaTree" :props="areaTreeProps"
-							node-key="value" check-strictly clearable placeholder="请选择" @change="handleSearch" />
+						<el-tree-select class="ztzf-data-cockpit-select" popper-class="ztzf-tree-cockpit-select-popper"
+							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">
@@ -32,17 +33,16 @@
 						</el-select>
 					</el-form-item>
 				</el-col>
-				<el-col :span="6" class="history-search-actions">
-					<el-form-item>
-						<el-button :icon="RefreshRight" @click="resetForm"></el-button>
-						<el-button :icon="Search" @click="handleSearch"></el-button>
-					</el-form-item>
-				</el-col>
+
+				<el-form-item class="history-search-actions">
+					<el-button :icon="RefreshRight" @click="resetForm"></el-button>
+					<el-button :icon="Search" @click="handleSearch"></el-button>
+				</el-form-item>
 			</el-row>
 		</el-form>
 
-		<div class="table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
-			<div class="table-content">
+		<div class="ztzf-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
+			<div class="ztzf-table-content">
 				<el-table class="ztzf-data-cockpit-table" :data="list">
 					<el-table-column type="index" width="60" label="序号" />
 					<el-table-column prop="droneName" label="无人机名称" min-width="120" />
@@ -68,11 +68,11 @@
 					</el-table-column>
 				</el-table>
 			</div>
-			
-			<div class="table-pagination">
-				<el-pagination popper-class="ztzf-data-cockpit-select-popper" v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
-					layout="total, prev, pager, next, sizes"
-					:total="total" @change="getList" />
+
+			<div class="ztzf-table-pagination">
+				<el-pagination popper-class="ztzf-data-cockpit-select-popper"
+					v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
+					layout="total, prev, pager, next, sizes" :total="total" @change="getList" />
 			</div>
 		</div>
 	</el-dialog>
diff --git a/applications/drone-command/src/views/dataCockpit/index.vue b/applications/drone-command/src/views/dataCockpit/index.vue
index 5226ea0..137328a 100644
--- a/applications/drone-command/src/views/dataCockpit/index.vue
+++ b/applications/drone-command/src/views/dataCockpit/index.vue
@@ -10,7 +10,11 @@
 -->
 <template>
   <div class="page-container">
-    <MapContainer :online-devices="onlineDevices" :left-collapsed="leftCollapsed" />  
+    <DeviceMapContainer
+      :online-devices="onlineDevices"
+      :left-collapsed="leftCollapsed"
+      container-id="data-cockpit-map"
+    />  
     <LeftContainer class="left-container" v-model:activeId="leftActiveId" v-model:collapsed="leftCollapsed" />  
     <RightContainer class="right-container" v-model:collapsed="rightCollapsed" v-model:onlineDevices="onlineDevices" />  
     <CenterContainer @select-warning="onSelectWarning" @select-equipment="onSelectEquipment" />  
@@ -18,7 +22,7 @@
 </template>
 
 <script setup>
-  import MapContainer from './components/MapContainer.vue';
+  import DeviceMapContainer from '@/components/map-container/device-map-container.vue';
   import LeftContainer from './components/LeftContainer.vue';
   import RightContainer from './components/RightContainer.vue';
   import CenterContainer from './components/CenterContainer.vue';
diff --git a/applications/drone-command/src/views/detectionCountermeasure/components/DetectionRangeDialog.vue b/applications/drone-command/src/views/detectionCountermeasure/components/DetectionRangeDialog.vue
new file mode 100644
index 0000000..071ad9f
--- /dev/null
+++ b/applications/drone-command/src/views/detectionCountermeasure/components/DetectionRangeDialog.vue
@@ -0,0 +1,348 @@
+<template>
+	<el-dialog
+		v-model="visible"
+		:title="dialogTitle"
+		class="detection-range-dialog"
+		destroy-on-close
+		@closed="handleClosed"
+	>
+		<div class="dialog-body">
+			<div class="dialog-map">
+				<DeviceMapContainer
+					:online-devices="mapDevices"
+					:show-layer-control="false"
+					container-id="detection-range-map"
+				/>
+				<div class="map-toolbar">
+					<button class="map-btn" type="button" aria-label="编辑范围"></button>
+					<button class="map-btn" type="button" aria-label="定位设备"></button>
+				</div>
+				<div class="map-mini-controls">
+					<button class="map-mini-btn" type="button" aria-label="放大">+</button>
+					<button class="map-mini-btn" type="button" aria-label="缩小">-</button>
+				</div>
+			</div>
+			<div class="dialog-form">
+				<div class="form-title">{{ formTitle }}</div>
+				<el-form
+					ref="formRef"
+					:model="formData"
+					:rules="rules"
+					label-width="84px"
+					:disabled="dialogReadonly"
+				>
+					<el-form-item label="侦测设备" prop="deviceId">
+						<el-select v-model="formData.deviceId" placeholder="请选择" clearable @change="handleDeviceChange">
+							<el-option
+								v-for="item in deviceOptions"
+								:key="item.value"
+								:label="item.label"
+								:value="item.value"
+							/>
+						</el-select>
+					</el-form-item>
+					<el-form-item label="设备类型" prop="deviceType">
+						<el-select v-model="formData.deviceType" placeholder="请选择" clearable>
+							<el-option
+								v-for="item in dictObj.deviceType"
+								:key="item.dictKey"
+								:label="item.dictValue"
+								:value="item.dictKey"
+							/>
+						</el-select>
+					</el-form-item>
+					<el-form-item label="设备位置" prop="deployLocation">
+						<el-input v-model="formData.deployLocation" placeholder="请选择位置">
+							<template #suffix>
+								<span class="suffix-action">地图选点</span>
+							</template>
+						</el-input>
+					</el-form-item>
+					<el-form-item label="设备编号" prop="deviceCode">
+						<el-input v-model="formData.deviceCode" placeholder="请输入" clearable />
+					</el-form-item>
+					<el-form-item label="设备型号" prop="deviceModel">
+						<el-input v-model="formData.deviceModel" placeholder="请输入" clearable />
+					</el-form-item>
+					<el-form-item label="覆盖范围" prop="effectiveRangeKm">
+						<el-input-number
+							v-model="formData.effectiveRangeKm"
+							:min="0"
+							:precision="2"
+							:controls="false"
+							placeholder="请输入"
+						/>
+					</el-form-item>
+				</el-form>
+			</div>
+		</div>
+		<template v-if="!dialogReadonly" #footer>
+			<el-button @click="handleCancel">取消</el-button>
+			<el-button
+				type="primary"
+				:loading="submitting"
+				:disabled="submitting"
+				@click="handleSubmit"
+			>
+				保存
+			</el-button>
+		</template>
+	</el-dialog>
+</template>
+
+<script setup>
+import { computed, inject, ref } from 'vue'
+import { ElMessage } from 'element-plus'
+import DeviceMapContainer from '@/components/map-container/device-map-container.vue'
+import {
+	detectionRangeDetailApi,
+	detectionRangePageApi,
+	detectionRangeSubmitApi,
+} from '@/api/detectionCountermeasure/detectionRange'
+
+const initForm = () => ({
+	deviceId: '', // 侦测设备ID
+	deviceName: '', // 侦测设备
+	deviceType: '', // 设备类型
+	deployLocation: '', // 设备位置
+	deviceCode: '', // 设备编号
+	deviceModel: '', // 设备型号
+	effectiveRangeKm: null, // 覆盖范围
+})
+
+const dictObj = inject('dictObj')
+const emit = defineEmits(['success'])
+const formRef = ref(null) // 表单实例
+const formData = ref(initForm()) // 表单数据
+const visible = ref(false) // 弹框显隐
+const dialogMode = ref('add') // 弹框模式
+const submitting = ref(false) // 提交中
+const mapDevices = ref([])
+const deviceOptions = ref([])
+const dialogReadonly = computed(() => dialogMode.value === 'view')
+const dialogTitle = computed(() => {
+	if (dialogMode.value === 'edit') {
+		return '编辑'
+	} else if (dialogMode.value === 'view') {
+		return '查看'
+	}
+	return '新增'
+})
+const formTitle = computed(() => {
+	if (dialogMode.value === 'edit') {
+		return '编辑侦测范围'
+	}
+	if (dialogMode.value === 'view') {
+		return '查看侦测范围'
+	}
+	return '新增侦测范围'
+})
+
+const rules = {
+	deviceId: [{ required: true, message: '请选择侦测设备', trigger: ['blur', 'change'] }],
+	deviceType: [{ required: true, message: '请选择设备类型', trigger: ['blur', 'change'] }],
+	effectiveRangeKm: [{ required: true, message: '请输入覆盖范围', trigger: ['blur', 'change'] }],
+}
+
+function handleDeviceChange(value) {
+	const target = deviceOptions.value.find(item => item.value === value)
+	const raw = target?.raw
+	if (!raw) return
+	formData.value.deviceId = raw.id ?? formData.value.deviceId
+	formData.value.deviceName = raw.deviceName ?? formData.value.deviceName
+	formData.value.deviceType = raw.deviceType ?? formData.value.deviceType
+	formData.value.deviceModel = raw.deviceModel ?? formData.value.deviceModel
+	formData.value.deviceCode =
+		raw.deviceCode ?? raw.deviceSn ?? raw.deviceNo ?? formData.value.deviceCode
+	formData.value.deployLocation =
+		raw.deployLocation ??
+		raw.address ??
+		raw.location ??
+		raw.deployAddress ??
+		formData.value.deployLocation
+}
+
+// 关闭弹框
+function handleCancel() {
+	visible.value = false
+}
+
+// 提交新增/编辑
+async function handleSubmit() {
+	const isValid = await formRef.value?.validate().catch(() => false)
+	if (!isValid) return
+	submitting.value = true
+	try {
+		const payload = {
+			...formData.value,
+			id: formData.value.id || formData.value.deviceId || undefined,
+			effectiveRangeKmIsNotNull: formData.value.effectiveRangeKm ? 1 : 2,
+		}
+		delete payload.deviceId
+		await detectionRangeSubmitApi(payload)
+		ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功')
+		visible.value = false
+		emit('success')
+	} finally {
+		submitting.value = false
+	}
+}
+
+// 加载详情
+async function loadDetail(id) {
+	if (!id) return null
+	const res = await detectionRangeDetailApi({ id })
+	return res?.data?.data ?? null
+}
+
+async function loadDeviceOptions() {
+	const res = await detectionRangePageApi({
+		current: 1,
+		size: 200,
+		effectiveRangeKmIsNotNull: 2,
+	})
+	const records = res?.data?.data?.records ?? []
+	deviceOptions.value = records.map(item => ({
+		label: item.deviceName ?? '-',
+		value: item.id ?? '',
+		raw: item,
+	}))
+}
+
+// 关闭后重置
+function handleClosed() {
+	formData.value = initForm()
+}
+
+// 打开弹框
+async function open({ mode, row } = {}) {
+	dialogMode.value = mode || 'add'
+	visible.value = true
+	if (dialogMode.value === 'add') {
+		await loadDeviceOptions()
+		formData.value = initForm()
+		return
+	}
+	formData.value = row
+	if (dialogMode.value !== 'add') {
+		const detail = await loadDetail(row?.id)
+		formData.value = detail ?? row
+	}
+	formData.value.deviceId = formData.value.id ?? formData.value.deviceId
+	await loadDeviceOptions()
+	const currentName = formData.value.deviceName
+	const currentId = formData.value.deviceId
+	if (currentId && !deviceOptions.value.some(item => item.value === currentId)) {
+		deviceOptions.value.unshift({ label: currentName || '-', value: currentId })
+	}
+}
+
+defineExpose({ open })
+</script>
+
+<style scoped lang="scss">
+.detection-range-dialog {
+	:deep(.el-dialog) {
+		width: 1100px;
+		background: #071833;
+		border-radius: 8px;
+	}
+
+	:deep(.el-dialog__header) {
+		border-bottom: 1px solid rgba(70, 110, 180, 0.35);
+	}
+}
+
+.dialog-body {
+	display: flex;
+	gap: 16px;
+	min-height: 560px;
+}
+
+.dialog-map {
+	position: relative;
+	flex: 1;
+	min-height: 520px;
+	border-radius: 8px;
+	overflow: hidden;
+	border: 1px solid rgba(70, 110, 180, 0.35);
+	background: #031024;
+}
+
+.map-toolbar {
+	position: absolute;
+	top: 16px;
+	right: 16px;
+	display: flex;
+	flex-direction: column;
+	gap: 8px;
+	z-index: 2;
+}
+
+.map-btn {
+	width: 34px;
+	height: 34px;
+	border-radius: 6px;
+	border: 1px solid rgba(80, 120, 180, 0.6);
+	background: rgba(7, 18, 44, 0.9);
+	cursor: pointer;
+}
+
+.map-mini-controls {
+	position: absolute;
+	left: 16px;
+	bottom: 16px;
+	display: flex;
+	flex-direction: column;
+	gap: 6px;
+	z-index: 2;
+}
+
+.map-mini-btn {
+	width: 28px;
+	height: 28px;
+	border-radius: 4px;
+	border: 1px solid rgba(80, 120, 180, 0.6);
+	background: rgba(7, 18, 44, 0.9);
+	color: #cfe3ff;
+	cursor: pointer;
+}
+
+.dialog-form {
+	width: 300px;
+	padding: 12px 12px 0;
+	border-radius: 8px;
+	background: linear-gradient(180deg, rgba(10, 28, 58, 0.95), rgba(6, 16, 34, 0.95));
+	border: 1px solid rgba(70, 110, 180, 0.35);
+	color: #d7e7ff;
+}
+
+.form-title {
+	font-size: 14px;
+	font-weight: 600;
+	margin-bottom: 12px;
+	letter-spacing: 1px;
+}
+
+:deep(.el-form-item__label) {
+	color: rgba(210, 230, 255, 0.85);
+}
+
+:deep(.el-input__wrapper),
+:deep(.el-select__wrapper),
+:deep(.el-input-number .el-input__wrapper) {
+	background: rgba(7, 20, 44, 0.85);
+	border: 1px solid rgba(80, 120, 190, 0.45);
+	box-shadow: none;
+}
+
+:deep(.el-input__inner) {
+	color: #d5e6ff;
+}
+
+.suffix-action {
+	font-size: 12px;
+	color: #7fb6ff;
+	cursor: pointer;
+}
+</style>
diff --git a/applications/drone-command/src/views/detectionCountermeasure/detectionRange.vue b/applications/drone-command/src/views/detectionCountermeasure/detectionRange.vue
index a9bcb54..d90fb99 100644
--- a/applications/drone-command/src/views/detectionCountermeasure/detectionRange.vue
+++ b/applications/drone-command/src/views/detectionCountermeasure/detectionRange.vue
@@ -1,9 +1,189 @@
 <template>
-  <basic-container>
-    侦测范围管理
-  </basic-container>
+	<basic-container>
+		<el-form ref="queryParamsRef" :model="searchParams" class="ztzf-page-history-search">
+			<el-form-item label="名称" prop="deviceName">
+				<el-input class="ztzf-data-cockpit-search-input" v-model="searchParams.deviceName" placeholder="请输入"
+					clearable @clear="handleSearch" />
+			</el-form-item>
+
+			<el-form-item label="类型" prop="deviceType">
+				<el-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-select-popper"
+					v-model="searchParams.deviceType" placeholder="请选择" clearable @change="handleSearch">
+					<el-option v-for="item in dictObj.deviceType" :key="item.dictKey" :label="item.dictValue"
+						:value="item.dictKey" />
+				</el-select>
+			</el-form-item>
+
+			<el-form-item class="history-search-actions">
+				<el-button :icon="RefreshRight" @click="resetForm"></el-button>
+				<el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+			</el-form-item>
+		</el-form>
+
+		<div class="ztzf-table-toolbar">
+			<el-button :icon="Plus" color="#284FE3" type="primary" @click="handleAdd">新增</el-button>
+		</div>
+
+		<div class="ztzf-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
+			<div class="ztzf-table-content ztzf-table-content-bg">
+				<el-table class="ztzf-data-cockpit-table" :data="list">
+					<el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
+					<el-table-column prop="deviceName" show-overflow-tooltip width="140" label="设备名称" />
+					<el-table-column prop="deviceType" show-overflow-tooltip width="120" label="设备类型">
+						<template v-slot="{ row }">
+							{{ getDictLabel(row.deviceType, dictObj.deviceType) }}
+						</template>
+					</el-table-column>
+					<el-table-column show-overflow-tooltip width="160" label="部署位置">
+						<template v-slot="{ row }">
+							{{ formatDeployLocation(row) }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="deviceModel" show-overflow-tooltip width="110" label="型号" />
+					<el-table-column show-overflow-tooltip width="120" label="覆盖范围">
+						<template v-slot="{ row }">
+							{{ formatRange(row) }}
+						</template>
+					</el-table-column>
+					<el-table-column show-overflow-tooltip width="150" label="设备编码">
+						<template v-slot="{ row }">
+							{{ formatDeviceCode(row) }}
+						</template>
+					</el-table-column>
+					<el-table-column label="操作" class-name="operation-btns">
+						<template v-slot="{ row }">
+							<el-link @click="handleView(row)">查看</el-link>
+							<el-link @click="handleEdit(row)">编辑</el-link>
+							<el-link @click="handleDelete(row)">删除</el-link>
+						</template>
+					</el-table-column>
+				</el-table>
+			</div>
+
+			<div class="ztzf-table-pagination">
+				<el-pagination popper-class="ztzf-data-cockpit-select-popper"
+					v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
+					layout="total, prev, pager, next, sizes" :total="total" @change="getList" />
+			</div>
+		</div>
+
+		<DetectionRangeDialog ref="dialogRef" @success="getList" />
+	</basic-container>
 </template>
 <script setup>
+import { Search, RefreshRight, Plus } from '@element-plus/icons-vue'
+import { onMounted, ref, provide } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { getDictionaryByCode } from '@/api/system/dictbiz'
+import { getDictLabel } from '@ztzf/utils'
+import { detectionRangePageApi, detectionRangeSubmitApi } from '@/api/detectionCountermeasure/detectionRange'
+import DetectionRangeDialog from './components/DetectionRangeDialog.vue'
+
+const initSearchParams = () => ({
+	deviceName: '', // 设备名称
+	deviceType: '', // 设备类型
+	effectiveRangeKmIsNotNull: 1, // 1-不为空
+	current: 1, // 当前页
+	size: 10, // 每页大小
+})
+const searchParams = ref(initSearchParams()) // 查询参数
+const loading = ref(false) // 列表加载中
+const list = ref([]) // 列表数据
+const total = ref(0) // 总数
+const queryParamsRef = ref(null) // 查询表单实例
+const dialogRef = ref(null) // 弹框实例
+const dictObj = ref({
+	deviceType: [], // 设备类型
+})
+
+provide('dictObj', dictObj)
+
+// 获取列表
+async function getList () {
+	loading.value = true
+	try {
+		const res = await detectionRangePageApi(searchParams.value)
+		list.value = res?.data?.data?.records ?? []
+		total.value = res?.data?.data?.total ?? 0
+	} finally {
+		loading.value = false
+	}
+}
+
+// 查询
+function handleSearch () {
+	searchParams.value.current = 1
+	getList()
+}
+
+// 重置查询
+function resetForm () {
+	queryParamsRef.value?.resetFields()
+	searchParams.value.current = 1
+	getList()
+}
+
+// 新增
+function handleAdd () {
+	dialogRef.value?.open({ mode: 'add' })
+}
+
+// 查看
+function handleView (row) {
+	dialogRef.value?.open({ mode: 'view', row: { ...row } })
+}
+
+// 编辑
+function handleEdit (row) {
+	dialogRef.value?.open({ mode: 'edit', row: { ...row } })
+}
+
+// 删除
+async function handleDelete (row) {
+	await ElMessageBox.confirm('确认删除该条数据吗?', '提示', { type: 'warning' })
+	await detectionRangeSubmitApi({ id: row.id, effectiveRangeKm: 0 })
+	ElMessage.success('删除成功')
+	getList()
+}
+
+// 获取字典
+function getDictList () {
+	getDictionaryByCode('deviceType').then(res => {
+		dictObj.value = res.data.data
+	})
+}
+
+function formatDeployLocation (row) {
+	if (!row) return '-'
+	const location = row.deployLocation ?? row.address ?? row.location ?? row.deployAddress
+	if (Array.isArray(location) && location.length) {
+		return location.filter(value => value !== null && value !== undefined).join(',')
+	}
+	if (typeof location === 'string' && location.trim()) {
+		return location
+	}
+	const longitude = row.deployLongitude ?? row.longitude
+	const latitude = row.deployLatitude ?? row.latitude
+	if (longitude != null || latitude != null) {
+		return `${longitude ?? '-'},${latitude ?? '-'}`
+	}
+	return '-'
+}
+
+function formatRange (row) {
+	if (!row) return '-'
+	const value = row.effectiveRangeKm ?? row.range
+	return value === null || value === undefined || value === '' ? '-' : value
+}
+
+function formatDeviceCode (row) {
+	if (!row) return '-'
+	return row.deviceCode || row.deviceSn || row.deviceNo || '-'
+}
+
+onMounted(() => {
+	getList()
+	getDictList()
+})
 </script>
-<style scoped lang="scss">
-</style>
+<style scoped lang="scss"></style>
diff --git a/packages/utils/date/index.js b/packages/utils/date/index.js
index 83104fc..e99f662 100644
--- a/packages/utils/date/index.js
+++ b/packages/utils/date/index.js
@@ -6,3 +6,18 @@
 	let end_date = dateRange?.length ? dayjs(dateRange?.[1]).endOf('day').format(timeFormat) : null
 	return [start_date, end_date]
 }
+
+export function formatDateToSlash(dateStr) {
+	if (!dateStr) return '-'
+  
+	// 兼容 'YYYY-MM-DD HH:mm:ss'
+	const date = new Date(dateStr.replace(/-/g, '/'))
+	if (isNaN(date.getTime())) return '-'
+  
+	const y = date.getFullYear()
+	const m = String(date.getMonth() + 1).padStart(2, '0')
+	const d = String(date.getDate()).padStart(2, '0')
+  
+	return `${y}/${m}/${d}`
+  }
+  
\ No newline at end of file

--
Gitblit v1.9.3