This commit is contained in:
2025-12-18 21:21:51 +08:00
parent 92c3052832
commit f33efef3bd
16 changed files with 287 additions and 357 deletions

18
pnpm-lock.yaml generated
View File

@@ -18,8 +18,8 @@ importers:
specifier: ^2.3.2
version: 2.3.2(vue@3.5.25)
DroneCtrl:
specifier: 1.0.2
version: 1.0.2
specifier: 1.0.1
version: 1.0.1
axios:
specifier: ^1.13.2
version: 1.13.2
@@ -137,28 +137,24 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.50':
resolution: {integrity: sha512-L0zRdH2oDPkmB+wvuTl+dJbXCsx62SkqcEqdM+79LOcB+PxbAxxjzHU14BuZIQdXcAVDzfpMfaHWzZuwhhBTcw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.50':
resolution: {integrity: sha512-gyoI8o/TGpQd3OzkJnh1M2kxy1Bisg8qJ5Gci0sXm9yLFzEXIFdtc4EAzepxGvrT2ri99ar5rdsmNG0zP0SbIg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-x64-musl@1.0.0-beta.50':
resolution: {integrity: sha512-zti8A7M+xFDpKlghpcCAzyOi+e5nfUl3QhU023ce5NCgUxRG5zGP2GR9LTydQ1rnIPwZUVBWd4o7NjZDaQxaXA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@rolldown/binding-openharmony-arm64@1.0.0-beta.50':
resolution: {integrity: sha512-eZUssog7qljrrRU9Mi0eqYEPm3Ch0UwB+qlWPMKSUXHNqhm3TvDZarJQdTevGEfu3EHAXJvBIe0YFYr0TPVaMA==}
@@ -252,8 +248,8 @@ packages:
'@vueuse/shared@9.13.0':
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
DroneCtrl@1.0.2:
resolution: {integrity: sha512-EQWN1q8S4mN64gMlBQkQyJIYSBVE75YLPsYI+L/67TPypOyGWnI/kxCYMPY1hNVB8sIxJO0Z3DU3wlKxwg4Qiw==}
DroneCtrl@1.0.1:
resolution: {integrity: sha512-3ibzb0sXZGXAkbSTg4Zb8heTx6ASBkWaI2yAO8V+4/Y2ygULruPCzb8o3c89wWlnfQQ/AALWlNmkpVV/ezBujQ==}
async-validator@4.2.5:
resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
@@ -411,28 +407,24 @@ packages:
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
libc: [glibc]
lightningcss-linux-arm64-musl@1.30.2:
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
libc: [musl]
lightningcss-linux-x64-gnu@1.30.2:
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
libc: [glibc]
lightningcss-linux-x64-musl@1.30.2:
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
libc: [musl]
lightningcss-win32-arm64-msvc@1.30.2:
resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==}
@@ -781,7 +773,7 @@ snapshots:
- '@vue/composition-api'
- vue
DroneCtrl@1.0.2: {}
DroneCtrl@1.0.1: {}
async-validator@4.2.5: {}

View File

@@ -24,7 +24,7 @@
<aside class="left-panel">
<!-- 实时画面 -->
<div class="info-panel">
<div class="panel-header">
<!-- <div class="panel-header">
<span class="panel-title">实时画面</span>
<span class="panel-count">35</span>
</div>
@@ -34,12 +34,12 @@
<span class="video-label">{{ i }}</span>
</div>
</div>
</div>
</div> -->
</div>
<!-- 巡检航线 -->
<div class="info-panel">
<div class="panel-header">
<!-- <div class="panel-header">
<span class="panel-title">巡检航线</span>
<span class="panel-count">35</span>
</div>
@@ -59,12 +59,12 @@
<span class="status-number">11</span>
<span class="status-text">待开始</span>
</div>
</div>
</div> -->
</div>
<!-- 识别场景 -->
<div class="info-panel">
<div class="panel-header">
<!-- <div class="panel-header">
<span class="panel-title">识别场景</span>
<span class="panel-count">35</span>
</div>
@@ -84,7 +84,7 @@
<span class="status-number">11</span>
<span class="status-text">烟雾</span>
</div>
</div>
</div> -->
</div>
</aside>
@@ -92,22 +92,17 @@
<div class="control-panel" v-show="showControlPanel">
<div class="panel-title">电子围栏控制</div>
<div>
<!-- 地图类型切换 -->
<div class="control-group">
<div class="draw-type-title">地图类型</div>
<div class="draw-buttons">
<el-button
@click="switchMapType('normal')"
:type="mapType === 'normal' ? 'primary' : 'default'"
size="default"
>
<el-button @click="switchMapType('normal')" :type="mapType === 'normal' ? 'primary' : 'default'"
size="default">
普通地图
</el-button>
<el-button
@click="switchMapType('satellite')"
:type="mapType === 'satellite' ? 'primary' : 'default'"
size="default"
>
<el-button @click="switchMapType('satellite')" :type="mapType === 'satellite' ? 'primary' : 'default'"
size="default">
卫星地图
</el-button>
</div>
@@ -117,28 +112,16 @@
<div class="control-group">
<div class="draw-type-title">选择绘制类型</div>
<div class="draw-buttons">
<el-button
@click="startDrawPolygon"
:type="currentDrawType === 'polygon' ? 'primary' : 'default'"
size="default"
>
<el-button @click="startDrawPolygon" :type="currentDrawType === 'polygon' ? 'primary' : 'default'"
size="default">
多边形
</el-button>
<el-button
@click="startDrawRectangle"
:type="currentDrawType === 'rectangle' ? 'primary' : 'default'"
size="default"
>
<el-button @click="startDrawRectangle" :type="currentDrawType === 'rectangle' ? 'primary' : 'default'"
size="default">
矩形
</el-button>
<el-button
@click="startDrawCircle"
:type="currentDrawType === 'circle' ? 'primary' : 'default'"
size="default"
>
<el-button @click="startDrawCircle" :type="currentDrawType === 'circle' ? 'primary' : 'default'"
size="default">
圆形
</el-button>
</div>
@@ -155,7 +138,8 @@
</div>
<div class="status-item" v-if="droneData">
<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 class="status-item" v-if="droneData">
<span class="status-label">高度:</span>
@@ -175,21 +159,12 @@
{{ isInFence ? '围栏内' : '围栏外' }}
</el-tag>
</div>
<el-button
@click="handleTakeoff"
:type="isFlying ? 'warning' : 'success'"
size="small"
style="width: 100%; margin-top: 8px;"
:disabled="isFlying"
>
<el-button @click="handleTakeoff" :type="isFlying ? 'warning' : 'success'" size="small"
style="width: 100%; margin-top: 8px;" :disabled="isFlying">
{{ isFlying ? '飞行中' : '起飞' }}
</el-button>
<el-button
@click="toggleWebSocket"
:type="wsConnected ? 'danger' : 'primary'"
size="small"
style="width: 100%; margin-top: 8px;margin-left: 0;"
>
<el-button @click="toggleWebSocket" :type="wsConnected ? 'danger' : 'primary'" size="small"
style="width: 100%; margin-top: 8px;margin-left: 0;">
{{ wsConnected ? '断开连接' : '开始连接' }}
</el-button>
</div>
@@ -197,58 +172,42 @@
<!-- 围栏列表 -->
<div class="fence-list" v-if="fences.length > 0">
<div class="list-title">已绘制围栏 ({{ fences.length }})</div>
<div
v-for="fence in fences"
:key="fence.id"
class="fence-item"
>
<div v-for="fence in fences" :key="fence.id" class="fence-item">
<span class="fence-info">
<span class="fence-name">{{ fence.name || '未命名围栏' }}</span>
</span>
<div class="fence-actions">
<el-button
@click="uploadFence(fence.id)"
type="primary"
size="small"
>
<el-button @click="uploadFence(fence.id)" type="primary" size="small">
上传
</el-button>
<el-button
@click="removeFence(fence.id)"
type="danger"
size="small"
>
<el-button @click="removeFence(fence.id)" type="danger" size="small">
删除
</el-button>
</div>
</div>
<el-button
@click="clearAllFences"
type="danger"
size="default"
style="width: 100%; margin-top: 8px;"
>
<el-button @click="clearAllFences" type="danger" size="default" style="width: 100%; margin-top: 8px;">
清除所有围栏
</el-button>
</div>
</div>
</div>
<!-- 右侧信息面板覆盖层 -->
<aside class="right-panel">
<!-- 区域管理 -->
<div class="info-panel">
<div class="panel-header">
<!-- <div class="panel-header">
<span class="panel-title">区域管理</span>
<span class="panel-count">12</span>
</div>
<div class="area-preview">
<img src="./assets/image/regional_management.png" alt="区域管理" class="area-image" />
</div>
</div> -->
</div>
<!-- 出勤设备 -->
<div class="info-panel">
<div class="panel-header">
<!-- <div class="panel-header">
<span class="panel-title">出勤设备</span>
<span class="panel-count">35</span>
</div>
@@ -268,12 +227,12 @@
<span class="status-number">12</span>
<span class="status-text">充电</span>
</div>
</div>
</div> -->
</div>
<!-- 执行任务 -->
<div class="info-panel">
<div class="panel-header">
<!-- <div class="panel-header">
<span class="panel-title">执行任务</span>
<span class="panel-count">12</span>
</div>
@@ -296,7 +255,7 @@
</div>
<span class="progress-text">60% 待开始</span>
</div>
</div>
</div> -->
</div>
</aside>
</div>
@@ -304,62 +263,17 @@
<!-- 底部导航栏 -->
<footer class="bottom-footer">
<div class="footer-left">
<span class="storage-info">62.3GB</span>
</div>
<div class="footer-center">
<div class="resolution-info">
<!-- <span class="resolution-text">1109px x 1902px</span> -->
</div>
<div class="footer-icons">
<img
:src="icon1"
class="footer-icon-img"
@click="handleFooterIconClick(1)"
alt="图标1"
/>
<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"
/>
<img src="./assets/image/d1.png" class="arrow-img" />
<img src="./assets/image/i1.png" class="icon-img" />
<img src="./assets/image/i2.png" class="icon-img" />
<img src="./assets/image/i3.png" class="icon-img" @click="handleFooterIconClick(4)"/>
<img src="./assets/image/i4.png" class="icon-img" />
<img src="./assets/image/i5.png" class="icon-img" />
<img src="./assets/image/d2.png" class="arrow-img" />
</div>
</div>
<div class="footer-right">
<span class="uptime-info">120.3 h</span>
</div>
</footer>
</div>
</template>
@@ -368,15 +282,6 @@
import { ref, onMounted, onUnmounted, computed } from 'vue'
import AMapLoader from '@amap/amap-jsapi-loader'
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 droneImage from './assets/image/wrj.png'
import icon1 from './assets/image/1.png'
@@ -1583,17 +1488,35 @@ onUnmounted(() => {
/* 左侧面板(覆盖层) */
.left-panel {
/* background: url('./assets/image/z1.png') no-repeat center center; */
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 320px;
padding: 20px;
overflow-y: auto;
z-index: 100;
display: flex;
flex-direction: column;
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;
}
}
/* 右侧面板(覆盖层) */
@@ -1609,6 +1532,24 @@ onUnmounted(() => {
display: flex;
flex-direction: column;
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 +1924,12 @@ onUnmounted(() => {
/* 底部导航栏 */
.bottom-footer {
height: 55px;
background: #0a0e27;
backdrop-filter: blur(15px);
border-top: 1px solid rgba(255, 255, 255, 0.15);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 40px;
z-index: 1000;
position: relative;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
@@ -2124,4 +2063,3 @@ onUnmounted(() => {
background: rgba(255, 255, 255, 0.5);
}
</style>

BIN
src/assets/image/d1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
src/assets/image/d2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 B

BIN
src/assets/image/i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/assets/image/i2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

BIN
src/assets/image/i3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/assets/image/i4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1008 B

BIN
src/assets/image/i5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
src/assets/image/wrj2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/assets/image/y1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/assets/image/y2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
src/assets/image/y3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
src/assets/image/z1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
src/assets/image/z2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
src/assets/image/z3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB