|
|
|
@ -0,0 +1,522 @@
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
|
|
|
<el-dialog
|
|
|
|
|
|
|
|
v-model="visible"
|
|
|
|
|
|
|
|
title="选择坐标"
|
|
|
|
|
|
|
|
width="800px"
|
|
|
|
|
|
|
|
:close-on-click-modal="false"
|
|
|
|
|
|
|
|
@closed="handleClose"
|
|
|
|
|
|
|
|
@opened="handleOpened"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<div class="map-container">
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
|
|
ref="mapContainer"
|
|
|
|
|
|
|
|
style="width: 100%; height: 400px; border: 1px solid #ccc; position: relative; z-index: 1"
|
|
|
|
|
|
|
|
v-loading="mapLoading || isGettingLocation"
|
|
|
|
|
|
|
|
:element-loading-text="isGettingLocation ? '正在获取当前位置...' : '正在加载地图...'"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<!-- 自定义标记 -->
|
|
|
|
|
|
|
|
<div v-if="markerPosition && map" class="custom-marker" :style="markerPosition">
|
|
|
|
|
|
|
|
<div class="marker-pin"></div>
|
|
|
|
|
|
|
|
<div class="marker-shadow"></div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 错误提示 -->
|
|
|
|
|
|
|
|
<div v-if="mapError" class="error-info">
|
|
|
|
|
|
|
|
<el-alert :title="mapError" type="error" :closable="false" show-icon />
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 坐标信息 -->
|
|
|
|
|
|
|
|
<div v-else class="coordinate-info">
|
|
|
|
|
|
|
|
<p>当前选择坐标:经度 {{ selectedLng || '未选择' }}, 纬度 {{ selectedLat || '未选择' }}</p>
|
|
|
|
|
|
|
|
<p class="tip">点击地图选择坐标位置</p>
|
|
|
|
|
|
|
|
<p
|
|
|
|
|
|
|
|
v-if="selectedLng && selectedLat && !props.longitude && !props.latitude"
|
|
|
|
|
|
|
|
class="current-location-info"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
📍 已自动定位到当前位置
|
|
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<p v-else-if="selectedLng && selectedLat" class="selected-info">✅ 已选择坐标点</p>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 使用原生按钮 -->
|
|
|
|
|
|
|
|
<div class="native-button-area">
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
|
|
class="location-btn"
|
|
|
|
|
|
|
|
@click="getCurrentLocationManually"
|
|
|
|
|
|
|
|
:disabled="isGettingLocation"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{{ isGettingLocation ? '定位中...' : '📍 获取当前位置' }}
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button type="button" class="cancel-btn" @click="handleClose">取消</button>
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
|
|
class="confirm-btn"
|
|
|
|
|
|
|
|
:disabled="!selectedLng || !selectedLat"
|
|
|
|
|
|
|
|
@click="confirmSelection"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
确定
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
|
|
import { MAP_CONFIG } from '@/config/map'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
|
|
|
modelValue: {
|
|
|
|
|
|
|
|
type: Boolean,
|
|
|
|
|
|
|
|
default: false,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
longitude: {
|
|
|
|
|
|
|
|
type: Number,
|
|
|
|
|
|
|
|
default: null,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
latitude: {
|
|
|
|
|
|
|
|
type: Number,
|
|
|
|
|
|
|
|
default: null,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits(['update:modelValue', 'confirm'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const visible = computed({
|
|
|
|
|
|
|
|
get: () => props.modelValue,
|
|
|
|
|
|
|
|
set: (val) => emit('update:modelValue', val),
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const mapContainer = ref(null)
|
|
|
|
|
|
|
|
const selectedLng = ref(props.longitude || null)
|
|
|
|
|
|
|
|
const selectedLat = ref(props.latitude || null)
|
|
|
|
|
|
|
|
const mapLoading = ref(false)
|
|
|
|
|
|
|
|
const mapError = ref('')
|
|
|
|
|
|
|
|
const markerPosition = ref(null)
|
|
|
|
|
|
|
|
const isGettingLocation = ref(false)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let map = null
|
|
|
|
|
|
|
|
let isMapInitialized = false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前位置
|
|
|
|
|
|
|
|
const getCurrentLocation = () => {
|
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
|
|
|
if (!navigator.geolocation) {
|
|
|
|
|
|
|
|
reject(new Error('浏览器不支持地理位置获取'))
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
isGettingLocation.value = true
|
|
|
|
|
|
|
|
console.log('开始获取当前位置...')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
navigator.geolocation.getCurrentPosition(
|
|
|
|
|
|
|
|
(position) => {
|
|
|
|
|
|
|
|
const { longitude, latitude } = position.coords
|
|
|
|
|
|
|
|
console.log('获取到当前位置:', { longitude, latitude })
|
|
|
|
|
|
|
|
resolve({ longitude, latitude })
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
(error) => {
|
|
|
|
|
|
|
|
console.error('获取位置失败:', error)
|
|
|
|
|
|
|
|
let errorMessage = '获取位置失败'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (error.code) {
|
|
|
|
|
|
|
|
case error.PERMISSION_DENIED:
|
|
|
|
|
|
|
|
errorMessage = '用户拒绝了位置请求'
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
case error.POSITION_UNAVAILABLE:
|
|
|
|
|
|
|
|
errorMessage = '位置信息不可用'
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
case error.TIMEOUT:
|
|
|
|
|
|
|
|
errorMessage = '获取位置超时'
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reject(new Error(errorMessage))
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
enableHighAccuracy: true,
|
|
|
|
|
|
|
|
timeout: 10000,
|
|
|
|
|
|
|
|
maximumAge: 60000,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}).finally(() => {
|
|
|
|
|
|
|
|
isGettingLocation.value = false
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 动态加载腾讯地图API
|
|
|
|
|
|
|
|
const loadTencentMapAPI = () => {
|
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
|
|
|
if (window.TMap) {
|
|
|
|
|
|
|
|
resolve()
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const script = document.createElement('script')
|
|
|
|
|
|
|
|
script.src = `https://map.qq.com/api/gljs?v=1.exp&key=${MAP_CONFIG.TENCENT_MAP_KEY}`
|
|
|
|
|
|
|
|
script.onload = () => {
|
|
|
|
|
|
|
|
if (window.TMap) {
|
|
|
|
|
|
|
|
resolve()
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
reject(new Error('腾讯地图API加载失败'))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
script.onerror = () => reject(new Error('腾讯地图API加载失败'))
|
|
|
|
|
|
|
|
document.head.appendChild(script)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 将经纬度转换为屏幕坐标
|
|
|
|
|
|
|
|
const latLngToPixel = (lat, lng) => {
|
|
|
|
|
|
|
|
if (!map) return null
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const point = map.projectToContainer(new window.TMap.LatLng(lat, lng))
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
left: point.getX() + 'px',
|
|
|
|
|
|
|
|
top: point.getY() + 'px',
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
console.error('坐标转换失败:', error)
|
|
|
|
|
|
|
|
return null
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 更新标记位置
|
|
|
|
|
|
|
|
const updateMarkerPosition = () => {
|
|
|
|
|
|
|
|
if (selectedLng.value && selectedLat.value && map) {
|
|
|
|
|
|
|
|
const position = latLngToPixel(selectedLat.value, selectedLng.value)
|
|
|
|
|
|
|
|
markerPosition.value = position
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
markerPosition.value = null
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化地图
|
|
|
|
|
|
|
|
const initMap = async () => {
|
|
|
|
|
|
|
|
if (!mapContainer.value || isMapInitialized) return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mapLoading.value = true
|
|
|
|
|
|
|
|
mapError.value = ''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
await loadTencentMapAPI()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 确定地图中心点
|
|
|
|
|
|
|
|
let centerLat = props.latitude || MAP_CONFIG.DEFAULT_CENTER.latitude
|
|
|
|
|
|
|
|
let centerLng = props.longitude || MAP_CONFIG.DEFAULT_CENTER.longitude
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 如果没有传入坐标,尝试获取当前位置
|
|
|
|
|
|
|
|
if (!props.latitude && !props.longitude) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const currentLocation = await getCurrentLocation()
|
|
|
|
|
|
|
|
centerLat = currentLocation.latitude
|
|
|
|
|
|
|
|
centerLng = currentLocation.longitude
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置选中的坐标为当前位置
|
|
|
|
|
|
|
|
selectedLat.value = currentLocation.latitude
|
|
|
|
|
|
|
|
selectedLng.value = currentLocation.longitude
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ElMessage.success('已获取到当前位置')
|
|
|
|
|
|
|
|
console.log('使用当前位置作为地图中心:', { centerLat, centerLng })
|
|
|
|
|
|
|
|
} catch (locationError) {
|
|
|
|
|
|
|
|
console.warn('获取当前位置失败,使用默认位置:', locationError.message)
|
|
|
|
|
|
|
|
ElMessage.warning('获取当前位置失败,使用默认位置')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 创建地图实例
|
|
|
|
|
|
|
|
map = new window.TMap.Map(mapContainer.value, {
|
|
|
|
|
|
|
|
center: new window.TMap.LatLng(centerLat, centerLng),
|
|
|
|
|
|
|
|
zoom: MAP_CONFIG.DEFAULT_ZOOM,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 添加点击事件
|
|
|
|
|
|
|
|
map.on('click', (event) => {
|
|
|
|
|
|
|
|
const lat = event.latLng.getLat()
|
|
|
|
|
|
|
|
const lng = event.latLng.getLng()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
selectedLat.value = lat
|
|
|
|
|
|
|
|
selectedLng.value = lng
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log('选择坐标:', { lng, lat })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 更新标记位置
|
|
|
|
|
|
|
|
updateMarkerPosition()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 移动地图中心到点击位置
|
|
|
|
|
|
|
|
map.setCenter(new window.TMap.LatLng(lat, lng))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 显示成功提示
|
|
|
|
|
|
|
|
ElMessage.success(`已选择坐标: ${lng.toFixed(6)}, ${lat.toFixed(6)}`)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 监听地图移动事件,更新标记位置
|
|
|
|
|
|
|
|
map.on('moveend', updateMarkerPosition)
|
|
|
|
|
|
|
|
map.on('zoomend', updateMarkerPosition)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 如果有初始坐标,更新标记位置
|
|
|
|
|
|
|
|
if (props.longitude && props.latitude) {
|
|
|
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
|
|
|
updateMarkerPosition()
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
isMapInitialized = true
|
|
|
|
|
|
|
|
console.log('腾讯地图初始化成功')
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
console.error('地图初始化失败:', error)
|
|
|
|
|
|
|
|
mapError.value = '地图加载失败: ' + error.message
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
mapLoading.value = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 更新地图中心
|
|
|
|
|
|
|
|
const updateMapCenter = () => {
|
|
|
|
|
|
|
|
if (map && (props.longitude || props.latitude)) {
|
|
|
|
|
|
|
|
const center = new window.TMap.LatLng(
|
|
|
|
|
|
|
|
props.latitude || MAP_CONFIG.DEFAULT_CENTER.latitude,
|
|
|
|
|
|
|
|
props.longitude || MAP_CONFIG.DEFAULT_CENTER.longitude
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
map.setCenter(center)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 更新标记位置
|
|
|
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
|
|
|
updateMarkerPosition()
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 手动获取当前位置
|
|
|
|
|
|
|
|
const getCurrentLocationManually = async () => {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const currentLocation = await getCurrentLocation()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
selectedLat.value = currentLocation.latitude
|
|
|
|
|
|
|
|
selectedLng.value = currentLocation.longitude
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 更新地图中心和标记
|
|
|
|
|
|
|
|
if (map) {
|
|
|
|
|
|
|
|
const center = new window.TMap.LatLng(currentLocation.latitude, currentLocation.longitude)
|
|
|
|
|
|
|
|
map.setCenter(center)
|
|
|
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
|
|
|
updateMarkerPosition()
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ElMessage.success('已获取到当前位置')
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
console.error('手动获取位置失败:', error)
|
|
|
|
|
|
|
|
ElMessage.error('获取当前位置失败: ' + error.message)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 确认选择
|
|
|
|
|
|
|
|
const confirmSelection = () => {
|
|
|
|
|
|
|
|
console.log('确认选择按钮被点击')
|
|
|
|
|
|
|
|
console.log('当前坐标:', { lng: selectedLng.value, lat: selectedLat.value })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (selectedLng.value && selectedLat.value) {
|
|
|
|
|
|
|
|
console.log('发送确认事件:', {
|
|
|
|
|
|
|
|
longitude: selectedLng.value,
|
|
|
|
|
|
|
|
latitude: selectedLat.value,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
emit('confirm', {
|
|
|
|
|
|
|
|
longitude: selectedLng.value,
|
|
|
|
|
|
|
|
latitude: selectedLat.value,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ElMessage.success('坐标确认成功!')
|
|
|
|
|
|
|
|
handleClose()
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
console.log('坐标未选择,无法确认')
|
|
|
|
|
|
|
|
ElMessage.warning('请先选择坐标位置')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 对话框打开时
|
|
|
|
|
|
|
|
const handleOpened = () => {
|
|
|
|
|
|
|
|
console.log('对话框已打开')
|
|
|
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
|
|
|
if (!isMapInitialized) {
|
|
|
|
|
|
|
|
initMap()
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
updateMapCenter()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭对话框
|
|
|
|
|
|
|
|
const handleClose = () => {
|
|
|
|
|
|
|
|
console.log('关闭对话框')
|
|
|
|
|
|
|
|
markerPosition.value = null
|
|
|
|
|
|
|
|
visible.value = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 监听props变化,更新选中的坐标
|
|
|
|
|
|
|
|
watch([() => props.longitude, () => props.latitude], ([newLng, newLat]) => {
|
|
|
|
|
|
|
|
selectedLng.value = newLng
|
|
|
|
|
|
|
|
selectedLat.value = newLat
|
|
|
|
|
|
|
|
updateMapCenter()
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 组件卸载时清理
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
|
|
|
if (map) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
map.destroy()
|
|
|
|
|
|
|
|
map = null
|
|
|
|
|
|
|
|
isMapInitialized = false
|
|
|
|
|
|
|
|
console.log('地图实例已清理')
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
console.warn('清理地图实例失败:', error)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
|
|
.map-container {
|
|
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.custom-marker {
|
|
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
|
|
z-index: 1000;
|
|
|
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
|
|
|
transform: translate(-50%, -100%);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.marker-pin {
|
|
|
|
|
|
|
|
width: 20px;
|
|
|
|
|
|
|
|
height: 20px;
|
|
|
|
|
|
|
|
background: #ff4444;
|
|
|
|
|
|
|
|
border: 3px solid #ffffff;
|
|
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&::after {
|
|
|
|
|
|
|
|
content: '';
|
|
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
|
|
top: 100%;
|
|
|
|
|
|
|
|
left: 50%;
|
|
|
|
|
|
|
|
transform: translateX(-50%);
|
|
|
|
|
|
|
|
width: 0;
|
|
|
|
|
|
|
|
height: 0;
|
|
|
|
|
|
|
|
border-left: 6px solid transparent;
|
|
|
|
|
|
|
|
border-right: 6px solid transparent;
|
|
|
|
|
|
|
|
border-top: 8px solid #ff4444;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.marker-shadow {
|
|
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
|
|
top: 100%;
|
|
|
|
|
|
|
|
left: 50%;
|
|
|
|
|
|
|
|
transform: translateX(-50%);
|
|
|
|
|
|
|
|
width: 16px;
|
|
|
|
|
|
|
|
height: 8px;
|
|
|
|
|
|
|
|
background: rgba(0, 0, 0, 0.2);
|
|
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
|
|
margin-top: 2px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.coordinate-info {
|
|
|
|
|
|
|
|
margin-top: 16px;
|
|
|
|
|
|
|
|
padding: 12px;
|
|
|
|
|
|
|
|
background-color: #f5f7fa;
|
|
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p {
|
|
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
|
|
color: #606266;
|
|
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&.tip {
|
|
|
|
|
|
|
|
color: #909399;
|
|
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
|
|
margin-top: 4px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&.selected-info {
|
|
|
|
|
|
|
|
color: #67c23a;
|
|
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
|
|
margin-top: 8px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&.current-location-info {
|
|
|
|
|
|
|
|
color: #409eff;
|
|
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
|
|
margin-top: 8px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.error-info {
|
|
|
|
|
|
|
|
margin-top: 16px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.native-button-area {
|
|
|
|
|
|
|
|
margin-top: 16px;
|
|
|
|
|
|
|
|
padding-top: 16px;
|
|
|
|
|
|
|
|
border-top: 1px solid #e4e7ed;
|
|
|
|
|
|
|
|
text-align: right;
|
|
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
z-index: 9999;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
button {
|
|
|
|
|
|
|
|
padding: 8px 16px;
|
|
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
|
|
border: 1px solid #dcdfe6;
|
|
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
|
|
color: #606266;
|
|
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
|
|
margin-left: 8px;
|
|
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
z-index: 10000;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
|
|
|
background-color: #f5f7fa;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&.confirm-btn {
|
|
|
|
|
|
|
|
background-color: #409eff;
|
|
|
|
|
|
|
|
border-color: #409eff;
|
|
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&:hover:not(:disabled) {
|
|
|
|
|
|
|
|
background-color: #66b1ff;
|
|
|
|
|
|
|
|
border-color: #66b1ff;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&:disabled {
|
|
|
|
|
|
|
|
background-color: #a0cfff;
|
|
|
|
|
|
|
|
border-color: #a0cfff;
|
|
|
|
|
|
|
|
cursor: not-allowed;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&.location-btn {
|
|
|
|
|
|
|
|
background-color: #67c23a;
|
|
|
|
|
|
|
|
border-color: #67c23a;
|
|
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&:hover:not(:disabled) {
|
|
|
|
|
|
|
|
background-color: #85ce61;
|
|
|
|
|
|
|
|
border-color: #85ce61;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&:disabled {
|
|
|
|
|
|
|
|
background-color: #b3e19d;
|
|
|
|
|
|
|
|
border-color: #b3e19d;
|
|
|
|
|
|
|
|
cursor: not-allowed;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
</style>
|