From 493a27022ad30291934db825bab591c7efdcbc09 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Wed, 12 Aug 2026 16:35:45 +0800
Subject: [PATCH] feat: 保存的时候一个按钮置灰

---
 applications/mobile-web-view/src/appComponents/workMap/index.vue |  198 +++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 173 insertions(+), 25 deletions(-)

diff --git a/applications/mobile-web-view/src/appComponents/workMap/index.vue b/applications/mobile-web-view/src/appComponents/workMap/index.vue
index 38bfc99..71bf4e0 100644
--- a/applications/mobile-web-view/src/appComponents/workMap/index.vue
+++ b/applications/mobile-web-view/src/appComponents/workMap/index.vue
@@ -5,12 +5,25 @@
 					<van-image width="20" height="20" :src="locationIcon" />
 					<div class="label">定位</div>
 				</div>
+				<div class="nav-btn" @click="openNavigation" v-show="navigationTarget">
+					<van-image width="20" height="20" :src="mapnavIcon" />
+					<div class="label">导航</div>
+				</div>
+				<van-action-sheet
+					v-model:show="navigationSheetShow"
+					:actions="navigationActions"
+					cancel-text="取消"
+					@select="handleNavigationSelect"
+				/>
 
+
+				
 	</div>
 </template>
 
 <script setup>
 import { searchGeocoder } from '@/utils/util'
+import { showToast } from 'vant'
 import mapnavIcon from '@/appDataSource/appwork/mapnav.svg'
 import incidentPoint from '@/appDataSource/appwork/positioning1.svg'
 import userLocationIcon from '@/appDataSource/leafletMapIcon/user-location.svg'
@@ -51,6 +64,21 @@
 	})
 const currentAddress = ref('')
 const AMAP_KEY = '5b8ba312d053e4bdb44911733ece7d63'
+const navigationSheetShow = ref(false)
+const navigationActions = [{ name: '高德地图' }, { name: '百度地图' }, { name: '腾讯地图' }]
+const navigationTarget = computed(() => {
+	if (!workNavigationShow || !mapCurrentDetail?.longitude || !mapCurrentDetail?.latitude) return null
+
+	const lat = parseFloat(mapCurrentDetail.latitude)
+	const lng = parseFloat(mapCurrentDetail.longitude)
+	if (Number.isNaN(lat) || Number.isNaN(lng)) return null
+
+	return {
+		lat,
+		lng,
+		name: mapCurrentDetail.eventLocation || mapCurrentDetail.address || '工单位置',
+	}
+})
 
 const basemap0 = L.layerGroup([basemapLayer0, basemapLayer1])
 const basemap1 = L.layerGroup([basemapLayer2, basemapLayer3])
@@ -103,9 +131,9 @@
 let locationFlag = false
 let watchId = null
 let userLocationMarker = null
-const setMapLocation = () => {
-	locationFlag = true
 
+// 初始化实时位置监听
+const initLocationWatch = () => {
 	// 在WebView加载的网页中
 	// 检查浏览器是否支持 geolocation
 	if (navigator.geolocation) {
@@ -113,7 +141,6 @@
 			// 停止监听位置
 			navigator.geolocation.clearWatch(watchId)
 		}
-
 		// 开始持续获取用户的位置
 		watchId = navigator.geolocation.watchPosition(
 			function (position) {
@@ -121,27 +148,27 @@
 				const lat = position.coords.latitude // 纬度
 				const lng = position.coords.longitude // 经度
 
+				// 确保位置标记存在并更新位置
 				if (userLocationMarker) {
 					userLocationMarker.setLatLng([lat, lng])
-				}
-
-				if (locationFlag) {
+				} else {
 					userLocationMarker = L.marker([lat, lng], {
 						icon: L.icon({
 							iconUrl: userLocationIcon, // 图片路径
-							iconSize: [24, 24], // 图标尺寸
-							iconAnchor: [12, 12], // 锚点位置
-						}),
+								iconSize: [24, 24], // 图标尺寸
+								iconAnchor: [12, 12], // 锚点位置
+							}),
 					}).addTo(map)
+				}
 
+				// 如果是点击定位按钮触发的,将地图视图定位到当前位置
+				if (locationFlag) {
 					mapSetView({
 						lat,
 						lng,
 					})
-
 					locationFlag = false
 				}
-				// 可以根据位置更新地图或界面
 			},
 			function (error) {
 				// 如果获取位置失败,执行回调
@@ -154,20 +181,62 @@
 			}
 		)
 	} else {
-		console.log('Geolocation is not supported by this browser.')
+		console.log('该浏览器不支持地理定位功能。')
+	}
+}
+
+const setMapLocation = () => {
+	locationFlag = true
+	// 如果还没有开始监听位置,先初始化监听
+	if (!watchId) {
+		initLocationWatch()
+	} else {
+		// 已经在监听位置,会自动定位到当前位置
+		// 可以添加一个视觉反馈,比如位置标记闪烁效果
+		if (userLocationMarker) {
+			// 添加闪烁效果
+			userLocationMarker.getElement().classList.add('location-blink')
+			setTimeout(() => {
+				userLocationMarker.getElement().classList.remove('location-blink')
+			}, 1000)
+		}
+	}
+}
+
+function openNavigation() {
+	if (!navigationTarget.value) {
+		showToast('暂无可导航的位置')
+		return
 	}
 
-	// 获取定位信息
-	// uni.getLocation({
-	// 	type: 'wgs84', // 返回的经纬度是 WGS84 坐标系(适合地图定位)
-	// 	isHighAccuracy: true,
-	// 	success: function (res) {
-	// 		location.value = res
-	// 	},
-	// 	fail: function (err) {
-	// 		console.log('定位失败:', err)
-	// 	},
-	// })
+	navigationSheetShow.value = true
+}
+
+function handleNavigationSelect(action) {
+	navigationSheetShow.value = false
+	const url = getNavigationUrl(action.name, navigationTarget.value)
+	if (url) {
+		window.location.href = url
+	}
+}
+
+function getNavigationUrl(type, target) {
+	const [gcjLng, gcjLat] = wgs84ToGcj02(target.lng, target.lat)
+	const name = encodeURIComponent(target.name)
+
+	if (type === '高德地图') {
+		return `https://uri.amap.com/navigation?to=${gcjLng},${gcjLat},${name}&mode=car&policy=1&coordinate=gaode&callnative=1`
+	}
+
+	if (type === '百度地图') {
+		return `https://api.map.baidu.com/direction?destination=latlng:${gcjLat},${gcjLng}|name:${name}&mode=driving&coord_type=gcj02&output=html&src=ja-web`
+	}
+
+	if (type === '腾讯地图') {
+		return `https://apis.map.qq.com/uri/v1/routeplan?type=drive&tocoord=${gcjLat},${gcjLng}&to=${name}&referer=ja-web`
+	}
+
+	return ''
 }
 
 let lastLocationMarker = null
@@ -243,6 +312,11 @@
 // 存储事件点标记实例,用于后续更新或移除
 let incidentMarker = null
 
+function formatCoordinate(value) {
+	const numberValue = Number(value)
+	return Number.isNaN(numberValue) ? value : numberValue.toFixed(6)
+}
+
 // 添加事件点标记
 function addIncidentMarker(data) {
 	// 检查地图和标记层是否已初始化
@@ -279,6 +353,19 @@
 
 	// 存储关联数据
 	incidentMarker.options.customData = data
+	incidentMarker.bindTooltip(
+		`<div class="coordinate-label">
+			<div>经度:${formatCoordinate(lng)}</div>
+			<div>纬度:${formatCoordinate(lat)}</div>
+		</div>`,
+		{
+			permanent: true,
+			direction: 'top',
+			offset: L.point(0, -16),
+			opacity: 1,
+			className: 'incident-coordinate-tooltip',
+		}
+	)
 
 	// 定位到该标记点
 	mapSetView({
@@ -291,7 +378,7 @@
 watch(
 	() => mapCurrentDetail,
 	newVal => {
-const newDataMap=JSON.parse(newVal)
+const newDataMap=newVal
 		// 只有 workNavigationShow 为 true 且有经纬度时才添加标记
 		if (workNavigationShow && newDataMap?.longitude && newDataMap?.latitude) {
 			addIncidentMarker(newDataMap)
@@ -312,10 +399,24 @@
 	initMap()
 	map.addLayer(layers[0].map)
 
+	// 初始化实时位置监听
+	initLocationWatch()
+
 	EventBus.on('mapSetView', mapSetView)
 })
 
 onUnmounted(() => {
+	// 清理位置监听
+	if (watchId) {
+		navigator.geolocation.clearWatch(watchId)
+		watchId = null
+	}
+	// 移除位置标记
+	if (userLocationMarker) {
+		map.removeLayer(userLocationMarker)
+		userLocationMarker = null
+	}
+	
 	EventBus.off('mapSetView', mapSetView)
 	if (map) {
 		map.remove()
@@ -340,7 +441,8 @@
 		width: 100%;
 		height: 100%;
 	}
-	.location-btn{
+	.location-btn,
+	.nav-btn{
 		display: flex;
 		flex-direction: column;
 		justify-content: center;
@@ -361,5 +463,51 @@
 	.location-btn {
 		bottom: 76px;
 	}
+	.nav-btn {
+		bottom: 28px;
+	}
+}
+
+// 位置标记闪烁效果
+.location-blink {
+	animation: blink 1s ease-in-out;
+}
+
+:deep(.incident-coordinate-tooltip) {
+	padding: 0;
+	border: 0;
+	background: transparent;
+	box-shadow: none;
+
+	&::before {
+		display: none;
+	}
+}
+
+:deep(.coordinate-label) {
+	padding: 4px 7px;
+	background: rgba(255, 255, 255, 0.95);
+	border: 1px solid rgba(76, 133, 255, 0.35);
+	border-radius: 4px;
+	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
+	font-size: 11px;
+	line-height: 16px;
+	color: #222324;
+	white-space: nowrap;
+}
+
+@keyframes blink {
+	0% {
+		transform: scale(1);
+		opacity: 1;
+	}
+	50% {
+		transform: scale(1.2);
+		opacity: 0.8;
+	}
+	100% {
+		transform: scale(1);
+		opacity: 1;
+	}
 }
 </style>

--
Gitblit v1.9.3