184
src/pages/open-location/index.vue
Normal file
184
src/pages/open-location/index.vue
Normal file
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<view class="open-location-page">
|
||||
<view class="open-location-panel">
|
||||
<text class="open-location-title">{{ title }}</text>
|
||||
<text class="open-location-desc">{{ description }}</text>
|
||||
<view class="open-location-actions">
|
||||
<view class="open-location-button primary" @tap="openLocation">
|
||||
<text class="open-location-button-text">重新打开</text>
|
||||
</view>
|
||||
<view class="open-location-button" @tap="goBack">
|
||||
<text class="open-location-button-text">返回导览</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
interface OpenLocationOptions {
|
||||
latitude?: string
|
||||
longitude?: string
|
||||
name?: string
|
||||
address?: string
|
||||
}
|
||||
|
||||
const latitude = ref<number | null>(null)
|
||||
const longitude = ref<number | null>(null)
|
||||
const locationName = ref('')
|
||||
const locationAddress = ref('')
|
||||
const hasOpened = ref(false)
|
||||
const hasError = ref(false)
|
||||
|
||||
const title = computed(() => {
|
||||
if (hasError.value) return '地图打开失败'
|
||||
if (hasOpened.value) return '已打开地图'
|
||||
return '正在打开地图'
|
||||
})
|
||||
|
||||
const description = computed(() => {
|
||||
if (hasError.value) return '请返回导览后重试,或检查小程序位置权限。'
|
||||
if (locationName.value) return locationName.value
|
||||
return '正在为你唤起地图位置页。'
|
||||
})
|
||||
|
||||
const safeDecode = (value?: string) => {
|
||||
if (!value) return ''
|
||||
|
||||
try {
|
||||
return decodeURIComponent(value)
|
||||
} catch {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
const goBack = () => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
fail: () => {
|
||||
uni.redirectTo({
|
||||
url: '/pages/index/index?tab=guide'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const openLocation = () => {
|
||||
if (latitude.value === null || longitude.value === null) {
|
||||
hasError.value = true
|
||||
uni.showToast({
|
||||
title: '缺少地图坐标',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
uni.openLocation({
|
||||
latitude: latitude.value,
|
||||
longitude: longitude.value,
|
||||
name: locationName.value,
|
||||
address: locationAddress.value,
|
||||
scale: 18,
|
||||
success: () => {
|
||||
hasOpened.value = true
|
||||
hasError.value = false
|
||||
setTimeout(goBack, 300)
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('打开地图位置失败:', error)
|
||||
hasError.value = true
|
||||
uni.showToast({
|
||||
title: '无法打开地图',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onLoad((options?: OpenLocationOptions) => {
|
||||
latitude.value = Number(options?.latitude)
|
||||
longitude.value = Number(options?.longitude)
|
||||
locationName.value = safeDecode(options?.name) || '深圳自然博物馆'
|
||||
locationAddress.value = safeDecode(options?.address)
|
||||
|
||||
if (!Number.isFinite(latitude.value) || !Number.isFinite(longitude.value)) {
|
||||
latitude.value = null
|
||||
longitude.value = null
|
||||
hasError.value = true
|
||||
return
|
||||
}
|
||||
|
||||
openLocation()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.open-location-page {
|
||||
min-height: 100vh;
|
||||
padding: 28px 20px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #f5f5ed;
|
||||
}
|
||||
|
||||
.open-location-panel {
|
||||
width: 100%;
|
||||
max-width: 360px;
|
||||
padding: 24px 20px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
background: #ffffff;
|
||||
border: 1px solid rgba(31, 35, 41, 0.08);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.open-location-title {
|
||||
font-size: 20px;
|
||||
line-height: 28px;
|
||||
font-weight: 700;
|
||||
color: #262421;
|
||||
}
|
||||
|
||||
.open-location-desc {
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: #424754;
|
||||
}
|
||||
|
||||
.open-location-actions {
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.open-location-button {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
height: 42px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid rgba(31, 35, 41, 0.12);
|
||||
border-radius: 8px;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.open-location-button.primary {
|
||||
border-color: #d7d800;
|
||||
background: #e0e100;
|
||||
}
|
||||
|
||||
.open-location-button-text {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
font-weight: 600;
|
||||
color: #262421;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user