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

791 lines
20 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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;
border: 2rpx solid #FF4767;
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>