吉安感知网项目-前端
罗广辉
6 days ago 6271c27815722f98e424d2eb69c562bcd8b7c34a
feat: 支持导航
1 files modified
111 ■■■■■ changed files
applications/mobile-web-view/src/appComponents/workMap/index.vue 111 ●●●●● patch | view | raw | blame | history
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])
@@ -175,6 +203,42 @@
    }
}
function openNavigation() {
    if (!navigationTarget.value) {
        showToast('暂无可导航的位置')
        return
    }
    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
const getMapLocation = async () => {
    const customIcon = L.icon({
@@ -248,6 +312,11 @@
// 存储事件点标记实例,用于后续更新或移除
let incidentMarker = null
function formatCoordinate(value) {
    const numberValue = Number(value)
    return Number.isNaN(numberValue) ? value : numberValue.toFixed(6)
}
// 添加事件点标记
function addIncidentMarker(data) {
    // 检查地图和标记层是否已初始化
@@ -284,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({
@@ -359,7 +441,8 @@
        width: 100%;
        height: 100%;
    }
    .location-btn{
    .location-btn,
    .nav-btn{
        display: flex;
        flex-direction: column;
        justify-content: center;
@@ -380,6 +463,9 @@
    .location-btn {
        bottom: 76px;
    }
    .nav-btn {
        bottom: 28px;
    }
}
// 位置标记闪烁效果
@@ -387,6 +473,29 @@
    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);