mrr.sj.front/pages/address/search-副本.nvue

791 lines
20 KiB
Plaintext
Raw Normal View History

2026-03-24 11:45:13 +08:00
<template>
<view class="search-address-page">
<!-- 自定义导航栏 -->
<custom-navbar title="搜索地址" :showBack="true" backgroundColor="#FFFFFF"></custom-navbar>
<!-- 搜索框 -->
<view class="search-container">
<text class="search-container-text" @click="goSelectCity" v-if="isSelectCity">
{{ city.name }}
</text>
<image src="/static/images/Fill.jpg" mode="aspectFit" class="text-img" v-if="isSelectCity"></image>
<search-box v-model="searchKeyword" placeholder="请输入地址" @confirm="onSearch" :showBack="false"></search-box>
</view>
<!-- 地图容器 -->
<view class="map-container" v-if="showMap">
<!-- @regionchange="onRegionChange" -->
<map id="map" class="map" :latitude="latitude" :longitude="longitude" scale="19" @tap="onMapTap"
@regionchange="changeMap"></map>
<!-- 中心点标记 -->
<view class="center-marker">
<image src="/static/images/mapCenter.png" class="center-marker-img" mode="widthFix"></image>
</view>
</view>
<!-- 地址列表 -->
<scroll-view scroll-y class="address-list" :style="'height: ' + listHeight + 'rpx'" v-if="searchResults">
<view class="address-item" v-for="(item, index) in searchResults" :key="index" @click="selectAddress(item)">
<view class="address-info">
<text class="address-name">{{item.name}}</text>
<text class="address-detail">{{item.address}}</text>
</view>
<view class="address-distance" v-if="item.distance">
<text class="distance-text">{{item.distance}}m</text>
</view>
</view>
</scroll-view>
<!-- 空状态 -->
<view class="empty-state" v-else>
<image src="/static/images/empty.png" class="empty-icon"></image>
<text class="empty-text">未找到相关地址</text>
</view>
</view>
</template>
<script>
import searchBox from '@/components/search/search-box.vue'
import request from '@/utils/request'
import ChinaCitys from '@/static/data/ChinaCitys.json'
export default {
components: {
searchBox
},
data() {
return {
isFirst:false,
systemInfo: {},
searchKeyword: '',
searchResults: [],
showMap: true,
latitude: 0, // 38.351942
longitude: 0, // 117.320266
newLatitude: 0,
newLongitude: 0,
markers: [],
currentDistance: '0m',
pageHeight: 0,
listHeight: 0,
city: {
center: '',
name: ''
},
isSelectCity: false,
searchCity: uni.getStorageSync('searchCity')
}
},
onLoad(options) {
// 存入环境状态
this.systemInfo = uni.getSystemInfoSync();
// 保存来源参数,用于选择地址后的返回
this.source = options.source || '';
// 如果有传入的坐标,优先使用
if (options.longitude && options.latitude) {
console.log('使用传入的坐标:', options.longitude, options.latitude);
this.longitude = parseFloat(options.longitude);
this.latitude = parseFloat(options.latitude);
this.newLongitude = this.longitude;
this.newLatitude = this.latitude;
// 直接使用传入的坐标
this.getNowLocation(`${this.longitude},${this.latitude}`);
// 获取视图高度
this.pageHeight = uni.getWindowInfo().safeHeight;
this.listHeight = parseInt(this.pageHeight) * 2 - 88 - 102 - 500;
return;
}
// 获取传入区域并查询中心坐标点
// dependency传入区域后定位区域中心点city传入这个的时候直接以这个坐标请求并显示城市选择
let that = this;
if (options.dependency) {
// 解码参数URL编码的字符串
let regions = decodeURIComponent(options.dependency).split('-');
let foundCode = options.dependency_code;
console.log('传入的地区信息:', regions);
// 判断是否有城市code如果没有就变量json
if (regions.length < 3) {
// 如果地区信息不完整,直接获取当前位置
console.warn('地区信息不完整,使用当前位置');
that.getCurrentLocation();
return;
}
// 使用高德地图API获取地区坐标
// 先尝试获取区级坐标,如果失败则尝试市级,最后尝试省级
const getDistrictCenter = (keyword, subdistrict = 0) => {
return new Promise((resolve) => {
uni.request({
url: 'https://restapi.amap.com/v3/config/district',
method: "GET",
data: {
key: '30b7eb1a1b2f88edc085b9b3ee9a2188',
subdistrict: subdistrict,
keywords: keyword,
extensions: 'all'
},
success(res) {
console.log('高德地图API响应:', res.data);
if (res.data.status === '1' && res.data.districts && res.data.districts
.length > 0) {
const district = res.data.districts[0];
if (district.center && district.center !== '' && res.data.districts
.length == 1) {
resolve(district.center);
return;
}
}
resolve(null);
},
fail() {
resolve(null);
}
});
});
};
// 尝试获取坐标的顺序:区 -> 市 -> 省
(async () => {
let center = null;
// 1. 尝试获取区的坐标
if (regions[2]) {
center = await getDistrictCenter(regions[2]);
console.log('区坐标获取结果:', center);
}
// 2. 如果区坐标失败,尝试获取市的坐标
if (!center && regions[1] && regions[1] !== regions[0]) {
center = await getDistrictCenter(regions[1]);
console.log('市坐标获取结果:', center);
}
// 3. 如果市坐标也失败,尝试获取省的坐标
if (!center && regions[0]) {
center = await getDistrictCenter(regions[0]);
console.log('省坐标获取结果:', center);
}
// 4. 如果所有坐标都获取失败,使用默认城市坐标(上海)
if (center) {
that.getNowLocation(center);
} else {
console.log('使用默认坐标(上海)');
// 上海市中心坐标
that.getNowLocation('121.473701,31.230416');
}
})();
} else if (options.city) {
let city = JSON.parse(decodeURIComponent(options.city));
that.city = city;
that.getNowLocation(city.center);
// 显示城市选择
that.isSelectCity = true;
} else if (options.isSelectCity) {
// 显示城市选择
that.isSelectCity = true;
that.getCurrentLocation();
} else {
// 获取当前位置
that.getCurrentLocation();
}
// 获取视图高度
this.pageHeight = uni.getWindowInfo().safeArea.height;
this.listHeight = parseInt(this.pageHeight) * 2 - 88 - 102 - 500;
},
onShow() {
if(!this.isFirst){
this.isFirst=true
return
}
//选择了城市后触发
let that = this
let searchCity = uni.getStorageSync('searchCity')
console.log("searchCity.name:", searchCity.name, searchCity.center)
if (this.city.name != searchCity.name) {
that.city = searchCity
that.searchCity = searchCity
this.$nextTick(() => {
that.getNowLocation(searchCity.center)
})
}
},
methods: {
//跳转城市选择页
goSelectCity() {
uni.navigateTo({
url: '/pages/address/selectCity'
})
},
//坐标转换
convert(item) {
let data = {
key: '30b7eb1a1b2f88edc085b9b3ee9a2188',
locations: `${item.longitude},${item.latitude}`,
coordsys: 'gps',
}
return new Promise((resolve, reject) => {
uni.request({
url: 'https://restapi.amap.com/v3/assistant/coordinate/convert',
method: "GET",
data: data,
success(res) {
resolve(res.data)
}
})
})
},
getLocation() {
let that = this
return new Promise((resolve, reject) => {
if (uni.getStorageSync('setVersion').DeviceBrand == 'ios') {
uni.getLocation({
type: 'wgs84',
isHighAccuracy: true,
success: async function(res) {
let convert = await that.convert(res)
let locations = convert.locations.split(',')
res.longitude = locations[0]
res.latitude = locations[1]
resolve(res)
},
fail(err) {
console.log(err)
uni.showToast({
title: '获取位置失败',
icon: 'none'
})
reject(err)
}
})
} else {
uni.getLocation({
type: 'gcj02',
geocode: true,
success: function(res) {
resolve(res)
},
fail(err) {
console.log(err)
uni.showToast({
title: '获取位置失败',
icon: 'none'
})
reject(err)
}
})
}
})
},
// 获取当前位置
async getCurrentLocation() {
let that = this;
let longitude = '';
let latitude = '';
const locationRes = await that.getLocation();
that.longitude = locationRes.longitude;
that.latitude = locationRes.latitude;
that.markers = [{
latitude: that.latitude,
longitude: that.longitude,
iconPath: '/static/images/position_icon_3x.png'
}]
// 请求附近地址
// types: '060000|070000|080000|090000|100000|120000|170000'
that.getPlaceAround();
},
// 通过中心点获取当前位置
getNowLocation(center) {
let that = this;
let longitude = '';
let latitude = '';
let locationRes = center.split(',');
that.longitude = locationRes[0];
that.latitude = locationRes[1];
that.newLongitude = locationRes[0];
that.newLatitude = locationRes[1];
that.markers = [{
latitude: that.latitude,
longitude: that.longitude,
iconPath: '/static/images/position_icon_3x.png'
}]
// 请求附近地址
// types: '060000|070000|080000|090000|100000|120000|170000'
that.getPlaceAround();
},
getPlaceAround() {
let that = this;
let data;
if (!that.searchKeyword) {
data = {
key: '30b7eb1a1b2f88edc085b9b3ee9a2188',
location: `${that.newLongitude},${that.newLatitude}`,
page: 1,
offset: 10
}
} else {
data = {
key: '30b7eb1a1b2f88edc085b9b3ee9a2188',
location: `${that.newLongitude},${that.newLatitude}`,
keywords: that.searchKeyword,
page: 1,
offset: 10
}
}
return new Promise((resolve, reject) => {
uni.request({
url: 'https://restapi.amap.com/v3/place/around',
method: "GET",
data: data,
success(res) {
that.city = {
name: res.data.pois[0]?.cityname,
center: res.data.pois[0]?.location
}
that.searchResults = res.data.pois;
}
})
})
},
// 更新地图标记
updateMarkers() {
// if (this.systemInfo.platform === 'ios') {
// this.markers = [{
// id: 1,
// latitude: this.newLatitude,
// longitude: this.newLongitude,
// width: 32,
// height: 32
// }]
// } else {
// this.markers = [{
// latitude: this.newLatitude,
// longitude: this.newLongitude,
// iconPath: '/static/images/position_icon_3x.png'
// }]
// }
},
// 搜索地址
async onSearch() {
let that = this;
if (!that.searchKeyword.trim()) {
uni.showToast({
title: '请输入搜索关键词',
icon: 'none'
})
return
}
try {
// 先清空之前的搜索结果
that.searchResults = [];
// 使用高德地图的搜索API
const searchData = {
key: '30b7eb1a1b2f88edc085b9b3ee9a2188',
keywords: that.searchKeyword,
city: that.city.name || '', // 限制在当前城市搜索
page: 1,
offset: 10
};
console.log('搜索参数:', searchData);
// 直接使用高德地图的搜索API
await new Promise((resolve, reject) => {
uni.request({
url: 'https://restapi.amap.com/v3/place/text',
method: "GET",
data: searchData,
success(res) {
console.log('搜索API响应:', res.data);
if (res.data.status === '1' && res.data.pois) {
that.searchResults = res.data.pois;
// 如果有搜索结果,将地图移动到第一个结果的位置
if (that.searchResults && that.searchResults.length > 0) {
const firstResult = that.searchResults[0];
if (firstResult.location) {
const locationParts = firstResult.location.split(',');
if (locationParts.length === 2) {
const newLongitude = parseFloat(locationParts[0]);
const newLatitude = parseFloat(locationParts[1]);
console.log('搜索结果位置:', newLongitude, newLatitude);
// 更新地图中心点
that.updateMapCenter(newLongitude, newLatitude);
}
}
}
} else {
that.searchResults = [];
}
resolve();
},
fail(error) {
console.error('搜索失败:', error);
reject(error);
}
})
});
} catch (error) {
console.error('搜索失败:', error);
uni.showToast({
title: '搜索失败',
icon: 'none'
})
}
},
// 添加更新地图中心点的方法
updateMapCenter(longitude, latitude) {
if (!longitude || !latitude) {
console.warn('无效的坐标:', longitude, latitude);
return;
}
// 更新坐标
this.longitude = longitude;
this.latitude = latitude;
this.newLongitude = longitude;
this.newLatitude = latitude;
console.log('更新地图中心到:', longitude, latitude);
// 使用setTimeout确保DOM已更新
setTimeout(() => {
try {
// 创建地图上下文
const mapCtx = uni.createMapContext('map', this);
// 方法1尝试使用moveToLocation
mapCtx.moveToLocation({
longitude: longitude,
latitude: latitude,
success: () => {
console.log('moveToLocation成功');
},
fail: (err) => {
console.error('移动地图失败:', err);
}
});
} catch (error) {
console.error('地图移动异常:', error);
}
}, 300);
},
// 选择地址
selectAddress(item) {
console.log('=== 地址选择页面:选择地址 ===');
// 获取页面来源参数
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
const options = currentPage.options || {};
console.log('页面参数:', options);
console.log('当前来源:', this.source);
// 检查是否来自手艺人入驻页面
if (options.source === 'syr_info') {
// 准备手艺人地址数据
const syrAddressData = {
name: item.name,
address: item.address || item.name,
location: item.location,
longitude: item.location ? item.location.split(',')[0] : '',
latitude: item.location ? item.location.split(',')[1] : '',
pname: item.pname || '', // 省
cityname: item.cityname || '', // 市
adname: item.adname || '', // 区
source: 'syr_info'
};
// 存储到手艺人专用位置
uni.setStorageSync('syr_selected_address', syrAddressData);
console.log('已存储手艺人地址数据:', syrAddressData);
// 触发事件通知手艺人页面
uni.$emit('address-selected-for-syr', syrAddressData);
}
// 检查是否来自商家页面
if (options.source === 'sj_info') {
// 准备商家地址数据
const sjAddressData = {
name: item.name,
address: item.address || item.name,
location: item.location,
longitude: item.location ? item.location.split(',')[0] : '',
latitude: item.location ? item.location.split(',')[1] : '',
pname: item.pname || '', // 省
cityname: item.cityname || '', // 市
adname: item.adname || '', // 区
source: 'sj_info'
};
// 存储到商家专用位置
uni.setStorageSync('sj_selected_address', sjAddressData);
console.log('已存储商家地址数据:', sjAddressData);
// 同时存入全局(备用)
if (getApp().globalData) {
getApp().globalData.selectedAddress = sjAddressData;
}
}
// 保持原有的回调逻辑(不影响其他页面)
const prevPage = pages[pages.length - 2];
if (prevPage) {
if (prevPage.$vm && typeof prevPage.$vm.editAddress === "function") {
try {
prevPage.$vm.editAddress(item);
} catch (error) {
console.error('调用 editAddress 失败:', error);
}
}
}
// 返回上一页
setTimeout(() => {
uni.navigateBack({
success: () => {
console.log('成功返回上一页');
}
});
}, 50);
},
// 点击地图
onMapTap(e) {
let that = this;
that.newLatitude = e.detail.latitude;
that.newLongitude = e.detail.longitude;
that.updateMarkers()
that.getPlaceAround()
},
//滑动了地图
changeMap(e) {
let type
const {
platform
} = uni.getSystemInfoSync();
switch (platform) {
case 'android':
type = e.type;
break;
case 'ios':
type = e.detail.type;
break;
}
// console.log("滑动");
// console.log(e);
if (type === "end") {
// 处理拖拽结束时的逻辑;
let mapCtx = uni.createMapContext("map", this);
// this.getPlaceAround();
// this.updateMarkers();
mapCtx.getCenterLocation({
success: (res) => {
console.log(111, res);
// if (
// this.latitude === res.latitude &&
// this.longitude === res.longitude
// ) {
// return;
// }
// console.log("结束了");
// // 当前中心经纬度位置
this.newLatitude = res.latitude;
this.newLongitude = res.longitude;
this.updateMarkers();
this.getPlaceAround();
},
});
}
},
// 去选择地图列表页
goAddress() {
uni.navigateTo({
url: '/pages/address/list'
})
}
}
}
</script>
<style scoped lang="less">
.search-container {
background-color: #FFFFFF;
display: flex;
flex-direction: row;
align-items: center;
padding: 32rpx 30rpx 20rpx 30rpx;
.search-container-text {
font-family: PingFangSC, PingFang SC;
font-weight: 500;
font-size: 32rpx;
color: #333333;
line-height: 45rpx;
text-align: left;
font-style: normal;
}
.text-img {
width: 20rpx;
height: 12rpx;
margin-left: 8rpx;
margin-right: 26rpx;
}
.address-header {
flex: 1;
height: 68rpx;
background: #FFFFFF;
2026-06-02 11:39:23 +08:00
border: 2rpx solid #FF4767;
2026-03-24 11:45:13 +08:00
border-radius: 60rpx;
position: relative;
.search-icon {
width: 29rpx;
height: 32rpx;
position: absolute;
top: 18rpx;
left: 22rpx;
}
.search-text {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 26rpx;
color: #CCCCCC;
text-align: left;
font-style: normal;
position: absolute;
top: 16rpx;
left: 72rpx;
}
}
}
.address-list {
background-color: #FFFFFF;
}
.address-item {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
padding: 32rpx;
border-bottom: 1rpx solid #EEEEEE;
}
.address-info {
flex: 1;
margin-right: 24rpx;
}
.address-name {
font-size: 28rpx;
color: #333333;
font-weight: 500;
margin-bottom: 8rpx;
}
.address-detail {
font-size: 24rpx;
color: #666666;
}
.distance-text {
font-size: 24rpx;
color: #999999;
}
.map-container {
width: 750rpx;
height: 500rpx;
position: relative;
z-index: 1;
}
.map {
width: 750rpx;
height: 500rpx;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding-top: 200rpx;
}
.empty-icon {
width: 240rpx;
height: 240rpx;
margin-bottom: 32rpx;
}
.empty-text {
font-size: 30rpx;
color: #999999;
}
/* 平台适配 */
/* #ifdef H5 */
.search-address-page {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
/* #endif */
/* #ifdef MP-WEIXIN */
.map-container {
overflow: hidden;
}
/* #endif */
.center-marker {
position: absolute;
left: 375rpx;
transform: translate(-50%);
top: 200rpx;
width: 42rpx;
height: 69rpx;
.center-marker-img {
width: 42rpx;
}
}
</style>