This commit is contained in:
zengmingjie 2025-06-25 23:29:21 +08:00
parent d98198b40d
commit e321227b96
4 changed files with 312 additions and 7 deletions

View File

@ -126,7 +126,7 @@
type="primary"
@click.stop="handlewhiteList(drone)"
>
{{ drone.IsWhitelist ? "信任" : "取消信任" }}
{{ !drone.IsWhitelist ? "信任" : "信任" }}
</el-button>
</div>
<div class="btn-navigation">
@ -519,7 +519,7 @@ export default {
company: " ",
mark: " "
};
if (drone.IsWhitelist) {
if (!drone.IsWhitelist) {
whitListAdd(params)
.then((res) => {
if (res.code === 0) {
@ -785,11 +785,11 @@ export default {
}
@keyframes greenanimated-shadow {
0% {
box-shadow: 0 0 0 0 #e1f850 inset;
box-shadow: 0 0 0 0 #ff0000 inset;
}
85% {
box-shadow: 0px 0px 100px 0px #e1f850 inset;
box-shadow: 0px 0px 100px 0px #ff0000 inset;
}
}
</style>

View File

@ -0,0 +1,295 @@
<template>
<div class="header">
<div class="header-left">
<div class="time_date">
{{ currentDate }} <span>{{ currentTime }}</span>
</div>
</div>
<div class="header-main">
<div class="textTile"></div>
</div>
<div class="header-menu">
<span>{{ leftText }}</span>
<span style="width: 20px"> | </span>
<span>{{ rightText }}</span>
</div>
<div v-if="showPermissionPrompt" class="permission-prompt">
<p>请允许地理位置权限以启用定位功能</p>
<p>您可以在浏览器地址栏设置中启用位置访问或点击下方按钮重试</p>
<button @click="retryTracking">重试定位</button>
</div>
</div>
</template>
<script>
import { mapGetters } from "vuex";
import { HomeSyncLocation } from "@/api/home";
import Geolocation from "ol/Geolocation";
import { fromLonLat, transform } from "ol/proj";
import { Vector as VectorLayer } from "ol/layer";
import VectorSource from "ol/source/Vector";
import Point from "ol/geom/Point";
import { Style, Icon, Stroke } from "ol/style";
import Feature from "ol/Feature";
export default {
name: "header-top",
props: {
homeData: {
type: Object,
default: () => ({})
}
},
data() {
return {
currentTime: "",
currentDate: "",
isAdmins: false,
leftText: "平台已连接",
rightText: "定位正常",
latitude: "",
longitude: "",
lastUpdated: "",
timer: null,
locationTimer: null,
geolocation: null,
showPermissionPrompt: false,
retryCount: 0,
positionLayer: null
};
},
computed: {
...mapGetters(["positionPoint"])
},
mounted() {
console.log("组件挂载,启动定位");
this.isAdmins = JSON.parse(localStorage.getItem("isAdmin"));
this.updateTime();
this.timer = setInterval(() => {
this.updateTime();
}, 1000);
this.startTracking();
},
watch: {
positionPoint: {
handler(newVal) {
if (newVal) {
// this.$message.success(this.latitude + ", " + this.longitude);
console.log("位置更新", newVal, this.latitude, this.longitude);
if (newVal && this.latitude && this.longitude && window.olMap) {
const newLocation = fromLonLat(
[this.longitude, this.latitude],
"EPSG:3857"
);
this.$message.success("定位成功");
this.updateMapPosition(this.longitude, this.latitude);
const zoomLevel = 13;
window.olMap.getView().animate({
center: newLocation,
zoom: zoomLevel
});
} else {
this.$message.error("定位失败,请稍后重试");
}
this.$store.commit("SET_POSITIONPOINT", false);
}
},
deep: true
}
},
methods: {
updateMapPosition(lng, lat) {
// positionLayer
if (this.positionLayer) {
window.olMap.removeLayer(this.positionLayer);
this.positionLayer = null;
}
let center = fromLonLat([lng, lat]);
var iconFeature = new Feature({
geometry: new Point(center),
name: "当前位置",
population: 4000,
rainfall: 500
});
var iconStyle = new Style({
image: new Icon({
anchor: [0.5, 46],
scale: 0.4,
anchorXUnits: "fraction",
anchorYUnits: "pixels",
src: require("@/assets/img/icon_dev.png")
})
});
iconFeature.setStyle(iconStyle);
var vectorSource = new VectorSource({
features: [iconFeature]
});
this.positionLayer = new VectorLayer({
source: vectorSource
});
window.olMap.addLayer(this.positionLayer);
},
updateTime() {
const now = new Date();
this.currentTime = now.toLocaleTimeString();
this.currentDate = now.toLocaleDateString();
},
startTracking() {
if (!window.olMap) {
console.error("OpenLayers 地图未传入,延迟重试");
setTimeout(() => this.startTracking(), 1000);
return;
}
// locationTimer
if (this.locationTimer) {
clearInterval(this.locationTimer);
}
// Geolocation
this.geolocation = new Geolocation({
trackingOptions: {
enableHighAccuracy: true,
timeout: 30000,
maximumAge: 10000
},
projection: window.olMap.getView().getProjection()
});
//
this.geolocation.on("error", (error) => {
let message = "";
this.retryCount = this.retryCount || 0;
switch (error.code) {
case error.PERMISSION_DENIED:
message = "请允许地理位置权限";
this.showPermissionPrompt = true;
this.$message.error("请在浏览器设置中启用地理位置权限");
break;
case error.POSITION_UNAVAILABLE:
message = "无法获取位置信息";
if (this.retryCount < 3) {
this.retryCount++;
setTimeout(() => this.startTracking(), 5000);
} else {
this.$message.error("多次尝试后仍无法定位,请检查设备设置");
}
break;
case error.TIMEOUT:
message = "获取位置超时";
if (this.retryCount < 3) {
this.retryCount++;
setTimeout(() => this.startTracking(), 5000);
} else {
this.$message.error("定位超时,请检查网络或 GPS 信号");
}
break;
default:
message = "未知错误";
}
this.leftText = message;
this.rightText = "定位异常";
});
//
this.geolocation.setTracking(true);
// 2
this.locationTimer = setInterval(() => {
const coordinates = this.geolocation.getPosition();
if (coordinates) {
this.handleSuccess(coordinates);
}
}, 2000);
},
handleSuccess(coordinates) {
// WGS84
const wgs84 = transform(coordinates, "EPSG:3857", "EPSG:4326");
this.longitude = wgs84[0];
this.latitude = wgs84[1];
this.lastUpdated = new Date().toLocaleString(); //EPSG:3857 EPSG:4326
this.showPermissionPrompt = false;
this.retryCount = 0;
// API
let params = {
lat: this.latitude,
lon: this.longitude,
userId: localStorage.getItem("userId")
};
this.updateMapPosition(this.longitude, this.latitude);
// console.log(":", {
// latitude: this.latitude,
// longitude: this.longitude,
// time: this.lastUpdated
// });
HomeSyncLocation(params)
.then((res) => {
if (res.code === 0) {
this.leftText = "平台已连接";
this.rightText = "定位正常";
} else {
this.leftText = "平台连接失败";
this.rightText = "定位异常";
}
})
.catch((err) => {
this.leftText = "平台连接失败";
this.rightText = "定位异常";
});
},
retryTracking() {
this.showPermissionPrompt = false;
this.retryCount = 0;
this.startTracking();
}
},
beforeDestroy() {
if (this.geolocation) {
this.geolocation.setTracking(false);
}
if (this.timer) {
clearInterval(this.timer);
}
if (this.locationTimer) {
clearInterval(this.locationTimer);
}
}
};
</script>
<style scoped>
.logo {
font-size: 20px;
font-weight: bold;
}
.time {
font-size: 14px;
}
.actions span {
margin-left: 10px;
cursor: pointer;
}
.permission-prompt {
position: fixed;
top: 20px;
right: 20px;
background: #fff;
padding: 15px;
border: 1px solid #ddd;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
z-index: 10000;
pointer-events: auto;
}
.permission-prompt p {
margin: 0 0 10px;
}
.permission-prompt button {
padding: 5px 10px;
background: #409eff;
color: #fff;
border: none;
cursor: pointer;
}
</style>

View File

@ -91,8 +91,6 @@ export default {
} else {
this.$message.error("定位失败,请稍后重试");
}
if (this.latitude === "" || this.longitude === "") {
}
this.$store.commit("SET_POSITIONPOINT", false);
}
},

View File

@ -4,6 +4,7 @@
<img :src="zoomLevelImage" alt="" />
</div>
<div class="zoom-control">刻度尺{{ zoomControl }}</div>
<div class="zoom-text">版本号V1.0</div>
<div class="btn-container" v-if="closeBtnVisible">
<el-button @click="handleClickClose()">返回</el-button>
</div>
@ -466,7 +467,18 @@ export default {
.zoom-control {
position: absolute;
left: 60px;
bottom: 30px;
bottom: 10px;
z-index: 1000;
color: #fff;
img {
width: 48px;
height: 48px;
}
}
.zoom-text {
position: absolute;
top: 18px;
right: 180px;
z-index: 1000;
color: #fff;
img {