From cc107a19b742acc306d9ab00b0a1cd0ce7081101 Mon Sep 17 00:00:00 2001
From: hx <190679152@qq.com>
Date: Fri, 20 Mar 2026 16:31:56 +0800
Subject: [PATCH] =?UTF-8?q?b=E7=AB=AF=E5=9B=BD=E9=99=85=E5=8C=96=20?=
=?UTF-8?q?=E5=9C=B0=E5=9B=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/device/TrajectoryDialog.vue | 71 +++++++++++++++++++---
1 file changed, 62 insertions(+), 9 deletions(-)
diff --git a/src/components/device/TrajectoryDialog.vue b/src/components/device/TrajectoryDialog.vue
index be57b63..fe16e38 100644
--- a/src/components/device/TrajectoryDialog.vue
+++ b/src/components/device/TrajectoryDialog.vue
@@ -122,6 +122,8 @@ const LEAFLET_DEFAULT_CENTER = [31.2304, 121.4737];
const AMAP_FALLBACK_MAX_ZOOM = 20;
const GOOGLE_DETAIL_ZOOM = 21;
const LEAFLET_MAX_ZOOM = 22;
+const LEAFLET_GOOGLE_MAX_ZOOM = 20;
+const LEAFLET_GOOGLE_TILE_URL = "https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}";
const LEAFLET_LINE_ARROW_MAX = 36;
const LEAFLET_SHOW_LINE_ARROWS = false;
const LEAFLET_TRAJECTORY_LINE_COLOR = "#1a73e8";
@@ -179,7 +181,7 @@ export default {
return !!(this.mapConfig && this.mapConfig.gaodeKey);
},
hasGoogleKey() {
- return !!(this.mapConfig && this.mapConfig.googleKey);
+ return true;
},
hasMaptilerKey() {
return !!(this.mapConfig && this.mapConfig.maptilerKey);
@@ -286,14 +288,10 @@ export default {
try {
const response = await getDeviceTrajectoryMapConfig();
const data = response && response.data ? response.data : {};
- if (!data.gaodeKey && !data.googleKey && !data.maptilerKey) {
- this.loadError = this.$t("device.trajectory.message.missingMapKey");
- return;
- }
this.mapConfig = data;
} catch (error) {
- this.mapConfig = null;
- this.loadError = error && error.message ? error.message : this.$t("device.trajectory.message.mapConfigLoadFailed");
+ // Google tiles mode does not depend on map config, keep dialog usable.
+ this.mapConfig = {};
}
},
async fetchTrajectory() {
@@ -340,9 +338,9 @@ export default {
return;
}
if (this.mapProvider === "google") {
- await this.ensureGoogleMap();
+ await this.ensureLeafletGoogleMap();
if (!this.loadError) {
- this.renderGoogleTrajectory();
+ this.renderLeafletTrajectory();
}
return;
}
@@ -386,6 +384,21 @@ export default {
this.mapVendor = "leaflet";
} else {
this.mapsApi = mapsApi;
+ if (this.tileLayer && typeof this.map.removeLayer === "function") {
+ this.map.removeLayer(this.tileLayer);
+ }
+ this.tileLayer = mapsApi.tileLayer(
+ "https://api.maptiler.com/maps/streets/{z}/{x}/{y}{r}.png?key=" +
+ encodeURIComponent(this.mapConfig.maptilerKey),
+ {
+ attribution:
+ '© MapTiler © OpenStreetMap',
+ maxZoom: LEAFLET_MAX_ZOOM,
+ maxNativeZoom: LEAFLET_MAX_ZOOM,
+ detectRetina: true,
+ }
+ );
+ this.tileLayer.addTo(this.map);
if (typeof this.map.invalidateSize === "function") {
this.map.invalidateSize();
}
@@ -396,6 +409,46 @@ export default {
this.mapLoading = false;
}
},
+ async ensureLeafletGoogleMap() {
+ this.mapLoading = true;
+ try {
+ const mapsApi = await loadLeaflet();
+ if (!this.$refs.map) {
+ return;
+ }
+ if (!this.map || this.mapVendor !== "leaflet") {
+ this.destroyMap();
+ this.mapsApi = mapsApi;
+ this.map = mapsApi.map(this.$refs.map, {
+ center: LEAFLET_DEFAULT_CENTER,
+ zoom: LEAFLET_GOOGLE_MAX_ZOOM,
+ zoomControl: true,
+ });
+ this.tileLayer = mapsApi.tileLayer(LEAFLET_GOOGLE_TILE_URL, {
+ maxZoom: LEAFLET_GOOGLE_MAX_ZOOM,
+ });
+ this.tileLayer.addTo(this.map);
+ this.mapVendor = "leaflet";
+ return;
+ }
+
+ this.mapsApi = mapsApi;
+ if (this.tileLayer && typeof this.map.removeLayer === "function") {
+ this.map.removeLayer(this.tileLayer);
+ }
+ this.tileLayer = mapsApi.tileLayer(LEAFLET_GOOGLE_TILE_URL, {
+ maxZoom: LEAFLET_GOOGLE_MAX_ZOOM,
+ });
+ this.tileLayer.addTo(this.map);
+ if (typeof this.map.invalidateSize === "function") {
+ this.map.invalidateSize();
+ }
+ } catch (error) {
+ this.loadError = error && error.message ? error.message : this.$t("device.trajectory.message.googleLoadFailed");
+ } finally {
+ this.mapLoading = false;
+ }
+ },
renderLeafletTrajectory() {
if (!this.map || !this.mapsApi || !this.trajectoryPoints.length) {
return;