559 lines
14 KiB
Vue
559 lines
14 KiB
Vue
<template>
|
||
<view class="page">
|
||
<u-navbar title="附近门店" :border-bottom="false" :background="bgc" title-color='#3D3D3D' back-icon-color="#3D3D3D"
|
||
title-size='44' height='44'></u-navbar>
|
||
<view class="dtxs">
|
||
<map class='map' id="map" :latitude="latitude" :longitude="longitude" @markertap="handleMarkerClick"
|
||
:show-location="true" :markers="covers" :scale="mapScale" @regionchange="regionchange" />
|
||
<image class="picimg" v-if="iconflag"
|
||
src="https://api.ccttiot.com/smartmeter/img/static/uEAmNMMt65U10qwijrsJ" mode=""></image>
|
||
</view>
|
||
<view class="listbox">
|
||
<view class="moshi">
|
||
<!-- <image src="https://api.ccttiot.com/smartmeter/img/static/uThUUsa3Zs1tMF9Bpdl9" mode=""
|
||
@click="btndt(1)" class="img"></image> -->
|
||
<image @click="onControltap"
|
||
style="width: 76rpx;height: 76rpx;position: absolute;right: 50rpx;top:25rpx"
|
||
src="https://api.ccttiot.com/smartmeter/img/static/uOS9p7Sy1K9WpVQgD3b9" mode=""></image>
|
||
</view>
|
||
<view class="list" v-for="(item,index) in gxlist" :key="index">
|
||
<view class="pic" @click="btndts(item)">
|
||
<image :src="item.picture" mode=""></image>
|
||
</view>
|
||
<view class="cen" @click="btndts(item)">
|
||
<view class="cena" style="font-weight: 600;">
|
||
{{item.name}}
|
||
</view>
|
||
<view class="cenb">
|
||
<image src="https://api.ccttiot.com/smartmeter/img/static/uHK2aJHvzEm3nbOPwpdr" mode=""></image>
|
||
{{item.address}}
|
||
</view>
|
||
<view class="cenc">
|
||
经营时间:{{item.businessTimeStart}}-{{item.businessTimeEnd}}<text class="bu">总数量:{{item.deviceCount}}</text>
|
||
</view>
|
||
</view>
|
||
<view class="right">
|
||
<image src="https://api.ccttiot.com/smartmeter/img/static/uraUDWkEx5OvJB29kMnS" mode="" @click="mapFun(item)"></image>
|
||
<text>{{String(item.distance).split('.')[0]}}m</text>
|
||
</view>
|
||
</view>
|
||
<view class="" v-if="gxlist.length == 0"
|
||
style="width: 100%;height: 200rpx;margin: auto;margin-top: 230rpx;text-align: center;">
|
||
<image style="width: 200rpx;height: 200rpx;"
|
||
src="https://api.ccttiot.com/smartmeter/img/static/uZFUpcz0YZZ4f4RjvGg2" mode=""></image>
|
||
<view class="" style="font-size: 28rpx;color: #808080;margin-top: 30rpx;">该区域暂无店铺...</view>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
data() {
|
||
return {
|
||
latitude: '',
|
||
longitude: '',
|
||
covers: [],
|
||
index: 1,
|
||
isMch: false,
|
||
gxlist: [],
|
||
bgc: {
|
||
background: 'linear-gradient(to right, #FFEFEF 20%, #D9F6FF 100%)'
|
||
},
|
||
mapScale: 15,
|
||
mapContext: null,
|
||
mapScaleInterval: null,
|
||
listmap: [],
|
||
iconflag: false
|
||
}
|
||
},
|
||
onLoad() {
|
||
|
||
},
|
||
onShow() {
|
||
this.getshanghu()
|
||
},
|
||
onReady() {
|
||
this.mapContext = uni.createMapContext('map', this)
|
||
this.mapScaleInterval = setInterval(this.updateMarkers, 1000)
|
||
},
|
||
// 分享到好友(会话)
|
||
onShareAppMessage: function() {
|
||
return {
|
||
title: '创亿康',
|
||
path: '/pages/index/index'
|
||
}
|
||
},
|
||
|
||
// 分享到朋友圈
|
||
onShareTimeline: function() {
|
||
return {
|
||
title: '创亿康',
|
||
query: '',
|
||
path: '/pages/index/index'
|
||
}
|
||
},
|
||
beforeDestroy() {
|
||
// 在组件卸载前清除定时器
|
||
if (this.mapScaleInterval) {
|
||
clearInterval(this.mapScaleInterval)
|
||
this.mapScaleInterval = null
|
||
}
|
||
},
|
||
methods: {
|
||
// 点击地图查询点击地方的店铺
|
||
regionchange(e) {
|
||
if (e.type == 'end') {
|
||
// this.gxlist = []
|
||
this.jinweidu = e.detail.centerLocation.longitude + ',' + e.detail.centerLocation.latitude
|
||
this.$u.get("/app/store/listNearBy?center=" + this.jinweidu + '&radius=' + 5000).then(
|
||
res => {
|
||
if (res.code == 200) {
|
||
this.gxlist = res.data
|
||
this.covers = []
|
||
this.listmap = res.data
|
||
res.data.forEach(item => {
|
||
const distance = this.getDistance(this.latitude, this.longitude, item.lat, item.lng)
|
||
// 将距离添加到店铺对象中
|
||
item.distance = distance
|
||
// if (item.deviceCount !== null && item.deviceCount > 0) {
|
||
const shopCover = {
|
||
id: parseFloat(item.storeId),
|
||
latitude: item.lat,
|
||
longitude: item.lng,
|
||
width: 25,
|
||
height: 30,
|
||
iconPath: 'https://api.ccttiot.com/smartmeter/img/static/u0yXGqCqoDjuK4QPJHZY',
|
||
distance:distance,
|
||
// iconPath:item.picture
|
||
label: {
|
||
content: item.name,
|
||
anchorX: this.calculateAnchorX(item.name),
|
||
fontWeight: 700,
|
||
color: '#8883F0',
|
||
borderColor: '#fff',
|
||
borderRadius: 5,
|
||
bgColor: '#fff'
|
||
}
|
||
}
|
||
this.covers.push(shopCover)
|
||
// }
|
||
})
|
||
}
|
||
})
|
||
this.iconflag = false
|
||
} else {
|
||
this.iconflag = true
|
||
}
|
||
},
|
||
updateMarkers() {
|
||
this.mapContext.getScale({
|
||
success: (res) => {
|
||
this.covers = [] // 清空之前的覆盖物
|
||
if (res.scale <= 14) {
|
||
this.addMarkersWithoutLabels()
|
||
} else {
|
||
this.addMarkersWithLabels()
|
||
}
|
||
},
|
||
fail: (error) => {
|
||
console.error('获取地图缩放级别失败:', error)
|
||
// 额外的错误处理逻辑...
|
||
},
|
||
});
|
||
},
|
||
addMarkersWithoutLabels() {
|
||
this.listmap.forEach((item) => {
|
||
// if (item.deviceCount !== null && item.deviceCount > 0) {
|
||
const shopCover = {
|
||
id: parseFloat(item.storeId),
|
||
latitude: item.lat,
|
||
longitude: item.lng,
|
||
width: 25,
|
||
height: 30,
|
||
iconPath: 'https://api.ccttiot.com/smartmeter/img/static/u0yXGqCqoDjuK4QPJHZY',
|
||
borderRadius: 5,
|
||
bgColor: '#fff'
|
||
}
|
||
this.covers.push(shopCover)
|
||
// }
|
||
|
||
})
|
||
},
|
||
addMarkersWithLabels() {
|
||
this.listmap.forEach((item) => {
|
||
// if (item.deviceCount !== null && item.deviceCount > 0) {
|
||
const shopCover = {
|
||
id: parseFloat(item.storeId),
|
||
latitude: item.lat,
|
||
longitude: item.lng,
|
||
width: 25,
|
||
height: 30,
|
||
iconPath: 'https://api.ccttiot.com/smartmeter/img/static/u0yXGqCqoDjuK4QPJHZY',
|
||
label: {
|
||
content: item.name,
|
||
anchorX: this.calculateAnchorX(item.name),
|
||
fontWeight: 700,
|
||
color: '#8883F0',
|
||
textShadow: '2px 2px 0px white, -2px -2px 0px white, 2px -2px 0px white, -2px 2px 0px white',
|
||
borderRadius: 5,
|
||
bgColor: '#fff'
|
||
}
|
||
}
|
||
this.covers.push(shopCover)
|
||
// }
|
||
|
||
})
|
||
},
|
||
calculateAnchorX(name) {
|
||
let chineseLength = 0
|
||
let englishLength = 0
|
||
for (let i = 0; i < name.length; i++) {
|
||
const charCode = name.charCodeAt(i)
|
||
// 判断是否为中文字符(这里简化了判断,只考虑了基本的中文字符范围)
|
||
if (charCode >= 0x4e00 && charCode <= 0x9fa5) {
|
||
chineseLength++
|
||
} else if (/[a-zA-Z]/.test(name[i])) { // 判断是否为英文字符
|
||
englishLength = englishLength + 0.3 // 英文长度加1,但视为两个中文字符长度
|
||
// console.log(englishLength)
|
||
}
|
||
}
|
||
const totalLength = chineseLength + englishLength * 2 // 总长度(以中文字符为单位)
|
||
return -totalLength * 6.5 // 假设每个中文字符对应的 anchorX 偏移是 -6.5
|
||
},
|
||
|
||
onControltap(control) {
|
||
this.setMapScale()
|
||
},
|
||
// 地图回正
|
||
async setMapScale(e, val) {
|
||
let mapContext = uni.createMapContext('map', this);
|
||
let setScale = () => {
|
||
return new Promise((resolve, reject) => {
|
||
mapContext.getScale({
|
||
success: r => {
|
||
this.mapScale = 15
|
||
resolve()
|
||
}
|
||
})
|
||
})
|
||
};
|
||
await setScale();
|
||
mapContext.moveToLocation({
|
||
success: (res) => {
|
||
const timer = setTimeout(() => {
|
||
this.mapScale = 15
|
||
clearTimeout(timer)
|
||
}, 500)
|
||
},
|
||
})
|
||
},
|
||
|
||
// 跳转导航
|
||
mapFun(item) {
|
||
uni.openLocation({
|
||
latitude: item.lat,
|
||
longitude: item.lng,
|
||
name: item.county,
|
||
address: item.address
|
||
})
|
||
},
|
||
getshanghu() {
|
||
this.$u.get("/app/user/userInfo").then((res) => {
|
||
if (res.code == 200) {
|
||
this.isMch = res.data.isMch
|
||
}
|
||
})
|
||
},
|
||
getMyLocation() {
|
||
uni.getLocation({
|
||
type: 'wgs84',
|
||
success: (res) => {
|
||
this.jinweidu = res.longitude + ',' + res.latitude
|
||
this.latitude = Number(res.latitude.toFixed(5)) - 0.005
|
||
this.longitude = Number(res.longitude.toFixed(5)) + 0.005
|
||
this.setMapScale()
|
||
// 请求附近的店铺
|
||
this.$u.get("/app/store/listNearBy?center=" + this.jinweidu + '&radius=' + 5000).then(
|
||
response => {
|
||
if (response.code == 200) {
|
||
this.listmap = response.data
|
||
let gxlist = response.data
|
||
gxlist.forEach(item => {
|
||
// if (item.deviceCount !== null && item.deviceCount > 0) {
|
||
// 计算距离
|
||
const distance = this.getDistance(this.latitude, this
|
||
.longitude, item.lat, item.lng)
|
||
// 将距离添加到店铺对象中
|
||
item.distance = distance
|
||
// 创建店铺覆盖物对象
|
||
const shopCover = {
|
||
id: parseFloat(item.storeId),
|
||
latitude: item.lat,
|
||
longitude: item.lng,
|
||
width: 25,
|
||
height: 30,
|
||
iconPath: 'https://api.ccttiot.com/smartmeter/img/static/u0yXGqCqoDjuK4QPJHZY',
|
||
distance: distance, // 可以在这里也添加距离到覆盖物对象中,但通常只需要在店铺对象中
|
||
label: {
|
||
content: item.name,
|
||
anchorX:this.calculateAnchorX(item.name),
|
||
fontWeight: 700,
|
||
color: '#8883F0',
|
||
textShadow: '2px 2px 0px white, -2px -2px 0px white, 2px -2px 0px white, -2px 2px 0px white',
|
||
borderRadius: 5,
|
||
bgColor: '#fff'
|
||
}
|
||
}
|
||
this.covers.push(shopCover)
|
||
this.gxlist.push(item)
|
||
// }
|
||
|
||
})
|
||
}
|
||
}).catch(error => {
|
||
console.error('请求店铺列表失败:', error)
|
||
})
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err)
|
||
}
|
||
});
|
||
},
|
||
// 计算距离函数
|
||
getDistance(lat1, lon1, lat2, lon2) {
|
||
const R = 6371000 // 地球半径,单位:米
|
||
const phi1 = lat1 * Math.PI / 180 // 纬度转为弧度
|
||
const phi2 = lat2 * Math.PI / 180
|
||
const deltaPhi = (lat2 - lat1) * Math.PI / 180
|
||
const deltaLambda = (lon2 - lon1) * Math.PI / 180
|
||
const a = Math.sin(deltaPhi / 2) * Math.sin(deltaPhi / 2) + Math.cos(phi1) * Math.cos(phi2) * Math.sin(
|
||
deltaLambda / 2) * Math.sin(deltaLambda / 2)
|
||
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
|
||
const distance = R * c
|
||
return distance
|
||
},
|
||
|
||
handleMarkerClick(event) {
|
||
const markerId = event.markerId
|
||
uni.navigateTo({
|
||
url: '/pages/myorder/index?markerId=' + markerId
|
||
})
|
||
},
|
||
btndts(item) {
|
||
const markerId = item.storeId
|
||
uni.navigateTo({
|
||
url: '/pages/myorder/returned/index?storeId=' + markerId
|
||
})
|
||
},
|
||
|
||
btntab(num) {
|
||
this.index = num
|
||
},
|
||
|
||
btndt(num) {
|
||
if (num == 1) {
|
||
uni.navigateTo({
|
||
url: '/page_user/homepage'
|
||
})
|
||
} else if (num == 2) {
|
||
// console.log(111);
|
||
uni.switchTab({
|
||
url: '/pages/index/index'
|
||
})
|
||
}
|
||
}
|
||
},
|
||
mounted() {
|
||
this.getMyLocation()
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
/deep/ .u-title {
|
||
padding-bottom: 15rpx;
|
||
}
|
||
|
||
/deep/ .u-icon__icon {
|
||
padding-bottom: 15rpx;
|
||
}
|
||
|
||
/deep/ .map {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
page {
|
||
background: linear-gradient(180deg, #D9D8FF 0%, rgba(255, 255, 255, 0) 100%);
|
||
border-radius: 0rpx 0rpx 0rpx 0rpx;
|
||
}
|
||
|
||
.page {
|
||
width: 750rpx;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
|
||
.dtxs {
|
||
width: 100%;
|
||
height: 100vh;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
z-index: -1;
|
||
.picimg {
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
position: absolute;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
top: 50%;
|
||
}
|
||
}
|
||
|
||
.listbox {
|
||
margin-top: 850rpx;
|
||
background: #FFFFFF;
|
||
border-radius: 64rpx 64rpx 0 0;
|
||
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
|
||
padding-left: 32rpx;
|
||
padding-right: 32rpx;
|
||
box-sizing: border-box;
|
||
height: 40vh;
|
||
overflow-y: scroll;
|
||
padding-bottom: 100rpx;
|
||
|
||
.moshi {
|
||
position: absolute;
|
||
bottom: 48vh;
|
||
left: 30rpx;
|
||
z-index: 99;
|
||
width: 100%;
|
||
|
||
image {
|
||
width: 76rpx;
|
||
height: 96rpx;
|
||
}
|
||
}
|
||
|
||
.title {
|
||
border-radius: 64rpx 64rpx 0 0;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
font-weight: 500;
|
||
font-size: 36rpx;
|
||
color: #3D3D3D;
|
||
line-height: 160rpx;
|
||
padding: 0 76rpx;
|
||
width: 100%;
|
||
background-color: #fff;
|
||
position: fixed;
|
||
height: 160rpx;
|
||
top: 40vh;
|
||
left: 0;
|
||
padding-bottom: 20rpx;
|
||
}
|
||
|
||
.list {
|
||
display: flex;
|
||
// justify-content: space-between;
|
||
margin-top: 44rpx;
|
||
border-bottom: 1px solid #eee;
|
||
padding-bottom: 16rpx;
|
||
|
||
.pic {
|
||
width: 134rpx;
|
||
height: 134rpx;
|
||
background-color: #D9D8FF;
|
||
border-radius: 10rpx;
|
||
margin-right: 20rpx;
|
||
border-radius: 20rpx;
|
||
|
||
image {
|
||
width: 100%;
|
||
height: 100%;
|
||
border-radius: 20rpx;
|
||
}
|
||
}
|
||
|
||
.cen {
|
||
width: 488rpx;
|
||
|
||
.cena {
|
||
font-weight: 700 !important;
|
||
font-size: 28rpx;
|
||
color: #3D3D3D;
|
||
line-height: 38rpx;
|
||
}
|
||
|
||
.cenb {
|
||
font-weight: 400;
|
||
font-size: 26rpx;
|
||
color: #3D3D3D;
|
||
line-height: 32rpx;
|
||
margin-top: 14rpx;
|
||
padding-right: 30rpx;
|
||
box-sizing: border-box;
|
||
|
||
image {
|
||
display: inline-block;
|
||
width: 22rpx;
|
||
height: 22rpx;
|
||
margin-right: 6rpx;
|
||
}
|
||
}
|
||
|
||
.cenc {
|
||
font-weight: 400;
|
||
font-size: 26rpx;
|
||
color: #3D3D3D;
|
||
line-height: 32rpx;
|
||
margin-top: 14rpx;
|
||
|
||
text {
|
||
display: inline-block;
|
||
padding: 4rpx 18rpx;
|
||
box-sizing: border-box;
|
||
border-radius: 20rpx;
|
||
}
|
||
|
||
.bu {
|
||
margin-left: 32rpx;
|
||
background: #D9D8FF;
|
||
color: #4D48B5;
|
||
font-size: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.right {
|
||
padding-top: 40rpx;
|
||
text-align: center;
|
||
|
||
image {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
text {
|
||
display: block;
|
||
font-weight: 400;
|
||
font-size: 20rpx;
|
||
color: #808080;
|
||
line-height: 28rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.active {
|
||
border-bottom: 10rpx solid #D9D8FF;
|
||
border-radius: 7rpx;
|
||
padding-bottom: 10rpx;
|
||
font-weight: 700;
|
||
}
|
||
</style> |