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 @@