优化地址选择,使用chooseLocation

This commit is contained in:
WindowBird 2025-09-03 17:57:17 +08:00
parent f4fac402d9
commit 6c738fb09c
2 changed files with 128 additions and 388 deletions

View File

@ -1,78 +1,40 @@
<template>
<view class="map-location-component">
<!-- 地址输入-->
<!-- 地址显示-->
<view class="form-item address-form-item">
<text class="field-label">{{ label || '地址' }}</text>
<view class="address-input-wrapper">
<input
v-model="addressValue"
:placeholder="placeholder || '请输入或选择收货地址'"
class="address-input"
@focus="onAddressFocus"
@input="onAddressInput"
/>
<view class="map-icon-wrapper" title="点击获取定位并打开地图" @click="openMapWithLocation">
<view class="address-display-wrapper">
<view class="address-display" @click="authVerification">
<text class="address-text">{{ addressValue || placeholder || '请选择收货地址' }}</text>
</view>
<view class="map-icon-wrapper" title="点击获取定位并打开地图" @click="authVerification">
<text class="map-icon">🗺</text>
</view>
</view>
</view>
<!-- 当前定位 -->
<!-- <view class="location-suggestion">-->
<!-- <view v-if="currentLocation" class="location-card">-->
<!-- <view class="location-content">-->
<!-- <view class="location-header">-->
<!-- <text class="location-title">当前定位</text>-->
<!-- </view>-->
<!-- <text class="location-address">{{ currentLocation.address }}</text>-->
<!-- </view>-->
<!-- <button class="use-location-btn" @click="useCurrentLocation">使用</button>-->
<!-- </view>-->
<!-- <view v-else class="location-card">-->
<!-- <view class="location-content">-->
<!-- <view class="location-header">-->
<!-- <text class="location-title">获取位置</text>-->
<!-- <text class="location-company">点击获取当前位置</text>-->
<!-- </view>-->
<!-- <text class="location-address">需要定位权限</text>-->
<!-- </view>-->
<!-- <button class="get-location-btn" @click="getCurrentLocation">获取</button>-->
<!-- </view>-->
<!-- </view>-->
</view>
</template>
<script>
import { getLocationWithPermission, handleLocationError } from '@/utils/permission.js'
export default {
name: 'MapLocation',
props: {
//
label: {
type: String,
default: '地址',
},
//
placeholder: {
type: String,
default: '请输入或选择收货地址',
default: '请选择收货地址',
},
//
value: {
type: String,
default: '',
},
//
showLocationCard: {
type: Boolean,
default: true,
},
},
data() {
return {
currentLocation: null,
isMapTriggered: false,
addressValue: this.value,
}
},
@ -85,179 +47,44 @@ export default {
},
},
methods: {
//
async getCurrentLocation() {
try {
uni.showLoading({
title: '获取位置中...',
})
const location = await getLocationWithPermission()
console.log('位置信息:', location)
// 使
this.currentLocation = {
address: `纬度: ${location.latitude.toFixed(6)}, 经度: ${location.longitude.toFixed(6)}`,
latitude: location.latitude,
longitude: location.longitude,
}
uni.hideLoading()
//
if (!this.isMapTriggered) {
uni.showToast({
title: '位置获取成功,点击地图图标查看',
icon: 'success',
duration: 3000,
})
}
//
this.$emit('location-success', this.currentLocation)
return this.currentLocation
} catch (err) {
uni.hideLoading()
handleLocationError(err)
this.$emit('location-error', err)
throw err
}
},
//
onAddressFocus() {
this.$emit('address-focus')
},
//
onAddressInput(e) {
const value = e.detail.value
this.addressValue = value
this.$emit('input', value)
this.$emit('address-input', value)
},
//
async openMapWithLocation() {
try {
this.isMapTriggered = true
//
await this.getCurrentLocation()
//
this.openMap()
} catch (err) {
console.error('获取位置失败:', err)
uni.showToast({
title: '获取位置失败',
icon: 'error',
})
} finally {
this.isMapTriggered = false
}
},
//
openMap() {
if (!this.currentLocation) {
uni.showToast({
title: '请先获取位置信息',
icon: 'none',
})
return
}
const { latitude, longitude } = this.currentLocation
//
uni.showLoading({
title: '打开地图中...',
authVerification() {
uni.getSetting({
success: res => {
if (res.authSetting['scope.userLocation']) {
this.handerChooseLocation()
} else if (res.authSetting['scope.userLocation'] === undefined) {
this.handleOpenSetting()
} else {
this.handleOpenSetting()
}
},
})
//
// #ifdef APP-PLUS
uni.openLocation({
latitude: latitude,
longitude: longitude,
name: '当前位置',
address: this.currentLocation.address || '未知地址',
scale: 18,
success: () => {
uni.hideLoading()
console.log('地图打开成功')
this.$emit('map-opened')
},
handerChooseLocation(latitude, longitude) {
uni.chooseLocation({
latitude: latitude || '',
longitude: longitude || '',
success: res => {
this.addressValue = res.address || res.name
this.$emit('location-selected', res)
this.$emit('location-success', res)
uni.setStorageSync('currentLocation', res)
},
fail: err => {
uni.hideLoading()
console.error('打开地图失败:', err)
this.showMapInApp()
console.log('取消选择位置', err)
this.$emit('location-cancel', err)
this.$emit('location-error', err)
},
})
// #endif
// #ifdef MP-WEIXIN
uni.openLocation({
latitude: latitude,
longitude: longitude,
name: '当前位置',
address: this.currentLocation.address || '未知地址',
scale: 18,
success: () => {
uni.hideLoading()
this.$emit('map-opened')
},
fail: err => {
uni.hideLoading()
console.error('打开地图失败:', err)
this.showMapInApp()
},
handleOpenSetting() {
wx.openSetting({
success: res => {
if (res.authSetting['scope.userLocation']) {
this.handerChooseLocation()
}
},
})
// #endif
// #ifdef H5
// H5使线
uni.hideLoading()
const mapUrl = `https://uri.amap.com/marker?position=${longitude},${latitude}&name=${encodeURIComponent('当前位置')}&address=${encodeURIComponent(this.currentLocation.address || '未知地址')}`
window.open(mapUrl, '_blank')
this.$emit('map-opened')
// #endif
},
//
showMapInApp() {
uni.showModal({
title: '地图功能',
content: `${this.currentLocation.address}\n\n经纬度${this.currentLocation.latitude.toFixed(6)}, ${this.currentLocation.longitude.toFixed(6)}`,
showCancel: false,
confirmText: '确定',
})
},
// 使
useCurrentLocation() {
if (!this.currentLocation) {
this.getCurrentLocation()
return
}
this.addressValue = this.currentLocation.address
this.$emit('input', this.currentLocation.address)
this.$emit('use-location', this.currentLocation)
uni.showToast({
title: '已使用当前定位',
icon: 'success',
})
},
//
setLocation(location) {
this.currentLocation = location
},
//
clearLocation() {
this.currentLocation = null
},
},
}
@ -269,44 +96,46 @@ export default {
width: 100%;
}
//
.address-form-item {
//margin-bottom: 20rpx;
display: flex;
align-items: center;
align-items: center; /* 改为 center 让标签和内容垂直居中 */
padding: 20rpx 0;
.field-label {
display: block;
font-size: 28rpx;
color: #333;
font-weight: 400;
flex: 1;
line-height: 1.5; /* 确保文本垂直居中 */
}
}
//
.address-input-wrapper {
.address-display-wrapper {
flex: 3;
display: flex;
align-items: center;
height: 80rpx;
min-height: 80rpx;
padding: 0 20rpx;
border-radius: 12rpx;
background: #fff;
transition: all 0.3s ease;
.address-input {
.address-display {
flex: 1;
height: 100%;
font-size: 28rpx;
color: #333;
border: none;
outline: none;
background: transparent;
display: flex;
align-items: center;
min-height: 56rpx;
}
&::placeholder {
color: #999;
}
.address-text {
font-size: 28rpx;
color: #999; /* 改为浅灰色,符合图片中的提示文字颜色 */
line-height: 1.5;
word-break: break-all;
white-space: pre-wrap;
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
.map-icon-wrapper {
@ -315,10 +144,10 @@ export default {
justify-content: center;
width: 48rpx;
height: 48rpx;
background: #f15a04;
background: #f15a04; /* 橙色背景 */
border-radius: 50%;
transition: all 0.3s ease;
margin-left: 16rpx;
flex-shrink: 0;
&:active {
transform: scale(0.9);
@ -331,96 +160,4 @@ export default {
}
}
}
//
.location-suggestion {
margin-bottom: 40rpx;
.location-card {
display: flex;
align-items: center;
justify-content: space-between;
background: white;
border: 2rpx solid #e8f4fd;
border-radius: 16rpx;
padding: 24rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
position: relative;
&::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 6rpx;
background: #f3f5f6;
border-radius: 6rpx 0 0 6rpx;
}
.location-content {
flex: 1;
margin-right: 20rpx;
.location-header {
display: flex;
align-items: center;
margin-bottom: 8rpx;
.location-title {
font-size: 24rpx;
color: #f15a04;
font-weight: 500;
margin-right: 12rpx;
}
.location-company {
font-size: 26rpx;
color: #333;
font-weight: 500;
}
}
.location-address {
font-size: 24rpx;
color: #666;
line-height: 1.4;
}
}
.use-location-btn {
background: #f15a04;
color: #000000;
border: none;
border-radius: 24rpx;
padding: 12rpx 24rpx;
font-size: 24rpx;
font-weight: 500;
box-shadow: 0 4rpx 12rpx rgba(255, 107, 107, 0.3);
transition: all 0.3s ease;
&:active {
transform: translateY(2rpx);
box-shadow: 0 2rpx 8rpx rgba(255, 107, 107, 0.4);
}
}
.get-location-btn {
background: #f15a04;
color: #ffffff;
border: none;
border-radius: 24rpx;
padding: 12rpx 24rpx;
font-size: 24rpx;
font-weight: 500;
box-shadow: 0 4rpx 12rpx rgba(255, 107, 107, 0.3);
transition: all 0.3s ease;
&:active {
transform: translateY(2rpx);
box-shadow: 0 2rpx 8rpx rgba(255, 107, 107, 0.4);
}
}
}
}
</style>

View File

@ -1,69 +1,72 @@
<template>
<view class="content">
<button @tap="authVerification">请选择位置</button>
<template v-if="currentLocation.address">
<div>name{{currentLocation.name}}</div>
<div>address{{currentLocation.address}}</div>
<div>latitude{{currentLocation.latitude}}</div>
<div>longitude{{currentLocation.longitude}}</div>
</template>
</view>
<view class="content">
<button @tap="authVerification">请选择位置</button>
<template v-if="currentLocation.address">
<div>name{{ currentLocation.name }}</div>
<div>address{{ currentLocation.address }}</div>
<div>latitude{{ currentLocation.latitude }}</div>
<div>longitude{{ currentLocation.longitude }}</div>
</template>
</view>
</template>
<script>
export default {
data() {
return {
currentLocation:{},
}
},
onShow () {
uni.getStorage({
key: 'currentLocation',
success: (res) => {
this.currentLocation = res.data
}
})
},
methods: {
authVerification () {
uni.getSetting({
success: (res) => {
if (res.authSetting['scope.userLocation']) { /* 用户授权成功时走这里 */
this.handerChooseLocation()
} else if (res.authSetting['scope.userLocation'] === undefined) { /* 用户未授权时走这里 */
console.log('没有授权')
this.handleOpenSetting()
} else { /* 用户拒绝了授权后走这里 */
console.log('拒绝了授权 false')
this.handleOpenSetting()
}
},
})
},
handerChooseLocation (latitude, longitude) {
uni.chooseLocation({
latitude: latitude || '',
longitude: longitude || '',
success: (res) => {
console.log('wx.chooseLocation res=', res)
uni.setStorageSync('currentLocation', res)
},
fail: function (err) {
console.log('取消按钮', err)
}
})
},
handleOpenSetting () {
wx.openSetting({
success: (res) => {
console.log('定位 openSetting', res)
if (res.authSetting["scope.userLocation"]) {
this.handerChooseLocation()
}
}
})
}
}
}
export default {
data() {
return {
currentLocation: {},
}
},
onShow() {
uni.getStorage({
key: 'currentLocation',
success: res => {
this.currentLocation = res.data
},
})
},
methods: {
authVerification() {
uni.getSetting({
success: res => {
if (res.authSetting['scope.userLocation']) {
/* 用户授权成功时走这里 */
this.handerChooseLocation()
} else if (res.authSetting['scope.userLocation'] === undefined) {
/* 用户未授权时走这里 */
console.log('没有授权')
this.handleOpenSetting()
} else {
/* 用户拒绝了授权后走这里 */
console.log('拒绝了授权 false')
this.handleOpenSetting()
}
},
})
},
handerChooseLocation(latitude, longitude) {
uni.chooseLocation({
latitude: latitude || '',
longitude: longitude || '',
success: res => {
console.log('wx.chooseLocation res=', res)
uni.setStorageSync('currentLocation', res)
},
fail: function (err) {
console.log('取消按钮', err)
},
})
},
handleOpenSetting() {
wx.openSetting({
success: res => {
console.log('定位 openSetting', res)
if (res.authSetting['scope.userLocation']) {
this.handerChooseLocation()
}
},
})
},
},
}
</script>