Compare commits
5 Commits
92c3052832
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b8e8d3926 | |||
| 8e2e55e645 | |||
| a147563b70 | |||
| baf2af1fc3 | |||
| f33efef3bd |
@@ -11,7 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@amap/amap-jsapi-loader": "^1.0.1",
|
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||||
"@element-plus/icons-vue": "^2.3.2",
|
"@element-plus/icons-vue": "^2.3.2",
|
||||||
"DroneCtrl": "1.0.1",
|
"DroneCtrl": "1.0.3",
|
||||||
"axios": "^1.13.2",
|
"axios": "^1.13.2",
|
||||||
"element-plus": "^2.12.0",
|
"element-plus": "^2.12.0",
|
||||||
"gcoord": "^1.0.7",
|
"gcoord": "^1.0.7",
|
||||||
|
|||||||
20
pnpm-lock.yaml
generated
@@ -18,8 +18,8 @@ importers:
|
|||||||
specifier: ^2.3.2
|
specifier: ^2.3.2
|
||||||
version: 2.3.2(vue@3.5.25)
|
version: 2.3.2(vue@3.5.25)
|
||||||
DroneCtrl:
|
DroneCtrl:
|
||||||
specifier: 1.0.2
|
specifier: 1.0.3
|
||||||
version: 1.0.2
|
version: 1.0.3
|
||||||
axios:
|
axios:
|
||||||
specifier: ^1.13.2
|
specifier: ^1.13.2
|
||||||
version: 1.13.2
|
version: 1.13.2
|
||||||
@@ -137,28 +137,24 @@ packages:
|
|||||||
engines: {node: ^20.19.0 || >=22.12.0}
|
engines: {node: ^20.19.0 || >=22.12.0}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
libc: [glibc]
|
|
||||||
|
|
||||||
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.50':
|
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.50':
|
||||||
resolution: {integrity: sha512-L0zRdH2oDPkmB+wvuTl+dJbXCsx62SkqcEqdM+79LOcB+PxbAxxjzHU14BuZIQdXcAVDzfpMfaHWzZuwhhBTcw==}
|
resolution: {integrity: sha512-L0zRdH2oDPkmB+wvuTl+dJbXCsx62SkqcEqdM+79LOcB+PxbAxxjzHU14BuZIQdXcAVDzfpMfaHWzZuwhhBTcw==}
|
||||||
engines: {node: ^20.19.0 || >=22.12.0}
|
engines: {node: ^20.19.0 || >=22.12.0}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
libc: [musl]
|
|
||||||
|
|
||||||
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.50':
|
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.50':
|
||||||
resolution: {integrity: sha512-gyoI8o/TGpQd3OzkJnh1M2kxy1Bisg8qJ5Gci0sXm9yLFzEXIFdtc4EAzepxGvrT2ri99ar5rdsmNG0zP0SbIg==}
|
resolution: {integrity: sha512-gyoI8o/TGpQd3OzkJnh1M2kxy1Bisg8qJ5Gci0sXm9yLFzEXIFdtc4EAzepxGvrT2ri99ar5rdsmNG0zP0SbIg==}
|
||||||
engines: {node: ^20.19.0 || >=22.12.0}
|
engines: {node: ^20.19.0 || >=22.12.0}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
libc: [glibc]
|
|
||||||
|
|
||||||
'@rolldown/binding-linux-x64-musl@1.0.0-beta.50':
|
'@rolldown/binding-linux-x64-musl@1.0.0-beta.50':
|
||||||
resolution: {integrity: sha512-zti8A7M+xFDpKlghpcCAzyOi+e5nfUl3QhU023ce5NCgUxRG5zGP2GR9LTydQ1rnIPwZUVBWd4o7NjZDaQxaXA==}
|
resolution: {integrity: sha512-zti8A7M+xFDpKlghpcCAzyOi+e5nfUl3QhU023ce5NCgUxRG5zGP2GR9LTydQ1rnIPwZUVBWd4o7NjZDaQxaXA==}
|
||||||
engines: {node: ^20.19.0 || >=22.12.0}
|
engines: {node: ^20.19.0 || >=22.12.0}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
libc: [musl]
|
|
||||||
|
|
||||||
'@rolldown/binding-openharmony-arm64@1.0.0-beta.50':
|
'@rolldown/binding-openharmony-arm64@1.0.0-beta.50':
|
||||||
resolution: {integrity: sha512-eZUssog7qljrrRU9Mi0eqYEPm3Ch0UwB+qlWPMKSUXHNqhm3TvDZarJQdTevGEfu3EHAXJvBIe0YFYr0TPVaMA==}
|
resolution: {integrity: sha512-eZUssog7qljrrRU9Mi0eqYEPm3Ch0UwB+qlWPMKSUXHNqhm3TvDZarJQdTevGEfu3EHAXJvBIe0YFYr0TPVaMA==}
|
||||||
@@ -211,7 +207,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==}
|
resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==}
|
||||||
engines: {node: ^20.19.0 || >=22.12.0}
|
engines: {node: ^20.19.0 || >=22.12.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: npm:rolldown-vite@7.2.5
|
vite: ^5.0.0 || ^6.0.0 || ^7.0.0
|
||||||
vue: ^3.2.25
|
vue: ^3.2.25
|
||||||
|
|
||||||
'@vue/compiler-core@3.5.25':
|
'@vue/compiler-core@3.5.25':
|
||||||
@@ -252,8 +248,8 @@ packages:
|
|||||||
'@vueuse/shared@9.13.0':
|
'@vueuse/shared@9.13.0':
|
||||||
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
|
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
|
||||||
|
|
||||||
DroneCtrl@1.0.2:
|
DroneCtrl@1.0.3:
|
||||||
resolution: {integrity: sha512-EQWN1q8S4mN64gMlBQkQyJIYSBVE75YLPsYI+L/67TPypOyGWnI/kxCYMPY1hNVB8sIxJO0Z3DU3wlKxwg4Qiw==}
|
resolution: {integrity: sha512-8SC/nx1byB/dhqSb0nNjamzQTQXi15JKkFRkMUnRErBcKBeNypz0Rjn6k7kGMuC/d0RNYODAgj8xc4NQEKokfw==}
|
||||||
|
|
||||||
async-validator@4.2.5:
|
async-validator@4.2.5:
|
||||||
resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
|
resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
|
||||||
@@ -411,28 +407,24 @@ packages:
|
|||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
libc: [glibc]
|
|
||||||
|
|
||||||
lightningcss-linux-arm64-musl@1.30.2:
|
lightningcss-linux-arm64-musl@1.30.2:
|
||||||
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
|
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
|
||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
libc: [musl]
|
|
||||||
|
|
||||||
lightningcss-linux-x64-gnu@1.30.2:
|
lightningcss-linux-x64-gnu@1.30.2:
|
||||||
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
|
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
|
||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
libc: [glibc]
|
|
||||||
|
|
||||||
lightningcss-linux-x64-musl@1.30.2:
|
lightningcss-linux-x64-musl@1.30.2:
|
||||||
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
|
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
|
||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
libc: [musl]
|
|
||||||
|
|
||||||
lightningcss-win32-arm64-msvc@1.30.2:
|
lightningcss-win32-arm64-msvc@1.30.2:
|
||||||
resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==}
|
resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==}
|
||||||
@@ -781,7 +773,7 @@ snapshots:
|
|||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
DroneCtrl@1.0.2: {}
|
DroneCtrl@1.0.3: {}
|
||||||
|
|
||||||
async-validator@4.2.5: {}
|
async-validator@4.2.5: {}
|
||||||
|
|
||||||
|
|||||||
304
src/App.vue
@@ -23,8 +23,8 @@
|
|||||||
<!-- 左侧信息面板(覆盖层) -->
|
<!-- 左侧信息面板(覆盖层) -->
|
||||||
<aside class="left-panel">
|
<aside class="left-panel">
|
||||||
<!-- 实时画面 -->
|
<!-- 实时画面 -->
|
||||||
<div class="info-panel">
|
<div class="info-panel" onclick="window.open('/web/video.html', '_blank')">
|
||||||
<div class="panel-header">
|
<!-- <div class="panel-header">
|
||||||
<span class="panel-title">实时画面</span>
|
<span class="panel-title">实时画面</span>
|
||||||
<span class="panel-count">35路</span>
|
<span class="panel-count">35路</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -34,12 +34,12 @@
|
|||||||
<span class="video-label">{{ i }}</span>
|
<span class="video-label">{{ i }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 巡检航线 -->
|
<!-- 巡检航线 -->
|
||||||
<div class="info-panel">
|
<div class="info-panel">
|
||||||
<div class="panel-header">
|
<!-- <div class="panel-header">
|
||||||
<span class="panel-title">巡检航线</span>
|
<span class="panel-title">巡检航线</span>
|
||||||
<span class="panel-count">35条</span>
|
<span class="panel-count">35条</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -59,12 +59,12 @@
|
|||||||
<span class="status-number">11</span>
|
<span class="status-number">11</span>
|
||||||
<span class="status-text">待开始</span>
|
<span class="status-text">待开始</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 识别场景 -->
|
<!-- 识别场景 -->
|
||||||
<div class="info-panel">
|
<div class="info-panel">
|
||||||
<div class="panel-header">
|
<!-- <div class="panel-header">
|
||||||
<span class="panel-title">识别场景</span>
|
<span class="panel-title">识别场景</span>
|
||||||
<span class="panel-count">35个</span>
|
<span class="panel-count">35个</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
<span class="status-number">11</span>
|
<span class="status-number">11</span>
|
||||||
<span class="status-text">烟雾</span>
|
<span class="status-text">烟雾</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
@@ -92,22 +92,17 @@
|
|||||||
<div class="control-panel" v-show="showControlPanel">
|
<div class="control-panel" v-show="showControlPanel">
|
||||||
<div class="panel-title">电子围栏控制</div>
|
<div class="panel-title">电子围栏控制</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
<!-- 地图类型切换 -->
|
<!-- 地图类型切换 -->
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<div class="draw-type-title">地图类型:</div>
|
<div class="draw-type-title">地图类型:</div>
|
||||||
<div class="draw-buttons">
|
<div class="draw-buttons">
|
||||||
<el-button
|
<el-button @click="switchMapType('normal')" :type="mapType === 'normal' ? 'primary' : 'default'"
|
||||||
@click="switchMapType('normal')"
|
size="default">
|
||||||
:type="mapType === 'normal' ? 'primary' : 'default'"
|
|
||||||
size="default"
|
|
||||||
>
|
|
||||||
普通地图
|
普通地图
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button @click="switchMapType('satellite')" :type="mapType === 'satellite' ? 'primary' : 'default'"
|
||||||
@click="switchMapType('satellite')"
|
size="default">
|
||||||
:type="mapType === 'satellite' ? 'primary' : 'default'"
|
|
||||||
size="default"
|
|
||||||
>
|
|
||||||
卫星地图
|
卫星地图
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -117,28 +112,16 @@
|
|||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<div class="draw-type-title">选择绘制类型:</div>
|
<div class="draw-type-title">选择绘制类型:</div>
|
||||||
<div class="draw-buttons">
|
<div class="draw-buttons">
|
||||||
<el-button
|
<el-button @click="startDrawPolygon" :type="currentDrawType === 'polygon' ? 'primary' : 'default'"
|
||||||
@click="startDrawPolygon"
|
size="default">
|
||||||
:type="currentDrawType === 'polygon' ? 'primary' : 'default'"
|
|
||||||
|
|
||||||
size="default"
|
|
||||||
>
|
|
||||||
多边形
|
多边形
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button @click="startDrawRectangle" :type="currentDrawType === 'rectangle' ? 'primary' : 'default'"
|
||||||
@click="startDrawRectangle"
|
size="default">
|
||||||
:type="currentDrawType === 'rectangle' ? 'primary' : 'default'"
|
|
||||||
|
|
||||||
size="default"
|
|
||||||
>
|
|
||||||
矩形
|
矩形
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button @click="startDrawCircle" :type="currentDrawType === 'circle' ? 'primary' : 'default'"
|
||||||
@click="startDrawCircle"
|
size="default">
|
||||||
:type="currentDrawType === 'circle' ? 'primary' : 'default'"
|
|
||||||
|
|
||||||
size="default"
|
|
||||||
>
|
|
||||||
圆形
|
圆形
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -155,7 +138,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="status-item" v-if="droneData">
|
<div class="status-item" v-if="droneData">
|
||||||
<span class="status-label">位置:</span>
|
<span class="status-label">位置:</span>
|
||||||
<span class="status-value">{{ droneData.latitude?.toFixed(6) }}, {{ droneData.longitude?.toFixed(6) }}</span>
|
<span class="status-value">{{ droneData.latitude?.toFixed(6) }}, {{ droneData.longitude?.toFixed(6)
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-item" v-if="droneData">
|
<div class="status-item" v-if="droneData">
|
||||||
<span class="status-label">高度:</span>
|
<span class="status-label">高度:</span>
|
||||||
@@ -175,21 +159,12 @@
|
|||||||
{{ isInFence ? '围栏内' : '围栏外' }}
|
{{ isInFence ? '围栏内' : '围栏外' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<el-button
|
<el-button @click="handleTakeoff" :type="isFlying ? 'warning' : 'success'" size="small"
|
||||||
@click="handleTakeoff"
|
style="width: 100%; margin-top: 8px;" :disabled="isFlying">
|
||||||
:type="isFlying ? 'warning' : 'success'"
|
|
||||||
size="small"
|
|
||||||
style="width: 100%; margin-top: 8px;"
|
|
||||||
:disabled="isFlying"
|
|
||||||
>
|
|
||||||
{{ isFlying ? '飞行中' : '起飞' }}
|
{{ isFlying ? '飞行中' : '起飞' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button @click="toggleWebSocket" :type="wsConnected ? 'danger' : 'primary'" size="small"
|
||||||
@click="toggleWebSocket"
|
style="width: 100%; margin-top: 8px;margin-left: 0;">
|
||||||
:type="wsConnected ? 'danger' : 'primary'"
|
|
||||||
size="small"
|
|
||||||
style="width: 100%; margin-top: 8px;margin-left: 0;"
|
|
||||||
>
|
|
||||||
{{ wsConnected ? '断开连接' : '开始连接' }}
|
{{ wsConnected ? '断开连接' : '开始连接' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -197,58 +172,42 @@
|
|||||||
<!-- 围栏列表 -->
|
<!-- 围栏列表 -->
|
||||||
<div class="fence-list" v-if="fences.length > 0">
|
<div class="fence-list" v-if="fences.length > 0">
|
||||||
<div class="list-title">已绘制围栏 ({{ fences.length }})</div>
|
<div class="list-title">已绘制围栏 ({{ fences.length }})</div>
|
||||||
<div
|
<div v-for="fence in fences" :key="fence.id" class="fence-item">
|
||||||
v-for="fence in fences"
|
|
||||||
:key="fence.id"
|
|
||||||
class="fence-item"
|
|
||||||
>
|
|
||||||
<span class="fence-info">
|
<span class="fence-info">
|
||||||
<span class="fence-name">{{ fence.name || '未命名围栏' }}</span>
|
<span class="fence-name">{{ fence.name || '未命名围栏' }}</span>
|
||||||
</span>
|
</span>
|
||||||
<div class="fence-actions">
|
<div class="fence-actions">
|
||||||
<el-button
|
<el-button @click="uploadFence(fence.id)" type="primary" size="small">
|
||||||
@click="uploadFence(fence.id)"
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
上传
|
上传
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button @click="removeFence(fence.id)" type="danger" size="small">
|
||||||
@click="removeFence(fence.id)"
|
|
||||||
type="danger"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-button
|
<el-button @click="clearAllFences" type="danger" size="default" style="width: 100%; margin-top: 8px;">
|
||||||
@click="clearAllFences"
|
|
||||||
type="danger"
|
|
||||||
size="default"
|
|
||||||
style="width: 100%; margin-top: 8px;"
|
|
||||||
>
|
|
||||||
清除所有围栏
|
清除所有围栏
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 右侧信息面板(覆盖层) -->
|
<!-- 右侧信息面板(覆盖层) -->
|
||||||
<aside class="right-panel">
|
<aside class="right-panel">
|
||||||
<!-- 区域管理 -->
|
<!-- 区域管理 -->
|
||||||
<div class="info-panel">
|
<div class="info-panel">
|
||||||
<div class="panel-header">
|
<!-- <div class="panel-header">
|
||||||
<span class="panel-title">区域管理</span>
|
<span class="panel-title">区域管理</span>
|
||||||
<span class="panel-count">12个</span>
|
<span class="panel-count">12个</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="area-preview">
|
<div class="area-preview">
|
||||||
<img src="./assets/image/regional_management.png" alt="区域管理" class="area-image" />
|
<img src="./assets/image/regional_management.png" alt="区域管理" class="area-image" />
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 出勤设备 -->
|
<!-- 出勤设备 -->
|
||||||
<div class="info-panel">
|
<div class="info-panel">
|
||||||
<div class="panel-header">
|
<!-- <div class="panel-header">
|
||||||
<span class="panel-title">出勤设备</span>
|
<span class="panel-title">出勤设备</span>
|
||||||
<span class="panel-count">35台</span>
|
<span class="panel-count">35台</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -268,12 +227,12 @@
|
|||||||
<span class="status-number">12</span>
|
<span class="status-number">12</span>
|
||||||
<span class="status-text">充电</span>
|
<span class="status-text">充电</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 执行任务 -->
|
<!-- 执行任务 -->
|
||||||
<div class="info-panel">
|
<div class="info-panel">
|
||||||
<div class="panel-header">
|
<!-- <div class="panel-header">
|
||||||
<span class="panel-title">执行任务</span>
|
<span class="panel-title">执行任务</span>
|
||||||
<span class="panel-count">12项</span>
|
<span class="panel-count">12项</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -296,7 +255,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<span class="progress-text">60% 待开始</span>
|
<span class="progress-text">60% 待开始</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
@@ -304,62 +263,17 @@
|
|||||||
|
|
||||||
<!-- 底部导航栏 -->
|
<!-- 底部导航栏 -->
|
||||||
<footer class="bottom-footer">
|
<footer class="bottom-footer">
|
||||||
<div class="footer-left">
|
|
||||||
<span class="storage-info">62.3GB</span>
|
|
||||||
</div>
|
|
||||||
<div class="footer-center">
|
<div class="footer-center">
|
||||||
<div class="resolution-info">
|
|
||||||
<!-- <span class="resolution-text">1109px x 1902px</span> -->
|
|
||||||
</div>
|
|
||||||
<div class="footer-icons">
|
<div class="footer-icons">
|
||||||
<img
|
<img src="./assets/image/d1.png" class="arrow-img" />
|
||||||
:src="icon1"
|
<img src="./assets/image/i1.png" class="icon-img" />
|
||||||
class="footer-icon-img"
|
<img src="./assets/image/i2.png" class="icon-img" />
|
||||||
@click="handleFooterIconClick(1)"
|
<img src="./assets/image/i3.png" class="icon-img" @click="handleFooterIconClick(4)"/>
|
||||||
alt="图标1"
|
<img src="./assets/image/i4.png" class="icon-img" />
|
||||||
/>
|
<img src="./assets/image/i5.png" class="icon-img" />
|
||||||
<img
|
<img src="./assets/image/d2.png" class="arrow-img" />
|
||||||
:src="icon2"
|
|
||||||
class="footer-icon-img"
|
|
||||||
@click="handleFooterIconClick(2)"
|
|
||||||
alt="图标2"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
:src="icon3"
|
|
||||||
class="footer-icon-img"
|
|
||||||
@click="handleFooterIconClick(3)"
|
|
||||||
alt="图标3"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
:src="icon4"
|
|
||||||
class="footer-icon-img"
|
|
||||||
:class="{ 'active': showControlPanel }"
|
|
||||||
@click="handleFooterIconClick(4)"
|
|
||||||
alt="图标4"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
:src="icon5"
|
|
||||||
class="footer-icon-img"
|
|
||||||
@click="handleFooterIconClick(5)"
|
|
||||||
alt="图标5"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
:src="icon6"
|
|
||||||
class="footer-icon-img"
|
|
||||||
@click="handleFooterIconClick(6)"
|
|
||||||
alt="图标6"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
:src="icon7"
|
|
||||||
class="footer-icon-img"
|
|
||||||
@click="handleFooterIconClick(7)"
|
|
||||||
alt="图标7"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-right">
|
|
||||||
<span class="uptime-info">120.3 h</span>
|
|
||||||
</div>
|
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -368,15 +282,6 @@
|
|||||||
import { ref, onMounted, onUnmounted, computed } from 'vue'
|
import { ref, onMounted, onUnmounted, computed } from 'vue'
|
||||||
import AMapLoader from '@amap/amap-jsapi-loader'
|
import AMapLoader from '@amap/amap-jsapi-loader'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import {
|
|
||||||
Upload,
|
|
||||||
Connection,
|
|
||||||
Folder,
|
|
||||||
Download,
|
|
||||||
ChatLineRound,
|
|
||||||
Link,
|
|
||||||
VideoPlay
|
|
||||||
} from '@element-plus/icons-vue'
|
|
||||||
import { WebSocketClient, MockWebSocketDataGenerator } from './utils/websocket.js'
|
import { WebSocketClient, MockWebSocketDataGenerator } from './utils/websocket.js'
|
||||||
import droneImage from './assets/image/wrj.png'
|
import droneImage from './assets/image/wrj.png'
|
||||||
import icon1 from './assets/image/1.png'
|
import icon1 from './assets/image/1.png'
|
||||||
@@ -414,6 +319,8 @@ let mouseTool = null
|
|||||||
const mapType = ref('satellite') // 'normal' | 'satellite'
|
const mapType = ref('satellite') // 'normal' | 'satellite'
|
||||||
const dronePath = ref([]) // 无人机轨迹点集合
|
const dronePath = ref([]) // 无人机轨迹点集合
|
||||||
let droneTrackLine = null
|
let droneTrackLine = null
|
||||||
|
const drone2Path = ref([]) // 无人机2轨迹点集合
|
||||||
|
let drone2TrackLine = null
|
||||||
const MAX_TRACK_POINTS = 2000
|
const MAX_TRACK_POINTS = 2000
|
||||||
|
|
||||||
// 围栏相关状态
|
// 围栏相关状态
|
||||||
@@ -638,7 +545,7 @@ const toggleWebSocket = () => {
|
|||||||
gcoord.GCJ02, // 目标坐标系
|
gcoord.GCJ02, // 目标坐标系
|
||||||
);
|
);
|
||||||
console.log(point, point2);
|
console.log(point, point2);
|
||||||
// updateDroneMarker(point[0], point[1], drone1.heading);
|
updateDroneMarker(point[0], point[1], point2[0], point2[1], drone1.heading);
|
||||||
// updateDrone2Marker(point2[0], point2[1], drone2.heading);
|
// updateDrone2Marker(point2[0], point2[1], drone2.heading);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -667,7 +574,7 @@ const handleDroneData = (data) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新无人机marker
|
// 更新无人机marker
|
||||||
const updateDroneMarker = (lng, lat, heading = 0) => {
|
const updateDroneMarker = (lng, lat, lng2, lat2, heading = 0) => {
|
||||||
if (!map || !AMap) return
|
if (!map || !AMap) return
|
||||||
|
|
||||||
if (!droneMarker.value) {
|
if (!droneMarker.value) {
|
||||||
@@ -684,25 +591,40 @@ const updateDroneMarker = (lng, lat, heading = 0) => {
|
|||||||
position: [lng, lat],
|
position: [lng, lat],
|
||||||
icon: icon,
|
icon: icon,
|
||||||
zIndex: 100,
|
zIndex: 100,
|
||||||
title: '无人机',
|
title: '侦查机',
|
||||||
offset: new AMap.Pixel(-20, -20),
|
offset: new AMap.Pixel(-20, -20),
|
||||||
// 优化:禁用动画,减少性能消耗
|
// 优化:禁用动画,减少性能消耗
|
||||||
animation: 'AMAP_ANIMATION_NONE'
|
animation: 'AMAP_ANIMATION_NONE'
|
||||||
})
|
})
|
||||||
|
|
||||||
map.add(droneMarker.value)
|
map.add(droneMarker.value)
|
||||||
|
|
||||||
|
drone2Marker.value = new AMap.Marker({
|
||||||
|
position: [lng, lat],
|
||||||
|
icon: icon,
|
||||||
|
zIndex: 100,
|
||||||
|
title: '投弹机',
|
||||||
|
offset: new AMap.Pixel(-20, -20),
|
||||||
|
// 优化:禁用动画,减少性能消耗
|
||||||
|
animation: 'AMAP_ANIMATION_NONE'
|
||||||
|
})
|
||||||
|
|
||||||
|
map.add(drone2Marker.value)
|
||||||
} else {
|
} else {
|
||||||
// 更新位置
|
// 更新位置
|
||||||
droneMarker.value.setPosition([lng, lat])
|
droneMarker.value.setPosition([lng, lat])
|
||||||
|
drone2Marker.value.setPosition([lng2, lat2])
|
||||||
|
|
||||||
// 更新旋转角度(如果有heading数据)
|
// 更新旋转角度(如果有heading数据)
|
||||||
if (heading !== undefined) {
|
if (heading !== undefined) {
|
||||||
droneMarker.value.setAngle(heading)
|
droneMarker.value.setAngle(heading)
|
||||||
|
drone2Marker.value.setAngle(heading)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新飞行轨迹
|
// 更新飞行轨迹
|
||||||
updateDroneTrack(lng, lat)
|
updateDroneTrack(lng, lat)
|
||||||
|
updateDrone2Track(lng2, lat2)
|
||||||
|
|
||||||
// 将地图中心移动到无人机位置(可选,可以注释掉)
|
// 将地图中心移动到无人机位置(可选,可以注释掉)
|
||||||
map.setCenter([lng, lat])
|
map.setCenter([lng, lat])
|
||||||
@@ -733,6 +655,30 @@ const initDroneTrack = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const initDrone2Track = () => {
|
||||||
|
if (!map || !AMap) return
|
||||||
|
|
||||||
|
// 如果已有轨迹线,先移除
|
||||||
|
if (drone2TrackLine) {
|
||||||
|
map.remove(drone2TrackLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
drone2TrackLine = new AMap.Polyline({
|
||||||
|
map,
|
||||||
|
path: [],
|
||||||
|
showDir: true,
|
||||||
|
isOutline: true,
|
||||||
|
outlineColor: 'rgba(0,0,0,0.3)',
|
||||||
|
borderWeight: 2,
|
||||||
|
strokeColor: '#00e0ff',
|
||||||
|
strokeOpacity: 0.8,
|
||||||
|
strokeWeight: 4,
|
||||||
|
lineJoin: 'round',
|
||||||
|
lineCap: 'round',
|
||||||
|
zIndex: 90
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 更新无人机轨迹
|
// 更新无人机轨迹
|
||||||
const updateDroneTrack = (lng, lat) => {
|
const updateDroneTrack = (lng, lat) => {
|
||||||
if (!map || !AMap) return
|
if (!map || !AMap) return
|
||||||
@@ -751,6 +697,24 @@ const updateDroneTrack = (lng, lat) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateDrone2Track = (lng, lat) => {
|
||||||
|
if (!map || !AMap) return
|
||||||
|
|
||||||
|
if (!drone2TrackLine) {
|
||||||
|
initDrone2Track()
|
||||||
|
}
|
||||||
|
|
||||||
|
drone2Path.value.push([lng, lat])
|
||||||
|
if (drone2Path.value.length > MAX_TRACK_POINTS) {
|
||||||
|
drone2Path.value.shift()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drone2TrackLine) {
|
||||||
|
drone2TrackLine.setPath(drone2Path.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 清空无人机轨迹
|
// 清空无人机轨迹
|
||||||
const clearDroneTrack = () => {
|
const clearDroneTrack = () => {
|
||||||
dronePath.value = []
|
dronePath.value = []
|
||||||
@@ -759,6 +723,13 @@ const clearDroneTrack = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const clearDrone2Track = () => {
|
||||||
|
drone2Path.value = []
|
||||||
|
if (drone2TrackLine) {
|
||||||
|
drone2TrackLine.setPath([])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 检测点是否在多边形内(射线法)
|
// 检测点是否在多边形内(射线法)
|
||||||
const isPointInPolygon = (point, polygon) => {
|
const isPointInPolygon = (point, polygon) => {
|
||||||
const [x, y] = point
|
const [x, y] = point
|
||||||
@@ -1293,7 +1264,7 @@ const uploadFence = (fenceId) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pointsData) {
|
if (pointsData) {
|
||||||
const points = pointsData.points.map(point=> {
|
const points = pointsData.points.map(point => {
|
||||||
const wgsPoint = gcoord.transform(
|
const wgsPoint = gcoord.transform(
|
||||||
point, // 原始坐标
|
point, // 原始坐标
|
||||||
gcoord.GCJ02, // 当前坐标系
|
gcoord.GCJ02, // 当前坐标系
|
||||||
@@ -1303,7 +1274,7 @@ const uploadFence = (fenceId) => {
|
|||||||
});
|
});
|
||||||
console.log(points)
|
console.log(points)
|
||||||
|
|
||||||
ctrl.UploadArea(new UploadAreaReq(points.map(point=>({
|
ctrl.UploadArea(new UploadAreaReq(points.map(point => ({
|
||||||
longitude: point[0],
|
longitude: point[0],
|
||||||
latitude: point[1],
|
latitude: point[1],
|
||||||
}))));
|
}))));
|
||||||
@@ -1478,6 +1449,11 @@ onUnmounted(() => {
|
|||||||
wsClient = null
|
wsClient = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conn) {
|
||||||
|
conn.close()
|
||||||
|
conn = null
|
||||||
|
}
|
||||||
|
|
||||||
// 清理地图
|
// 清理地图
|
||||||
if (droneMarker.value) {
|
if (droneMarker.value) {
|
||||||
map?.remove(droneMarker.value)
|
map?.remove(droneMarker.value)
|
||||||
@@ -1583,17 +1559,35 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
/* 左侧面板(覆盖层) */
|
/* 左侧面板(覆盖层) */
|
||||||
.left-panel {
|
.left-panel {
|
||||||
|
/* background: url('./assets/image/z1.png') no-repeat center center; */
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 320px;
|
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
|
:nth-child(1) {
|
||||||
|
background: url('./assets/image/z1.png') no-repeat center center;
|
||||||
|
width: 320px;
|
||||||
|
height: 270px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:nth-child(2) {
|
||||||
|
background: url('./assets/image/z2.png') no-repeat center center;
|
||||||
|
width: 320px;
|
||||||
|
height: 270px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:nth-child(3) {
|
||||||
|
background: url('./assets/image/z3.png') no-repeat center center;
|
||||||
|
width: 320px;
|
||||||
|
height: 270px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 右侧面板(覆盖层) */
|
/* 右侧面板(覆盖层) */
|
||||||
@@ -1602,13 +1596,30 @@ onUnmounted(() => {
|
|||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 320px;
|
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
|
:nth-child(1) {
|
||||||
|
background: url('./assets/image/y1.png') no-repeat center center;
|
||||||
|
width: 320px;
|
||||||
|
height: 270px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:nth-child(2) {
|
||||||
|
background: url('./assets/image/y2.png') no-repeat center center;
|
||||||
|
width: 320px;
|
||||||
|
height: 270px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:nth-child(3) {
|
||||||
|
background: url('./assets/image/y3.png') no-repeat center center;
|
||||||
|
width: 320px;
|
||||||
|
height: 270px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 信息面板 */
|
/* 信息面板 */
|
||||||
@@ -1983,14 +1994,12 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
/* 底部导航栏 */
|
/* 底部导航栏 */
|
||||||
.bottom-footer {
|
.bottom-footer {
|
||||||
height: 55px;
|
background: #0a0e27;
|
||||||
background:#0a0e27;
|
|
||||||
backdrop-filter: blur(15px);
|
backdrop-filter: blur(15px);
|
||||||
border-top: 1px solid rgba(255, 255, 255, 0.15);
|
border-top: 1px solid rgba(255, 255, 255, 0.15);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 40px;
|
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
position: relative;
|
position: relative;
|
||||||
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
|
||||||
@@ -2124,4 +2133,3 @@ onUnmounted(() => {
|
|||||||
background: rgba(255, 255, 255, 0.5);
|
background: rgba(255, 255, 255, 0.5);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
BIN
src/assets/image/d1.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
src/assets/image/d2.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/image/i1.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/image/i2.png
Normal file
|
After Width: | Height: | Size: 677 B |
BIN
src/assets/image/i3.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/image/i4.png
Normal file
|
After Width: | Height: | Size: 1008 B |
BIN
src/assets/image/i5.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src/assets/image/wrj2.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/image/y1.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src/assets/image/y2.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
src/assets/image/y3.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
src/assets/image/z1.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
src/assets/image/z2.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
src/assets/image/z3.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
@@ -97,9 +97,9 @@ function upload(url, params) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// export let host = `${window.location.protocol}//${window.location.host}`;
|
export let host = `${window.location.protocol}//${window.location.host}`;
|
||||||
// export let host = "http://192.168.43.98:5678";
|
// export let host = "http://192.168.43.98:5678";
|
||||||
export let host = "http://192.168.3.81:5678";
|
// export let host = "http://192.168.3.81:5678";
|
||||||
// export let host = "http://127.0.0.1:5678";
|
// export let host = "http://127.0.0.1:5678";
|
||||||
|
|
||||||
export const getConfig = () => {
|
export const getConfig = () => {
|
||||||
|
|||||||