feat:对接获取附近设备列表

This commit is contained in:
2025-10-29 16:35:51 +08:00
parent 3d67dc928d
commit 409da480b1
9 changed files with 266 additions and 168 deletions
+66 -19
View File
@@ -19,7 +19,10 @@
<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"></view>
<view class="thumb">
<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">
<view class="row top">
<view class="name">{{ item.name }}</view>
@@ -34,6 +37,15 @@
<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>
@@ -68,8 +80,9 @@
} from 'vue'
import MapComponent from '../../components/MapComponent.vue'
import {
URL
} from '../../config/url.js'
getNearbyDevices,
transformDeviceData
} from '../../config/api/device.js'
import {
getUserLocation,
getRegeo,
@@ -109,7 +122,10 @@
const setTab = (name) => {
activeTab.value = name
applyFilter()
// 切换 tab 时重新查询设备列表(因为接口需要不同的 queryType)
if (userLocation.value) {
loadPositions(userLocation.value)
}
}
const applyFilter = () => {
@@ -157,28 +173,43 @@
const loadPositions = async (center) => {
try {
isLoading.value = true
const res = await uni.request({
url: `${URL}/device/position/app/list`,
method: 'GET',
header: {
'Authorization': 'Bearer ' + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
}
if (!center || !center.latitude || !center.longitude) {
console.warn('中心点位置信息不完整,无法查询附近设备')
return
}
const res = await getNearbyDevices({
userLatitude: center.latitude,
userLongitude: center.longitude,
queryType: activeTab.value, // 使用当前选中的 tab (rent/return)
radiusKm: 5,
pageNum: 1,
pageSize: 100
})
if (res.statusCode === 200 && res.data?.code === 200) {
// 过滤掉特定的 positionId
const filteredData = (res.data.rows || []).filter(item => item.positionId !== '1979008434641670145')
positionList.value = filteredData
calculateDistances(center)
} else if (res.statusCode === 401 || res.data?.code === 401 || res.data?.code === 40101) {
uni.reLaunch({
url: '/pages/login/index'
if (res.code === 200) {
// 新接口返回的是 data.records
const devices = res.data?.records || []
// 将设备数据转换为统一格式
positionList.value = devices.map(device => {
const transformed = transformDeviceData(device)
// 根据当前 tab 设置租借和归还能力
return {
...transformed,
canRent: activeTab.value === 'rent' ? true : (device.availablePowerBankCount > 0),
canReturn: activeTab.value === 'return' ? true : (device.availableEmptyGridCount > 0)
}
})
calculateDistances(center)
} else {
positionList.value = []
filteredPositions.value = []
}
} catch (e) {
console.error('查询附近设备失败:', e)
positionList.value = []
filteredPositions.value = []
} finally {
@@ -359,6 +390,13 @@
height: 120rpx;
border-radius: 16rpx;
background: #F0F2F5;
overflow: hidden;
.thumb-img {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
}
.info {
@@ -397,6 +435,15 @@
.row.meta {
color: #999;
font-size: 22rpx;
&.remark-info {
color: #FF6B35;
font-weight: 500;
.time {
color: #FF6B35;
}
}
}
.tags {