From 409da480b1de4de2802611008c5c40fe6ead73c9 Mon Sep 17 00:00:00 2001
From: ISFP_T <68358856@qq.com>
Date: Wed, 29 Oct 2025 16:35:51 +0800
Subject: [PATCH] =?UTF-8?q?feat:=E5=AF=B9=E6=8E=A5=E8=8E=B7=E5=8F=96?=
=?UTF-8?q?=E9=99=84=E8=BF=91=E8=AE=BE=E5=A4=87=E5=88=97=E8=A1=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
App.vue | 2 +-
config/api/device.js | 41 ++++++++
config/url.js | 4 +-
main.js | 2 +-
pages.json | 3 +-
pages/index/index.vue | 198 +++++++++++++++++---------------------
pages/position/detail.vue | 97 ++++++++++++-------
pages/search/index.vue | 85 ++++++++++++----
uni.scss | 2 +-
9 files changed, 266 insertions(+), 168 deletions(-)
diff --git a/App.vue b/App.vue
index 6e3a3fc..6689284 100644
--- a/App.vue
+++ b/App.vue
@@ -68,7 +68,7 @@
\ No newline at end of file
diff --git a/config/api/device.js b/config/api/device.js
index 42bdb43..77793b0 100644
--- a/config/api/device.js
+++ b/config/api/device.js
@@ -8,6 +8,47 @@ export const getDeviceInfo = (deviceNo) => {
})
}
+// 查询附近设备
+export const getNearbyDevices = ({ userLatitude, userLongitude, queryType = 'rent', radiusKm = 5, pageNum = 1, pageSize = 100 }) => {
+ return request({
+ url: `/device/device/nearby?pageNum=${pageNum}&pageSize=${pageSize}`,
+ method: 'post',
+ data: {
+ userLatitude,
+ userLongitude,
+ queryType, // 'rent' 可租借 或 'return' 可归还
+ radiusKm
+ },
+ hideLoading: true // 不显示加载提示,由页面自己控制
+ })
+}
+
+// 转换设备数据为统一格式(兼容旧的场地数据结构)
+export const transformDeviceData = (device) => {
+ return {
+ ...device,
+ // 保持原有字段
+ positionId: device.deviceId, // 使用 deviceId 作为 positionId
+ name: device.name || device.positionName,
+ location: device.deviceLocation,
+ latitude: device.latitude,
+ longitude: device.longitude,
+ distance: device.distance ? `${device.distance}km` : '',
+ distanceInMeters: device.distance ? device.distance * 1000 : 999000,
+ // 设备特有字段
+ deviceNo: device.deviceNo,
+ deviceImg: device.deviceImg,
+ availablePowerBankCount: device.availablePowerBankCount,
+ availableEmptyGridCount: device.availableEmptyGridCount,
+ totalGridCount: device.totalGridCount,
+ remark: device.remark || '', // 计费备注信息
+ status: device.status || 'online',
+ // 添加租借和归还能力标识
+ canRent: (device.availablePowerBankCount || 0) > 0,
+ canReturn: (device.availableEmptyGridCount || 0) > 0
+ }
+}
+
// 立即租借
export const rentPowerBank = (deviceNo, phone) => {
return request({
diff --git a/config/url.js b/config/url.js
index b7c9bd0..0be9782 100644
--- a/config/url.js
+++ b/config/url.js
@@ -1,6 +1,6 @@
// export const URL = "https://my.gxfs123.com/api" //正式服务器
-export const URL = "https://fansdev.gxfs123.com/api" //测试服务器
-// export const URL = "http://192.168.5.120:8080" //本地调试
+// export const URL = "https://fansdev.gxfs123.com/api" //测试服务器
+export const URL = "http://192.168.5.120:8080" //本地调试
// export const URL = "http://127.0.0.1:8080" //本地调试
export const appid = "wx2165f0be356ae7a9" //小程序appid
\ No newline at end of file
diff --git a/main.js b/main.js
index 7b98ed6..cf7dcde 100644
--- a/main.js
+++ b/main.js
@@ -4,7 +4,7 @@ import { createSSRApp } from 'vue'
import { createI18n } from 'vue-i18n'
import zhCN from './locale/zh-CN.js'
import enUS from './locale/en-US.js'
-import uView from "uview-ui"
+import uView from '@climblee/uv-ui'
// 获取系统语言
const getSystemLanguage = () => {
diff --git a/pages.json b/pages.json
index 9a99fba..4ca68e6 100644
--- a/pages.json
+++ b/pages.json
@@ -2,8 +2,7 @@
"easycom": {
"autoscan": true,
"custom": {
- "^uv-(.*)": "@climblee/uv-ui/components/uv-$1/uv-$1.vue",
- "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
+ "^uv-(.*)": "@climblee/uv-ui/components/uv-$1/uv-$1.vue"
}
},
"pages": [{
diff --git a/pages/index/index.vue b/pages/index/index.vue
index 902d1a7..0415375 100644
--- a/pages/index/index.vue
+++ b/pages/index/index.vue
@@ -167,7 +167,9 @@
URL
} from "../../config/url.js"
import {
- getDeviceInfo
+ getDeviceInfo,
+ getNearbyDevices,
+ transformDeviceData
} from '../../config/api/device.js'
import {
getPotionsDetail
@@ -422,32 +424,34 @@ const noticePopup = ref(null)
const loadPositions = async () => {
try {
- const res = await uni.request({
- url: `${URL}/device/position/app/list`,
- method: 'GET',
- header: {
- 'Authorization': "Bearer " + uni.getStorageSync('token'),
- 'Clientid': uni.getStorageSync('client_id')
- },
- data: {
- latitude: userLocation.value.latitude,
- longitude: userLocation.value.longitude
- }
- })
- console.log(res);
-
- if (res.statusCode === 401 || res.data?.code === 401 || res.data?.code === 40101) {
- redirectToLogin()
+ if (!userLocation.value || !userLocation.value.latitude || !userLocation.value.longitude) {
+ console.warn('用户位置信息不完整,无法查询附近设备')
return
- } else if (res.statusCode === 200 && res.data.code === 200) {
- positionList.value = res.data.rows || []
+ }
+
+ const res = await getNearbyDevices({
+ userLatitude: userLocation.value.latitude,
+ userLongitude: userLocation.value.longitude,
+ queryType: 'rent', // 默认查询可租借设备
+ radiusKm: 5,
+ pageNum: 1,
+ pageSize: 100
+ })
+
+ console.log('查询附近设备结果:', res)
+
+ if (res.code === 200) {
+ // 新接口返回的是 data.records,需要适配字段名
+ const devices = res.data?.records || []
+ // 将设备数据转换为统一格式
+ positionList.value = devices.map(transformDeviceData)
calculateDistances()
filteredPositions.value = [...positionList.value]
} else {
- console.error('获取场地列表失败:', res.data.msg)
+ console.error('获取设备列表失败:', res.msg)
}
} catch (error) {
- console.error('获取场地列表异常:', error)
+ console.error('获取设备列表异常:', error)
}
}
@@ -494,50 +498,45 @@ const noticePopup = ref(null)
return
}
- console.log('根据地图中心加载场地:', center)
+ console.log('根据地图中心加载设备:', center)
try {
- // 使用原有接口获取所有场地,传入中心点经纬度
- const res = await uni.request({
- url: `${URL}/device/position/app/list`,
- method: 'GET',
- header: {
- 'Authorization': "Bearer " + uni.getStorageSync('token'),
- 'Clientid': uni.getStorageSync('client_id')
- },
- data: {
- latitude: center.latitude,
- longitude: center.longitude
- }
+ // 使用新的附近设备查询接口
+ const res = await getNearbyDevices({
+ userLatitude: center.latitude,
+ userLongitude: center.longitude,
+ queryType: 'rent', // 默认查询可租借设备
+ radiusKm: 5,
+ pageNum: 1,
+ pageSize: 100
})
- if (res.statusCode === 401 || res.data?.code === 401 || res.data?.code === 40101) {
- redirectToLogin()
- return
- } else if (res.statusCode === 200 && res.data.code === 200) {
- const rows = res.data.rows || []
- console.log('加载到场地数量:', rows.length)
+ if (res.code === 200) {
+ const devices = res.data?.records || []
+ console.log('加载到设备数量:', devices.length)
+
+ // 将设备数据转换为统一格式
+ positionList.value = devices.map(transformDeviceData)
- positionList.value = rows
// 基于地图中心计算距离
calculateDistances(center)
- // 可以选择性过滤距离过远的场地(比如超过10km的)
+ // 可以选择性过滤距离过远的设备(比如超过10km的)
const maxDistanceInMeters = 10000 // 最大显示距离,单位米(10km)
filteredPositions.value = positionList.value.filter(item => {
return !item.distanceInMeters || item.distanceInMeters <= maxDistanceInMeters
})
- console.log('过滤后场地数量:', filteredPositions.value.length)
+ console.log('过滤后设备数量:', filteredPositions.value.length)
} else {
- console.error('根据地图中心加载场地失败:', res.data.msg)
+ console.error('根据地图中心加载设备失败:', res.msg)
positionList.value = []
filteredPositions.value = []
}
} catch (error) {
- console.error('根据地图中心加载场地异常:', error)
- // 如果请求失败,保持当前的场地列表不变
+ console.error('根据地图中心加载设备异常:', error)
+ // 如果请求失败,保持当前的设备列表不变
}
}
@@ -1238,37 +1237,39 @@ const closeNoticePopup = () => {
flex-direction: row;
align-items: center;
justify-content: space-between;
- // gap: 16rpx;
+ gap: 16rpx;
padding: 0;
.action-btn {
display: flex;
flex-direction: column;
align-items: center;
- align-content: center;
justify-content: center;
- font-size: 26rpx;
- font-weight: 600;
+ font-size: 24rpx;
+ font-weight: 500;
+ transition: all 0.3s ease;
+
+ &:active {
+ transform: scale(0.95);
+ opacity: 0.8;
+ }
&.primary {
background: #3EAB64;
color: #fff;
- border-radius: 64rpx;
- height: 100rpx;
- min-width: 320rpx;
- // box-shadow: 0 16rpx 40rpx rgba(7, 193, 96, 0.35);
- padding: 12rpx 24rpx;
+ border-radius: 56rpx;
+ height: 112rpx;
+ flex: 1;
+ max-width: 400rpx;
+ padding: 0 24rpx;
+ // box-shadow: 0 8rpx 24rpx rgba(62, 171, 100, 0.3);
.icon-wrap {
- width: 50rpx;
- height: 50rpx;
- border-radius: 50%;
- // background: rgba(255, 255, 255, 0.25);
+ width: 48rpx;
+ height: 48rpx;
display: flex;
align-items: center;
- align-content: center;
justify-content: center;
- // margin-bottom: 10rpx;
}
}
@@ -1277,66 +1278,44 @@ const closeNoticePopup = () => {
color: #333;
border-radius: 24rpx;
height: 100rpx;
- min-width: 180rpx;
- // box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
- padding: 12rpx 16rpx;
+ width: 140rpx;
+ flex-shrink: 0;
+ padding: 8rpx 12rpx;
+ // box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
+ // border: 1rpx solid #f0f0f0;
.icon-wrap {
- width: 40rpx;
- height: 40rpx;
- border-radius: 50%;
- // background: #f7f8fa;
- // border: 2rpx solid #eaeaea;
+ width: 36rpx;
+ height: 36rpx;
display: flex;
align-items: center;
justify-content: center;
- margin-bottom: 10rpx;
+ margin-bottom: 6rpx;
}
}
-
- &.small {
- height: 120rpx;
- min-width: 180rpx;
- border-radius: 28rpx;
- }
- }
-
- .btn-nearby,
- .btn-my {
- gap: 10rpx;
}
.btn-scan {
- /* 尺寸与布局(覆盖 primary 的默认尺寸) */
- height: 112rpx;
- min-width: 360rpx;
- padding: 0 32rpx;
- border-radius: 56rpx;
+ /* 中间扫码按钮:横向布局 */
flex-direction: row;
- // gap: 16rpx;
- align-items: center;
- justify-content: center;
+ gap: 8rpx;
- /* 左侧图标容器 */
.icon-wrap {
- width: 64rpx;
- height: 64rpx;
- border-radius: 50%;
+ width: 48rpx;
+ height: 48rpx;
margin: 0;
- margin-right: 12rpx;
- // background: rgba(255, 255, 255, 0.18);
- display: flex;
- align-items: center;
- justify-content: center;
- box-shadow: none;
}
- /* 图标大小与反色 */
.action-icon {
- width: 40rpx;
- height: 40rpx;
+ width: 32rpx;
+ height: 32rpx;
filter: brightness(0) invert(1);
}
+
+ .primary-label {
+ font-size: 28rpx;
+ font-weight: 600;
+ }
}
}
@@ -1506,17 +1485,18 @@ const closeNoticePopup = () => {
}
.action-icon {
- width: 42rpx;
- height: 42rpx;
+ width: 36rpx;
+ height: 36rpx;
filter: none;
- box-shadow: none;
- }
-
- .btn-scan .action-icon {
- filter: brightness(0) invert(1);
}
.action-label {
+ line-height: 1.2;
+ text-align: center;
+ }
+
+ .primary-label {
+ color: #ffffff;
line-height: 1;
}
diff --git a/pages/position/detail.vue b/pages/position/detail.vue
index 5464b01..30a08dd 100644
--- a/pages/position/detail.vue
+++ b/pages/position/detail.vue
@@ -2,7 +2,8 @@
-
+
+
@@ -27,6 +28,17 @@
{{ $t('device.pricing') }}:{{ pricingText }}
+
+
+
+
+ 可租借风扇:{{ positionInfo.availablePowerBankCount }} 台
+
+
+
+
+ 可归还空位:{{ positionInfo.availableEmptyGridCount }} 个
+
@@ -48,17 +60,21 @@