|
@@ -1,7 +1,6 @@
|
|
|
import { useState } from 'react';
|
|
import { useState } from 'react';
|
|
|
import { View, Text, ScrollView } from '@tarojs/components';
|
|
import { View, Text, ScrollView } from '@tarojs/components';
|
|
|
import { Button } from '@/components/ui/button';
|
|
import { Button } from '@/components/ui/button';
|
|
|
-import { Card, CardContent, CardFooter } from '@/components/ui/card';
|
|
|
|
|
import Taro from '@tarojs/taro';
|
|
import Taro from '@tarojs/taro';
|
|
|
import { useQuery } from '@tanstack/react-query';
|
|
import { useQuery } from '@tanstack/react-query';
|
|
|
import { orderClient } from '@/api';
|
|
import { orderClient } from '@/api';
|
|
@@ -23,86 +22,156 @@ const OrderCard = ({ order, onViewDetail }) => {
|
|
|
const getStatusColor = (status: OrderStatus) => {
|
|
const getStatusColor = (status: OrderStatus) => {
|
|
|
switch (status) {
|
|
switch (status) {
|
|
|
case OrderStatus.WAITING_DEPARTURE:
|
|
case OrderStatus.WAITING_DEPARTURE:
|
|
|
- return 'text-warning bg-warning/10';
|
|
|
|
|
|
|
+ return 'bg-warning/15 text-warning border-warning/30';
|
|
|
case OrderStatus.IN_PROGRESS:
|
|
case OrderStatus.IN_PROGRESS:
|
|
|
- return 'text-info bg-info/10';
|
|
|
|
|
|
|
+ return 'bg-info/15 text-info border-info/30';
|
|
|
case OrderStatus.COMPLETED:
|
|
case OrderStatus.COMPLETED:
|
|
|
- return 'text-success bg-success/10';
|
|
|
|
|
|
|
+ return 'bg-success/15 text-success border-success/30';
|
|
|
case OrderStatus.CANCELLED:
|
|
case OrderStatus.CANCELLED:
|
|
|
- return 'text-error bg-error/10';
|
|
|
|
|
|
|
+ return 'bg-error/15 text-error border-error/30';
|
|
|
default:
|
|
default:
|
|
|
- return 'text-muted-foreground bg-gray-100';
|
|
|
|
|
|
|
+ return 'bg-gray-100 text-muted-foreground border-gray-200';
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ // 判断是否为包车订单
|
|
|
|
|
+ const isCharterOrder = order.routeSnapshot?.vehicleType?.includes('包车') || order.routeSnapshot?.vehicleType?.includes('商务');
|
|
|
|
|
+
|
|
|
return (
|
|
return (
|
|
|
- <Card className="mb-4 rounded-card shadow-medium" onClick={() => onViewDetail(order.id)}>
|
|
|
|
|
- <CardContent className="p-card">
|
|
|
|
|
- {/* 订单头部 */}
|
|
|
|
|
- <View className="flex justify-between items-start mb-3">
|
|
|
|
|
|
|
+ <View
|
|
|
|
|
+ className={`mb-6 rounded-[28rpx] shadow-medium backdrop-blur-[16rpx] border border-white/40 overflow-hidden transition-all active:translate-y-[2rpx] active:shadow-[0_8rpx_24rpx_rgba(74,144,194,0.12)] ${
|
|
|
|
|
+ isCharterOrder
|
|
|
|
|
+ ? 'bg-gradient-to-br from-charter-dark to-charter-bg border-2 border-charter shadow-charter'
|
|
|
|
|
+ : 'bg-white/96'
|
|
|
|
|
+ }`}
|
|
|
|
|
+ onClick={() => onViewDetail(order.id)}
|
|
|
|
|
+ >
|
|
|
|
|
+ {/* 订单头部 */}
|
|
|
|
|
+ <View className="flex justify-between items-start p-[36rpx] border-b border-gray-200/60">
|
|
|
|
|
+ <View className="flex-1">
|
|
|
|
|
+ <Text className={`text-[24rpx] ${isCharterOrder ? 'text-gray-300' : 'text-gray-500'}`}>
|
|
|
|
|
+ 订单号:{order.id}
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ <Text className={`block text-[34rpx] font-semibold mt-2 leading-[1.4] tracking-[0.5rpx] ${
|
|
|
|
|
+ isCharterOrder ? 'text-charter' : 'text-gray-900'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ {order.routeSnapshot?.name || '未知活动'}
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View className={`px-[20rpx] py-[8rpx] rounded-[20rpx] text-[24rpx] font-bold border ${getStatusColor(order.status)}`}>
|
|
|
|
|
+ {order.status}
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 行程信息 */}
|
|
|
|
|
+ <View className="p-[28rpx_36rpx_32rpx]">
|
|
|
|
|
+ {/* 路线信息 */}
|
|
|
|
|
+ <View className="flex items-center mb-[28rpx] p-[20rpx] bg-primary/5 rounded-[16rpx] border border-primary/10">
|
|
|
<View className="flex-1">
|
|
<View className="flex-1">
|
|
|
- <Text className="text-sm text-gray-500">订单号:{order.id}</Text>
|
|
|
|
|
- <Text className="block text-base font-medium mt-1">
|
|
|
|
|
- {order.routeSnapshot?.name || '未知活动'}
|
|
|
|
|
|
|
+ <Text className={`text-[24rpx] ${isCharterOrder ? 'text-gray-300' : 'text-gray-500'}`}>出发</Text>
|
|
|
|
|
+ <Text className={`block text-[30rpx] font-semibold leading-[1.3] ${
|
|
|
|
|
+ isCharterOrder ? 'text-white' : 'text-gray-900'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ {order.routeSnapshot?.pickupPoint}
|
|
|
</Text>
|
|
</Text>
|
|
|
</View>
|
|
</View>
|
|
|
- <View className={`px-3 py-1 rounded-full text-xs font-medium ${getStatusColor(order.status)}`}>
|
|
|
|
|
- {order.status}
|
|
|
|
|
|
|
+ <Text className={`mx-[28rpx] text-[36rpx] font-semibold opacity-80 ${
|
|
|
|
|
+ isCharterOrder ? 'text-charter' : 'text-primary'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ →
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ <View className="flex-1">
|
|
|
|
|
+ <Text className={`text-[24rpx] ${isCharterOrder ? 'text-gray-300' : 'text-gray-500'}`}>到达</Text>
|
|
|
|
|
+ <Text className={`block text-[30rpx] font-semibold leading-[1.3] ${
|
|
|
|
|
+ isCharterOrder ? 'text-white' : 'text-gray-900'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ {order.routeSnapshot?.dropoffPoint}
|
|
|
|
|
+ </Text>
|
|
|
</View>
|
|
</View>
|
|
|
</View>
|
|
</View>
|
|
|
|
|
|
|
|
- {/* 行程信息 */}
|
|
|
|
|
- <View className="mb-3">
|
|
|
|
|
- <View className="flex items-center mb-2">
|
|
|
|
|
- <View className="flex-1">
|
|
|
|
|
- <Text className="text-sm text-gray-500">出发</Text>
|
|
|
|
|
- <Text className="block text-sm">{order.routeSnapshot?.pickupPoint}</Text>
|
|
|
|
|
- </View>
|
|
|
|
|
- <Text className="mx-2 text-gray-500">→</Text>
|
|
|
|
|
- <View className="flex-1">
|
|
|
|
|
- <Text className="text-sm text-gray-500">到达</Text>
|
|
|
|
|
- <Text className="block text-sm">{order.routeSnapshot?.dropoffPoint}</Text>
|
|
|
|
|
- </View>
|
|
|
|
|
|
|
+ {/* 行程详情 */}
|
|
|
|
|
+ <View className={`p-[24rpx] rounded-[18rpx] border ${
|
|
|
|
|
+ isCharterOrder
|
|
|
|
|
+ ? 'bg-gray-800 border-gray-700'
|
|
|
|
|
+ : 'bg-primary/6 border-primary/8'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ <View className="flex mb-[16rpx] items-center">
|
|
|
|
|
+ <Text className={`text-[26rpx] w-[160rpx] flex-shrink-0 ${
|
|
|
|
|
+ isCharterOrder ? 'text-gray-300' : 'text-gray-600'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ 出发时间:
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ <Text className={`text-[26rpx] flex-1 ${
|
|
|
|
|
+ isCharterOrder ? 'text-white' : 'text-gray-900'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ {order.routeSnapshot?.departureTime
|
|
|
|
|
+ ? new Date(order.routeSnapshot.departureTime).toLocaleString('zh-CN')
|
|
|
|
|
+ : '未知时间'
|
|
|
|
|
+ }
|
|
|
|
|
+ </Text>
|
|
|
</View>
|
|
</View>
|
|
|
-
|
|
|
|
|
- <View className="space-y-1 text-sm">
|
|
|
|
|
- <View className="flex justify-between">
|
|
|
|
|
- <Text className="text-gray-500">出发时间:</Text>
|
|
|
|
|
- <Text>
|
|
|
|
|
- {order.routeSnapshot?.departureTime
|
|
|
|
|
- ? new Date(order.routeSnapshot.departureTime).toLocaleString('zh-CN')
|
|
|
|
|
- : '未知时间'
|
|
|
|
|
- }
|
|
|
|
|
- </Text>
|
|
|
|
|
- </View>
|
|
|
|
|
- <View className="flex justify-between">
|
|
|
|
|
- <Text className="text-gray-500">车辆型号:</Text>
|
|
|
|
|
- <Text>{order.routeSnapshot?.vehicleType || '未知车型'}</Text>
|
|
|
|
|
- </View>
|
|
|
|
|
- <View className="flex justify-between">
|
|
|
|
|
- <Text className="text-gray-500">乘车人数:</Text>
|
|
|
|
|
- <Text>{order.passengerCount}人</Text>
|
|
|
|
|
- </View>
|
|
|
|
|
|
|
+ <View className="flex mb-[16rpx] items-center">
|
|
|
|
|
+ <Text className={`text-[26rpx] w-[160rpx] flex-shrink-0 ${
|
|
|
|
|
+ isCharterOrder ? 'text-gray-300' : 'text-gray-600'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ 车辆型号:
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ <Text className={`text-[26rpx] flex-1 ${
|
|
|
|
|
+ isCharterOrder ? 'text-white' : 'text-gray-900'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ {order.routeSnapshot?.vehicleType || '未知车型'}
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View className="flex items-center">
|
|
|
|
|
+ <Text className={`text-[26rpx] w-[160rpx] flex-shrink-0 ${
|
|
|
|
|
+ isCharterOrder ? 'text-gray-300' : 'text-gray-600'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ 乘车人数:
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ <Text className={`text-[26rpx] flex-1 ${
|
|
|
|
|
+ isCharterOrder ? 'text-white' : 'text-gray-900'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ {order.passengerCount}人
|
|
|
|
|
+ </Text>
|
|
|
</View>
|
|
</View>
|
|
|
</View>
|
|
</View>
|
|
|
- </CardContent>
|
|
|
|
|
|
|
+ </View>
|
|
|
|
|
|
|
|
- <CardFooter className="border-t border-gray-200 pt-3">
|
|
|
|
|
- <View className="flex justify-between items-center w-full">
|
|
|
|
|
- <Text className="text-sm text-gray-500">
|
|
|
|
|
|
|
+ {/* 价格和操作区域 */}
|
|
|
|
|
+ <View className={`p-[28rpx_36rpx] border-t ${
|
|
|
|
|
+ isCharterOrder
|
|
|
|
|
+ ? 'bg-gray-800 border-gray-700'
|
|
|
|
|
+ : 'bg-primary/4 border-primary/8'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ <View className="flex justify-between items-center mb-3">
|
|
|
|
|
+ <Text className={`text-[26rpx] flex-1 min-w-0 font-medium leading-[1.4] ${
|
|
|
|
|
+ isCharterOrder ? 'text-gray-300' : 'text-gray-500'
|
|
|
|
|
+ }`}>
|
|
|
下单时间:{new Date(order.createdAt).toLocaleString('zh-CN')}
|
|
下单时间:{new Date(order.createdAt).toLocaleString('zh-CN')}
|
|
|
</Text>
|
|
</Text>
|
|
|
- <View className="flex items-center">
|
|
|
|
|
- <Text className="text-sm text-gray-500 mr-2">订单金额</Text>
|
|
|
|
|
- <Text className="text-lg font-semibold text-primary">¥{order.totalAmount}</Text>
|
|
|
|
|
|
|
+ <View className="flex items-center flex-shrink-0">
|
|
|
|
|
+ <Text className={`text-[28rpx] mr-2 ${
|
|
|
|
|
+ isCharterOrder ? 'text-gray-300' : 'text-gray-600'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ 订单金额
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ <Text className={`text-[36rpx] font-bold ${
|
|
|
|
|
+ isCharterOrder ? 'text-charter' : 'text-primary'
|
|
|
|
|
+ }`}>
|
|
|
|
|
+ ¥{order.totalAmount}
|
|
|
|
|
+ </Text>
|
|
|
</View>
|
|
</View>
|
|
|
</View>
|
|
</View>
|
|
|
|
|
|
|
|
{/* 操作按钮 */}
|
|
{/* 操作按钮 */}
|
|
|
- <View className="flex justify-end w-full mt-3">
|
|
|
|
|
|
|
+ <View className="flex justify-end w-full">
|
|
|
<Button
|
|
<Button
|
|
|
- variant="default"
|
|
|
|
|
- size="sm"
|
|
|
|
|
|
|
+ className={`rounded-[50rpx] px-[28rpx] py-[16rpx] text-[26rpx] font-semibold shadow-primary transition-all active:translate-y-[1rpx] active:shadow-[0_4rpx_12rpx_rgba(74,144,194,0.25)] ${
|
|
|
|
|
+ isCharterOrder
|
|
|
|
|
+ ? 'bg-charter text-charter-dark'
|
|
|
|
|
+ : 'bg-gradient-to-br from-primary to-primary-dark text-white'
|
|
|
|
|
+ }`}
|
|
|
onClick={(e) => {
|
|
onClick={(e) => {
|
|
|
e.stopPropagation();
|
|
e.stopPropagation();
|
|
|
onViewDetail(order.id);
|
|
onViewDetail(order.id);
|
|
@@ -111,8 +180,8 @@ const OrderCard = ({ order, onViewDetail }) => {
|
|
|
查看详情
|
|
查看详情
|
|
|
</Button>
|
|
</Button>
|
|
|
</View>
|
|
</View>
|
|
|
- </CardFooter>
|
|
|
|
|
- </Card>
|
|
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
);
|
|
);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -136,10 +205,10 @@ const EmptyOrders = ({ currentTab }) => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
- <View className="flex flex-col items-center justify-center py-20">
|
|
|
|
|
- <Text className="text-6xl mb-6 text-gray-300">📋</Text>
|
|
|
|
|
- <Text className="text-lg text-gray-500 mb-3">{getEmptyMessage()}</Text>
|
|
|
|
|
- <Text className="text-sm text-gray-400">您还没有相关状态的订单</Text>
|
|
|
|
|
|
|
+ <View className="text-center p-[120rpx_32rpx] bg-white/10 rounded-[24rpx] backdrop-blur-[10rpx] border border-white/20 mx-auto my-[32rpx] w-full max-w-[680rpx] box-border">
|
|
|
|
|
+ <Text className="text-[120rpx] mb-[32rpx] text-white/80">📋</Text>
|
|
|
|
|
+ <Text className="text-[32rpx] text-white/90 mb-[16rpx] font-bold">{getEmptyMessage()}</Text>
|
|
|
|
|
+ <Text className="text-[26rpx] text-white/70">您还没有相关状态的订单</Text>
|
|
|
</View>
|
|
</View>
|
|
|
);
|
|
);
|
|
|
};
|
|
};
|
|
@@ -208,33 +277,34 @@ const OrdersPage = () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
- <TabBarLayout activeKey="orders" className='bg-gray-50'>
|
|
|
|
|
|
|
+ <TabBarLayout activeKey="orders" className='bg-gradient-to-b from-primary to-primary-dark min-h-screen'>
|
|
|
<Navbar
|
|
<Navbar
|
|
|
title="我的订单"
|
|
title="我的订单"
|
|
|
- backgroundColor="bg-primary"
|
|
|
|
|
|
|
+ backgroundColor="bg-transparent"
|
|
|
textColor="text-white"
|
|
textColor="text-white"
|
|
|
border={false}
|
|
border={false}
|
|
|
leftIcon=""
|
|
leftIcon=""
|
|
|
rightIcon=""
|
|
rightIcon=""
|
|
|
/>
|
|
/>
|
|
|
|
|
+
|
|
|
{/* 状态选项卡 */}
|
|
{/* 状态选项卡 */}
|
|
|
- <View className="bg-white border-b border-border">
|
|
|
|
|
|
|
+ <View className="bg-white/95 p-[24rpx_20rpx] rounded-[24rpx] shadow-medium backdrop-blur-[12rpx] mx-auto mt-[24rpx] max-w-[700rpx] w-[calc(100%-32rpx)]">
|
|
|
<ScrollView
|
|
<ScrollView
|
|
|
- className="px-4"
|
|
|
|
|
scrollX
|
|
scrollX
|
|
|
showScrollbar={false}
|
|
showScrollbar={false}
|
|
|
>
|
|
>
|
|
|
- <View className="flex flex-row py-3">
|
|
|
|
|
|
|
+ <View className="flex justify-between items-center w-full box-border p-0 gap-[12rpx]">
|
|
|
{statusTabs.map((tab) => (
|
|
{statusTabs.map((tab) => (
|
|
|
<View
|
|
<View
|
|
|
key={tab.key}
|
|
key={tab.key}
|
|
|
- className={`px-4 py-2 rounded-full mr-3 cursor-pointer transition-colors whitespace-nowrap ${currentTab === tab.key
|
|
|
|
|
- ? 'bg-primary text-white'
|
|
|
|
|
- : 'bg-gray-100 text-gray-600'
|
|
|
|
|
- }`}
|
|
|
|
|
|
|
+ className={`flex items-center justify-center p-[16rpx_20rpx] rounded-[50rpx] text-[26rpx] font-medium transition-all whitespace-nowrap overflow-hidden text-ellipsis min-w-0 tracking-[0.5rpx] flex-1 text-center border-2 ${
|
|
|
|
|
+ currentTab === tab.key
|
|
|
|
|
+ ? 'bg-gradient-to-br from-primary to-primary-dark text-white font-semibold -translate-y-[2rpx] shadow-[0_6rpx_20rpx_rgba(74,144,194,0.35)] border-primary/30'
|
|
|
|
|
+ : 'bg-primary/8 text-gray-600 border-primary/15'
|
|
|
|
|
+ }`}
|
|
|
onClick={() => handleTabChange(tab.key)}
|
|
onClick={() => handleTabChange(tab.key)}
|
|
|
>
|
|
>
|
|
|
- <Text className="text-sm font-medium">{tab.label}</Text>
|
|
|
|
|
|
|
+ <Text>{tab.label}</Text>
|
|
|
</View>
|
|
</View>
|
|
|
))}
|
|
))}
|
|
|
</View>
|
|
</View>
|
|
@@ -243,14 +313,14 @@ const OrdersPage = () => {
|
|
|
|
|
|
|
|
{/* 订单列表 */}
|
|
{/* 订单列表 */}
|
|
|
<ScrollView
|
|
<ScrollView
|
|
|
- className="px-4 py-4"
|
|
|
|
|
|
|
+ className="p-[40rpx_16rpx_32rpx] flex flex-col items-center w-full box-border"
|
|
|
scrollY
|
|
scrollY
|
|
|
refresherEnabled
|
|
refresherEnabled
|
|
|
onRefresherRefresh={onPullDownRefresh}
|
|
onRefresherRefresh={onPullDownRefresh}
|
|
|
>
|
|
>
|
|
|
{isLoading ? (
|
|
{isLoading ? (
|
|
|
<View className="flex flex-col items-center justify-center py-16">
|
|
<View className="flex flex-col items-center justify-center py-16">
|
|
|
- <Text className="text-muted-foreground">加载中...</Text>
|
|
|
|
|
|
|
+ <Text className="text-white/80">加载中...</Text>
|
|
|
</View>
|
|
</View>
|
|
|
) : orders.length === 0 ? (
|
|
) : orders.length === 0 ? (
|
|
|
<EmptyOrders currentTab={currentTab} />
|
|
<EmptyOrders currentTab={currentTab} />
|