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

689 lines
15 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.orderStatus]?.class">
{{ orderStatusMap[order.orderStatus]?.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 member" v-else-if="order.payWay == 'wx_member_pay'">
<text class="badge-text">会员订单</text>
</view>
<!-- 押金租借标识微信支付订单 -->
<view class="payment-badge deposit" v-else-if="order.payWay == 'wx_pay'">
<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 === 'waiting_for_payment' || order.orderStatus === 'waiting_for_payment'" class="action-item primary" @click="handlePayment(order)">
立即支付
</view>
<view v-if="order.status === 'waiting_for_payment' || order.orderStatus === 'waiting_for_payment'" class="action-item secondary" @click="handleCancelOrder(order)">
取消订单
</view>
<!-- 使用中状态显示归还设备按钮 -->
<view v-if="order.status=='in_used' || order.orderStatus=='in_used'" class="action-item primary"
@click="navigateToReturn(order.deviceId, order.orderId)">
归还设备
</view>
<!-- 查看详情按钮对所有订单都显示 -->
<view class="action-item secondary" @click="navigateToDetails(order)">
查看详情
</view>
<!-- 同步订单状态按钮 -->
<!-- <view v-if="order.status === 'waiting_for_payment' || order.orderStatus === '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,
cancelOrder,
confirmPaymentAndRent,
updateUserBalance
} from '../../config/user.js';
import {
URL
} from '../../config/url.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'
},
'order_cancelled': {
text: '已取消',
class: 'status-cancelled'
},
'express_return': {
text: '快递归还',
class: 'status-express-return'
}
});
// 订单状态标签
const orderStatusTabs = reactive([{
text: '全部',
status: []
},
{
text: '待付款',
status: ['waiting_for_payment']
},
{
text: '使用中',
status: ['in_used']
},
{
text: '已完成',
status: ['used_done']
},
{
text: '已取消',
status: ['order_cancelled']
}
]);
// 页面加载
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[0];
await loadOrderList(statusList);
};
// 加载订单列表
const loadOrderList = async (statusList) => {
try {
if(statusList!=undefined){
statusList = {
orderStatus:statusList
}
}
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,
orderStatus: 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}`
});
};
// 跳转到订单详情页
const navigateToDetails = (order) => {
uni.navigateTo({
url: `/pages/return/index?orderId=${order.orderId || order.orderNo}&deviceId=${order.deviceId}`
});
};
// 立即支付
const handlePayment = async (order) => {
try {
uni.showLoading({
title: '处理中'
});
// 调用后端创建微信支付订单接口
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')
}
});
if (res.statusCode === 200 && res.data.code === 200) {
const payParams = res.data.data;
// 调用微信支付
await uni.requestPayment({
...payParams,
success: async () => {
uni.showToast({
title: '支付成功',
icon: 'success'
});
// 更新用户余额
try {
await updateUserBalance(order.orderId || order.orderNo);
} catch (error) {
console.warn('更新用户余额失败:', error);
}
// 刷新订单列表
await loadOrderList(orderStatusTabs[currentTab.value].status);
},
fail: (err) => {
console.error('支付失败:', err);
throw new Error('支付失败,请重试');
}
});
} else {
throw new Error(res.data.msg || '创建支付订单失败');
}
uni.hideLoading();
} catch (error) {
uni.hideLoading();
uni.showToast({
title: error.message || '支付失败',
icon: 'none'
});
}
};
// 取消订单
const handleCancelOrder = async (order) => {
try {
uni.showModal({
title: '确认取消',
content: '确定要取消此订单吗?',
success: async (res) => {
if (res.confirm) {
uni.showLoading({
title: '处理中'
});
const result = await cancelOrder({
orderId: order.orderNo
});
if (result) {
uni.hideLoading();
uni.showToast({
title: '订单已取消',
icon: 'success'
});
// 刷新订单列表
await loadOrderList();
} else {
throw new Error(result.msg || '取消订单失败');
}
}
}
});
} catch (error) {
uni.hideLoading();
uni.showToast({
title: error.message || '取消订单失败',
icon: 'none'
});
}
};
</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;
}
&.status-express-return {
color: #FF9800;
}
}
}
// 订单内容
.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;
}
}
}
&.member {
background: rgba(25, 118, 210, 0.08);
.badge-text {
font-size: 22rpx;
color: #1976D2;
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;
flex-wrap: wrap;
justify-content: flex-end;
.action-item {
font-size: 26rpx;
padding: 10rpx 30rpx;
border-radius: 30rpx;
margin-left: 20rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10rpx;
&.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>