|
|
@@ -1,7 +1,6 @@
|
|
|
import { useState, useEffect } from 'react';
|
|
|
import { View, Text, ScrollView } from '@tarojs/components';
|
|
|
import { Button } from '@/components/ui/button';
|
|
|
-import { Card, CardContent, CardHeader } from '@/components/ui/card';
|
|
|
import Taro from '@tarojs/taro';
|
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
|
import { orderClient } from '@/api';
|
|
|
@@ -107,13 +106,13 @@ const OrderDetailPage = () => {
|
|
|
const getStatusColor = (status: OrderStatus) => {
|
|
|
switch (status) {
|
|
|
case OrderStatus.WAITING_DEPARTURE:
|
|
|
- return 'text-warning';
|
|
|
+ return 'text-[#FFA940]';
|
|
|
case OrderStatus.IN_PROGRESS:
|
|
|
- return 'text-info';
|
|
|
+ return 'text-[#1890ff]';
|
|
|
case OrderStatus.COMPLETED:
|
|
|
- return 'text-success';
|
|
|
+ return 'text-[#52C41A]';
|
|
|
case OrderStatus.CANCELLED:
|
|
|
- return 'text-error';
|
|
|
+ return 'text-[#ff4d4f]';
|
|
|
default:
|
|
|
return 'text-gray-500';
|
|
|
}
|
|
|
@@ -142,143 +141,131 @@ const OrderDetailPage = () => {
|
|
|
}
|
|
|
|
|
|
return (
|
|
|
- <View className="min-h-screen bg-gray-50">
|
|
|
+ <View className="min-h-screen bg-gradient-to-b from-[#5B9BD5] to-[#4A90C2] pb-[calc(100rpx+env(safe-area-inset-bottom))]">
|
|
|
<Navbar
|
|
|
title="订单详情"
|
|
|
- backgroundColor="bg-primary"
|
|
|
+ backgroundColor="bg-transparent"
|
|
|
textColor="text-white"
|
|
|
border={false}
|
|
|
leftIcon="i-heroicons-arrow-left-20-solid"
|
|
|
onClickLeft={() => Taro.navigateBack()}
|
|
|
rightIcon=""
|
|
|
/>
|
|
|
- <ScrollView className="px-4 pt-4" scrollY>
|
|
|
+ <ScrollView className="px-[32rpx] pt-4" scrollY>
|
|
|
{/* 订单基本信息 */}
|
|
|
- <Card className="rounded-card shadow-medium mb-4">
|
|
|
- <CardHeader className="border-b border-gray-200">
|
|
|
- <Text className="text-lg font-semibold">订单信息</Text>
|
|
|
- </CardHeader>
|
|
|
- <CardContent className="p-card">
|
|
|
- <View className="space-y-3">
|
|
|
- <View className="flex justify-between">
|
|
|
- <Text className="text-gray-500">订单号:</Text>
|
|
|
- <Text>{order.id}</Text>
|
|
|
- </View>
|
|
|
+ <View className="bg-white/96 backdrop-blur-[16rpx] rounded-[28rpx] p-[36rpx] mb-[32rpx] shadow-[0_12rpx_40rpx_rgba(74,144,194,0.18)] border border-white/40">
|
|
|
+ <Text className="text-[36rpx] font-semibold text-gray-900 mb-[24rpx] tracking-[0.5rpx]">订单信息</Text>
|
|
|
+ <View className="space-y-[20rpx]">
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-[28rpx] text-gray-600 w-[160rpx] flex-shrink-0">订单号:</Text>
|
|
|
+ <Text className="text-[28rpx] text-gray-900 flex-1 font-medium">{order.id}</Text>
|
|
|
+ </View>
|
|
|
|
|
|
- <View className="flex justify-between">
|
|
|
- <Text className="text-gray-500">行程路线:</Text>
|
|
|
- <Text className="text-right">
|
|
|
- {order.routeSnapshot?.pickupPoint} → {order.routeSnapshot?.dropoffPoint}
|
|
|
- </Text>
|
|
|
- </View>
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-[28rpx] text-gray-600 w-[160rpx] flex-shrink-0">行程路线:</Text>
|
|
|
+ <Text className="text-[28rpx] text-gray-900 flex-1 font-medium text-right">
|
|
|
+ {order.routeSnapshot?.pickupPoint} → {order.routeSnapshot?.dropoffPoint}
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
|
|
|
- <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 items-center">
|
|
|
+ <Text className="text-[28rpx] text-gray-600 w-[160rpx] flex-shrink-0">出发时间:</Text>
|
|
|
+ <Text className="text-[28rpx] text-gray-900 flex-1 font-medium">
|
|
|
+ {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>{getVehicleTypeText(order.routeSnapshot?.vehicleType)}</Text>
|
|
|
- </View>
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-[28rpx] text-gray-600 w-[160rpx] flex-shrink-0">车辆型号:</Text>
|
|
|
+ <Text className="text-[28rpx] text-gray-900 flex-1 font-medium">{getVehicleTypeText(order.routeSnapshot?.vehicleType)}</Text>
|
|
|
+ </View>
|
|
|
|
|
|
- <View className="flex justify-between">
|
|
|
- <Text className="text-gray-500">乘车人数:</Text>
|
|
|
- <Text>{order.passengerCount}人</Text>
|
|
|
- </View>
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-[28rpx] text-gray-600 w-[160rpx] flex-shrink-0">乘车人数:</Text>
|
|
|
+ <Text className="text-[28rpx] text-gray-900 flex-1 font-medium">{order.passengerCount}人</Text>
|
|
|
+ </View>
|
|
|
|
|
|
- <View className="flex justify-between">
|
|
|
- <Text className="text-gray-500">订单状态:</Text>
|
|
|
- <Text className={`font-medium ${getStatusColor(order.status)}`}>
|
|
|
- {order.status}
|
|
|
- </Text>
|
|
|
- </View>
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-[28rpx] text-gray-600 w-[160rpx] flex-shrink-0">订单状态:</Text>
|
|
|
+ <Text className={`text-[28rpx] flex-1 font-medium ${getStatusColor(order.status)}`}>
|
|
|
+ {order.status}
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
|
|
|
- <View className="flex justify-between">
|
|
|
- <Text className="text-gray-500">支付状态:</Text>
|
|
|
- <Text>{order.paymentStatus}</Text>
|
|
|
- </View>
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-[28rpx] text-gray-600 w-[160rpx] flex-shrink-0">支付状态:</Text>
|
|
|
+ <Text className="text-[28rpx] text-gray-900 flex-1 font-medium">{order.paymentStatus}</Text>
|
|
|
+ </View>
|
|
|
|
|
|
- <View className="flex justify-between">
|
|
|
- <Text className="text-gray-500">订单金额:</Text>
|
|
|
- <Text className="text-lg font-semibold text-primary">¥{order.totalAmount}</Text>
|
|
|
- </View>
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-[28rpx] text-gray-600 w-[160rpx] flex-shrink-0">订单金额:</Text>
|
|
|
+ <Text className="text-[30rpx] text-primary flex-1 font-semibold">¥{order.totalAmount}</Text>
|
|
|
+ </View>
|
|
|
|
|
|
- <View className="flex justify-between">
|
|
|
- <Text className="text-gray-500">下单时间:</Text>
|
|
|
- <Text>{new Date(order.createdAt).toLocaleString('zh-CN')}</Text>
|
|
|
- </View>
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-[28rpx] text-gray-600 w-[160rpx] flex-shrink-0">下单时间:</Text>
|
|
|
+ <Text className="text-[28rpx] text-gray-900 flex-1 font-medium">{new Date(order.createdAt).toLocaleString('zh-CN')}</Text>
|
|
|
</View>
|
|
|
- </CardContent>
|
|
|
- </Card>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
|
|
|
{/* 乘客信息 */}
|
|
|
{order.passengerSnapshots && order.passengerSnapshots.length > 0 && (
|
|
|
- <Card className="rounded-card shadow-medium mb-4">
|
|
|
- <CardHeader className="border-b border-gray-200">
|
|
|
- <Text className="text-lg font-semibold">乘客信息</Text>
|
|
|
- </CardHeader>
|
|
|
- <CardContent className="p-card">
|
|
|
- <View className="space-y-3">
|
|
|
- {order.passengerSnapshots.map((passenger, index) => (
|
|
|
- <View key={index} className="border-b border-gray-200 pb-3 last:border-b-0 last:pb-0">
|
|
|
- <View className="flex justify-between mb-1">
|
|
|
- <Text className="font-medium">{passenger.name}</Text>
|
|
|
- <Text className="text-sm text-gray-500">
|
|
|
- {passenger.idType === 'ID_CARD' ? '身份证' : '护照'}
|
|
|
- </Text>
|
|
|
+ <View className="bg-white/96 backdrop-blur-[16rpx] rounded-[28rpx] p-[36rpx] mb-[32rpx] shadow-[0_12rpx_40rpx_rgba(74,144,194,0.18)] border border-white/40">
|
|
|
+ <Text className="text-[36rpx] font-semibold text-gray-900 mb-[24rpx] tracking-[0.5rpx]">乘客信息</Text>
|
|
|
+ <View className="space-y-[24rpx]">
|
|
|
+ {order.passengerSnapshots.map((passenger, index) => (
|
|
|
+ <View key={index} className="border-b border-gray-200/60 pb-[24rpx] last:border-b-0 last:pb-0">
|
|
|
+ <View className="flex justify-between mb-[12rpx]">
|
|
|
+ <Text className="text-[28rpx] font-medium text-gray-900">{passenger.name}</Text>
|
|
|
+ <Text className="text-[24rpx] text-gray-500">
|
|
|
+ {passenger.idType === 'ID_CARD' ? '身份证' : '护照'}
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <View className="space-y-[8rpx] text-[24rpx]">
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-gray-600 w-[120rpx] flex-shrink-0">证件号码:</Text>
|
|
|
+ <Text className="text-gray-900 flex-1 font-medium">{passenger.idNumber}</Text>
|
|
|
</View>
|
|
|
|
|
|
- <View className="space-y-1 text-sm">
|
|
|
- <View className="flex justify-between">
|
|
|
- <Text className="text-gray-500">证件号码:</Text>
|
|
|
- <Text>{passenger.idNumber}</Text>
|
|
|
+ {passenger.phone && (
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-gray-600 w-[120rpx] flex-shrink-0">联系电话:</Text>
|
|
|
+ <Text className="text-gray-900 flex-1 font-medium">{passenger.phone}</Text>
|
|
|
</View>
|
|
|
-
|
|
|
- {passenger.phone && (
|
|
|
- <View className="flex justify-between">
|
|
|
- <Text className="text-gray-500">联系电话:</Text>
|
|
|
- <Text>{passenger.phone}</Text>
|
|
|
- </View>
|
|
|
- )}
|
|
|
- </View>
|
|
|
+ )}
|
|
|
</View>
|
|
|
- ))}
|
|
|
- </View>
|
|
|
- </CardContent>
|
|
|
- </Card>
|
|
|
+ </View>
|
|
|
+ ))}
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
)}
|
|
|
|
|
|
{/* 路线快照信息 */}
|
|
|
{order.routeSnapshot && (
|
|
|
- <Card className="rounded-card shadow-medium mb-4">
|
|
|
- <CardHeader className="border-b border-gray-200">
|
|
|
- <Text className="text-lg font-semibold">行程详情</Text>
|
|
|
- </CardHeader>
|
|
|
- <CardContent className="p-card">
|
|
|
- <View className="space-y-3">
|
|
|
- <View className="flex justify-between">
|
|
|
- <Text className="text-gray-500">活动名称:</Text>
|
|
|
- <Text>{order.routeSnapshot.name}</Text>
|
|
|
- </View>
|
|
|
+ <View className="bg-white/96 backdrop-blur-[16rpx] rounded-[28rpx] p-[36rpx] mb-[32rpx] shadow-[0_12rpx_40rpx_rgba(74,144,194,0.18)] border border-white/40">
|
|
|
+ <Text className="text-[36rpx] font-semibold text-gray-900 mb-[24rpx] tracking-[0.5rpx]">行程详情</Text>
|
|
|
+ <View className="space-y-[20rpx]">
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-[28rpx] text-gray-600 w-[160rpx] flex-shrink-0">活动名称:</Text>
|
|
|
+ <Text className="text-[28rpx] text-gray-900 flex-1 font-medium">{order.routeSnapshot.name}</Text>
|
|
|
+ </View>
|
|
|
|
|
|
- <View className="flex justify-between">
|
|
|
- <Text className="text-gray-500">出行方式:</Text>
|
|
|
- <Text>{getTravelModeText(order.routeSnapshot.travelMode)}</Text>
|
|
|
- </View>
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-[28rpx] text-gray-600 w-[160rpx] flex-shrink-0">出行方式:</Text>
|
|
|
+ <Text className="text-[28rpx] text-gray-900 flex-1 font-medium">{getTravelModeText(order.routeSnapshot.travelMode)}</Text>
|
|
|
+ </View>
|
|
|
|
|
|
- <View className="flex justify-between">
|
|
|
- <Text className="text-gray-500">单价:</Text>
|
|
|
- <Text>¥{order.routeSnapshot.price}</Text>
|
|
|
- </View>
|
|
|
+ <View className="flex items-center">
|
|
|
+ <Text className="text-[28rpx] text-gray-600 w-[160rpx] flex-shrink-0">单价:</Text>
|
|
|
+ <Text className="text-[28rpx] text-gray-900 flex-1 font-medium">¥{order.routeSnapshot.price}</Text>
|
|
|
</View>
|
|
|
- </CardContent>
|
|
|
- </Card>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
)}
|
|
|
{/* 底部占位,避免被操作按钮遮挡 */}
|
|
|
<View className="h-20"></View>
|
|
|
@@ -286,10 +273,9 @@ const OrderDetailPage = () => {
|
|
|
|
|
|
{/* 底部操作按钮 */}
|
|
|
{order.status === OrderStatus.WAITING_DEPARTURE && (
|
|
|
- <View className="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 p-4">
|
|
|
+ <View className="fixed bottom-0 left-0 right-0 bg-white/95 backdrop-blur-[12rpx] p-[24rpx_32rpx] pb-[calc(24rpx+env(safe-area-inset-bottom))] shadow-[0_-4rpx_20rpx_rgba(0,0,0,0.1)] border-t border-gray-200/60">
|
|
|
<Button
|
|
|
- variant="destructive"
|
|
|
- className="w-full"
|
|
|
+ className="w-full bg-gradient-to-r from-[#ff4d4f] to-[#ff7875] text-white border-none rounded-[50rpx] p-[24rpx] text-[32rpx] font-semibold shadow-[0_8rpx_24rpx_rgba(255,77,79,0.3)] transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] active:translate-y-[2rpx] active:shadow-[0_4rpx_12rpx_rgba(255,77,79,0.2)]"
|
|
|
onClick={handleCancelOrder}
|
|
|
loading={cancelOrderMutation.isPending}
|
|
|
>
|