修复地图定位bug
This commit is contained in:
+89
-60
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<view class="search-page">
|
||||
<view class="map-wrap">
|
||||
<MapComponent :userLocation="userLocation" :filteredPositions="filteredPositions"
|
||||
:enableMarkers="true" :customHeight="'100%'" :hideControls="true" :fullWidth="true"
|
||||
@mapCenterChange="onMapCenterChange" @relocate="init" @markerTap="goToPositionDetail" />
|
||||
<MapComponent :userLocation="userLocation" :filteredPositions="filteredPositions" :enableMarkers="true"
|
||||
:customHeight="'100%'" :hideControls="true" :fullWidth="true" @mapCenterChange="onMapCenterChange"
|
||||
@relocate="init" @markerTap="goToPositionDetail" />
|
||||
<!-- 定位按钮 -->
|
||||
<view class="relocate-btn" @click="init">
|
||||
<image src="/static/location.png" class="relocate-icon" mode="aspectFit"></image>
|
||||
@@ -12,15 +12,19 @@
|
||||
<view class="list-wrap">
|
||||
<view class="panel">
|
||||
<view class="filter-tabs">
|
||||
<view class="tab" :class="{ active: activeTab === 'rent' }" @click="setTab('rent')">{{ $t('location.rent') }}</view>
|
||||
<view class="tab" :class="{ active: activeTab === 'return' }" @click="setTab('return')">{{ $t('location.return') }}</view>
|
||||
<view class="tab" :class="{ active: activeTab === 'rent' }" @click="setTab('rent')">
|
||||
{{ $t('location.rent') }}</view>
|
||||
<view class="tab" :class="{ active: activeTab === 'return' }" @click="setTab('return')">
|
||||
{{ $t('location.return') }}</view>
|
||||
</view>
|
||||
<scroll-view class="list-scroll" scroll-y="true">
|
||||
<view class="card" :class="{ available: isRentable(item), invalid: !isValidCoordinate(item.latitude, item.longitude) }"
|
||||
<view class="card"
|
||||
:class="{ available: isRentable(item), invalid: !isValidCoordinate(item.latitude, item.longitude) }"
|
||||
v-for="(item, index) in filteredPositions" :key="item.positionId || index"
|
||||
@click="goToPositionDetail(item)">
|
||||
<view class="thumb">
|
||||
<image v-if="item.deviceImg" :src="item.deviceImg" class="thumb-img" mode="aspectFill"></image>
|
||||
<image v-if="item.deviceImg" :src="item.deviceImg" class="thumb-img" mode="aspectFill">
|
||||
</image>
|
||||
<image v-else src="/static/device-info.png" class="thumb-img" mode="aspectFit"></image>
|
||||
</view>
|
||||
<view class="info">
|
||||
@@ -31,41 +35,44 @@
|
||||
<view class="row sub" v-if="item.location">
|
||||
<text class="addr">{{ item.location }}</text>
|
||||
</view>
|
||||
<view class="row meta" v-if="item.workTime && item.workTime !== '0'">
|
||||
<text class="time">{{ $t('location.businessHours') }}{{ item.workTime }}</text>
|
||||
</view>
|
||||
<view class="row meta" v-if="!isValidCoordinate(item.latitude, item.longitude)">
|
||||
<text class="time" style="color: #ff6b6b;">{{ $t('location.coordinateError') }}</text>
|
||||
</view>
|
||||
<view class="row meta" v-if="item.availablePowerBankCount !== undefined && item.availablePowerBankCount !== null">
|
||||
<text class="time">可租借:{{ item.availablePowerBankCount }} 台</text>
|
||||
</view>
|
||||
<view class="row meta" v-if="item.availableEmptyGridCount !== undefined && item.availableEmptyGridCount !== null">
|
||||
<text class="time">可归还:{{ item.availableEmptyGridCount }} 个空位</text>
|
||||
</view>
|
||||
<view class="row meta remark-info" v-if="item.remark">
|
||||
<text class="time">💰 {{ item.remark }}</text>
|
||||
</view>
|
||||
<view class="tags">
|
||||
<view class="tag rent" v-if="isRentable(item)">{{ $t('location.rent') }}</view>
|
||||
<view class="tag return" v-if="isReturnable(item)">{{ $t('location.return') }}</view>
|
||||
</view>
|
||||
<view class="row meta" v-if="item.workTime && item.workTime !== '0'">
|
||||
<text class="time">{{ $t('location.businessHours') }}{{ item.workTime }}</text>
|
||||
</view>
|
||||
<view class="row meta" v-if="!isValidCoordinate(item.latitude, item.longitude)">
|
||||
<text class="time" style="color: #ff6b6b;">{{ $t('location.coordinateError') }}</text>
|
||||
</view>
|
||||
<view class="row meta"
|
||||
v-if="item.availablePowerBankCount !== undefined && item.availablePowerBankCount !== null">
|
||||
<text class="time">可租借:{{ item.availablePowerBankCount }} 台</text>
|
||||
</view>
|
||||
<view class="row meta"
|
||||
v-if="item.availableEmptyGridCount !== undefined && item.availableEmptyGridCount !== null">
|
||||
<text class="time">可归还:{{ item.availableEmptyGridCount }} 个空位</text>
|
||||
</view>
|
||||
<view class="row meta remark-info" v-if="item.remark">
|
||||
<text class="time">💰 {{ item.remark }}</text>
|
||||
</view>
|
||||
<view class="tags">
|
||||
<view class="tag rent" v-if="isRentable(item)">{{ $t('location.rent') }}</view>
|
||||
<view class="tag return" v-if="isReturnable(item)">{{ $t('location.return') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="actions">
|
||||
|
||||
<view class="nav"
|
||||
:class="{ disabled: !isValidCoordinate(item.latitude, item.longitude) }"
|
||||
<view class="nav" :class="{ disabled: !isValidCoordinate(item.latitude, item.longitude) }"
|
||||
@click.stop="navigateToPosition(item)">
|
||||
<image src="/static/luxian.png" class="action-icon" mode="aspectFit"></image>
|
||||
</view>
|
||||
<view class="distance" v-if="item.distance && isValidCoordinate(item.latitude, item.longitude)">{{ item.distance }}</view>
|
||||
<view class="distance"
|
||||
v-if="item.distance && isValidCoordinate(item.latitude, item.longitude)">
|
||||
{{ item.distance }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="empty-state" v-if="!isLoading && (!positionList || positionList.length === 0)">
|
||||
<image class="empty-icon" src="/static/scan-icon.png" mode="aspectFit" />
|
||||
<text class="empty-text">{{ $t('home.noNearbyDevice') }}</text>
|
||||
</view>
|
||||
<view class="empty-state" v-if="!isLoading && (!positionList || positionList.length === 0)">
|
||||
<image class="empty-icon" src="/static/scan-icon.png" mode="aspectFit" />
|
||||
<text class="empty-text">{{ $t('home.noNearbyDevice') }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -88,15 +95,25 @@
|
||||
getRegeo,
|
||||
calculateDistanceSync
|
||||
} from '../../utils/mapUtils.js'
|
||||
import { useI18n } from '@/utils/i18n.js'
|
||||
import {
|
||||
useI18n
|
||||
} from '@/utils/i18n.js'
|
||||
|
||||
const { t: $t } = useI18n()
|
||||
const {
|
||||
t: $t
|
||||
} = useI18n()
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
uni.setNavigationBarTitle({
|
||||
title: $t('search.title')
|
||||
})
|
||||
// uni.showLoading({
|
||||
// title:'11111',
|
||||
// mask:true
|
||||
// })
|
||||
init()
|
||||
// uni.hideLoading();
|
||||
})
|
||||
|
||||
const userLocation = ref(null)
|
||||
@@ -173,7 +190,7 @@
|
||||
const loadPositions = async (center) => {
|
||||
try {
|
||||
isLoading.value = true
|
||||
|
||||
|
||||
if (!center || !center.latitude || !center.longitude) {
|
||||
console.warn('中心点位置信息不完整,无法查询附近设备')
|
||||
return
|
||||
@@ -187,11 +204,11 @@
|
||||
pageNum: 1,
|
||||
pageSize: 100
|
||||
})
|
||||
|
||||
|
||||
if (res.code === 200) {
|
||||
// 新接口返回的是 data.records
|
||||
const devices = res.data?.records || []
|
||||
|
||||
|
||||
// 将设备数据转换为统一格式
|
||||
positionList.value = devices.map(device => {
|
||||
const transformed = transformDeviceData(device)
|
||||
@@ -199,10 +216,11 @@
|
||||
return {
|
||||
...transformed,
|
||||
canRent: activeTab.value === 'rent' ? true : (device.availablePowerBankCount > 0),
|
||||
canReturn: activeTab.value === 'return' ? true : (device.availableEmptyGridCount > 0)
|
||||
canReturn: activeTab.value === 'return' ? true : (device.availableEmptyGridCount >
|
||||
0)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
calculateDistances(center)
|
||||
} else {
|
||||
positionList.value = []
|
||||
@@ -217,24 +235,35 @@
|
||||
}
|
||||
}
|
||||
|
||||
const init = async () => {
|
||||
isLoading.value = true
|
||||
try {
|
||||
const loc = await getUserLocation()
|
||||
userLocation.value = {
|
||||
longitude: loc.longitude,
|
||||
latitude: loc.latitude
|
||||
}
|
||||
await loadPositions(userLocation.value)
|
||||
} catch (e) {
|
||||
await loadPositions(userLocation.value || {
|
||||
longitude: 0,
|
||||
latitude: 0
|
||||
})
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
const init = async () => {
|
||||
isLoading.value = true
|
||||
uni.showLoading({
|
||||
mask: true
|
||||
})
|
||||
try {
|
||||
const loc = await getUserLocation()
|
||||
if (!loc?.longitude || !loc?.latitude) {
|
||||
throw new Error('invalid location result')
|
||||
}
|
||||
userLocation.value = {
|
||||
longitude: loc.longitude,
|
||||
latitude: loc.latitude
|
||||
}
|
||||
await loadPositions(userLocation.value)
|
||||
} catch (e) {
|
||||
console.error('初始化定位失败:', e)
|
||||
userLocation.value = null
|
||||
positionList.value = []
|
||||
filteredPositions.value = []
|
||||
uni.showToast({
|
||||
title: $t('home.getLocationFailed'),
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
uni.hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
const onMapCenterChange = (center) => {
|
||||
if (center && typeof center.longitude !== 'undefined' && typeof center.latitude !== 'undefined') {
|
||||
@@ -276,7 +305,6 @@
|
||||
url: `/pages/position/detail?positionId=${position.positionId}`
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -391,7 +419,7 @@
|
||||
border-radius: 16rpx;
|
||||
background: #F0F2F5;
|
||||
overflow: hidden;
|
||||
|
||||
|
||||
.thumb-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -427,6 +455,7 @@
|
||||
|
||||
.addr {
|
||||
display: -webkit-box;
|
||||
line-clamp: 1;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
@@ -435,11 +464,11 @@
|
||||
.row.meta {
|
||||
color: #999;
|
||||
font-size: 22rpx;
|
||||
|
||||
|
||||
&.remark-info {
|
||||
color: #FF6B35;
|
||||
font-weight: 500;
|
||||
|
||||
|
||||
.time {
|
||||
color: #FF6B35;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user