ly-front/src/views/contentData/LeftSidebar/index.vue

420 lines
13 KiB
Vue
Raw Normal View History

2025-03-31 15:26:29 +00:00
<template>
<div class="left-sidebar" :class="{ contracted: isContracted }">
<div class="stats">
<div class="stat-item" v-for="(item, index) in warningDay" :key="index">
<div class="stat-name">{{ item.name }}</div>
2025-06-18 15:08:37 +00:00
<div class="stat-name">
<span>{{ item.value }}</span>
</div>
2025-03-31 15:26:29 +00:00
</div>
</div>
<div class="drone-list">
<ul>
2025-04-01 16:12:21 +00:00
<li
v-for="(drone, index) in drones"
:key="index"
@click="handleDroneClick(drone)"
2025-06-18 15:08:37 +00:00
:style="{
height: drone.detailsShow ? '60px' : '330px',
backgroundImage: drone.detailsShow
? `url(${require('@/assets/img/uavBackfff.png')})`
: `url(${require('@/assets/img/uavBackfff-big.png')})`,
padding: 0
}"
2025-04-01 16:12:21 +00:00
>
2025-06-18 15:08:37 +00:00
<div class="details-one" v-if="drone.detailsShow">
<div class="top">
<div class="left">
{{ index < 9 ? "0" + (index + 1) : index + 1 }}
</div>
<div class="text">{{ drone.serial_number }}</div>
<div class="img-vector">
<img src="@/assets/img/Vector.png" alt="" />
</div>
</div>
<div class="main">
<div class="top_main">
<div class="text">
<span class="color-ef">距离</span>
<span class="text-fff">{{ drone.currTime || 0 }}</span>
</div>
<div class="text">
<span class="color-ef">高度</span>
<span class="text-fff">{{ drone.height }}</span>
</div>
</div>
2025-03-31 15:26:29 +00:00
</div>
</div>
2025-06-18 15:08:37 +00:00
<div class="details-all" v-else>
<div class="top">
<div class="left">
{{ index < 9 ? "0" + (index + 1) : index + 1 }}
</div>
<div class="text">{{ drone.serial_number }}</div>
<div class="img-vector">
<img src="@/assets/img/Vector.png" alt="" />
</div>
2025-03-31 15:26:29 +00:00
</div>
2025-06-18 15:08:37 +00:00
<div class="content-main">
<div class="content-top">
<div class="top-left">
<span class="color-ef"> 距离</span>
<span class="text-fff">{{ drone.currTime || 0 }}</span>
</div>
<div class="top-right">
<span class="color-ef"> 高度</span>
<span class="text-fff">{{ drone.height || 0 }}</span>
</div>
</div>
<div class="content-serial">
<span class="color-ef"> 序列号</span>
<span class="text-fff">11VJF4D00201LE</span>
</div>
<div class="content-serial">
<span class="color-ef"> 型号</span>
<span class="text-fff">DJI Air 2S</span>
</div>
<div class="content-serial">
<span class="color-ef"> 更新时间</span>
<span class="text-fff">2025.6.15 21:12:43</span>
</div>
<div class="content-serial">
<span class="color-ef-fw">无人机方位</span>
</div>
<div class="content-serial" style="height: 25%">
<div class="content-potions">
<div class="content-potions-lon">
<p class="text">经纬度</p>
<p class="characters">
{{ drone.drone_lon }}, {{ drone.drone_lat }}
</p>
</div>
<div class="content-potions-bottom">
<div class="content-text content-potions-lat">
<p class="text">高度</p>
<p class="characters">{{ drone.height || 0 }}M</p>
</div>
<div class="content-text content-potions-speed">
<p class="text">速度</p>
<p class="characters">{{ drone.height }}M/h</p>
</div>
</div>
</div>
</div>
<div class="content-serial">
<span class="color-ef-fw">飞手方位</span>
</div>
<div class="content-serial" style="height: 25%">
<div class="content-potions">
<div class="content-text1 content-potions-lon">
<p class="text">经纬度</p>
<p class="characters">
{{ drone.drone_lon }}, {{ drone.drone_lat }}
</p>
</div>
<div class="content-text1 content-potions-lat">
<p class="text">高度</p>
<p class="characters">{{ drone.height || 0 }}m</p>
</div>
</div>
</div>
<div class="content-serial">
<div class="btns">
<div class="btn-trust"></div>
<div class="btn-navigation"></div>
</div>
</div>
2025-03-31 15:26:29 +00:00
</div>
</div>
</li>
</ul>
</div>
2025-04-03 14:28:51 +00:00
<audio
controls
loop
ref="uavAudio"
2025-04-02 14:38:27 +00:00
v-show="iswarning"
2025-04-03 14:28:51 +00:00
style="display: none"
>
<source src="@/assets/img/wargin.mp3" type="audio/mpeg" />
</audio>
<div class="audio-prompt" v-if="showAudioPrompt" @click="enableAudio">
<div class="prompt-content">
<p>因浏览器限制点击打开声音</p>
</div>
</div>
2025-03-31 15:26:29 +00:00
</div>
</template>
<script>
2025-04-01 16:12:21 +00:00
import moment from "moment";
import { mapUavFiex } from "../index.js";
2025-03-31 15:26:29 +00:00
export default {
name: "LeftSidebar",
props: {
homeData: {
type: Object,
default: () => ({})
2025-04-01 16:12:21 +00:00
},
signaData: {
type: Array,
default: () => []
2025-03-31 15:26:29 +00:00
}
},
data() {
return {
leftContract: require("@/assets/img/left-contract.png"),
rightContract: require("@/assets/img/right-contract.png"),
warningDay: [
{
id: "1",
name: "今日预警",
value: 20
},
{
id: "2",
name: "累计预警",
value: 20
2025-06-18 15:08:37 +00:00
}
],
drones: [
2025-03-31 15:26:29 +00:00
{
2025-06-18 15:08:37 +00:00
id: "1",
serial_number: "123456789",
DeviceName: "设备名称",
freq: "123.456GHz",
device_type: "UAV",
drone_lat: 30.592852,
drone_lon: 104.060059,
height: 100,
alarmLevel: 1,
times: "2021-01-01 12:00:00",
BatchId: "123456789",
DeviceId: "123456789",
currTime: 15,
detailsShow: false
2025-03-31 15:26:29 +00:00
}
],
isContracted: false,
2025-04-01 16:12:21 +00:00
homeView: {},
2025-04-02 14:29:18 +00:00
droneTimers: new Map(),
2025-04-04 11:57:33 +00:00
iswarning: false,
showAudioPrompt: false
2025-03-31 15:26:29 +00:00
};
},
2025-04-03 14:28:51 +00:00
mounted() {},
2025-03-31 15:26:29 +00:00
watch: {
homeData: {
handler(newVal) {
this.homeView = newVal;
this.warningDay[0].value = newVal.alarmCount.todaywaring;
this.warningDay[1].value = newVal.alarmCount.totalcount;
this.warningDay[2].value = newVal.alarmCount.todayhandle;
this.warningDay[3].value = newVal.alarmCount.totalhandle;
},
deep: true
2025-04-01 16:12:21 +00:00
},
signaData: {
handler(newVal) {
if (newVal) {
newVal.forEach((newItem) => {
// 如果已经存在相同BatchId的数据重置计时器
if (newItem.BatchId) {
const existingTimer = this.droneTimers.get(newItem.BatchId);
if (existingTimer) {
clearInterval(existingTimer); // 清除旧计时器
}
// 设置15秒初始时间
2025-04-26 08:37:01 +00:00
newItem.currTime = window.mapConfig.currTime;
2025-04-01 16:12:21 +00:00
// 创建新计时器
const timer = this.startTimer(newItem);
this.droneTimers.set(newItem.BatchId, timer);
// 更新无人机列表
const existingIndex = this.drones.findIndex(
(d) => d.BatchId === newItem.BatchId
);
newItem.times = moment(newItem.CreateTime).format("HH:mm:ss");
if (existingIndex !== -1) {
this.$set(this.drones, existingIndex, { ...newItem });
} else {
this.drones.push({ ...newItem });
}
}
});
2025-04-04 11:57:33 +00:00
if (newVal.length === 0) {
this.iswarning = false;
2025-04-04 12:00:59 +00:00
this.showAudioPrompt = false; // 没有数据 不显示提示框
2025-04-04 11:57:33 +00:00
}
2025-04-01 16:12:21 +00:00
if (this.drones) {
mapUavFiex(this.drones);
}
2025-04-02 14:29:18 +00:00
let alarm = this.drones.find((d) => d.alarmLevel === 1);
2025-04-03 14:28:51 +00:00
const media = this.$refs.uavAudio; // 修正 ref 名称为 "uavAudio"
2025-04-02 14:29:18 +00:00
if (alarm) {
this.iswarning = true;
2025-04-03 14:28:51 +00:00
this.$nextTick(() => {
if (media) {
media.muted = true; // 初始静音
media
.play()
.then(() => {
console.log("播放成功,取消静音");
media.muted = false; // 播放成功后取消静音
})
.catch((error) => {
console.log("播放失败:", error);
this.showAudioPrompt = true; // 播放失败时显示提示框
});
}
});
2025-04-02 14:29:18 +00:00
} else {
this.iswarning = false;
2025-04-03 14:28:51 +00:00
if (media) {
media.pause(); // 无告警时停止播放
media.currentTime = 0; // 重置到开始
}
2025-04-02 14:29:18 +00:00
}
2025-04-01 16:12:21 +00:00
}
},
deep: true
2025-03-31 15:26:29 +00:00
}
},
methods: {
2025-04-03 14:28:51 +00:00
enableAudio() {
this.iswarning = true;
const media = this.$refs.uavAudio;
let time = setInterval(() => {
console.log("用户手动启用音频", media);
if (media !== undefined) {
clearInterval(time);
media.muted = false; // 取消静音
media
.play()
.then(() => {
console.log("用户手动启用音频成功");
this.showAudioPrompt = false; // 关闭提示框
})
.catch((error) => {
console.error("手动播放失败:", error);
});
}
}, 500);
},
2025-04-01 16:12:21 +00:00
startTimer(item) {
return setInterval(() => {
if (item.currTime > 0) {
item.currTime--;
// 更新显示时间(可选)
const index = this.drones.findIndex(
(d) => d.BatchId === item.BatchId
);
if (index !== -1) {
this.$set(this.drones, index, { ...item });
}
} else {
clearInterval(this.droneTimers.get(item.BatchId));
this.droneTimers.delete(item.BatchId);
this.handleTimerExpiration(item);
2025-04-04 11:58:34 +00:00
this.showAudioPrompt = false; // 关闭提示框
2025-04-04 11:57:33 +00:00
this.iswarning = false;
const media = this.$refs.uavAudio;
media.muted = true; // 静音
2025-04-01 16:12:21 +00:00
}
}, 1000);
},
handleTimerExpiration(item) {
// 如果drones也需要同步更新
if (this.drones.length === 1) {
this.drones = [];
} else {
this.drones = this.drones.filter((d) => d.BatchId !== item.BatchId);
}
// 清理地图上的图形
let graphicLayer = window.marsMap.getLayerById("uavFiex");
if (graphicLayer) {
let graphic = graphicLayer.getGraphicById(item.BatchId);
let startPoint = graphicLayer.getGraphicById(item.BatchId + "start");
if (graphic) {
graphic.destroy();
graphicLayer.removeGraphic(graphic);
}
if (startPoint) {
graphicLayer.removeGraphic(startPoint);
}
if (this.drones.length === 0) {
window.marsMap.removeLayer(graphicLayer);
}
}
2025-04-16 14:58:11 +00:00
let graphicDevice = window.marsMap.getLayerById("devLog");
if (graphicDevice) {
let deviceGraphic = graphicDevice.getGraphicById(item.DeviceId);
if (deviceGraphic !== undefined) {
deviceGraphic.setOptions({
style: {
scale: 1.5
}
});
}
}
2025-04-01 16:12:21 +00:00
},
2025-03-31 15:26:29 +00:00
handleContractClick() {
this.isContracted = !this.isContracted; // 切换状态
2025-04-01 16:12:21 +00:00
},
handleDroneClick(value) {
2025-06-18 15:08:37 +00:00
value.detailsShow = !value.detailsShow;
2025-04-01 16:12:21 +00:00
if (value.drone_lon == 0 || value.drone_lat == 0) {
} else {
2025-04-06 14:39:09 +00:00
window.marsMap.setCameraView({
lat: value.drone_lat,
lng: value.drone_lon,
alt: value.height + 800,
pitch: -90
});
2025-04-01 16:12:21 +00:00
let graphicLayer = window.marsMap.getLayerById("uavFiex");
// let startPoint = graphicLayer.getGraphicById(value.BatchId + "start");
if (graphicLayer) {
graphicLayer.eachGraphic((car) => {
// 取出对应无人机的轨迹列表
if (value.BatchId === car.id) {
// car.openPopup();
car.polyline.show = !car.polyline.show; // 轨迹线
}
});
}
}
2025-03-31 15:26:29 +00:00
}
}
};
</script>
<style lang="scss" scoped>
.left-sidebar {
transition: transform 0.5s;
}
.left-sidebar.contracted {
transform: translateX(-90%);
}
2025-04-03 14:28:51 +00:00
.audio-prompt {
position: fixed;
top: 0;
left: 50%;
width: 15%;
height: 10%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
color: #fff;
border-radius: 5px;
transform: translateX(-50%);
}
2025-03-31 15:26:29 +00:00
</style>