Files
uni-fans-score/pages/index/index.vue
T
8vd8 f96ff2b030 feat: 添加归还成功页面及相关功能
在 `pages.json` 中新增归还成功页面的配置,并在 `order/success.vue` 中实现设备状态提示和加载动画。同时,更新了订单支付逻辑,确保在支付成功后能够正确弹出充电宝。优化了订单状态查询和处理逻辑,提升用户体验。
2025-04-11 18:03:32 +08:00

337 lines
8.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="container">
<!-- 宣传图片区域 -->
<view class="banner">
<view class="temp-banner">
<text class="banner-text">共享风扇</text>
<text class="banner-subtitle">让清凉随身携带</text>
<view class="banner-bg"></view>
</view>
</view>
<!-- 扫码按钮区域 -->
<view class="scan-area">
<view class="scan-btn" @click="handleScan">
<view class="btn-content">
<image class="btn-icon" src="../../static/scan-icon.png" mode="aspectFit" />
<text class="btn-text">扫一扫</text>
</view>
<text class="btn-desc">扫描设备二维码使用或归还</text>
</view>
</view>
<!-- 使用提示区域 -->
<view class="tips-section">
<view class="tips-header">
<view class="tips-title">使用小贴士</view>
</view>
<view class="tips-list">
<view class="tip-item">
<view class="tip-dot"></view>
<text>租借时间每次最长可租借12小时</text>
</view>
<view class="tip-item">
<view class="tip-dot"></view>
<text>押金说明租借需支付99元押金归还后自动退还</text>
</view>
<view class="tip-item">
<view class="tip-dot"></view>
<text>收费标准2/小时不足1小时按1小时计算</text>
</view>
<view class="tip-item">
<view class="tip-dot"></view>
<text>爱护提示请勿将设备带离指定区域保持设备清洁</text>
</view>
</view>
</view>
</view>
</template>
<script>
import {getQueryString, wxLogin }from '@/util/index.js'
export default {
methods: {
async handleScan() {
try {
const scanResult = await new Promise((resolve, reject) => {
uni.scanCode({
success: resolve,
fail: reject
})
})
let deviceNo = getQueryString(scanResult.path, 'deviceNo')
console.log('扫码路径:', scanResult.path)
console.log('解析到的设备号:', deviceNo)
if (!deviceNo) {
uni.showToast({
title: '无效的设备二维码',
icon: 'none'
})
return
}
// 直接在当前页面查询是否有使用中的订单,避免跳转到中间页面
if (!uni.getStorageSync('token')) {
await wxLogin()
}
// 检查是否有使用中的订单
const inUseRes = await uni.request({
url: `${uni.getStorageSync('baseUrl') || 'http://127.0.0.1:8080'}/app/order/inUse`,
method: 'GET',
header: {
'Authorization': "Bearer " + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
}
})
console.log('使用中订单检查结果:', JSON.stringify(inUseRes))
if (inUseRes.statusCode === 200 && inUseRes.data.code === 200 && inUseRes.data.data) {
// 存在使用中的订单,跳转到归还页面
const inUseOrder = inUseRes.data.data
console.log('检测到使用中订单,准备跳转:', inUseOrder)
// 直接使用reLaunch而不是navigateTo以确保页面跳转
uni.reLaunch({
url: `/pages/return/index?orderId=${inUseOrder.orderId}&deviceId=${deviceNo || inUseOrder.deviceNo}`
})
console.log('已发起页面跳转')
return
}
// 检查是否有待支付订单
const orderRes = await uni.request({
url: `${uni.getStorageSync('baseUrl') || 'http://127.0.0.1:8080'}/app/order/unpaid`,
method: 'GET',
header: {
'Authorization': "Bearer " + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
}
})
console.log('待支付订单检查结果:', JSON.stringify(orderRes))
if (orderRes.statusCode === 200 && orderRes.data.code === 200 && orderRes.data.data) {
// 存在待支付订单,跳转到支付页面
const unpaidOrder = orderRes.data.data
console.log('检测到待支付订单,准备跳转:', unpaidOrder)
uni.navigateTo({
url: `/pages/order/payment?orderId=${unpaidOrder.orderId}`
})
} else {
// 查询设备信息并直接跳转到设备详情页面
console.log('无待支付订单,直接跳转到设备详情页面, deviceNo:', deviceNo)
uni.navigateTo({
url: `/pages/device/detail?deviceNo=${deviceNo}`
})
}
} catch (error) {
console.error('扫码处理失败:', error)
uni.showToast({
title: '扫码失败',
icon: 'none'
})
}
}
}
}
</script>
<style lang="scss" scoped>
.container {
height: 87.5vh;
background: #f8f8f8;
padding-bottom: 40rpx;
.banner {
padding: 30rpx;
.temp-banner {
height: 300rpx;
background: linear-gradient(135deg, #1976D2, #42A5F5);
border-radius: 30rpx;
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
box-shadow: 0 8rpx 32rpx rgba(25, 118, 210, 0.2);
.banner-text {
font-size: 56rpx;
font-weight: bold;
margin-bottom: 20rpx;
position: relative;
z-index: 1;
text-shadow: 0 2rpx 4rpx rgba(0,0,0,0.1);
}
.banner-subtitle {
font-size: 32rpx;
opacity: 0.95;
position: relative;
z-index: 1;
text-shadow: 0 2rpx 4rpx rgba(0,0,0,0.1);
}
.banner-bg {
position: absolute;
right: -60rpx;
bottom: -60rpx;
width: 300rpx;
height: 300rpx;
background: rgba(255,255,255,0.1);
border-radius: 50%;
transform: rotate(-15deg);
}
&::after {
content: '';
position: absolute;
left: -80rpx;
top: -80rpx;
width: 240rpx;
height: 240rpx;
background: rgba(255,255,255,0.08);
border-radius: 50%;
}
}
}
.scan-area {
padding: 20rpx 30rpx 40rpx;
display: flex;
justify-content: center;
.scan-btn {
width: 460rpx;
height: 200rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #00C853, #69F0AE);
border-radius: 30rpx;
box-shadow: 0 8rpx 32rpx rgba(0, 200, 83, 0.2);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
&:active {
transform: scale(0.98);
box-shadow: 0 4rpx 16rpx rgba(0, 200, 83, 0.15);
}
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(rgba(255,255,255,0.1), transparent);
}
.btn-content {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 12rpx;
position: relative;
z-index: 1;
.btn-icon {
width: 48rpx;
height: 48rpx;
margin-right: 16rpx;
}
.btn-text {
font-size: 42rpx;
font-weight: 600;
color: #fff;
text-shadow: 0 2rpx 4rpx rgba(0,0,0,0.1);
}
}
.btn-desc {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.95);
position: relative;
z-index: 1;
}
}
}
.tips-section {
margin: 0 30rpx;
background: #fff;
border-radius: 24rpx;
box-shadow: 0 8rpx 32rpx rgba(0,0,0,0.05);
overflow: hidden;
.tips-header {
padding: 30rpx;
background: linear-gradient(to right, #F5F9FF, #fff);
border-bottom: 2rpx solid #f0f0f0;
.tips-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
position: relative;
padding-left: 24rpx;
&::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 8rpx;
height: 32rpx;
background: #1976D2;
border-radius: 4rpx;
}
}
}
.tips-list {
padding: 20rpx 30rpx;
.tip-item {
display: flex;
align-items: center;
margin-bottom: 24rpx;
padding: 0 10rpx;
&:last-child {
margin-bottom: 0;
}
.tip-dot {
width: 12rpx;
height: 12rpx;
background: #1976D2;
border-radius: 50%;
margin-right: 16rpx;
flex-shrink: 0;
box-shadow: 0 2rpx 6rpx rgba(25,118,210,0.2);
}
text {
font-size: 28rpx;
color: #666;
line-height: 1.6;
}
}
}
}
}
</style>