feat: 添加订单支付和成功页面,更新订单状态逻辑
新增了订单支付页面和支付成功页面,分别用于处理用户的支付流程和展示支付结果。同时,更新了订单状态的逻辑,确保在订单列表中正确显示各个状态。调整了设备租借逻辑,优化了扫码处理流程,提升用户体验。
This commit is contained in:
+6
-10
@@ -219,6 +219,9 @@
|
||||
title: '处理中'
|
||||
})
|
||||
|
||||
// 获取选中的套餐信息
|
||||
const selectedPkg = this.packages[this.selectedPackage]
|
||||
|
||||
// 调用设备租借接口
|
||||
const rentResult = await rentPowerBank(this.deviceId, this.phoneNumber)
|
||||
if (rentResult.code !== 200) {
|
||||
@@ -230,17 +233,10 @@
|
||||
|
||||
uni.hideLoading()
|
||||
|
||||
uni.showToast({
|
||||
title: '租借成功',
|
||||
icon: 'success'
|
||||
// 跳转到订单支付页面,传递订单ID和套餐信息
|
||||
uni.redirectTo({
|
||||
url: `/pages/order/payment?orderId=${order.orderId}&packageTime=${selectedPkg.time}&packagePrice=${selectedPkg.price}`
|
||||
})
|
||||
|
||||
// 跳转到订单页面
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: `/pages/order/index?orderId=${order.orderId}`
|
||||
})
|
||||
}, 1500)
|
||||
} catch (error) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
|
||||
@@ -1,387 +0,0 @@
|
||||
<template>
|
||||
<view class="return-container">
|
||||
<!-- 订单信息卡片 -->
|
||||
<view class="order-card">
|
||||
<view class="order-header">
|
||||
<text class="title">使用中</text>
|
||||
<text class="order-no">订单号:{{ orderInfo.orderId }}</text>
|
||||
</view>
|
||||
|
||||
<view class="device-info">
|
||||
<text class="device-name">共享风扇</text>
|
||||
<text class="device-id">设备号:{{ deviceNo }}</text>
|
||||
</view>
|
||||
|
||||
<view class="time-info">
|
||||
<view class="time-item">
|
||||
<text class="label">开始时间</text>
|
||||
<text class="value">{{ orderInfo.createTime }}</text>
|
||||
</view>
|
||||
<view class="time-item">
|
||||
<text class="label">已使用时长</text>
|
||||
<text class="value highlight">{{ orderInfo.usedTime }}</text>
|
||||
</view>
|
||||
<view class="time-item">
|
||||
<text class="label">当前费用</text>
|
||||
<text class="value">¥{{ orderInfo.currentFee }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 归还说明 -->
|
||||
<view class="notice-card">
|
||||
<view class="notice-title">归还说明</view>
|
||||
<view class="notice-list">
|
||||
<view class="notice-item">
|
||||
<view class="dot"></view>
|
||||
<text>请确保设备完好无损</text>
|
||||
</view>
|
||||
<view class="notice-item">
|
||||
<view class="dot"></view>
|
||||
<text>请在指定区域内归还设备</text>
|
||||
</view>
|
||||
<view class="notice-item">
|
||||
<view class="dot"></view>
|
||||
<text>归还后押金将自动退还</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view class="bottom-bar">
|
||||
<button class="unlock-btn" @click="handleUnlock" :disabled="unlocking">
|
||||
{{ unlocking ? '归还中...' : '归还设备' }}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { queryHasOrder, overOrderById } from '@/config/user.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
deviceNo: '',
|
||||
orderInfo: {
|
||||
orderId: '',
|
||||
startTime: '',
|
||||
usedTime: '',
|
||||
currentFee: '0.00'
|
||||
},
|
||||
unlocking: false,
|
||||
timer: null
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.deviceNo = options.deviceNo
|
||||
this.getActiveOrder()
|
||||
},
|
||||
onUnload() {
|
||||
this.clearTimer()
|
||||
},
|
||||
methods: {
|
||||
// 获取进行中的订单信息
|
||||
async getActiveOrder() {
|
||||
try {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
const result = await queryHasOrder(this.deviceNo)
|
||||
|
||||
if (result.code === 200 && result.data && result.data.length > 0) {
|
||||
const orderData = result.data[0]
|
||||
this.orderInfo = {
|
||||
orderId: orderData.orderId,
|
||||
startTime: this.formatTime(orderData.createTime),
|
||||
usedTime: this.calculateUsedTime(orderData.createTime),
|
||||
currentFee: orderData.amount || '0.00'
|
||||
}
|
||||
this.startTimer()
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '没有进行中的订单',
|
||||
icon: 'none'
|
||||
})
|
||||
// 如果没有进行中的订单,返回首页
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}, 1500)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取订单信息失败:', error)
|
||||
uni.showToast({
|
||||
title: '获取订单信息失败',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
},
|
||||
|
||||
// 处理归还请求
|
||||
async handleUnlock() {
|
||||
if (this.unlocking) return
|
||||
|
||||
try {
|
||||
this.unlocking = true
|
||||
uni.showLoading({ title: '归还中' })
|
||||
|
||||
// 发送结束订单请求
|
||||
const result = await overOrderById(this.orderInfo.orderId)
|
||||
|
||||
if (result.code === 200) {
|
||||
uni.showToast({
|
||||
title: '归还成功',
|
||||
icon: 'success'
|
||||
})
|
||||
// 归还成功后,跳转到订单页面
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: '/pages/order/index'
|
||||
})
|
||||
}, 1500)
|
||||
} else {
|
||||
throw new Error(result.msg || '归还失败')
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: error.message || '归还失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
this.unlocking = false
|
||||
uni.hideLoading()
|
||||
}
|
||||
},
|
||||
|
||||
// 格式化时间
|
||||
formatTime(date) {
|
||||
// 检查是否是字符串格式的日期(如 "Mon Apr 07 16:36:35 CST 2025")
|
||||
if (typeof date === 'string' && date.match(/\w{3}\s\w{3}\s\d{2}\s\d{2}:\d{2}:\d{2}\s\w{3}\s\d{4}/)) {
|
||||
// 直接使用字符串创建Date对象,JS会自动解析这种标准格式
|
||||
date = new Date(date);
|
||||
} else if (!(date instanceof Date)) {
|
||||
// 如果不是Date对象,尝试创建一个
|
||||
date = new Date(date);
|
||||
}
|
||||
|
||||
// 检查日期是否有效
|
||||
if (isNaN(date.getTime())) {
|
||||
console.error('无效的日期格式:', date);
|
||||
return '无效日期';
|
||||
}
|
||||
|
||||
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}`
|
||||
},
|
||||
|
||||
// 计算使用时长
|
||||
calculateUsedTime(startTime) {
|
||||
// 检查是否是字符串格式的日期(如 "Mon Apr 07 16:36:35 CST 2025")
|
||||
let start;
|
||||
if (typeof startTime === 'string') {
|
||||
// 尝试直接创建Date对象,JS会自动解析标准格式
|
||||
start = new Date(startTime);
|
||||
|
||||
// 检查日期是否有效
|
||||
if (isNaN(start.getTime())) {
|
||||
console.error('无效的日期格式:', startTime);
|
||||
return '0小时0分钟';
|
||||
}
|
||||
} else if (startTime instanceof Date) {
|
||||
start = startTime;
|
||||
} else {
|
||||
console.error('无效的日期类型:', startTime);
|
||||
return '0小时0分钟';
|
||||
}
|
||||
|
||||
const now = new Date()
|
||||
const diffMs = now - start
|
||||
|
||||
const diffHours = Math.floor(diffMs / (1000 * 60 * 60))
|
||||
const diffMinutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60))
|
||||
|
||||
return `${diffHours}小时${diffMinutes}分钟`
|
||||
},
|
||||
|
||||
// 更新使用时长
|
||||
startTimer() {
|
||||
this.timer = setInterval(() => {
|
||||
// 更新使用时长
|
||||
if (this.orderInfo.orderId) {
|
||||
// 直接使用原始的createTime计算使用时长
|
||||
this.orderInfo.usedTime = this.calculateUsedTime(this.orderInfo.startTime)
|
||||
}
|
||||
}, 60000) // 每分钟更新一次
|
||||
},
|
||||
|
||||
clearTimer() {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.return-container {
|
||||
min-height: 100vh;
|
||||
background: #f8f8f8;
|
||||
padding: 30rpx;
|
||||
padding-bottom: 180rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.order-card {
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.04);
|
||||
|
||||
.order-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #1976D2;
|
||||
}
|
||||
|
||||
.order-no {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.device-info {
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.device-name {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.device-id {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.time-info {
|
||||
.time-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
|
||||
&.highlight {
|
||||
color: #1976D2;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.notice-card {
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.04);
|
||||
|
||||
.notice-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.notice-list {
|
||||
.notice-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.dot {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
background: #1976D2;
|
||||
border-radius: 50%;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #fff;
|
||||
padding: 20rpx 30rpx;
|
||||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
box-shadow: 0 -4rpx 16rpx rgba(0,0,0,0.04);
|
||||
|
||||
.unlock-btn {
|
||||
width: 80%;
|
||||
height: 88rpx;
|
||||
background: linear-gradient(135deg, #1976D2, #42A5F5);
|
||||
border-radius: 44rpx;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: none;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
background: #ccc;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user