| | |
| | | class="search-input" |
| | | placeholder="请输入地址" |
| | | v-model="searchKeyword" |
| | | @input="onSearchInput" |
| | | @focus="onSearchFocus" |
| | | /> |
| | | <button class="search-btn" @click="searchAddress">搜索</button> |
| | | <button class="location-btn" @click="getCurrentLocation" :disabled="isGettingLocation"> |
| | | <uni-icons v-if="!isGettingLocation" type="location" size="18" color="white"></uni-icons> |
| | | <uni-icons v-else type="spinner-cycle" size="18" color="white"></uni-icons> |
| | | </button> |
| | | </view> |
| | | |
| | | <!-- 微信小程序使用原生map组件 --> |
| | | <!-- 选中地址界面 - 显示在列表上方 --> |
| | | <view class="selected-address" v-if="selectedAddress"> |
| | | <view class="selected-header"> |
| | | <uni-icons type="checkmarkempty" size="20" color="#007AFF"></uni-icons> |
| | | <text class="address-title">已选中地址</text> |
| | | <view class="cancel-btn" @click="cancelSelection"> |
| | | <uni-icons type="closeempty" size="16" color="#999"></uni-icons> |
| | | </view> |
| | | </view> |
| | | <view class="address-info"> |
| | | <view class="address-name">{{ selectedAddress.title }}</view> |
| | | <view class="address-detail">{{ selectedAddress.address }}</view> |
| | | </view> |
| | | <button class="confirm-btn" @click="confirmAddress"> |
| | | <uni-icons type="checkmarkempty" size="18" color="white"></uni-icons> |
| | | <text>确认选择此地址</text> |
| | | </button> |
| | | </view> |
| | | |
| | | <!-- 地址搜索结果列表 --> |
| | | <view class="address-list" v-if="showSearchResults && searchResults.length > 0"> |
| | | <view |
| | | class="address-item" |
| | | v-for="(item, index) in searchResults" |
| | | :key="'search-' + index" |
| | | @click="selectAddress(item)" |
| | | > |
| | | <!-- 确保使用插值语法 --> |
| | | <view class="address-title">{{ item.title }}</view> |
| | | <view class="address-detail">{{ item.address }}</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 搜索无结果提示 --> |
| | | <view class="no-results" v-if="showSearchResults && searchResults.length === 0 && searchCompleted"> |
| | | <text>未找到相关地址</text> |
| | | </view> |
| | | |
| | | <!-- UniApp原生地图组件,支持多平台 --> |
| | | <view class="map-container" id="mapContainer"> |
| | | <!-- #ifdef MP-WEIXIN --> |
| | | <!-- 所有平台统一使用uniapp原生map组件 --> |
| | | <map |
| | | id="map" |
| | | :longitude="longitude" |
| | |
| | | :controls="controls" |
| | | :include-points="includePoints" |
| | | :show-location="true" |
| | | :enable-3D="false" |
| | | :show-compass="false" |
| | | :enable-overlooking="false" |
| | | :enable-zoom="true" |
| | | :enable-scroll="true" |
| | | :enable-rotate="false" |
| | | :enable-satellite="false" |
| | | :enable-traffic="false" |
| | | @markertap="onMarkerTap" |
| | | @callouttap="onCalloutTap" |
| | | @controltap="onControlTap" |
| | |
| | | @tap="onMapTap" |
| | | class="map-webview" |
| | | ></map> |
| | | <!-- #endif --> |
| | | |
| | | <!-- H5平台使用web-view加载百度地图 --> |
| | | <!-- #ifdef H5 --> |
| | | <web-view |
| | | v-if="baiduMapUrl" |
| | | :src="baiduMapUrl" |
| | | class="map-webview" |
| | | @message="onWebviewMessage" |
| | | ></web-view> |
| | | <!-- #endif --> |
| | | |
| | | <view class="map-placeholder" v-if="!isMapLoaded"> |
| | | <text>地图加载中...</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="address-list" v-if="searchResults.length > 0"> |
| | | <view |
| | | class="address-item" |
| | | v-for="(item, index) in searchResults" |
| | | :key="index" |
| | | @click="selectAddress(item)" |
| | | > |
| | | <view class="address-title">{{ item.title }}</view> |
| | | <view class="address-detail">{{ item.address }}</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="selected-address" v-if="selectedAddress"> |
| | | <view class="address-title">选中地址:</view> |
| | | <view class="address-detail">{{ selectedAddress.title }}</view> |
| | | <view class="address-detail">{{ selectedAddress.address }}</view> |
| | | <button class="confirm-btn" @click="confirmAddress">确认选择</button> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import { searchAddress, reverseGeocoder } from '@/api/map' |
| | | |
| | | export default { |
| | | name: 'MapSelector', |
| | | props: { |
| | |
| | | data() { |
| | | return { |
| | | searchKeyword: '', |
| | | searchResults: [], |
| | | searchResults: [], // 确保这是响应式数据 |
| | | selectedAddress: null, |
| | | isMapLoaded: false, |
| | | // H5平台相关 |
| | | baiduMapUrl: '', |
| | | ak: '您的百度地图AK', |
| | | // 微信小程序相关 |
| | | showSearchResults: false, // 控制是否显示搜索结果 |
| | | searchCompleted: false, // 标记搜索是否完成 |
| | | showDebug: true, // 调试开关 |
| | | // 地图相关 |
| | | longitude: 113.324520, |
| | | latitude: 23.099994, |
| | | markers: [], |
| | | polyline: [], |
| | | circles: [], |
| | | controls: [], |
| | | includePoints: [] |
| | | includePoints: [], |
| | | isGettingLocation: false, // 是否正在获取位置 |
| | | // 防止自动聚焦的标志 |
| | | shouldPreventAutoFocus: true |
| | | } |
| | | }, |
| | | mounted() { |
| | | // #ifdef H5 |
| | | // 初始化百度地图 |
| | | this.initBaiduMap() |
| | | // #endif |
| | | console.log('地图选择器组件已挂载'); |
| | | |
| | | // #ifdef MP-WEIXIN |
| | | // 初始化微信小程序地图 |
| | | this.initWechatMap() |
| | | // #endif |
| | | // 检查API Key是否已配置 |
| | | if (!this.isTencentMapKeyConfigured()) { |
| | | console.error('[system] Map key not configured.') |
| | | this.$modal.showToast('地图API Key未配置,请联系管理员') |
| | | return |
| | | } |
| | | |
| | | // 初始化地图 |
| | | this.initMap() |
| | | |
| | | // 延迟处理初始地址,避免跨域问题 |
| | | if (this.initialAddress) { |
| | | this.searchKeyword = this.initialAddress |
| | | // 延迟设置焦点,避免跨域问题 |
| | | setTimeout(() => { |
| | | // 不自动聚焦,让用户手动点击 |
| | | }, 500) |
| | | // 不再尝试自动聚焦,避免跨域问题 |
| | | // 用户需要手动点击输入框才能聚焦 |
| | | } |
| | | |
| | | // 延迟一段时间后允许自动操作(如果需要的话) |
| | | setTimeout(() => { |
| | | this.shouldPreventAutoFocus = false |
| | | }, 1000) |
| | | }, |
| | | methods: { |
| | | // 检查腾讯地图API Key是否已配置 |
| | | isTencentMapKeyConfigured() { |
| | | // 对于后端代理方式,前端不再需要检查Key配置 |
| | | return true |
| | | }, |
| | | |
| | | // 搜索框获得焦点事件 |
| | | onSearchFocus() { |
| | | // 用户主动聚焦,不会触发跨域问题 |
| | | console.log('搜索框获得焦点') |
| | | // 重置防聚焦标志 |
| | | this.shouldPreventAutoFocus = false |
| | | }, |
| | | |
| | | // #ifdef H5 |
| | | // 处理web-view消息 |
| | | onWebviewMessage(e) { |
| | | // 处理来自web-view的消息 |
| | | console.log('收到来自web-view的消息:', e) |
| | | }, |
| | | |
| | | // 初始化百度地图(H5平台) |
| | | initBaiduMap() { |
| | | // 构造百度地图URL |
| | | this.baiduMapUrl = `https://api.map.baidu.com/mapjs?v=3.0&ak=${this.ak}&callback=initMap` |
| | | this.isMapLoaded = true |
| | | // 获取当前位置 |
| | | getCurrentLocation() { |
| | | if (this.isGettingLocation) { |
| | | return |
| | | } |
| | | |
| | | // 延迟加载地图,避免阻塞 |
| | | setTimeout(() => { |
| | | this.isMapLoaded = true |
| | | }, 1000) |
| | | this.isGettingLocation = true |
| | | this.$modal.showToast('正在获取当前位置...') |
| | | |
| | | uni.getLocation({ |
| | | type: 'gcj02', |
| | | success: (res) => { |
| | | console.log('获取位置成功:', res) |
| | | this.handleLocationSuccess(res.longitude, res.latitude) |
| | | this.isGettingLocation = false |
| | | }, |
| | | fail: (error) => { |
| | | console.error('获取位置失败:', error) |
| | | this.$modal.showToast('获取位置失败,请检查定位权限') |
| | | this.isGettingLocation = false |
| | | } |
| | | }) |
| | | }, |
| | | // #endif |
| | | |
| | | // #ifdef MP-WEIXIN |
| | | // 初始化微信小程序地图 |
| | | initWechatMap() { |
| | | // 处理位置获取成功 |
| | | handleLocationSuccess(longitude, latitude) { |
| | | // 参数验证 |
| | | if (longitude === undefined || longitude === null || latitude === undefined || latitude === null) { |
| | | console.error('位置获取失败,参数不完整', { longitude, latitude }); |
| | | this.$modal.showToast('位置获取失败'); |
| | | return; |
| | | } |
| | | |
| | | // 检查参数有效性 |
| | | if (isNaN(longitude) || isNaN(latitude)) { |
| | | console.error('位置获取失败,坐标包含非法值', { longitude, latitude }); |
| | | this.$modal.showToast('位置获取失败,坐标无效'); |
| | | return; |
| | | } |
| | | |
| | | this.longitude = longitude |
| | | this.latitude = latitude |
| | | |
| | | // 设置标记 |
| | | this.markers = [{ |
| | | id: Date.now(), |
| | | longitude: longitude, |
| | | latitude: latitude, |
| | | title: '当前位置', |
| | | iconPath: '/static/icons/location.png', |
| | | width: 30, |
| | | height: 30 |
| | | }] |
| | | |
| | | // 逆地址解析 |
| | | this.reverseGeocode(latitude, longitude, true) |
| | | |
| | | this.$modal.showToast('已定位到当前位置') |
| | | this.isMapLoaded = true |
| | | }, |
| | | |
| | | // 初始化地图 |
| | | initMap() { |
| | | // 获取用户位置 |
| | | uni.getLocation({ |
| | | type: 'gcj02', |
| | | success: (res) => { |
| | | // 参数验证 |
| | | if (res.longitude === undefined || res.longitude === null || |
| | | res.latitude === undefined || res.latitude === null) { |
| | | console.error('初始化地图时位置获取失败,参数不完整', res); |
| | | this.$modal.showToast('位置获取失败'); |
| | | this.isMapLoaded = true; |
| | | return; |
| | | } |
| | | |
| | | // 检查参数有效性 |
| | | if (isNaN(res.longitude) || isNaN(res.latitude)) { |
| | | console.error('初始化地图时位置获取失败,坐标包含非法值', res); |
| | | this.$modal.showToast('位置获取失败,坐标无效'); |
| | | this.isMapLoaded = true; |
| | | return; |
| | | } |
| | | |
| | | this.longitude = res.longitude |
| | | this.latitude = res.latitude |
| | | |
| | |
| | | height: 30 |
| | | }] |
| | | |
| | | // 延迟设置加载状态,确保地图完全初始化 |
| | | setTimeout(() => { |
| | | this.isMapLoaded = true |
| | | }, 500) |
| | | // 设置加载状态 |
| | | this.isMapLoaded = true |
| | | }, |
| | | fail: () => { |
| | | // 延迟设置加载状态 |
| | | setTimeout(() => { |
| | | this.isMapLoaded = true |
| | | }, 500) |
| | | // 设置加载状态 |
| | | this.isMapLoaded = true |
| | | this.$modal.showToast('获取位置失败') |
| | | } |
| | | }) |
| | |
| | | onMapTap(e) { |
| | | // 在点击位置添加标记 |
| | | const { longitude, latitude } = e.detail |
| | | |
| | | // 参数验证 |
| | | if (longitude === undefined || longitude === null || latitude === undefined || latitude === null) { |
| | | console.error('地图点击事件参数不完整', { longitude, latitude }); |
| | | this.$modal.showToast('位置信息获取失败'); |
| | | return; |
| | | } |
| | | |
| | | this.markers = [{ |
| | | id: Date.now(), |
| | | longitude, |
| | |
| | | }, |
| | | |
| | | // 逆地址解析 |
| | | reverseGeocode(lat, lng) { |
| | | // 这里应该调用后台API进行逆地址解析 |
| | | // 模拟数据 |
| | | this.selectedAddress = { |
| | | title: '选中位置', |
| | | address: `经纬度: ${lat.toFixed(6)}, ${lng.toFixed(6)}`, |
| | | lat: lat, |
| | | lng: lng |
| | | reverseGeocode(lat, lng, isCurrentLocation = false) { |
| | | // 参数验证 |
| | | if (lat === undefined || lat === null || lng === undefined || lng === null) { |
| | | console.error('逆地址解析参数不完整,缺少经纬度坐标', { lat, lng }); |
| | | this.$modal.showToast('参数错误:缺少经纬度坐标'); |
| | | return; |
| | | } |
| | | |
| | | // 检查参数有效性 |
| | | if (isNaN(lat) || isNaN(lng)) { |
| | | console.error('逆地址解析参数无效,坐标包含非法值', { lat, lng }); |
| | | this.$modal.showToast('参数错误:坐标格式无效'); |
| | | return; |
| | | } |
| | | |
| | | // 使用后端代理接口进行逆地址解析 |
| | | reverseGeocoder(lat, lng).then(res => { |
| | | if (res.code === 200) { |
| | | // 解析后端返回的腾讯地图API响应 |
| | | const responseData = typeof res.data === 'string' ? JSON.parse(res.data) : res.data; |
| | | if (responseData && responseData.status === 0 && responseData.result) { |
| | | const result = responseData.result |
| | | this.selectedAddress = { |
| | | title: isCurrentLocation ? '当前位置' : (result.address || '选中位置'), |
| | | address: result.address || `经纬度: ${lat.toFixed(6)}, ${lng.toFixed(6)}`, |
| | | lat: lat, |
| | | lng: lng |
| | | } |
| | | } else { |
| | | this.selectedAddress = { |
| | | title: isCurrentLocation ? '当前位置' : '选中位置', |
| | | address: `经纬度: ${lat.toFixed(6)}, ${lng.toFixed(6)}`, |
| | | lat: lat, |
| | | lng: lng |
| | | } |
| | | } |
| | | } else { |
| | | this.selectedAddress = { |
| | | title: isCurrentLocation ? '当前位置' : '选中位置', |
| | | address: `经纬度: ${lat.toFixed(6)}, ${lng.toFixed(6)}`, |
| | | lat: lat, |
| | | lng: lng |
| | | } |
| | | } |
| | | }).catch(error => { |
| | | console.error('逆地址解析失败:', error) |
| | | this.$modal.showToast('地址解析失败:' + (error.message || '请稍后重试')) |
| | | this.selectedAddress = { |
| | | title: isCurrentLocation ? '当前位置' : '选中位置', |
| | | address: `经纬度: ${lat.toFixed(6)}, ${lng.toFixed(6)}`, |
| | | lat: lat, |
| | | lng: lng |
| | | } |
| | | }) |
| | | }, |
| | | // #endif |
| | | |
| | | // 搜索地址 |
| | | // 搜索地址 - 只在点击搜索按钮时调用 |
| | | searchAddress() { |
| | | console.log('执行搜索,关键词:', this.searchKeyword); |
| | | if (!this.searchKeyword) { |
| | | this.$modal.showToast('请输入地址') |
| | | return |
| | | } |
| | | |
| | | // 在实际项目中,这里应该调用对应平台的地图API |
| | | // 例如H5平台调用百度地图API,微信小程序调用微信地图API |
| | | |
| | | // 模拟搜索结果 |
| | | this.searchResults = [ |
| | | { |
| | | title: this.searchKeyword + '附近地点1', |
| | | address: '广东省广州市天河区' + this.searchKeyword + '123号', |
| | | lat: 23.123 + Math.random() * 0.1, |
| | | lng: 113.321 + Math.random() * 0.1 |
| | | }, |
| | | { |
| | | title: this.searchKeyword + '附近地点2', |
| | | address: '广东省广州市越秀区' + this.searchKeyword + '456号', |
| | | lat: 23.145 + Math.random() * 0.1, |
| | | lng: 113.289 + Math.random() * 0.1 |
| | | }, |
| | | { |
| | | title: this.searchKeyword + '附近地点3', |
| | | address: '广东省广州市白云区' + this.searchKeyword + '789号', |
| | | lat: 23.167 + Math.random() * 0.1, |
| | | lng: 113.345 + Math.random() * 0.1 |
| | | } |
| | | ] |
| | | // 使用后端代理接口进行地址搜索 |
| | | this.searchAddressViaBackend() |
| | | }, |
| | | |
| | | // 输入框输入事件 |
| | | onSearchInput() { |
| | | // 防抖搜索 |
| | | // 通过后端代理搜索地址 |
| | | searchAddressViaBackend() { |
| | | // 显示搜索结果区域 |
| | | this.showSearchResults = true; |
| | | this.searchCompleted = false; |
| | | |
| | | console.log('开始搜索地址:', this.searchKeyword); |
| | | |
| | | searchAddress(this.searchKeyword, '广州').then(res => { |
| | | console.log('地址搜索返回结果:', res); |
| | | // 确保正确更新搜索结果 |
| | | this.searchResults = []; |
| | | |
| | | if (res.code === 200) { |
| | | // 解析后端返回的腾讯地图API响应 |
| | | const responseData = typeof res.data === 'string' ? JSON.parse(res.data) : res.data; |
| | | console.log('解析后的响应数据:', responseData); |
| | | |
| | | if (responseData && responseData.status === 0 && responseData.data && responseData.data.length > 0) { |
| | | // 直接赋值数组,确保响应式更新 |
| | | this.searchResults = responseData.data.map(item => ({ |
| | | title: item.title, |
| | | address: item.address, |
| | | lat: item.location.lat, |
| | | lng: item.location.lng |
| | | })); |
| | | console.log('处理后的搜索结果:', this.searchResults); |
| | | |
| | | // 添加调试信息 |
| | | console.log('搜索结果数量:', this.searchResults.length); |
| | | console.log('showSearchResults:', this.showSearchResults); |
| | | console.log('v-if条件结果:', this.showSearchResults && this.searchResults.length > 0); |
| | | } else { |
| | | console.log('未找到相关地址'); |
| | | // 即使没有数据也要显示"未找到相关地址" |
| | | this.searchCompleted = true; |
| | | } |
| | | } else { |
| | | console.log('搜索失败,错误代码:', res.code); |
| | | this.$modal.showToast('搜索失败,请重试') |
| | | } |
| | | |
| | | // 标记搜索完成 |
| | | this.searchCompleted = true; |
| | | }).catch(error => { |
| | | console.error('搜索失败:', error) |
| | | this.$modal.showToast('搜索失败,请重试') |
| | | // 标记搜索完成 |
| | | this.searchCompleted = true; |
| | | }) |
| | | }, |
| | | |
| | | // 选择地址 |
| | | selectAddress(item) { |
| | | this.selectedAddress = item |
| | | this.markLocation(item.lat, item.lng) |
| | | |
| | | // 选中地址后,保持搜索结果列表显示 |
| | | console.log('地址已选中:', item); |
| | | }, |
| | | |
| | | // 在地图上标记位置 |
| | | markLocation(lat, lng) { |
| | | // #ifdef H5 |
| | | // H5平台标记位置逻辑 |
| | | console.log(`H5平台标记位置: ${lat}, ${lng}`) |
| | | this.$modal.showToast(`已标记位置`) |
| | | // #endif |
| | | |
| | | // #ifdef MP-WEIXIN |
| | | // 微信小程序标记位置逻辑 |
| | | this.longitude = lng |
| | | this.latitude = lat |
| | | this.markers = [{ |
| | | id: Date.now(), |
| | | longitude: lng, |
| | | latitude: lat, |
| | | title: item.title, |
| | | title: this.selectedAddress?.title || '选中位置', |
| | | iconPath: '/static/icons/location-selected.png', |
| | | width: 30, |
| | | height: 30 |
| | | }] |
| | | // #endif |
| | | }, |
| | | |
| | | // 确认选择地址 |
| | |
| | | return |
| | | } |
| | | |
| | | // 显示确认提示 |
| | | this.$modal.showToast('地址选择成功') |
| | | |
| | | // 触发事件,将选中的地址传递给父组件 |
| | | this.$emit('addressSelected', { |
| | | title: this.selectedAddress.title, |
| | |
| | | lat: this.selectedAddress.lat, |
| | | lng: this.selectedAddress.lng |
| | | }) |
| | | |
| | | // 确认后隐藏搜索结果和选中地址界面 |
| | | setTimeout(() => { |
| | | this.selectedAddress = null |
| | | this.showSearchResults = false |
| | | this.searchResults = [] |
| | | }, 1000) |
| | | }, |
| | | |
| | | // 取消选择地址 |
| | | cancelSelection() { |
| | | this.selectedAddress = null |
| | | // 只清空选中地址,不清空搜索结果 |
| | | // this.showSearchResults = false |
| | | // this.searchResults = [] |
| | | } |
| | | } |
| | | } |
| | |
| | | <style lang="scss"> |
| | | .map-selector-container { |
| | | width: 100%; |
| | | height: 100%; |
| | | height: 100vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .search-bar { |
| | | display: flex; |
| | | padding: 20rpx; |
| | | padding: 15rpx 20rpx; |
| | | background-color: white; |
| | | flex-shrink: 0; |
| | | position: relative; |
| | | z-index: 100; /* 提高层级 */ |
| | | |
| | | .search-input { |
| | | flex: 1; |
| | |
| | | border-radius: 10rpx; |
| | | font-size: 28rpx; |
| | | } |
| | | |
| | | .location-btn { |
| | | width: 70rpx; |
| | | height: 70rpx; |
| | | margin-left: 10rpx; |
| | | background-color: #1AAD19; |
| | | color: white; |
| | | border-radius: 10rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | |
| | | &:active { |
| | | background-color: #179B16; |
| | | } |
| | | |
| | | &[disabled] { |
| | | background-color: #ccc; |
| | | opacity: 0.6; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .debug-panel { |
| | | padding: 15rpx 20rpx; |
| | | background-color: #fff3cd; |
| | | border: 1rpx solid #ffeaa7; |
| | | z-index: 100; /* 提高层级 */ |
| | | position: relative; |
| | | |
| | | .debug-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 10rpx; |
| | | |
| | | .debug-title { |
| | | font-weight: bold; |
| | | color: #856404; |
| | | } |
| | | |
| | | .debug-toggle { |
| | | font-size: 24rpx; |
| | | padding: 5rpx 10rpx; |
| | | background-color: #ffc107; |
| | | border: none; |
| | | border-radius: 5rpx; |
| | | } |
| | | } |
| | | |
| | | .debug-content { |
| | | font-size: 24rpx; |
| | | color: #856404; |
| | | |
| | | text { |
| | | display: block; |
| | | margin-bottom: 5rpx; |
| | | word-break: break-all; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* 地址搜索结果列表 - 调整位置 */ |
| | | .address-list { |
| | | max-height: 40vh; |
| | | min-height: 200rpx; |
| | | overflow-y: auto; |
| | | background-color: white; |
| | | position: absolute; |
| | | top: 300rpx; /* 在选中地址界面下方显示 */ |
| | | left: 0; |
| | | right: 0; |
| | | z-index: 90; /* 确保在地图上方 */ |
| | | box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1); |
| | | |
| | | .address-item { |
| | | padding: 25rpx 30rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | min-height: 100rpx; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | |
| | | .address-title { |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | margin-bottom: 8rpx; |
| | | color: #333; |
| | | line-height: 1.3; |
| | | } |
| | | |
| | | .address-detail { |
| | | font-size: 28rpx; |
| | | color: #666; |
| | | line-height: 1.4; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* 无结果提示 - 调整位置 */ |
| | | .no-results { |
| | | padding: 30rpx; |
| | | text-align: center; |
| | | background-color: white; |
| | | color: #999; |
| | | font-size: 28rpx; |
| | | position: absolute; |
| | | top: 150rpx; /* 调整位置 */ |
| | | left: 0; |
| | | right: 0; |
| | | z-index: 90; /* 确保在地图上方 */ |
| | | box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1); |
| | | min-height: 200rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .map-container { |
| | | flex: 1; |
| | | height: 400rpx; |
| | | min-height: 50vh; |
| | | max-height: 70vh; |
| | | position: relative; |
| | | |
| | | .map-webview { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | // 微信小程序地图样式 |
| | | // 地图样式 |
| | | map { |
| | | width: 100%; |
| | | height: 100%; |
| | |
| | | } |
| | | } |
| | | |
| | | .address-list { |
| | | max-height: 300rpx; |
| | | overflow-y: auto; |
| | | background-color: white; |
| | | |
| | | .address-item { |
| | | padding: 20rpx 30rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | |
| | | .address-title { |
| | | font-size: 30rpx; |
| | | font-weight: bold; |
| | | margin-bottom: 10rpx; |
| | | } |
| | | |
| | | .address-detail { |
| | | font-size: 26rpx; |
| | | color: #666; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .selected-address { |
| | | padding: 20rpx 30rpx; |
| | | background-color: white; |
| | | border-top: 1rpx solid #f0f0f0; |
| | | flex-shrink: 0; |
| | | position: absolute; |
| | | top: 150rpx; /* 在搜索栏下方显示 */ |
| | | left: 0; |
| | | right: 0; |
| | | z-index: 95; /* 确保在地图上方 */ |
| | | box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1); |
| | | |
| | | .address-title { |
| | | font-size: 30rpx; |
| | | font-weight: bold; |
| | | margin-bottom: 10rpx; |
| | | .selected-header { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | margin-bottom: 15rpx; |
| | | |
| | | .address-title { |
| | | font-size: 28rpx; |
| | | font-weight: bold; |
| | | color: #007AFF; |
| | | margin-left: 10rpx; |
| | | } |
| | | |
| | | .cancel-btn { |
| | | width: 40rpx; |
| | | height: 40rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border-radius: 50%; |
| | | background-color: #f5f5f5; |
| | | |
| | | &:active { |
| | | background-color: #e0e0e0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .address-detail { |
| | | font-size: 26rpx; |
| | | color: #666; |
| | | margin-bottom: 10rpx; |
| | | .address-info { |
| | | background-color: #f8f9fa; |
| | | padding: 25rpx; |
| | | border-radius: 12rpx; |
| | | margin-bottom: 20rpx; |
| | | |
| | | .address-name { |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | color: #333; |
| | | margin-bottom: 10rpx; |
| | | line-height: 1.3; |
| | | } |
| | | |
| | | .address-detail { |
| | | font-size: 28rpx; |
| | | color: #666; |
| | | line-height: 1.5; |
| | | } |
| | | } |
| | | |
| | | .confirm-btn { |
| | |
| | | color: white; |
| | | border-radius: 10rpx; |
| | | font-size: 32rpx; |
| | | margin-top: 20rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | |
| | | text { |
| | | margin-left: 10rpx; |
| | | } |
| | | |
| | | &:active { |
| | | background-color: #0056CC; |
| | | } |
| | | } |
| | | } |
| | | } |