821 lines
24 KiB
Vue
821 lines
24 KiB
Vue
<template>
|
||
<AppLayout title="选择地址" :showBack="true">
|
||
<view class="map-container">
|
||
<!-- 搜索框 -->
|
||
<view class="search-box">
|
||
<view class="search-input-wrapper">
|
||
<uni-icons type="search" size="20" color="#999"></uni-icons>
|
||
<input
|
||
class="search-input"
|
||
v-model="searchKeyword"
|
||
placeholder="输入关键词搜索地址(支持模糊搜索)"
|
||
@input="onSearchInput"
|
||
@confirm="searchLocation"
|
||
/>
|
||
<uni-icons
|
||
v-if="searchKeyword"
|
||
type="clear"
|
||
size="18"
|
||
color="#999"
|
||
@click="clearSearch"
|
||
></uni-icons>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 搜索结果列表 -->
|
||
<view class="search-results" v-if="showSearchResults">
|
||
<scroll-view scroll-y class="results-scroll" v-if="searchResults.length > 0">
|
||
<view
|
||
class="result-item"
|
||
v-for="(item, index) in searchResults"
|
||
:key="index"
|
||
@click="selectSearchResult(item)"
|
||
>
|
||
<view class="result-name">{{ item.name }}</view>
|
||
<view class="result-address">{{ item.address }}</view>
|
||
</view>
|
||
</scroll-view>
|
||
<view class="empty-results" v-else-if="isSearching">
|
||
<view class="loading-icon">
|
||
<uni-icons type="loop" size="40" color="#999"></uni-icons>
|
||
</view>
|
||
<text>搜索中...</text>
|
||
</view>
|
||
<view class="empty-results" v-else>
|
||
<uni-icons type="info" size="40" color="#999"></uni-icons>
|
||
<text>未找到相关地址,请尝试其他关键词</text>
|
||
<view class="search-tips">
|
||
<text class="tip-title">搜索建议:</text>
|
||
<text class="tip-item">• 输入具体地址名称</text>
|
||
<text class="tip-item">• 输入地标建筑名称</text>
|
||
<text class="tip-item">• 输入街道或区域名称</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 地图 -->
|
||
<view class="map-wrapper" v-show="!showSearchResults">
|
||
<!-- #ifdef H5 -->
|
||
<view id="amap-container" class="amap-container"></view>
|
||
<!-- #endif -->
|
||
|
||
<!-- #ifndef H5 -->
|
||
<map
|
||
id="map"
|
||
class="map"
|
||
:latitude="latitude"
|
||
:longitude="longitude"
|
||
:markers="markers"
|
||
:show-location="true"
|
||
@markertap="onMarkerTap"
|
||
@regionchange="onRegionChange"
|
||
@tap="onMapTap"
|
||
>
|
||
<cover-view class="map-center-marker">
|
||
<cover-image src="/static/icon/Location.png" class="marker-icon"></cover-image>
|
||
</cover-view>
|
||
</map>
|
||
<!-- #endif -->
|
||
</view>
|
||
|
||
<!-- 当前位置信息 -->
|
||
<view class="location-info" v-if="currentAddress && !showSearchResults">
|
||
<view class="info-title">当前选择位置</view>
|
||
<view class="info-name">{{ currentAddress.name }}</view>
|
||
<view class="info-address">{{ currentAddress.address }}</view>
|
||
</view>
|
||
|
||
<!-- 底部按钮 -->
|
||
<view class="bottom-actions">
|
||
<button class="locate-btn" @click="getCurrentLocation" :disabled="isLocating">
|
||
<uni-icons type="location-filled" size="20" color="#256BFA"></uni-icons>
|
||
<text>{{ isLocating ? '定位中...' : '定位' }}</text>
|
||
</button>
|
||
<button class="confirm-btn" @click="confirmLocation">确认选择</button>
|
||
</view>
|
||
</view>
|
||
</AppLayout>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, inject, onMounted } from 'vue'
|
||
import { onLoad } from '@dcloudio/uni-app'
|
||
|
||
const { $api } = inject('globalFunction')
|
||
|
||
// 搜索相关
|
||
const searchKeyword = ref('')
|
||
const searchResults = ref([])
|
||
const showSearchResults = ref(false)
|
||
const isSearching = ref(false)
|
||
const isLocating = ref(false)
|
||
let searchTimer = null
|
||
|
||
// 地图相关
|
||
const latitude = ref(36.066938)
|
||
const longitude = ref(120.382665)
|
||
const markers = ref([])
|
||
const currentAddress = ref(null)
|
||
|
||
// H5地图实例
|
||
let map = null
|
||
let AMap = null
|
||
let geocoder = null
|
||
let placeSearch = null
|
||
|
||
onLoad((options) => {
|
||
// 可以接收初始位置参数
|
||
if (options.latitude && options.longitude) {
|
||
latitude.value = parseFloat(options.latitude)
|
||
longitude.value = parseFloat(options.longitude)
|
||
}
|
||
})
|
||
|
||
onMounted(() => {
|
||
// #ifdef H5
|
||
initAmapH5()
|
||
// #endif
|
||
|
||
// #ifndef H5
|
||
// 先设置默认位置,避免地图显示空白
|
||
markers.value = [{
|
||
id: 1,
|
||
latitude: latitude.value,
|
||
longitude: longitude.value,
|
||
iconPath: '/static/icon/Location.png',
|
||
width: 30,
|
||
height: 30
|
||
}]
|
||
|
||
// 延迟执行定位,避免页面加载时立即定位失败
|
||
setTimeout(() => {
|
||
getCurrentLocation()
|
||
}, 1000)
|
||
// #endif
|
||
})
|
||
|
||
// H5端初始化高德地图
|
||
const initAmapH5 = () => {
|
||
// #ifdef H5
|
||
if (window.AMap) {
|
||
AMap = window.AMap
|
||
initMap()
|
||
} else {
|
||
const script = document.createElement('script')
|
||
script.src = 'https://webapi.amap.com/maps?v=2.0&key=9cfc9370bd8a941951da1cea0308e9e3&plugin=AMap.Geocoder,AMap.PlaceSearch'
|
||
script.onload = () => {
|
||
AMap = window.AMap
|
||
initMap()
|
||
}
|
||
document.head.appendChild(script)
|
||
}
|
||
// #endif
|
||
}
|
||
|
||
// 初始化地图
|
||
const initMap = () => {
|
||
// #ifdef H5
|
||
map = new AMap.Map('amap-container', {
|
||
zoom: 15,
|
||
center: [longitude.value, latitude.value],
|
||
resizeEnable: true
|
||
})
|
||
|
||
// 创建标记
|
||
const marker = new AMap.Marker({
|
||
position: [longitude.value, latitude.value],
|
||
draggable: true
|
||
})
|
||
|
||
marker.on('dragend', (e) => {
|
||
const position = e.target.getPosition()
|
||
longitude.value = position.lng
|
||
latitude.value = position.lat
|
||
reverseGeocode(position.lng, position.lat)
|
||
})
|
||
|
||
map.add(marker)
|
||
|
||
// 初始化地理编码
|
||
geocoder = new AMap.Geocoder({
|
||
city: '全国'
|
||
})
|
||
|
||
// 初始化地点搜索
|
||
placeSearch = new AMap.PlaceSearch({
|
||
city: '全国',
|
||
pageSize: 10
|
||
})
|
||
|
||
// 地图点击事件
|
||
map.on('click', (e) => {
|
||
const { lng, lat } = e.lnglat
|
||
longitude.value = lng
|
||
latitude.value = lat
|
||
marker.setPosition([lng, lat])
|
||
reverseGeocode(lng, lat)
|
||
})
|
||
|
||
// 获取当前位置信息
|
||
reverseGeocode(longitude.value, latitude.value)
|
||
// #endif
|
||
}
|
||
|
||
// 搜索输入
|
||
const onSearchInput = () => {
|
||
if (searchTimer) {
|
||
clearTimeout(searchTimer)
|
||
}
|
||
|
||
if (!searchKeyword.value.trim()) {
|
||
showSearchResults.value = false
|
||
searchResults.value = []
|
||
isSearching.value = false
|
||
return
|
||
}
|
||
|
||
showSearchResults.value = true
|
||
isSearching.value = true
|
||
|
||
searchTimer = setTimeout(() => {
|
||
if (searchKeyword.value.trim()) {
|
||
searchLocation()
|
||
}
|
||
}, 300) // 优化防抖时间从500ms改为300ms
|
||
}
|
||
|
||
// 搜索地点
|
||
const searchLocation = () => {
|
||
if (!searchKeyword.value.trim()) {
|
||
return
|
||
}
|
||
|
||
showSearchResults.value = true
|
||
isSearching.value = true
|
||
|
||
// #ifdef H5
|
||
if (placeSearch) {
|
||
placeSearch.search(searchKeyword.value, (status, result) => {
|
||
isSearching.value = false
|
||
if (status === 'complete' && result.poiList) {
|
||
searchResults.value = result.poiList.pois.map(poi => ({
|
||
name: poi.name,
|
||
address: poi.address || poi.pname + poi.cityname + poi.adname,
|
||
location: poi.location,
|
||
lng: poi.location.lng,
|
||
lat: poi.location.lat
|
||
}))
|
||
} else {
|
||
searchResults.value = []
|
||
}
|
||
})
|
||
}
|
||
// #endif
|
||
|
||
// #ifndef H5
|
||
// 小程序端使用uni.request调用高德API
|
||
uni.request({
|
||
url: 'https://restapi.amap.com/v3/place/text',
|
||
data: {
|
||
key: '9cfc9370bd8a941951da1cea0308e9e3',
|
||
keywords: searchKeyword.value,
|
||
city: '全国',
|
||
offset: 20,
|
||
citylimit: false, // 不限制城市,支持全国搜索
|
||
extensions: 'all' // 返回详细信息
|
||
},
|
||
success: (res) => {
|
||
isSearching.value = false
|
||
console.log('搜索响应:', res.data) // 调试日志
|
||
|
||
if (res.data.status === '1' && res.data.pois && res.data.pois.length > 0) {
|
||
searchResults.value = res.data.pois.map(poi => {
|
||
const [lng, lat] = poi.location.split(',')
|
||
return {
|
||
name: poi.name,
|
||
address: poi.address || `${poi.pname || ''}${poi.cityname || ''}${poi.adname || ''}`,
|
||
lng: parseFloat(lng),
|
||
lat: parseFloat(lat)
|
||
}
|
||
})
|
||
console.log('搜索结果:', searchResults.value) // 调试日志
|
||
} else {
|
||
// 如果第一次搜索没有结果,尝试更宽泛的搜索
|
||
if (searchKeyword.value.length > 2) {
|
||
tryAlternativeSearch()
|
||
} else {
|
||
searchResults.value = []
|
||
console.log('搜索无结果:', res.data) // 调试日志
|
||
}
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
isSearching.value = false
|
||
searchResults.value = []
|
||
console.error('搜索请求失败:', err) // 调试日志
|
||
$api.msg('搜索失败,请检查网络连接')
|
||
}
|
||
})
|
||
// #endif
|
||
}
|
||
|
||
// 备用搜索策略
|
||
const tryAlternativeSearch = () => {
|
||
// 尝试使用地理编码API搜索
|
||
uni.request({
|
||
url: 'https://restapi.amap.com/v3/geocode/geo',
|
||
data: {
|
||
key: '9cfc9370bd8a941951da1cea0308e9e3',
|
||
address: searchKeyword.value,
|
||
city: '全国'
|
||
},
|
||
success: (res) => {
|
||
isSearching.value = false
|
||
console.log('备用搜索响应:', res.data) // 调试日志
|
||
|
||
if (res.data.status === '1' && res.data.geocodes && res.data.geocodes.length > 0) {
|
||
searchResults.value = res.data.geocodes.map(geo => {
|
||
const [lng, lat] = geo.location.split(',')
|
||
return {
|
||
name: geo.formatted_address,
|
||
address: geo.formatted_address,
|
||
lng: parseFloat(lng),
|
||
lat: parseFloat(lat)
|
||
}
|
||
})
|
||
console.log('备用搜索结果:', searchResults.value) // 调试日志
|
||
} else {
|
||
searchResults.value = []
|
||
console.log('备用搜索也无结果:', res.data) // 调试日志
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
isSearching.value = false
|
||
searchResults.value = []
|
||
console.error('备用搜索失败:', err) // 调试日志
|
||
}
|
||
})
|
||
}
|
||
|
||
// 选择搜索结果
|
||
const selectSearchResult = (item) => {
|
||
longitude.value = item.lng
|
||
latitude.value = item.lat
|
||
currentAddress.value = {
|
||
name: item.name,
|
||
address: item.address,
|
||
longitude: item.lng,
|
||
latitude: item.lat
|
||
}
|
||
|
||
// #ifdef H5
|
||
if (map) {
|
||
map.setCenter([item.lng, item.lat])
|
||
const marker = map.getAllOverlays('marker')[0]
|
||
if (marker) {
|
||
marker.setPosition([item.lng, item.lat])
|
||
}
|
||
}
|
||
// #endif
|
||
|
||
// #ifndef H5
|
||
markers.value = [{
|
||
id: 1,
|
||
latitude: item.lat,
|
||
longitude: item.lng,
|
||
iconPath: '/static/icon/Location.png',
|
||
width: 30,
|
||
height: 30
|
||
}]
|
||
// #endif
|
||
|
||
showSearchResults.value = false
|
||
searchKeyword.value = ''
|
||
}
|
||
|
||
// 清除搜索
|
||
const clearSearch = () => {
|
||
searchKeyword.value = ''
|
||
searchResults.value = []
|
||
showSearchResults.value = false
|
||
isSearching.value = false
|
||
if (searchTimer) {
|
||
clearTimeout(searchTimer)
|
||
}
|
||
}
|
||
|
||
// 逆地理编码(根据坐标获取地址)
|
||
const reverseGeocode = (lng, lat) => {
|
||
// #ifdef H5
|
||
if (geocoder) {
|
||
geocoder.getAddress([lng, lat], (status, result) => {
|
||
if (status === 'complete' && result.regeocode) {
|
||
const addressComponent = result.regeocode.addressComponent
|
||
const formattedAddress = result.regeocode.formattedAddress
|
||
currentAddress.value = {
|
||
name: addressComponent.building || addressComponent.township,
|
||
address: formattedAddress,
|
||
longitude: lng,
|
||
latitude: lat
|
||
}
|
||
}
|
||
})
|
||
}
|
||
// #endif
|
||
|
||
// #ifndef H5
|
||
uni.request({
|
||
url: 'https://restapi.amap.com/v3/geocode/regeo',
|
||
data: {
|
||
key: '9cfc9370bd8a941951da1cea0308e9e3',
|
||
location: `${lng},${lat}`
|
||
},
|
||
success: (res) => {
|
||
if (res.data.status === '1' && res.data.regeocode) {
|
||
const addressComponent = res.data.regeocode.addressComponent
|
||
const formattedAddress = res.data.regeocode.formatted_address
|
||
currentAddress.value = {
|
||
name: addressComponent.building || addressComponent.township || '选择的位置',
|
||
address: formattedAddress,
|
||
longitude: lng,
|
||
latitude: lat
|
||
}
|
||
}
|
||
}
|
||
})
|
||
// #endif
|
||
}
|
||
|
||
// 获取当前定位
|
||
const getCurrentLocation = () => {
|
||
if (isLocating.value) return // 防止重复定位
|
||
|
||
isLocating.value = true
|
||
uni.showLoading({ title: '定位中...' })
|
||
|
||
// 先检查定位权限
|
||
uni.getSetting({
|
||
success: (settingRes) => {
|
||
if (settingRes.authSetting['scope.userLocation'] === false) {
|
||
// 用户拒绝了定位权限,引导用户开启
|
||
isLocating.value = false
|
||
uni.hideLoading()
|
||
uni.showModal({
|
||
title: '定位权限',
|
||
content: '需要获取您的位置信息来提供更好的服务,请在设置中开启定位权限',
|
||
confirmText: '去设置',
|
||
success: (modalRes) => {
|
||
if (modalRes.confirm) {
|
||
uni.openSetting()
|
||
}
|
||
}
|
||
})
|
||
return
|
||
}
|
||
|
||
// 执行定位
|
||
uni.getLocation({
|
||
type: 'gcj02',
|
||
altitude: false,
|
||
success: (res) => {
|
||
console.log('定位成功:', res) // 调试日志
|
||
longitude.value = res.longitude
|
||
latitude.value = res.latitude
|
||
|
||
// #ifdef H5
|
||
if (map) {
|
||
map.setCenter([res.longitude, res.latitude])
|
||
const marker = map.getAllOverlays('marker')[0]
|
||
if (marker) {
|
||
marker.setPosition([res.longitude, res.latitude])
|
||
}
|
||
}
|
||
// #endif
|
||
|
||
// #ifndef H5
|
||
// 更新小程序端标记
|
||
markers.value = [{
|
||
id: 1,
|
||
latitude: res.latitude,
|
||
longitude: res.longitude,
|
||
iconPath: '/static/icon/Location.png',
|
||
width: 30,
|
||
height: 30
|
||
}]
|
||
// #endif
|
||
|
||
reverseGeocode(res.longitude, res.latitude)
|
||
uni.hideLoading()
|
||
isLocating.value = false
|
||
},
|
||
fail: (err) => {
|
||
console.error('定位失败:', err) // 调试日志
|
||
uni.hideLoading()
|
||
isLocating.value = false
|
||
|
||
// 根据错误类型给出不同提示
|
||
let errorMsg = '定位失败'
|
||
if (err.errMsg.includes('auth deny')) {
|
||
errorMsg = '定位权限被拒绝,请在设置中开启'
|
||
} else if (err.errMsg.includes('timeout')) {
|
||
errorMsg = '定位超时,请重试'
|
||
} else if (err.errMsg.includes('network')) {
|
||
errorMsg = '网络异常,请检查网络连接'
|
||
}
|
||
|
||
uni.showModal({
|
||
title: '定位失败',
|
||
content: errorMsg + ',是否使用默认位置?',
|
||
confirmText: '使用默认位置',
|
||
cancelText: '重试',
|
||
success: (modalRes) => {
|
||
if (modalRes.confirm) {
|
||
// 使用默认位置(北京)
|
||
longitude.value = 116.397428
|
||
latitude.value = 39.90923
|
||
reverseGeocode(longitude.value, latitude.value)
|
||
} else {
|
||
// 重试定位
|
||
setTimeout(() => {
|
||
getCurrentLocation()
|
||
}, 2000)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
},
|
||
fail: () => {
|
||
uni.hideLoading()
|
||
isLocating.value = false
|
||
$api.msg('无法获取定位权限设置')
|
||
}
|
||
})
|
||
}
|
||
|
||
// 地图区域变化(小程序端)
|
||
const onRegionChange = (e) => {
|
||
// #ifndef H5
|
||
// 只有在用户手动拖动地图结束时才更新位置
|
||
if (e.type === 'end' && e.causedBy === 'drag') {
|
||
const mapContext = uni.createMapContext('map')
|
||
mapContext.getCenterLocation({
|
||
success: (res) => {
|
||
longitude.value = res.longitude
|
||
latitude.value = res.latitude
|
||
reverseGeocode(res.longitude, res.latitude)
|
||
}
|
||
})
|
||
}
|
||
// #endif
|
||
}
|
||
|
||
// 地图点击事件(小程序端)
|
||
const onMapTap = (e) => {
|
||
// #ifndef H5
|
||
const { latitude: lat, longitude: lng } = e.detail
|
||
longitude.value = lng
|
||
latitude.value = lat
|
||
|
||
// 更新标记
|
||
markers.value = [{
|
||
id: 1,
|
||
latitude: lat,
|
||
longitude: lng,
|
||
iconPath: '/static/icon/Location.png',
|
||
width: 30,
|
||
height: 30
|
||
}]
|
||
|
||
reverseGeocode(lng, lat)
|
||
// #endif
|
||
}
|
||
|
||
// 确认选择
|
||
const confirmLocation = () => {
|
||
if (!currentAddress.value) {
|
||
$api.msg('请选择地址')
|
||
return
|
||
}
|
||
|
||
// 返回上一页并传递数据
|
||
const pages = getCurrentPages()
|
||
const prevPage = pages[pages.length - 2]
|
||
|
||
if (prevPage) {
|
||
prevPage.$vm.handleLocationSelected({
|
||
address: currentAddress.value.address,
|
||
name: currentAddress.value.name,
|
||
longitude: currentAddress.value.longitude,
|
||
latitude: currentAddress.value.latitude
|
||
})
|
||
}
|
||
|
||
uni.navigateBack()
|
||
}
|
||
|
||
const onMarkerTap = (e) => {
|
||
console.log('marker点击', e)
|
||
}
|
||
</script>
|
||
|
||
<style lang="stylus" scoped>
|
||
.map-container
|
||
width: 100%
|
||
height: 100vh
|
||
position: relative
|
||
display: flex
|
||
flex-direction: column
|
||
|
||
.search-box
|
||
position: absolute
|
||
top: 20rpx
|
||
left: 32rpx
|
||
right: 32rpx
|
||
z-index: 10
|
||
|
||
.search-input-wrapper
|
||
background: #fff
|
||
border-radius: 40rpx
|
||
padding: 20rpx 30rpx
|
||
display: flex
|
||
align-items: center
|
||
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1)
|
||
|
||
.search-input
|
||
flex: 1
|
||
margin: 0 20rpx
|
||
font-size: 28rpx
|
||
|
||
uni-icons
|
||
flex-shrink: 0
|
||
|
||
.search-results
|
||
position: absolute
|
||
top: 100rpx
|
||
left: 32rpx
|
||
right: 32rpx
|
||
bottom: 180rpx
|
||
background: #fff
|
||
border-radius: 20rpx
|
||
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1)
|
||
z-index: 9
|
||
overflow: hidden
|
||
|
||
.results-scroll
|
||
height: 100%
|
||
|
||
.result-item
|
||
padding: 30rpx
|
||
border-bottom: 1rpx solid #f0f0f0
|
||
|
||
&:active
|
||
background: #f5f5f5
|
||
|
||
.result-name
|
||
font-size: 32rpx
|
||
color: #333
|
||
font-weight: 500
|
||
margin-bottom: 10rpx
|
||
|
||
.result-address
|
||
font-size: 26rpx
|
||
color: #999
|
||
|
||
.empty-results
|
||
height: 100%
|
||
display: flex
|
||
flex-direction: column
|
||
align-items: center
|
||
justify-content: center
|
||
color: #999
|
||
font-size: 28rpx
|
||
|
||
.loading-icon
|
||
animation: rotate 1s linear infinite
|
||
margin-bottom: 20rpx
|
||
|
||
uni-icons
|
||
margin-bottom: 20rpx
|
||
|
||
text
|
||
padding: 0 60rpx
|
||
text-align: center
|
||
line-height: 1.5
|
||
|
||
.search-tips
|
||
margin-top: 40rpx
|
||
padding: 0 40rpx
|
||
|
||
.tip-title
|
||
font-size: 26rpx
|
||
color: #666
|
||
font-weight: 500
|
||
margin-bottom: 20rpx
|
||
display: block
|
||
|
||
.tip-item
|
||
font-size: 24rpx
|
||
color: #999
|
||
line-height: 1.8
|
||
display: block
|
||
margin-bottom: 8rpx
|
||
|
||
@keyframes rotate
|
||
from
|
||
transform: rotate(0deg)
|
||
to
|
||
transform: rotate(360deg)
|
||
|
||
.map-wrapper
|
||
flex: 1
|
||
position: relative
|
||
|
||
.map, .amap-container
|
||
width: 100%
|
||
height: 100%
|
||
|
||
.map-center-marker
|
||
position: absolute
|
||
left: 50%
|
||
top: 50%
|
||
transform: translate(-50%, -100%)
|
||
z-index: 5
|
||
|
||
.marker-icon
|
||
width: 60rpx
|
||
height: 80rpx
|
||
|
||
.location-info
|
||
position: absolute
|
||
bottom: 180rpx
|
||
left: 32rpx
|
||
right: 32rpx
|
||
background: #fff
|
||
border-radius: 20rpx
|
||
padding: 30rpx
|
||
box-shadow: 0 -4rpx 12rpx rgba(0,0,0,0.1)
|
||
z-index: 10
|
||
|
||
.info-title
|
||
font-size: 24rpx
|
||
color: #999
|
||
margin-bottom: 10rpx
|
||
|
||
.info-name
|
||
font-size: 32rpx
|
||
color: #333
|
||
font-weight: 500
|
||
margin-bottom: 10rpx
|
||
|
||
.info-address
|
||
font-size: 28rpx
|
||
color: #666
|
||
|
||
.bottom-actions
|
||
position: absolute
|
||
bottom: 0
|
||
left: 0
|
||
right: 0
|
||
background: #fff
|
||
padding: 20rpx 32rpx
|
||
display: flex
|
||
gap: 20rpx
|
||
box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.1)
|
||
z-index: 11
|
||
|
||
.locate-btn
|
||
width: 120rpx
|
||
height: 80rpx
|
||
background: #fff
|
||
border: 2rpx solid #256BFA
|
||
border-radius: 40rpx
|
||
display: flex
|
||
flex-direction: column
|
||
align-items: center
|
||
justify-content: center
|
||
font-size: 24rpx
|
||
color: #256BFA
|
||
|
||
&:disabled
|
||
opacity: 0.5
|
||
color: #999
|
||
border-color: #999
|
||
|
||
text
|
||
margin-top: 4rpx
|
||
|
||
.confirm-btn
|
||
flex: 1
|
||
height: 80rpx
|
||
background: #256BFA
|
||
color: #fff
|
||
border-radius: 40rpx
|
||
font-size: 32rpx
|
||
border: none
|
||
|
||
button::after
|
||
border: none
|
||
</style>
|
||
|