Files
uni-fans-score/pages/order/index.vue
T

527 lines
11 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="order-container">
<!-- 状态切换 -->
<view class="status-tabs">
<view v-for="(tab, index) in orderStatusTabs" :key="index" class="tab-item"
:class="{ active: currentTab === index }" @click="switchTab(index)">
{{ tab.text }}
</view>
</view>
<!-- 订单列表 -->
<view class="order-list">
<view class="empty-state" v-if="orderList.length === 0">
<view class="empty-icon"></view>
<text class="empty-text">暂无订单记录</text>
</view>
<view class="order-item" v-for="(order, index) in orderList" :key="index">
<!-- 订单头部信息 -->
<view class="order-header">
<view class="order-id">
<text>订单号{{ order.orderNo }}</text>
</view>
<view class="order-status" :class="orderStatusMap[order.status]?.class">
{{ orderStatusMap[order.status]?.text }}
</view>
</view>
<!-- 订单内容 -->
<view class="order-body">
<view class="device-info">
<view class="device-left">
<view class="device-name">共享风扇</view>
<view class="device-id">设备号{{ order.deviceId }}</view>
</view>
<!-- 支付方式标识 -->
<view class="device-right">
<!-- 微信支付分标识 -->
<view class="payment-badge wx-score" v-if="order.payWay == 'wx_score_pay'">
<image src="/static/images/wxpayflag.png" mode="aspectFit" class="badge-icon"></image>
<view class="badge-text">
<text>微信支付分</text>
<text class="divider">|</text>
<text class="highlight">免押租借</text>
</view>
</view>
<!-- 押金租借标识 -->
<view class="payment-badge deposit" v-else>
<text class="badge-text">押金租借</text>
</view>
</view>
</view>
<!-- 订单时间信息 -->
<view class="order-times">
<view class="time-row">
<text class="time-label">开始时间</text>
<text class="time-value">{{ order.startTime }}</text>
</view>
<view class="time-row">
<text class="time-label">结束时间</text>
<text class="time-value">{{ order.endTime || '-' }}</text>
</view>
</view>
</view>
<!-- 订单底部 -->
<view class="order-footer">
<view class="price">{{ order.amount }}</view>
<view class="actions">
<view v-if="order.status=='in_used'" class="action-item primary" @click="navigateToReturn(order.deviceId, order.orderId)">
归还设备
</view>
<view v-if="order.status === 'waiting_for_payment'" class="action-item secondary"
@click="getOrderStatus(order)">
同步订单状态
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import {
ref,
reactive,
onMounted
} from 'vue';
import {
onLoad
} from '@dcloudio/uni-app';
import {
getOrderList,
queryById,
getOrderByOrderNoScorePayStatus
} from '../../config/user.js';
// 初始化状态
const currentTab = ref(0);
const orderList = ref([]);
// 订单状态映射
const orderStatusMap = reactive({
'0': {
text: '待支付',
class: 'status-waiting'
},
'1': {
text: '使用中',
class: 'status-using'
},
'2': {
text: '已完成',
class: 'status-finished'
},
'3': {
text: '已取消',
class: 'status-cancelled'
},
'waiting_for_payment': {
text: '待支付',
class: 'status-waiting'
},
'in_used': {
text: '使用中',
class: 'status-using'
},
'used_done': {
text: '已完成',
class: 'status-finished'
},
'canceled': {
text: '已取消',
class: 'status-cancelled'
}
});
// 订单状态标签
const orderStatusTabs = reactive([{
text: '全部',
status: []
},
{
text: '使用中',
status: ['1', 'in_used']
},
{
text: '已完成',
status: ['2', 'used_done']
},
{
text: '已取消',
status: ['3', 'canceled']
}
]);
// 页面加载
onLoad(async (options) => {
// 如果有传入orderId参数,说明是从设备租借页面跳转过来的
if (options && options.orderId) {
try {
// 获取特定订单信息
const res = await queryById(options.orderId);
if (res.code === 200 && res.data) {
// 获取到的订单数据
const orderData = res.data;
// 使用实际的startTime字段,如果没有则尝试使用createTime
const orderStartTime = orderData.startTime || orderData.createTime || '';
// 格式化订单数据
const formattedOrder = {
orderNo: orderData.orderId,
status: orderData.orderStatus,
deviceId: orderData.deviceNo,
payWay: orderData.payWay,
startTime: orderStartTime,
endTime: orderData.endTime || '',
amount: orderData.payAmount || orderData.actualDeviceAmount || '0.00'
};
// 将订单添加到列表开头
orderList.value = [formattedOrder, ...orderList.value];
// 根据订单状态切换到对应标签
const tabIndex = orderStatusTabs.findIndex(tab =>
tab.status.includes(orderData.orderStatus)
);
if (tabIndex !== -1) {
switchTab(tabIndex);
}
}
} catch (error) {
console.error('获取订单详情失败:', error);
}
}
// 获取订单列表
await loadOrderList();
});
// 切换标签
const switchTab = async (index) => {
currentTab.value = index;
// 根据状态获取订单列表
const statusList = orderStatusTabs[index].status;
await loadOrderList(statusList);
};
// 加载订单列表
const loadOrderList = async (statusList = []) => {
try {
const res = await getOrderList(statusList);
if (res.code === 200 && res.data && res.data.records) {
// 处理订单列表数据
orderList.value = res.data.records.map(item => {
// 使用实际的startTime字段,如果没有则尝试使用createTime
const orderStartTime = item.startTime || item.createTime || '';
return {
orderNo: item.orderNo,
orderId: item.orderId,
status: item.orderStatus,
deviceId: item.deviceNo,
payWay: item.payWay,
startTime: orderStartTime,
endTime: item.endTime || '',
amount: item.payAmount || item.actualDeviceAmount || '0.00'
};
});
}
} catch (error) {
console.error('获取订单列表失败:', error);
uni.showToast({
title: '获取订单列表失败',
icon: 'none'
});
}
};
// 同步订单状态
const getOrderStatus = async (order) => {
try {
const res = await getOrderByOrderNoScorePayStatus(order.orderNo);
if (res.code === 200) {
uni.showToast({
title: '状态同步成功',
icon: 'success'
});
await loadOrderList(orderStatusTabs[currentTab.value].status);
}
} catch (error) {
uni.showToast({
title: '同步状态失败',
icon: 'none'
});
}
};
// 跳转到归还设备页面
const navigateToReturn = (deviceId, orderId) => {
console.log(orderId);
uni.navigateTo({
url: `/pages/return/index?deviceId=${deviceId}&orderId=${orderId}`
});
};
</script>
<style lang="scss" scoped>
.order-container {
min-height: 100vh;
background: #f7f8fa;
padding-bottom: 30rpx;
// 状态标签栏
.status-tabs {
display: flex;
background: #fff;
padding: 0 20rpx;
position: sticky;
top: 0;
z-index: 10;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
.tab-item {
flex: 1;
height: 90rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #666;
position: relative;
&.active {
color: #1976D2;
font-weight: 500;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 40rpx;
height: 4rpx;
background: #1976D2;
border-radius: 2rpx;
}
}
}
}
// 订单列表
.order-list {
padding: 20rpx;
// 订单项
.order-item {
background: #fff;
border-radius: 16rpx;
margin-bottom: 20rpx;
overflow: hidden;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
// 订单头部
.order-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx;
border-bottom: 1rpx solid #f0f0f0;
.order-id {
font-size: 26rpx;
color: #666;
}
.order-status {
font-size: 26rpx;
font-weight: 500;
&.status-waiting {
color: #FF9800;
}
&.status-using {
color: #2196F3;
}
&.status-finished {
color: #4CAF50;
}
&.status-cancelled {
color: #9E9E9E;
}
}
}
// 订单内容
.order-body {
padding: 24rpx;
.device-info {
margin-bottom: 20rpx;
display: flex;
justify-content: space-between;
align-items: flex-start;
.device-left {
flex: 1;
margin-right: 20rpx;
.device-name {
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 6rpx;
}
.device-id {
font-size: 26rpx;
color: #999;
margin-bottom: 0;
}
}
.device-right {
// 支付分标识
.payment-badge {
display: inline-flex;
align-items: center;
padding: 6rpx 12rpx;
border-radius: 8rpx;
white-space: nowrap;
&.wx-score {
background: rgba(7, 193, 96, 0.08);
.badge-icon {
width: 32rpx;
height: 26rpx;
margin-right: 8rpx;
}
.badge-text {
font-size: 22rpx;
color: #07c160;
display: flex;
align-items: center;
.divider {
margin: 0 6rpx;
}
.highlight {
font-weight: 500;
}
}
}
&.deposit {
background: #f5f5f5;
.badge-text {
font-size: 22rpx;
color: #666;
font-weight: 500;
}
}
}
}
}
.order-times {
.time-row {
display: flex;
font-size: 26rpx;
margin-bottom: 8rpx;
.time-label {
color: #999;
width: 140rpx;
}
.time-value {
color: #333;
flex: 1;
}
}
}
}
// 订单底部
.order-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 24rpx;
background: #fafafa;
border-top: 1rpx solid #f0f0f0;
.price {
font-size: 34rpx;
font-weight: 500;
color: #ff6b6b;
}
.actions {
display: flex;
.action-item {
font-size: 26rpx;
padding: 10rpx 30rpx;
border-radius: 30rpx;
margin-left: 20rpx;
display: flex;
align-items: center;
justify-content: center;
&.primary {
background: #1976D2;
color: #fff;
}
&.secondary {
background: #f5f5f5;
color: #666;
border: 1rpx solid #e0e0e0;
}
&:active {
opacity: 0.8;
}
}
}
}
}
// 空状态
.empty-state {
padding: 100rpx 0;
text-align: center;
.empty-icon {
width: 180rpx;
height: 180rpx;
margin: 0 auto 30rpx;
background: #f5f5f5;
border-radius: 50%;
}
.empty-text {
font-size: 28rpx;
color: #999;
}
}
}
}
</style>