- - + + @@ -101,7 +101,7 @@ - @@ -318,7 +318,7 @@ 'Content-Language': languageCode }, data: { - type: 'wx_user_type' // 微信小程序用户端 + type: 'wx_user_type' // 微信小程序用户端 } }) @@ -366,8 +366,9 @@ 'Content-Language': languageCode }, data: { - appPlatform: 'wechat', // 微信平台 - appType: 'user' // 用户端 + appPlatform: 'wechat', // 微信平台 + appType: 'user' ,// 用户端 + pictureLocation:'home_banner' } }) @@ -567,94 +568,94 @@ console.warn('清理旧缓存失败:', e); } - // 开发环境测试距离计算 - if (process.env.NODE_ENV === 'development') { - testDistanceCalculation() - } - - // 并行加载公告和广告(不依赖定位) - await Promise.all([ - getNoticeText(), - getBannerImages() - ]) + // 开发环境测试距离计算 + if (process.env.NODE_ENV === 'development') { + testDistanceCalculation() + } - // 1. 先获取用户位置 - await getUserLocationAndAddress() + // 并行加载公告和广告(不依赖定位) + await Promise.all([ + getNoticeText(), + getBannerImages() + ]) - // 2. 加载场地列表(依赖定位) - await loadPositions() + // 1. 先获取用户位置 + await getUserLocationAndAddress() - // 3. 查询活动并显示弹窗 - await checkActiveActivity() + // 2. 加载场地列表(依赖定位) + await loadPositions() + + // 3. 查询活动并显示弹窗 + await checkActiveActivity() } catch (error) { console.error('初始化失败:', error) - uni.showToast({ - title: $t('home.getLocationFailed'), - icon: 'none' - }) + uni.showToast({ + title: $t('home.getLocationFailed'), + icon: 'none' + }) } finally { isLoading.value = false } } const getUserLocationAndAddress = async () => { - // 使用腾讯地图SDK获取位置(若失败抛出,由调用方统一处理) - const location = await getUserLocation() + // 使用腾讯地图SDK获取位置(若失败抛出,由调用方统一处理) + const location = await getUserLocation() - if (!location?.longitude || !location?.latitude) { - throw new Error('invalid location result') - } + if (!location?.longitude || !location?.latitude) { + throw new Error('invalid location result') + } - // 保存用户位置 - userLocation.value = { - longitude: location.longitude, - latitude: location.latitude - } - - console.log(userLocation.value); - // 将经纬度写入本地缓存(基础信息) - try { - uni.setStorageSync('userLocation', { + // 保存用户位置 + userLocation.value = { longitude: location.longitude, latitude: location.latitude - }) - } catch (e) { - console.warn('缓存基础定位信息失败:', e) - } - - // 只在首次初始化时设置标记 - if (!isLocationInitialized.value) { - isLocationInitialized.value = true - } - - // 获取详细地址信息 - try { - const addressResult = await getRegeo(location.longitude, location.latitude) - if (addressResult.success) { - const addressInfo = addressResult.data - userLocation.value.address = addressInfo.formatted_address - userLocation.value.city = addressInfo.addressComponent.city - userLocation.value.district = addressInfo.addressComponent.district - - // 更新本地缓存,包含地址信息 - try { - uni.setStorageSync('userLocation', { - longitude: userLocation.value.longitude, - latitude: userLocation.value.latitude, - address: userLocation.value.address, - city: userLocation.value.city, - district: userLocation.value.district - }) - } catch (e) { - console.warn('缓存带地址的定位信息失败:', e) - } } - } catch (error) { - // 忽略地址信息错误,使用基础定位信息 - } - return userLocation.value + console.log(userLocation.value); + // 将经纬度写入本地缓存(基础信息) + try { + uni.setStorageSync('userLocation', { + longitude: location.longitude, + latitude: location.latitude + }) + } catch (e) { + console.warn('缓存基础定位信息失败:', e) + } + + // 只在首次初始化时设置标记 + if (!isLocationInitialized.value) { + isLocationInitialized.value = true + } + + // 获取详细地址信息 + try { + const addressResult = await getRegeo(location.longitude, location.latitude) + if (addressResult.success) { + const addressInfo = addressResult.data + userLocation.value.address = addressInfo.formatted_address + userLocation.value.city = addressInfo.addressComponent.city + userLocation.value.district = addressInfo.addressComponent.district + + // 更新本地缓存,包含地址信息 + try { + uni.setStorageSync('userLocation', { + longitude: userLocation.value.longitude, + latitude: userLocation.value.latitude, + address: userLocation.value.address, + city: userLocation.value.city, + district: userLocation.value.district + }) + } catch (e) { + console.warn('缓存带地址的定位信息失败:', e) + } + } + } catch (error) { + // 忽略地址信息错误,使用基础定位信息 + } + + return userLocation.value } const loadPositions = async () => { @@ -934,7 +935,16 @@ }) }) - let deviceNo = getQueryString(scanResult.path, 'deviceNo') + console.log(scanResult); + let deviceNo; + if (scanResult.scanType=='"QR_CODE"') { + + deviceNo = getQueryString(scanResult.result, 'deviceNo') + } else { + deviceNo = getQueryString(scanResult.path, 'deviceNo') + } + + if (!deviceNo) { uni.showToast({ diff --git a/pages/my/index.vue b/pages/my/index.vue index 5a26c2f..ef65609 100644 --- a/pages/my/index.vue +++ b/pages/my/index.vue @@ -186,7 +186,8 @@ import { }, data: { appPlatform: 'wechat', // 微信平台 - appType: 'user' // 用户端 + appType: 'user' ,// 用户端 + pictureLocation:'userProfile_banner' } }) diff --git a/pages/order/detail.vue b/pages/order/detail.vue index 1fdc9ce..aef321f 100644 --- a/pages/order/detail.vue +++ b/pages/order/detail.vue @@ -80,8 +80,25 @@ + + + {{ $t('order.convertToOwn') }} + + + + + @@ -140,8 +162,13 @@ import { onLoad, onShow, onHide, onUnload } from '@dcloudio/uni-app' import { queryById, - cancelOrder + cancelOrder, + reportDeviceNoEject, + convertToOwned } from '@/config/api/order.js' + import { + addUserFeedback + } from '@/config/api/feedback.js' import { getSystemConfig } from '@/config/api/system.js' @@ -497,18 +524,11 @@ } } - // 从订单监控服务中移除当前订单 + // 从订单详情页角度不再主动移除订单监控 + // 订单监控的生命周期完全交给全局 orderMonitor,在订单真正完成时自动移除 const removeFromOrderMonitor = () => { - if (orderInfo.value.orderId && $orderMonitor) { - try { - $orderMonitor.removeOrder({ - orderId: orderInfo.value.orderId - }) - console.log('订单已从监控队列移除:', orderInfo.value.orderId) - } catch (error) { - console.error('从监控队列移除订单失败:', error) - } - } + // 保留函数以兼容已有调用,但不再从全局监控中删除订单 + console.log('removeFromOrderMonitor 调用:已不再从全局监控中移除订单,交由 orderMonitor 在订单完成时处理') } // 处理订单完成事件 @@ -691,7 +711,7 @@ // 更新订单信息 updateOrderInfo(orderData) - // 只有使用中的订单才启动定时器和监控 + // 只有使用中的订单才启动本页的计时器逻辑 if (orderInfo.value.orderStatus === 'in_used') { startTimer() startStatusCheckTimer() @@ -699,10 +719,13 @@ if (orderInfo.value.isSupportExpressReturn !== 'no') { startExpressCountdown() } + } + // 无论当前订单状态如何,只要进入订单详情页,就把当前订单交给全局订单监控 + if (orderInfo.value.orderId) { uni.setStorageSync('activeOrderId', orderInfo.value.orderId) - // 添加到监控队列 + // 添加/更新到监控队列 try { if ($orderMonitor) { $orderMonitor.removeOrder({ @@ -711,7 +734,9 @@ $orderMonitor.addOrder({ orderId: orderInfo.value.orderId }, 'detail') - console.log('订单已添加到监控队列:', orderInfo.value.orderId) + console.log('订单已添加到监控队列(无论当前状态):', orderInfo.value.orderId, '当前状态:', orderInfo.value.orderStatus) + } else { + console.warn('$orderMonitor 未定义,无法添加订单到监控队列') } } catch (error) { console.error('添加订单到监控队列失败:', error) @@ -880,6 +905,98 @@ }) } + // 处理"宝未弹出"反馈 + const handleDeviceNoEject = () => { + uni.showModal({ + title: $t('order.deviceNoEjectTitle'), + content: $t('order.deviceNoEjectConfirm'), + confirmText: $t('common.confirm'), + cancelText: $t('common.cancel'), + success: async (res) => { + if (res.confirm) { + try { + uni.showLoading({ + title: $t('common.submitting') + }) + + // 调用反馈API提交工单 + const feedbackData = { + type: 'device_issue', + content: `订单号:${orderInfo.value.orderNo}\n设备号:${deviceId.value}\n问题:充电宝未弹出`, + phone: orderInfo.value.phone || '', + orderId: orderInfo.value.orderId, + orderNo: orderInfo.value.orderNo + } + + const result = await addUserFeedback(feedbackData) + + if (result.code === 200) { + uni.hideLoading() + uni.showToast({ + title: $t('order.deviceNoEjectSuccess'), + icon: 'success', + duration: 3000 + }) + } else { + throw new Error(result.msg || $t('order.deviceNoEjectFailed')) + } + } catch (error) { + uni.hideLoading() + uni.showToast({ + title: error.message || $t('order.deviceNoEjectFailed'), + icon: 'none', + duration: 2000 + }) + } + } + } + }) + } + + // 处理"转为自用" + const handleConvertToOwned = () => { + uni.showModal({ + title: $t('order.convertToOwnTitle'), + content: $t('order.convertToOwnConfirm'), + confirmText: $t('common.confirm'), + cancelText: $t('common.cancel'), + success: async (res) => { + if (res.confirm) { + try { + uni.showLoading({ + title: $t('common.processing') + }) + + const result = await convertToOwned(orderInfo.value.orderId) + + if (result.code === 200) { + uni.hideLoading() + uni.showToast({ + title: $t('order.convertToOwnSuccess'), + icon: 'success', + duration: 2000 + }) + + // 刷新订单详情 + setTimeout(() => { + getOrderDetails() + }, 2000) + } else { + throw new Error(result.msg || $t('order.convertToOwnFailed')) + } + } catch (error) { + uni.hideLoading() + uni.showToast({ + title: error.message || $t('order.convertToOwnFailed'), + icon: 'none', + duration: 2000 + }) + } + } + } + }) + } + // 生命周期钩子 onLoad((options) => { console.log('订单详情页加载,参数:', JSON.stringify(options)) @@ -1029,6 +1146,24 @@ } } + // 转为自用提示 + .convert-tip { + position: fixed; + left: 30rpx; + right: 30rpx; + bottom: calc(120rpx + env(safe-area-inset-bottom)); + color: #000; + text-align: center; + padding: 20rpx 30rpx; + border-radius: 12rpx; + font-size: 26rpx; + z-index: 9; + + &:active { + opacity: 0.85; + } + } + // 租借信息卡片 .rent-card { background: #fff; diff --git a/pages/order/index.vue b/pages/order/index.vue index 1c615cc..5e3c046 100644 --- a/pages/order/index.vue +++ b/pages/order/index.vue @@ -35,7 +35,8 @@ import { ref, reactive, - onMounted + onMounted, + onUnmounted } from 'vue'; import OrderItemCard from '../../components/OrderItemCard.vue'; import { @@ -60,13 +61,6 @@ const { t: $t } = useI18n() - // 设置页面标题 - onMounted(() => { - uni.setNavigationBarTitle({ - title: $t('order.myOrders') - }) - }) - // 初始化状态 const currentTab = ref(0); const orderList = ref([]); @@ -228,6 +222,29 @@ } }; + // 处理订单完成事件 + const handleOrderCompleted = (orderData) => { + console.log('订单列表页收到订单完成事件:', orderData) + // 刷新订单列表,根据当前选中的标签刷新对应状态的订单 + const statusList = orderStatusTabs[currentTab.value].status[0] + loadOrderList(statusList) + } + + // 设置页面标题并监听订单完成事件 + onMounted(() => { + uni.setNavigationBarTitle({ + title: $t('order.myOrders') + }) + + // 监听订单完成事件 + uni.$on('orderCompleted', handleOrderCompleted) + }) + + // 页面卸载时移除事件监听 + onUnmounted(() => { + uni.$off('orderCompleted', handleOrderCompleted) + }) + // 同步订单状态 const getOrderStatus = async (order) => { try { diff --git a/pages/waiting/index.vue b/pages/waiting/index.vue index 20c01b0..319980f 100644 --- a/pages/waiting/index.vue +++ b/pages/waiting/index.vue @@ -93,7 +93,7 @@ } catch (e) {} uni.showToast({ title: $t('waiting.rentFailed'), icon: 'none' }) setTimeout(() => { - uni.switchTab({ url: '/pages/index/index' }) + uni.reLaunch({ url: '/pages/index/index' }) }, 800) } @@ -131,7 +131,7 @@ stopAllTimers() uni.showToast({ title: $t('waiting.timeout'), icon: 'none' }) setTimeout(() => { - uni.switchTab({ url: '/pages/index/index' }) + uni.reLaunch({ url: '/pages/index/index' }) }, 800) }, 60000) } diff --git a/utils/orderMonitor.js b/utils/orderMonitor.js index e9050cc..f9b96be 100644 --- a/utils/orderMonitor.js +++ b/utils/orderMonitor.js @@ -173,15 +173,15 @@ class OrderMonitor { // 如果时间差超过1分钟,不进行提醒 if (timeDiff > 3) { - console.log(`订单 ${orderId} 完成时间与当前时间相差${timeDiff.toFixed(2)}分钟,超过3分钟,不进行提醒`); + console.log(`订单 ${orderId} 完成时间与当前时间相差${timeDiff.toFixed(2)}分钟,超过3分钟,不进行弹窗提醒`); shouldNotify = false; } } + // 无论是否需要弹窗提醒,都要触发全局订单完成事件(用于订单列表、详情等页面刷新) + uni.$emit('orderCompleted', orderData) + if (shouldNotify) { - // 触发全局事件(订单详情页会监听此事件自动刷新) - uni.$emit('orderCompleted', orderData) - // 显示全局通知 uni.showToast({ title: '风扇归还成功',