fix:修复bug

This commit is contained in:
2026-01-22 10:52:58 +08:00
parent b0daa7b59b
commit 6a1dff4b94
46 changed files with 3779 additions and 2522 deletions
+154 -87
View File
@@ -4,7 +4,13 @@
<view class="page-header">
<view class="header-top">
<view class="header-left">
<view class="header-title">{{ getOrderStatusText() }}</view>
<view class="header-title-row">
<text class="header-title">{{ getOrderStatusText() }}</text>
<!-- 优惠券/会员卡可用提示标签 -->
<view v-if="orderInfo.orderStatus === 'in_used' && canUsePromotionTag" class="promotion-tag">
{{ $t('order.canUsePromotion') }}
</view>
</view>
<view class="header-desc">{{ getStatusDesc() }}</view>
</view>
<view class="header-right" v-if="orderInfo.orderStatus === 'in_used'">
@@ -78,6 +84,14 @@
<view class="rent-label">{{ $t('order.paymentMethod') }}</view>
<view class="rent-value">{{ getPayWayText() }}</view>
</view>
<!-- 优惠信息显示 - 订单完成且使用了优惠 -->
<view class="rent-item" v-if="isOrderCompleted() && orderInfo.discountTypeName">
<view class="rent-label">{{ $t('order.usedPromotion') }}</view>
<view class="rent-value promotion-value">
<image src="/static/promotion-icon.png" class="promotion-icon" mode="aspectFit"></image>
{{ orderInfo.discountTypeName }}
</view>
</view>
<view class="rent-item" v-if="isOrderCompleted() && orderInfo.endTime">
<view class="rent-label">{{ $t('order.returnTime') }}</view>
<view class="rent-value">{{ orderInfo.endTime }}</view>
@@ -94,7 +108,7 @@
</view>
<view class="">
<view class="" style="font-size: 24rpx;text-align: center;">
产品归还入仓后订单仍未结束请前往<text @click="contactService" style="color:#07c160 ;">客服中心</text>联系工作人员
{{ $t('order.returnProblemTip') }}<text @click="contactService" style="color:#07c160 ;">{{ $t('user.customerService') }}</text>{{ $t('order.contactStaff') }}
</view>
</view>
@@ -209,8 +223,12 @@
cancelOrder,
reportDeviceNoEject,
convertToOwned,
closeWithMaxFee
closeWithMaxFee,
getInUseOrder
} from '@/config/api/order.js'
import {
withdrawDeposit
} from '@/config/api/user.js'
import {
addUserFeedback
} from '@/config/api/feedback.js'
@@ -222,7 +240,7 @@
} from "@/config/url.js"
import { useI18n } from '@/utils/i18n.js'
const { t: $t } = useI18n()
const { t } = useI18n()
const instance = getCurrentInstance()
const $orderMonitor = instance?.proxy?.$orderMonitor || null
@@ -251,7 +269,12 @@
isSupportExpressReturn: 'yes',
freeRentTime: '',
unitPrice: '',
orderType: ''
orderType: '',
canUseMember: false,
canUseCoupon: false,
userMemberCardId: '',
userPurchaseId: '',
discountTypeName: ''
})
const timer = ref(null)
const statusCheckTimer = ref(null)
@@ -264,8 +287,28 @@
const countdownRemaining = ref(0)
const showExpressAction = ref(false)
const countdownTimer = ref(null)
const feeRuleText = ref('5.0元/60分钟 前15分钟内归还免费 不足60分钟按60分钟计费 封顶99元 持续计费至99元视为买断')
const feeRuleText = ref('')
const convertToOwnPopup = ref(null)
// 计算属性:是否显示优惠券/会员卡可用提示
const canUsePromotionTag = computed(() => {
return orderInfo.value.canUseMember === true || orderInfo.value.canUseCoupon === true
})
// 计算属性:是否使用了优惠
const hasUsedPromotion = computed(() => {
return !!(orderInfo.value.userMemberCardId || orderInfo.value.userPurchaseId)
})
// 获取已使用优惠的文本
const getUsedPromotionText = () => {
if (orderInfo.value.userMemberCardId) {
return t('user.myCards')
} else if (orderInfo.value.userPurchaseId) {
return t('user.myCoupons')
}
return '-'
}
// 判断订单是否已完成
const isOrderCompleted = () => {
return orderInfo.value.orderStatus === 'used_done' ||
@@ -275,27 +318,27 @@
// 获取订单状态文字
const getOrderStatusText = () => {
const statusMap = {
'waiting_for_payment': $t('order.waitingForPayment'),
'payment_in_progress': $t('order.paymentInProgress'),
'payment_successful': $t('order.paymentSuccess'),
'in_used': $t('order.inUse'),
'payment_failed': $t('order.paymentFailed'),
'order_cancelled': $t('order.cancelled'),
'used_done': $t('order.finished'),
'used_down': $t('order.finished')
'waiting_for_payment': t('order.waitingForPayment'),
'payment_in_progress': t('order.paymentInProgress'),
'payment_successful': t('order.paymentSuccess'),
'in_used': t('order.inUse'),
'payment_failed': t('order.paymentFailed'),
'order_cancelled': t('order.cancelled'),
'used_done': t('order.finished'),
'used_down': t('order.finished')
}
return statusMap[orderInfo.value.orderStatus] || $t('order.orderDetail')
return statusMap[orderInfo.value.orderStatus] || t('order.orderDetail')
}
// 获取状态描述
const getStatusDesc = () => {
const descMap = {
'waiting_for_payment': $t('order.pleasePaySoon'),
'in_used': $t('order.pleaseReturnInTime'),
'used_done': $t('order.returnedThankYou'),
'used_down': $t('order.returnedThankYou'),
'order_cancelled': $t('order.orderCancelled'),
'payment_failed': $t('order.paymentFailedRetry')
'waiting_for_payment': t('order.pleasePaySoon'),
'in_used': t('order.pleaseReturnInTime'),
'used_done': t('order.returnedThankYou'),
'used_down': t('order.returnedThankYou'),
'order_cancelled': t('order.orderCancelled'),
'payment_failed': t('order.paymentFailedRetry')
}
return descMap[orderInfo.value.orderStatus] || ''
}
@@ -303,11 +346,11 @@
// 获取支付方式文本
const getPayWayText = () => {
const payWayMap = {
'wx_score_pay': $t('order.depositFree'),
'wx_member_pay': $t('order.memberOrder'),
'wx_pay': $t('order.depositPay')
'wx_score_pay': t('order.depositFree'),
'wx_member_pay': t('order.memberOrder'),
'wx_pay': t('order.depositPay')
}
return payWayMap[orderInfo.value.payWay] || $t('order.depositFree')
return payWayMap[orderInfo.value.payWay] || t('order.depositFree')
}
// 获取免费时长显示
@@ -321,13 +364,13 @@
if (!orderInfo.value.unitPrice || !orderInfo.value.orderType) return '-'
const orderTypeMap = {
'hours': $t('time.hours'),
'minutes': $t('time.minutes'),
'halfhours': $t('time.halfHours')
'hours': t('time.hours'),
'minutes': t('time.minutes'),
'halfhours': t('time.halfHours')
}
const orderTypeText = orderTypeMap[orderInfo.value.orderType] || orderInfo.value.orderType
return `${orderInfo.value.unitPrice}${$t('unit.yuan')}/${orderTypeText}`
return `${orderInfo.value.unitPrice}${t('unit.yuan')}/${orderTypeText}`
}
// 格式化倒计时(显示为 HH:MM:SS 格式)
@@ -378,21 +421,21 @@
if (totalMinutes >= 60) {
const hours = Math.floor(totalMinutes / 60)
const minutes = totalMinutes % 60
usedTime = minutes > 0 ? `${hours}小时${minutes}分钟` : `${hours}小时`
usedTime = minutes > 0 ? `${hours}${t('time.hour')}${minutes}${t('time.minute')}` : `${hours}${t('time.hour')}`
} else {
usedTime = `${totalMinutes}分钟`
usedTime = `${totalMinutes}${t('time.minute')}`
}
}
}
// 如果还是没有值,使用默认值
if (!usedTime) {
usedTime = '0分钟'
usedTime = `0${t('time.minute')}`
}
// 解析时长字符串,例如 "1小时5分钟" 或 "5分钟"
const hourMatch = usedTime.match(/(\d+)小时/)
const minuteMatch = usedTime.match(/(\d+)分钟/)
const hourMatch = usedTime.match(new RegExp(`(\\d+)${t('time.hour')}`))
const minuteMatch = usedTime.match(new RegExp(`(\\d+)${t('time.minute')}`))
let displayNumber = ''
let displayUnit = ''
@@ -400,19 +443,19 @@
if (hourMatch && minuteMatch) {
// 有小时也有分钟,如 "1小时5分钟"
displayNumber = `${hourMatch[1]}`
displayUnit = `小时${minuteMatch[1]}分钟`
displayUnit = `${t('time.hour')}${minuteMatch[1]}${t('time.minute')}`
} else if (hourMatch) {
// 只有小时,如 "1小时"
displayNumber = hourMatch[1]
displayUnit = '小时'
displayUnit = t('time.hour')
} else if (minuteMatch) {
// 只有分钟,如 "5分钟"
displayNumber = minuteMatch[1]
displayUnit = '分钟'
displayUnit = t('time.minute')
} else {
// 默认情况
displayNumber = '0'
displayUnit = '分钟'
displayUnit = t('time.minute')
}
return {
@@ -424,7 +467,7 @@
// 获取使用时长标签文本
const getUsedTimeLabel = () => {
// 使用中状态显示"已使用",已完成状态显示"使用时长"
return orderInfo.value.orderStatus === 'in_used' ? $t('order.used') : $t('order.duration')
return orderInfo.value.orderStatus === 'in_used' ? t('order.used') : t('order.duration')
}
// 获取订单费用(不含单位)
@@ -663,7 +706,7 @@
if (currentStatusChecks.value >= maxStatusChecks.value) {
clearStatusCheckTimer()
uni.showToast({
title: $t('order.pleaseRefreshManually'),
title: t('order.pleaseRefreshManually'),
icon: 'none',
duration: 3000
})
@@ -709,6 +752,13 @@
orderInfo.value.unitPrice = orderData.unitPrice || ''
orderInfo.value.orderType = orderData.orderType || ''
// 保存优惠券/会员卡相关信息
orderInfo.value.canUseMember = orderData.canUseMember === true
orderInfo.value.canUseCoupon = orderData.canUseCoupon === true
orderInfo.value.userMemberCardId = orderData.userMemberCardId || ''
orderInfo.value.userPurchaseId = orderData.userPurchaseId || ''
orderInfo.value.discountTypeName = orderData.discountTypeName || ''
// 保存快递归还开始时间(小时为单位)
orderInfo.value.expressReturnStart = orderData.expressReturnStart || null
@@ -741,7 +791,7 @@
// 显示订单完成提示
if (orderInfo.value.orderStatus === 'used_done' || orderInfo.value.orderStatus === 'used_down') {
uni.showToast({
title: $t('order.orderCompleted'),
title: t('order.orderCompleted'),
icon: 'success'
})
}
@@ -763,7 +813,7 @@
try {
if (!orderInfo.value.orderId) {
throw new Error($t('order.orderIdRequired'))
throw new Error(t('order.orderIdRequired'))
}
isLoadingOrder.value = true
@@ -813,12 +863,12 @@
}
}
} else {
throw new Error(result.msg || $t('order.getOrderFailed'))
throw new Error(result.msg || t('order.getOrderFailed'))
}
} catch (error) {
console.error('获取订单详情错误:', error)
uni.showToast({
title: error.message || $t('order.getOrderFailed'),
title: error.message || t('order.getOrderFailed'),
icon: 'none'
})
setTimeout(() => {
@@ -834,22 +884,15 @@
const getOrderByDevice = async () => {
try {
if (!deviceId.value) {
throw new Error($t('device.deviceNoRequired'))
throw new Error(t('device.deviceNoRequired'))
}
const inUseRes = await uni.request({
url: `${URL || 'http://127.0.0.1:8080'}/app/order/inUse`,
method: 'GET',
header: {
'Authorization': "Bearer " + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
}
})
const inUseRes = await getInUseOrder()
console.log('通过设备号查询订单结果:', JSON.stringify(inUseRes))
if (inUseRes.statusCode === 200 && inUseRes.data.code === 200 && inUseRes.data.data) {
const inUseOrder = inUseRes.data.data
if (inUseRes && inUseRes.code === 200 && inUseRes.data) {
const inUseOrder = inUseRes.data
console.log('使用中的订单:', inUseOrder)
orderInfo.value.orderId = inUseOrder.orderId
@@ -859,12 +902,12 @@
getOrderDetails()
} else {
throw new Error($t('order.noOrderInUse'))
throw new Error(t('order.noOrderInUse'))
}
} catch (error) {
console.error('通过设备号查询订单失败:', error)
uni.showToast({
title: error.message || $t('order.getOrderFailed'),
title: error.message || t('order.getOrderFailed'),
icon: 'none'
})
setTimeout(() => {
@@ -885,13 +928,13 @@
// 取消订单
const handleCancelOrder = () => {
uni.showModal({
title: $t('order.confirmCancel'),
content: $t('order.confirmCancelContent'),
title: t('order.confirmCancel'),
content: t('order.confirmCancelContent'),
success: async (res) => {
if (res.confirm) {
try {
uni.showLoading({
title: $t('common.processing')
title: t('common.processing')
})
const result = await cancelOrder({
orderId: orderInfo.value.orderId
@@ -899,17 +942,17 @@
if (result.code === 200) {
uni.hideLoading()
uni.showToast({
title: $t('order.cancelSuccess'),
title: t('order.cancelSuccess'),
icon: 'success'
})
await getOrderDetails()
} else {
throw new Error(result.msg || $t('order.cancelFailed'))
throw new Error(result.msg || t('order.cancelFailed'))
}
} catch (error) {
uni.hideLoading()
uni.showToast({
title: error.message || $t('order.cancelFailed'),
title: error.message || t('order.cancelFailed'),
icon: 'none'
})
}
@@ -929,22 +972,14 @@
const handleWithdraw = async () => {
try {
uni.showLoading({
title: $t('common.processing')
title: t('common.processing')
})
const res = await uni.request({
url: `${URL || 'http://127.0.0.1:8080'}/app/withdraw/add/${orderInfo.value.orderNo}`,
method: 'GET',
header: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
}
})
const res = await withdrawDeposit(orderInfo.value.orderNo)
if (res.statusCode === 200 && res.data.code === 200) {
if (res && res.code === 200) {
uni.showToast({
title: $t('order.refundSuccess'),
title: t('order.refundSuccess'),
icon: 'success'
})
@@ -955,12 +990,12 @@
getOrderDetails()
}, 1500)
} else {
throw new Error(res.data.msg || $t('order.refundFailed'))
throw new Error(res?.msg || t('order.refundFailed'))
}
} catch (error) {
console.error('退款申请错误:', error)
console.error('退款申请失败:', error)
uni.showToast({
title: error.message || $t('order.refundFailed'),
title: error.message || t('order.refundFailed'),
icon: 'none'
})
} finally {
@@ -1002,14 +1037,14 @@
})
uni.showToast({
title: '订阅成功',
title: t('payment.subscriptionSuccess'),
icon: 'success',
duration: 2000
})
} catch (error) {
console.log('订阅消息异常', error)
uni.showToast({
title: '订阅失败,请稍后重试',
title: t('payment.subscriptionFailed'),
icon: 'none',
duration: 2000
})
@@ -1040,7 +1075,7 @@
try {
closeConvertToOwnPopup()
uni.showLoading({
title: $t('common.processing')
title: t('common.processing')
})
const result = await closeWithMaxFee(orderInfo.value.orderNo)
@@ -1048,7 +1083,7 @@
if (result.code === 200) {
uni.hideLoading()
uni.showToast({
title: $t('order.convertToOwnWithMaxFeeSuccess'),
title: t('order.convertToOwnWithMaxFeeSuccess'),
icon: 'success',
duration: 2000
})
@@ -1058,12 +1093,12 @@
getOrderDetails()
}, 2000)
} else {
throw new Error(result.msg || $t('order.convertToOwnWithMaxFeeFailed'))
throw new Error(result.msg || t('order.convertToOwnWithMaxFeeFailed'))
}
} catch (error) {
uni.hideLoading()
uni.showToast({
title: error.message || $t('order.convertToOwnWithMaxFeeFailed'),
title: error.message || t('order.convertToOwnWithMaxFeeFailed'),
icon: 'none',
duration: 2000
})
@@ -1076,7 +1111,7 @@
// 设置页面标题
uni.setNavigationBarTitle({
title: $t('order.orderDetail')
title: t('order.orderDetail')
})
isPageActive.value = true
@@ -1101,7 +1136,7 @@
getOrderDetails()
} else {
uni.showToast({
title: $t('order.orderInfoMissing'),
title: t('order.orderInfoMissing'),
icon: 'none'
})
setTimeout(() => {
@@ -1161,12 +1196,18 @@
.header-left {
flex: 1;
}
.header-title-row {
display: flex;
align-items: center;
gap: 12rpx;
margin-bottom: 12rpx;
}
.header-title {
font-size: 48rpx;
font-weight: bold;
color: #333;
margin-bottom: 12rpx;
}
.header-desc {
@@ -1210,6 +1251,18 @@
}
}
}
.promotion-tag {
padding: 6rpx 16rpx;
background: linear-gradient(135deg, #FFF4E6 0%, #FFE9CC 100%);
border-radius: 10rpx;
border: 1rpx solid #FFB84D;
font-size: 22rpx;
color: #FF8C00;
font-weight: 500;
white-space: nowrap;
flex-shrink: 0;
}
// 订单信息卡片
.info-card {
@@ -1355,6 +1408,20 @@
color: #333;
text-align: right;
max-width: 400rpx;
&.promotion-value {
display: flex;
align-items: center;
justify-content: flex-end;
color: #FF8C00;
font-weight: 500;
.promotion-icon {
width: 32rpx;
height: 32rpx;
margin-right: 8rpx;
}
}
}
}
+35 -41
View File
@@ -46,7 +46,8 @@
getOrderList,
queryById,
getOrderByOrderNoScorePayStatus,
cancelOrder
cancelOrder,
createWxPayment
} from '../../config/api/order.js';
import {
confirmPaymentAndRent
@@ -59,7 +60,7 @@
} from '../../config/url.js';
import { useI18n } from '@/utils/i18n.js'
const { t: $t } = useI18n()
const { t } = useI18n()
// 初始化状态
const currentTab = ref(0);
@@ -68,62 +69,62 @@
// 订单状态映射
const orderStatusMap = reactive({
'0': {
get text() { return $t('order.waitingForPayment') },
get text() { return t('order.waitingForPayment') },
class: 'status-waiting'
},
'1': {
get text() { return $t('order.inUse') },
get text() { return t('order.inUse') },
class: 'status-using'
},
'2': {
get text() { return $t('order.finished') },
get text() { return t('order.finished') },
class: 'status-finished'
},
'3': {
get text() { return $t('order.cancelled') },
get text() { return t('order.cancelled') },
class: 'status-cancelled'
},
'waiting_for_payment': {
get text() { return $t('order.waitingForPayment') },
get text() { return t('order.waitingForPayment') },
class: 'status-waiting'
},
'in_used': {
get text() { return $t('order.inUse') },
get text() { return t('order.inUse') },
class: 'status-using'
},
'used_done': {
get text() { return $t('order.finished') },
get text() { return t('order.finished') },
class: 'status-finished'
},
'order_cancelled': {
get text() { return $t('order.cancelled') },
get text() { return t('order.cancelled') },
class: 'status-cancelled'
},
'express_return': {
get text() { return $t('express.title') },
get text() { return t('express.title') },
class: 'status-express-return'
}
});
// 订单状态标签
const orderStatusTabs = reactive([{
get text() { return $t('common.all') },
get text() { return t('common.all') },
status: []
},
{
get text() { return $t('order.waitingForPayment') },
get text() { return t('order.waitingForPayment') },
status: ['waiting_for_payment']
},
{
get text() { return $t('order.inUse') },
get text() { return t('order.inUse') },
status: ['in_used']
},
{
get text() { return $t('order.finished') },
get text() { return t('order.finished') },
status: ['used_done']
},
{
get text() { return $t('order.cancelled') },
get text() { return t('order.cancelled') },
status: ['order_cancelled']
}
]);
@@ -216,7 +217,7 @@
} catch (error) {
console.error('获取订单列表失败:', error);
uni.showToast({
title: $t('order.getOrderListFailed'),
title: t('order.getOrderListFailed'),
icon: 'none'
});
}
@@ -233,7 +234,7 @@
// 设置页面标题并监听订单完成事件
onMounted(() => {
uni.setNavigationBarTitle({
title: $t('order.myOrders')
title: t('order.myOrders')
})
// 监听订单完成事件
@@ -251,14 +252,14 @@
const res = await getOrderByOrderNoScorePayStatus(order.orderNo);
if (res.code === 200) {
uni.showToast({
title: $t('order.syncSuccess'),
title: t('order.syncSuccess'),
icon: 'success'
});
await loadOrderList(orderStatusTabs[currentTab.value].status);
}
} catch (error) {
uni.showToast({
title: $t('order.syncFailed'),
title: t('order.syncFailed'),
icon: 'none'
});
}
@@ -285,28 +286,21 @@
const handlePayment = async (order) => {
try {
uni.showLoading({
title: $t('common.processing')
title: t('common.processing')
});
// 调用后端创建微信支付订单接口
const res = await uni.request({
url: `${URL || 'http://127.0.0.1:8080'}/app/wx-payment/create/${order.orderNo}`,
method: 'GET',
header: {
'Authorization': "Bearer " + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
}
});
const res = await createWxPayment(order.orderNo);
if (res.statusCode === 200 && res.data.code === 200) {
const payParams = res.data.data;
if (res && res.code === 200) {
const payParams = res.data;
// 调用微信支付
await uni.requestPayment({
...payParams,
success: async () => {
uni.showToast({
title: $t('payment.paymentSuccess'),
title: t('payment.paymentSuccess'),
icon: 'success'
});
@@ -322,18 +316,18 @@
},
fail: (err) => {
console.error('支付失败:', err);
throw new Error($t('payment.paymentFailedRetry'));
throw new Error(t('payment.paymentFailedRetry'));
}
});
} else {
throw new Error(res.data.msg || '创建支付订单失败');
throw new Error(res?.msg || '创建支付订单失败');
}
uni.hideLoading();
} catch (error) {
uni.hideLoading();
uni.showToast({
title: error.message || $t('payment.paymentFailed'),
title: error.message || t('payment.paymentFailed'),
icon: 'none'
});
}
@@ -343,12 +337,12 @@
const handleCancelOrder = async (order) => {
try {
uni.showModal({
title: $t('order.confirmCancel'),
content: $t('order.confirmCancelContent'),
title: t('order.confirmCancel'),
content: t('order.confirmCancelContent'),
success: async (res) => {
if (res.confirm) {
uni.showLoading({
title: $t('common.processing')
title: t('common.processing')
});
const result = await cancelOrder({
@@ -358,14 +352,14 @@
if (result) {
uni.hideLoading();
uni.showToast({
title: $t('order.cancelSuccess'),
title: t('order.cancelSuccess'),
icon: 'success'
});
// 刷新订单列表
await loadOrderList();
} else {
throw new Error(result.msg || $t('order.cancelFailed'));
throw new Error(result.msg || t('order.cancelFailed'));
}
}
}
@@ -373,7 +367,7 @@
} catch (error) {
uni.hideLoading();
uni.showToast({
title: error.message || $t('order.cancelFailed'),
title: error.message || t('order.cancelFailed'),
icon: 'none'
});
}
+196 -322
View File
@@ -59,345 +59,219 @@
</view>
</template>
<script>
import { queryById, updateOrderPackage } from '@/config/api/order.js'
<script setup>
import { ref, computed, reactive } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { queryById, createWxPayment } from '@/config/api/order.js'
import { getDeviceInfo } from '@/config/api/device.js'
import { updateUserBalance } from '@/config/api/user.js'
import {
URL
}from"@/config/url.js"
import { useI18n } from '@/utils/i18n.js'
export default {
data() {
return {
orderId: null,
deviceNo: null,
orderInfo: {},
packageInfo: {
time: '',
price: '0.00'
},
deviceInfo: null,
passedTotalAmount: null,
passedDepositAmount: null,
orderStatus: {
get text() { return this.$t('payment.waitingForPayment') },
get desc() { return this.$t('payment.pleasePayIn15Min') },
class: 'waiting'
}
}
},
computed: {
totalAmount() {
if (this.passedTotalAmount !== null) {
return parseFloat(this.passedTotalAmount).toFixed(2);
}
const deposit = parseFloat(this.orderInfo.deposit || this.passedDepositAmount || 99)
const packagePrice = parseFloat(this.packageInfo.price || 0)
return (deposit + packagePrice).toFixed(2)
},
// 计算每小时的价格
hourlyRate() {
const price = parseFloat(this.packageInfo.price || 0);
let time = parseFloat(this.packageInfo.time || 1);
// 如果时间单位不是小时(例如分钟),需要转换
if (this.packageInfo.time && this.packageInfo.time.includes('分钟')) {
time = time / 60; // 将分钟转换为小时
} else if (this.packageInfo.time && this.packageInfo.time.includes('次')) {
// 按次计费时,暂时显示单次价格
return price.toFixed(2);
}
// 避免除以零
if (time <= 0) time = 1;
// 计算每小时价格
return (price / time).toFixed(2);
}
},
onLoad(options) {
// 设置页面标题
uni.setNavigationBarTitle({
title: this.$t('payment.orderPayment')
const { t } = useI18n()
const orderId = ref(null)
const deviceNo = ref(null)
const orderInfo = ref({})
const packageInfo = ref({
time: '',
price: '0.00'
})
const deviceInfo = ref(null)
const passedTotalAmount = ref(null)
const passedDepositAmount = ref(null)
const orderStatus = reactive({
get text() { return t('payment.waitingForPayment') },
get desc() { return t('payment.pleasePayIn15Min') },
class: 'waiting'
})
const totalAmount = computed(() => {
if (passedTotalAmount.value !== null) {
return parseFloat(passedTotalAmount.value).toFixed(2);
}
const deposit = parseFloat(orderInfo.value.deposit || passedDepositAmount.value || 99)
const packagePrice = parseFloat(packageInfo.value.price || 0)
return (deposit + packagePrice).toFixed(2)
})
// 加载订单信息
const loadOrderInfo = async () => {
try {
uni.showLoading({
title: t('common.loading')
})
if (options && options.orderId) {
this.orderId = options.orderId
const res = await queryById(orderId.value)
if (res.code === 200 && res.data) {
const orderData = res.data
if (options.totalAmount) {
this.passedTotalAmount = options.depositAmount;
// 处理创建时间
let formattedTime;
try {
if (orderData.createTime) {
formattedTime = formatTime(new Date(orderData.createTime));
} else {
formattedTime = formatTime(new Date());
}
} catch (e) {
console.error('时间格式化错误:', e);
formattedTime = formatTime(new Date());
}
if (options.depositAmount) {
this.passedDepositAmount = options.depositAmount;
orderInfo.value = {
orderNo: orderData.orderNo || orderData.orderId,
deviceNo: orderData.deviceNo,
createTime: formattedTime,
phone: orderData.phone,
deposit: passedDepositAmount.value || orderData.depositAmount || '99.00',
}
// 如果URL中包含了feeConfig参数,保存它
if (options.feeConfig) {
try {
console.log('从URL获取到feeConfig:', options.feeConfig)
const feeConfigStr = decodeURIComponent(options.feeConfig)
// 创建一个临时的deviceInfo对象保存feeConfig
this.deviceInfo = { feeConfig: feeConfigStr }
} catch (e) {
console.error('解析URL中的feeConfig失败:', e)
if (orderData.packageTime && orderData.packagePrice) {
const timeInHours = (parseFloat(orderData.packageTime) / 60).toFixed(1);
packageInfo.value = {
time: timeInHours.toString(),
price: orderData.packagePrice.toString()
}
}
this.loadOrderInfo()
} else {
uni.showToast({
title: this.$t('order.orderNotExist'),
icon: 'none'
})
setTimeout(() => {
uni.redirectTo({
url: '/pages/index/index'
})
}, 1500)
deviceNo.value = orderData.deviceNo;
await loadDeviceInfo();
} else {
throw new Error(t('order.getOrderFailed'))
}
},
methods: {
// 加载订单信息
async loadOrderInfo() {
try {
uni.showLoading({
title: this.$t('common.loading')
})
const res = await queryById(this.orderId)
if (res.code === 200 && res.data) {
const orderData = res.data
// 处理创建时间,确保显示的是格式化后的时间
let formattedTime;
try {
// 如果orderData.createTime存在并且是有效的日期字符串/时间戳,则格式化它
if (orderData.createTime) {
formattedTime = this.formatTime(new Date(orderData.createTime));
} else {
// 如果createTime不存在,使用当前时间作为创建时间
formattedTime = this.formatTime(new Date());
}
} catch (e) {
console.error('时间格式化错误:', e);
formattedTime = this.formatTime(new Date());
}
this.orderInfo = {
orderNo: orderData.orderNo || orderData.orderId,
deviceNo: orderData.deviceNo,
createTime: formattedTime,
phone: orderData.phone,
deposit: this.passedDepositAmount || orderData.depositAmount || '99.00',
}
// 直接从订单数据中获取套餐信息
if (orderData.packageTime && orderData.packagePrice) {
// 将分钟转换为小时
const timeInHours = (parseFloat(orderData.packageTime) / 60).toFixed(1);
this.packageInfo = {
time: timeInHours.toString(),
price: orderData.packagePrice.toString()
}
}
// 获取设备信息(但不再用于设置套餐信息)
this.deviceNo = orderData.deviceNo;
await this.loadDeviceInfo();
} else {
throw new Error('获取订单信息失败')
}
uni.hideLoading()
} catch (error) {
uni.hideLoading()
uni.showToast({
title: error.message || '获取订单信息失败',
icon: 'none'
})
}
},
// 加载设备信息
async loadDeviceInfo() {
if (!this.deviceNo) return;
try {
const res = await getDeviceInfo(this.deviceNo);
if (res.code === 200 && res.data) {
this.deviceInfo = res.data.device;
// 设置存款金额
if (this.deviceInfo && this.deviceInfo.depositAmount) {
this.orderInfo.deposit = this.deviceInfo.depositAmount;
}
}
} catch (error) {
console.error('获取设备信息失败:', error);
}
},
// 处理支付
async handlePayment() {
try {
uni.showLoading({
title: this.$t('common.processing')
})
// 调用后端创建微信支付订单接口
const res = await uni.request({
url: `${URL || 'http://127.0.0.1:8080'}/app/wx-payment/create/${this.orderInfo.orderNo}`,
method: 'GET',
header: {
'Authorization': "Bearer " + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
}
})
if (res.statusCode === 200 && res.data.code === 200) {
const payParams = res.data.data
// 调用微信支付
await uni.requestPayment({
...payParams,
success: async () => {
uni.showToast({
title: this.$t('payment.paymentSuccess'),
icon: 'success'
});
// 更新用户余额
try {
await updateUserBalance(this.orderId);
} catch (error) {
console.warn('更新用户余额失败:', error);
}
// 支付成功后直接跳转到订单页面,不再轮询
setTimeout(() => {
uni.redirectTo({
url: `/pages/order/index?orderId=${this.orderId}`
});
}, 1500);
},
fail: (err) => {
console.error('支付失败:', err)
throw new Error(this.$t('payment.paymentFailedRetry'))
}
})
} else {
throw new Error(res.data.msg || '创建支付订单失败')
}
} catch (error) {
uni.hideLoading()
uni.showToast({
title: error.message || '支付失败',
icon: 'none'
})
}
},
// 发送租借指令
async sendRentCommand() {
try {
uni.showLoading({
title: this.$t('common.processing')
})
// 调用发送租借指令的接口
const res = await this.sendRentRequest()
if (res.code === 200) {
uni.hideLoading()
uni.showToast({
title: this.$t('device.rentSuccess'),
icon: 'success'
})
// 跳转到订单列表页面
setTimeout(() => {
uni.redirectTo({
url: `/pages/order/index?orderId=${this.orderId}`
})
}, 1500)
} else {
throw new Error(res.msg || this.$t('device.rentFailed'))
}
} catch (error) {
uni.hideLoading()
uni.showToast({
title: error.message || this.$t('device.rentFailed'),
icon: 'none'
})
}
},
// 发送租借请求
sendRentRequest() {
return new Promise((resolve, reject) => {
uni.request({
url: `${URL || 'http://127.0.0.1:8080'}/app/device/sendRentCommand`,
method: 'POST',
data: {
orderId: this.orderId
},
header: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': "Bearer " + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
},
success(res) {
if (res.statusCode === 200) {
resolve(res.data)
} else {
reject(new Error('请求失败'))
}
},
fail(err) {
reject(err)
}
})
})
},
// 格式化时间
formatTime(date) {
const year = date.getFullYear()
const month = (date.getMonth() + 1).toString().padStart(2, '0')
const day = date.getDate().toString().padStart(2, '0')
const hour = date.getHours().toString().padStart(2, '0')
const minute = date.getMinutes().toString().padStart(2, '0')
return `${year}-${month}-${day} ${hour}:${minute}`
},
// 检查订单状态(单次查询,不轮询)
async checkOrderStatus() {
try {
const res = await uni.request({
url: `${URL || 'http://127.0.0.1:8080'}/app/wx-payment/status/${this.orderInfo.orderNo}`,
method: 'GET',
header: {
'Authorization': "Bearer " + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
}
});
if (res.statusCode === 200 && res.data.code === 200) {
return res.data.data;
} else {
throw new Error('查询订单状态失败');
}
} catch (error) {
console.error('查询订单状态错误:', error);
return null;
}
},
} catch (error) {
console.error('获取订单信息失败:', error)
uni.showToast({
title: error.message || t('order.getOrderFailed'),
icon: 'none'
})
} finally {
uni.hideLoading()
}
}
// 加载设备信息
const loadDeviceInfo = async () => {
if (!deviceNo.value) return;
try {
const res = await getDeviceInfo(deviceNo.value);
if (res.code === 200 && res.data) {
deviceInfo.value = res.data.device;
if (deviceInfo.value && deviceInfo.value.depositAmount) {
orderInfo.value.deposit = deviceInfo.value.depositAmount;
}
}
} catch (error) {
console.error('获取设备信息失败:', error);
}
}
// 处理支付
const handlePayment = async () => {
try {
uni.showLoading({
title: t('common.processing')
})
const res = await createWxPayment(orderInfo.value.orderNo)
if (res && res.code === 200) {
const payParams = res.data
await uni.requestPayment({
...payParams,
success: async () => {
uni.showToast({
title: t('payment.paymentSuccess'),
icon: 'success'
});
try {
await updateUserBalance(orderId.value);
} catch (error) {
console.warn('更新用户余额失败:', error);
}
setTimeout(() => {
uni.redirectTo({
url: `/pages/order/index?orderId=${orderId.value}`
});
}, 1500);
},
fail: (err) => {
console.error('支付失败:', err)
uni.showToast({
title: t('payment.paymentFailedRetry'),
icon: 'none'
})
}
})
} else {
throw new Error(res?.msg || t('payment.createPayOrderFailed'))
}
} catch (error) {
console.error('支付失败:', error)
uni.showToast({
title: error.message || t('payment.paymentFailed'),
icon: 'none'
})
} finally {
uni.hideLoading()
}
}
// 格式化时间
const formatTime = (date) => {
const year = date.getFullYear()
const month = (date.getMonth() + 1).toString().padStart(2, '0')
const day = date.getDate().toString().padStart(2, '0')
const hour = date.getHours().toString().padStart(2, '0')
const minute = date.getMinutes().toString().padStart(2, '0')
return `${year}-${month}-${day} ${hour}:${minute}`
}
onLoad((options) => {
uni.setNavigationBarTitle({
title: t('payment.orderPayment')
})
if (options && options.orderId) {
orderId.value = options.orderId
if (options.totalAmount) {
passedTotalAmount.value = options.totalAmount;
}
if (options.depositAmount) {
passedDepositAmount.value = options.depositAmount;
}
if (options.feeConfig) {
try {
const feeConfigStr = decodeURIComponent(options.feeConfig)
deviceInfo.value = { feeConfig: feeConfigStr }
} catch (e) {
console.error('解析URL中的feeConfig失败:', e)
}
}
loadOrderInfo()
} else {
uni.showToast({
title: t('order.orderNotExist'),
icon: 'none'
})
setTimeout(() => {
uni.redirectTo({
url: '/pages/index/index'
})
}, 1500)
}
})
</script>
<style lang="scss" scoped>
+4 -11
View File
@@ -85,6 +85,7 @@
<script>
import { queryById } from '@/config/api/order.js'
import { withdrawDeposit } from '@/config/api/user.js'
import {
URL
}from"@/config/url.js"
@@ -234,17 +235,9 @@ export default {
try {
uni.showLoading({ title: this.$t('common.processing') });
const res = await uni.request({
url: `${URL || 'http://127.0.0.1:8080'}/app/withdraw/add/${this.orderInfo.orderNo}`,
method: 'GET',
header: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
}
})
const res = await withdrawDeposit(this.orderInfo.orderNo)
if (res.statusCode === 200 && res.data.code === 200) {
if (res && res.code === 200) {
uni.showToast({
title: this.$t('order.refundSuccess'),
icon: 'success'
@@ -259,7 +252,7 @@ export default {
this.loadOrderInfo();
}, 1500);
} else {
throw new Error(res.data.msg || this.$t('order.refundFailed'));
throw new Error(res?.msg || this.$t('order.refundFailed'));
}
} catch (error) {
console.error('退款申请错误:', error);