252 lines
5.3 KiB
Vue
252 lines
5.3 KiB
Vue
|
<template>
|
|||
|
<view class="container">
|
|||
|
<!-- 顶部搜索框 -->
|
|||
|
<view class="search-bar">
|
|||
|
<input type="text" v-model="keyword" placeholder="搜索地点" @confirm="onSearch" />
|
|||
|
<button @click="onSearch">搜索</button>
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 地图展示区 -->
|
|||
|
<view id="map" class="map"></view>
|
|||
|
|
|||
|
<!-- 搜索结果列表 -->
|
|||
|
<view class="result-list" v-if="pois.length">
|
|||
|
<view class="poi-item" v-for="(poi, idx) in pois" :key="idx" @click="selectPoi(poi)">
|
|||
|
<text class="poi-name">{{ poi.name }}</text>
|
|||
|
<text class="poi-address">{{ poi.address }}</text>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 默认提示区 -->
|
|||
|
<view class="info" v-else>
|
|||
|
<text>请选择或搜索地点</text>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<script setup>
|
|||
|
import {
|
|||
|
onMounted,
|
|||
|
ref
|
|||
|
} from 'vue';
|
|||
|
import {
|
|||
|
useRoute
|
|||
|
} from 'vue-router';
|
|||
|
|
|||
|
// 从路由获取备用默认坐标
|
|||
|
const route = useRoute();
|
|||
|
const defaultLat = Number(route.query.lat) || 39.9042;
|
|||
|
const defaultLng = Number(route.query.lng) || 116.4074;
|
|||
|
|
|||
|
const keyword = ref('');
|
|||
|
const pois = ref([]);
|
|||
|
let map = null;
|
|||
|
let marker = null;
|
|||
|
let searchService = null;
|
|||
|
|
|||
|
function initMap(lat, lng) {
|
|||
|
const center = new qq.maps.LatLng(lat, lng);
|
|||
|
map = new qq.maps.Map(document.getElementById('map'), {
|
|||
|
center,
|
|||
|
zoom: 15
|
|||
|
});
|
|||
|
marker = new qq.maps.Marker({
|
|||
|
position: center,
|
|||
|
map
|
|||
|
});
|
|||
|
searchService = new qq.maps.SearchService({
|
|||
|
map,
|
|||
|
pageCapacity: 10
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
// 1. 动态加载微信 JSSDK 脚本
|
|||
|
async function loadWxJSSDK() {
|
|||
|
if (window.wx) return
|
|||
|
await new Promise(resolve => {
|
|||
|
const script = document.createElement('script')
|
|||
|
script.src = 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js'
|
|||
|
script.onload = resolve
|
|||
|
document.head.appendChild(script)
|
|||
|
getapi()
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
const getapi = () => {
|
|||
|
const post = `${uni.getStorageSync('serverUrl')}/weiXinPay/getJsApiInfo`;
|
|||
|
const pay = {
|
|||
|
url: location.href.split('#')[0],
|
|||
|
};
|
|||
|
console.log("????", pay)
|
|||
|
fetch(post, {
|
|||
|
method: 'POST',
|
|||
|
headers: {
|
|||
|
'Content-Type': 'application/json'
|
|||
|
},
|
|||
|
body: JSON.stringify(pay)
|
|||
|
})
|
|||
|
.then(res => res.json())
|
|||
|
.then(data => {
|
|||
|
// secondArray.value = [...data.result];
|
|||
|
// console.log("???调取微信", data)
|
|||
|
wx.config({
|
|||
|
debug: false, // 开启调试会 alert 所有调用结果
|
|||
|
appId: `wx8fc3e4305d2fbf0b`, // 必填,公众号的唯一标识
|
|||
|
timestamp: data.timestamp, // 必填,生成签名的时间戳
|
|||
|
nonceStr: data.nonceStr, // 必填,生成签名的随机串
|
|||
|
signature: data.signature, // 必填,签名
|
|||
|
jsApiList: [ // 必填,需要使用的 JS 接口列表
|
|||
|
'chooseAddress',
|
|||
|
'getLocation',
|
|||
|
'openLocation',
|
|||
|
/* …根据实际业务增删 */
|
|||
|
]
|
|||
|
})
|
|||
|
|
|||
|
|
|||
|
})
|
|||
|
.catch(err => {
|
|||
|
console.error('请求失败:', err);
|
|||
|
});
|
|||
|
}
|
|||
|
// async function locate() {
|
|||
|
// // 优先使用 uni.getLocation(App+小程序)
|
|||
|
// try {
|
|||
|
// const res = await new Promise((resolve, reject) => {
|
|||
|
// uni.getLocation({
|
|||
|
// type: 'gcj02',
|
|||
|
// success: resolve,
|
|||
|
// fail: reject
|
|||
|
// });
|
|||
|
// });
|
|||
|
// return {
|
|||
|
// lat: res.latitude,
|
|||
|
// lng: res.longitude
|
|||
|
// };
|
|||
|
// } catch {
|
|||
|
// // H5 使用浏览器 Geolocation
|
|||
|
// if (navigator.geolocation) {
|
|||
|
// try {
|
|||
|
// const pos = await new Promise((resolve, reject) => {
|
|||
|
// navigator.geolocation.getCurrentPosition(resolve, reject, {
|
|||
|
// enableHighAccuracy: true
|
|||
|
// });
|
|||
|
// });
|
|||
|
// return {
|
|||
|
// lat: pos.coords.latitude,
|
|||
|
// lng: pos.coords.longitude
|
|||
|
// };
|
|||
|
// } catch {
|
|||
|
// return null;
|
|||
|
// }
|
|||
|
// }
|
|||
|
// return null;
|
|||
|
// }
|
|||
|
// }
|
|||
|
|
|||
|
onMounted(async () => {
|
|||
|
// loadWxJSSDK()
|
|||
|
// 后端接口要接受当前页面 URL(不能带 # 后面),用于计算 signature
|
|||
|
// const loc = await locate();
|
|||
|
// if (loc) {
|
|||
|
// initMap(loc.lat, loc.lng);
|
|||
|
// } else {
|
|||
|
// uni.showToast({
|
|||
|
// title: '定位失败,使用默认位置',
|
|||
|
// icon: 'none'
|
|||
|
// });
|
|||
|
// initMap(defaultLat, defaultLng);
|
|||
|
// }
|
|||
|
initMap(defaultLat, defaultLng)
|
|||
|
});
|
|||
|
|
|||
|
function onSearch() {
|
|||
|
const kw = keyword.value.trim();
|
|||
|
if (!kw) {
|
|||
|
uni.showToast({
|
|||
|
title: '请输入搜索内容',
|
|||
|
icon: 'none'
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
pois.value = [];
|
|||
|
// 腾讯地图的 SearchService.search 回调只有一个参数
|
|||
|
searchService.search(kw, (results) => {
|
|||
|
if (results && results.length) {
|
|||
|
pois.value = results;
|
|||
|
} else {
|
|||
|
uni.showToast({
|
|||
|
title: '未搜索到结果',
|
|||
|
icon: 'none'
|
|||
|
});
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
function selectPoi(poi) {
|
|||
|
const pos = new qq.maps.LatLng(poi.lat, poi.lng);
|
|||
|
map.setCenter(pos);
|
|||
|
marker.setPosition(pos);
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
<style scoped>
|
|||
|
.container {
|
|||
|
display: flex;
|
|||
|
flex-direction: column;
|
|||
|
height: 100vh;
|
|||
|
}
|
|||
|
|
|||
|
.search-bar {
|
|||
|
display: flex;
|
|||
|
padding: 8px;
|
|||
|
background: #fff;
|
|||
|
}
|
|||
|
|
|||
|
.search-bar input {
|
|||
|
flex: 1;
|
|||
|
padding: 6px;
|
|||
|
border: 1px solid #ccc;
|
|||
|
border-radius: 4px;
|
|||
|
}
|
|||
|
|
|||
|
.search-bar button {
|
|||
|
margin-left: 8px;
|
|||
|
padding: 6px 12px;
|
|||
|
background-color: #1aad19;
|
|||
|
color: #fff;
|
|||
|
border: none;
|
|||
|
border-radius: 4px;
|
|||
|
}
|
|||
|
|
|||
|
.map {
|
|||
|
flex: 1;
|
|||
|
}
|
|||
|
|
|||
|
.result-list {
|
|||
|
max-height: 200px;
|
|||
|
overflow-y: auto;
|
|||
|
background: #fff;
|
|||
|
}
|
|||
|
|
|||
|
.poi-item {
|
|||
|
padding: 8px;
|
|||
|
border-bottom: 1px solid #eee;
|
|||
|
}
|
|||
|
|
|||
|
.poi-name {
|
|||
|
font-weight: bold;
|
|||
|
}
|
|||
|
|
|||
|
.poi-address {
|
|||
|
font-size: 12px;
|
|||
|
color: #666;
|
|||
|
}
|
|||
|
|
|||
|
.info {
|
|||
|
padding: 16px;
|
|||
|
background: #fff;
|
|||
|
text-align: center;
|
|||
|
color: #999;
|
|||
|
}
|
|||
|
</style>
|