235 lines
6.0 KiB
Markdown
235 lines
6.0 KiB
Markdown
# 临时方案:使用微信小程序位置选择
|
||
|
||
## 背景
|
||
|
||
由于腾讯地图API Key未开启WebService权限,暂时无法使用逆地理编码自动获取地址。
|
||
|
||
## 临时解决方案
|
||
|
||
使用微信小程序的 `wx.chooseLocation` API,让用户手动选择位置。
|
||
|
||
## 优缺点对比
|
||
|
||
### 当前方案(逆地理编码)
|
||
- ✅ 自动获取,无需用户操作
|
||
- ✅ 精确到街道门牌号
|
||
- ❌ 需要配置API Key
|
||
- ❌ 有调用次数限制
|
||
|
||
### 临时方案(手动选择)
|
||
- ✅ 无需配置API Key
|
||
- ✅ 用户可以精确选择位置
|
||
- ✅ 微信小程序原生支持
|
||
- ❌ 需要用户手动操作
|
||
- ❌ 体验稍差
|
||
|
||
## 实施方案
|
||
|
||
### 方案A:完全替换为手动选择
|
||
|
||
修改 `getLocation()` 方法:
|
||
|
||
```javascript
|
||
getLocation() {
|
||
// 使用微信小程序的位置选择
|
||
uni.chooseLocation({
|
||
success: (res) => {
|
||
console.log('选择的位置:', res)
|
||
this.latitude = res.latitude
|
||
this.longitude = res.longitude
|
||
this.address = res.address + (res.name ? ' ' + res.name : '')
|
||
|
||
uni.showToast({
|
||
title: '位置已选择',
|
||
icon: 'success'
|
||
})
|
||
},
|
||
fail: (err) => {
|
||
console.error('选择位置失败:', err)
|
||
uni.showToast({
|
||
title: '请选择位置',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
})
|
||
}
|
||
```
|
||
|
||
### 方案B:混合方案(推荐)
|
||
|
||
先自动获取GPS坐标,如果逆地理编码失败,提示用户手动选择:
|
||
|
||
```javascript
|
||
async getLocation() {
|
||
uni.showLoading({ title: '获取位置中...', mask: false })
|
||
|
||
try {
|
||
// 1. 先获取GPS坐标
|
||
const locationRes = await new Promise((resolve, reject) => {
|
||
uni.getLocation({
|
||
type: 'gcj02',
|
||
success: resolve,
|
||
fail: reject
|
||
})
|
||
})
|
||
|
||
this.latitude = locationRes.latitude
|
||
this.longitude = locationRes.longitude
|
||
|
||
// 2. 尝试逆地理编码
|
||
try {
|
||
await this.getAddress(locationRes.latitude, locationRes.longitude)
|
||
uni.hideLoading()
|
||
uni.showToast({ title: '位置已获取', icon: 'success', duration: 1000 })
|
||
} catch (e) {
|
||
// 3. 逆地理编码失败,提示用户手动选择
|
||
uni.hideLoading()
|
||
|
||
const confirmRes = await new Promise((resolve) => {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '自动获取地址失败,是否手动选择位置?',
|
||
success: (res) => resolve(res.confirm)
|
||
})
|
||
})
|
||
|
||
if (confirmRes) {
|
||
// 用户同意手动选择
|
||
const chooseRes = await new Promise((resolve, reject) => {
|
||
uni.chooseLocation({
|
||
latitude: this.latitude,
|
||
longitude: this.longitude,
|
||
success: resolve,
|
||
fail: reject
|
||
})
|
||
})
|
||
|
||
this.latitude = chooseRes.latitude
|
||
this.longitude = chooseRes.longitude
|
||
this.address = chooseRes.address + (chooseRes.name ? ' ' + chooseRes.name : '')
|
||
|
||
uni.showToast({ title: '位置已选择', icon: 'success' })
|
||
} else {
|
||
// 用户拒绝,使用坐标显示
|
||
this.address = `位置: ${this.latitude.toFixed(6)}, ${this.longitude.toFixed(6)}`
|
||
}
|
||
}
|
||
} catch (err) {
|
||
uni.hideLoading()
|
||
console.error('获取位置失败', err)
|
||
this.address = '位置获取失败,请检查权限'
|
||
uni.showToast({ title: '获取位置失败', icon: 'none' })
|
||
}
|
||
}
|
||
```
|
||
|
||
### 方案C:添加"手动选择位置"按钮
|
||
|
||
在页面上添加一个按钮,让用户可以主动选择位置:
|
||
|
||
```vue
|
||
<template>
|
||
<view class="location-section">
|
||
<view class="section-header">
|
||
<text class="section-title">📍 当前位置</text>
|
||
<view class="location-actions">
|
||
<view class="refresh-location" @click="getLocation">
|
||
<text>刷新</text>
|
||
</view>
|
||
<view class="choose-location" @click="chooseLocation">
|
||
<text>手动选择</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="location-info">
|
||
<text class="location-text">{{ address || '获取位置中...' }}</text>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
methods: {
|
||
// 手动选择位置
|
||
chooseLocation() {
|
||
uni.chooseLocation({
|
||
latitude: this.latitude || 31.230416,
|
||
longitude: this.longitude || 121.473701,
|
||
success: (res) => {
|
||
this.latitude = res.latitude
|
||
this.longitude = res.longitude
|
||
this.address = res.address + (res.name ? ' ' + res.name : '')
|
||
|
||
uni.showToast({
|
||
title: '位置已选择',
|
||
icon: 'success'
|
||
})
|
||
},
|
||
fail: (err) => {
|
||
console.error('选择位置失败:', err)
|
||
uni.showToast({
|
||
title: '选择位置失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
})
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style>
|
||
.location-actions {
|
||
display: flex;
|
||
gap: 10rpx;
|
||
}
|
||
|
||
.choose-location {
|
||
font-size: 24rpx;
|
||
color: #4a9b9f;
|
||
padding: 8rpx 16rpx;
|
||
background: rgba(74, 155, 159, 0.1);
|
||
border-radius: 20rpx;
|
||
}
|
||
</style>
|
||
```
|
||
|
||
## 推荐实施顺序
|
||
|
||
1. **立即实施:** 方案C - 添加"手动选择位置"按钮
|
||
- 不影响现有功能
|
||
- 给用户提供备选方案
|
||
- 开发成本低
|
||
|
||
2. **短期:** 配置腾讯地图API Key
|
||
- 按照《腾讯地图API配置指南》操作
|
||
- 开启WebService权限
|
||
- 恢复自动获取地址功能
|
||
|
||
3. **长期:** 方案B - 混合方案
|
||
- 自动获取 + 手动选择
|
||
- 最佳用户体验
|
||
- 容错性强
|
||
|
||
## 注意事项
|
||
|
||
1. **权限配置**
|
||
- 需要在 `manifest.json` 中配置位置权限
|
||
- 需要在微信小程序后台配置"位置接口"权限
|
||
|
||
2. **用户体验**
|
||
- 手动选择位置需要用户操作,可能影响体验
|
||
- 建议在UI上明确提示用户
|
||
|
||
3. **数据准确性**
|
||
- 手动选择的位置可能不是用户当前位置
|
||
- 建议在签到时记录选择方式(自动/手动)
|
||
|
||
## 相关文档
|
||
|
||
- 微信小程序位置API:https://developers.weixin.qq.com/miniprogram/dev/api/location/wx.chooseLocation.html
|
||
- uni-app位置API:https://uniapp.dcloud.net.cn/api/location/location.html
|
||
|
||
---
|
||
|
||
**创建时间:** 2026-01-26
|
||
**适用场景:** 腾讯地图API暂时无法使用时的临时方案
|