卢春龙
2026-04-20 13c960a2b6bb54797bdbd03aa3184af507d94a9b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import { View, Image } from "@tarojs/components";
import './css-folder/calling-car.less'
import { formatDurationDisplay } from '../../../../utils/Robotaxi-public-method';
 
import useTripCountdown from './calling-car-modules/use-trip-countdown';
import TripStatusHeader from './calling-car-modules/trip-status-header';
import VehicleInfoCard from './calling-car-modules/vehicle-info-card';
import TemperatureControl from './calling-car-modules/temperature-control';
import DoorTrunkControl from './calling-car-modules/door-trunk-control';
import FareDetailCard from './calling-car-modules/fare-detail-card';
import EvaluationCard from './calling-car-modules/evaluation-card';
 
type Props = {
    /** 行程状态:3呼叫中、4即将到达、5已到达上车点、6行程中、7到达终点、8待支付、9已支付 */
    tripStatus?: number;
    /** 打开取消弹窗,入参为预计到达展示文案 */
    handleOpenCancelPopup?: (durationDisplay: any) => void;
    /** 上车点超时后的回调 */
    handleCancelTimeout?: () => void;
    /** 到达终点后倒计时结束回调 */
    handleFinishTimeout?: () => void;
    /** 重置费用明细展开态的版本号 */
    resetDetailVersion?: number;
    /** 服务端推送价格更新版本号 */
    priceUpdateVersion?: number;
    /** 外部触发“评价已提交”版本号 */
    evaluateSubmitVersion?: number;
    /** 外部触发“评价弹窗关闭”版本号 */
    evaluateCloseVersion?: number;
    /** 打开结束行程弹窗 */
    handleOpenOverRoutePopup?: () => void;
    /** 费用明细展开/收起时同步地图视觉状态 */
    onToggleDetailFade?: (expanded: boolean, hasFare: boolean) => void;
    /** 立即支付回调 */
    handlePay?: () => void;
    /** 打开详细评价弹窗 */
    handleOpenEvaluatePopup?: () => void;
    /** 首次开门后打开安全须知弹窗 */
    handleOpenAnnouncementsPopup?: () => void;
    /** 预估等待分钟数 */
    estimatedWaitMinutes?: number;
    /** 预估行程秒数 */
    routeDurationSeconds?: number | null;
    /** 是否启用到达终点后的离车倒计时 */
    finishCountdownEnabled?: boolean;
    /** 车辆信息 */
    vehicleInfo?: {
        vehiclePictures?: string;
        vehicleCode?: string;
        vehicleColor?: string;
        plateNumber?: string;
    };
    orderId?: string;
    orderTrunkStatus?: boolean;
}
 
export default function CallingCar({
    tripStatus = 3,
    handleOpenCancelPopup,
    handleCancelTimeout,
    handleFinishTimeout,
    resetDetailVersion,
    priceUpdateVersion,
    evaluateSubmitVersion,
    evaluateCloseVersion,
    handleOpenOverRoutePopup,
    onToggleDetailFade,
    handlePay,
    handleOpenEvaluatePopup,
    handleOpenAnnouncementsPopup,
    estimatedWaitMinutes,
    routeDurationSeconds,
    finishCountdownEnabled = false,
    vehicleInfo,
    orderId,
    orderTrunkStatus,
}: Props) {
 
    // 汇总行程中的倒计时与费用数据
    const {
        waitMinutes,
        limitMinutes,
        pickupCountdownSeconds,
        finishCountdownSeconds,
        fareBreakdown
    } = useTripCountdown({
        tripStatus,
        orderId,
        estimatedWaitMinutes,
        finishCountdownEnabled,
        handleCancelTimeout,
        handleFinishTimeout,
        priceUpdateVersion
    });
 
    /** 预计到达时长展示(秒/分钟) */
    const durationDisplay = formatDurationDisplay(routeDurationSeconds);
    /** 车辆即将到达上车点(<=60秒) */
    const isArriveSoon = tripStatus === 4 && (typeof routeDurationSeconds === 'number' && routeDurationSeconds <= 60);
    /** 上车倒计时即将结束(<60秒) */
    const isPickupCountdownSoon = tripStatus === 5 && (typeof pickupCountdownSeconds === 'number' && pickupCountdownSeconds < 60);
 
    // 按状态组合渲染行程卡片模块
    return (
        <View className='calling-car'>
            <Image className="calling-car-bg" src='https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/site-top-bg.png' />
            
            <TripStatusHeader 
                tripStatus={tripStatus}
                waitMinutes={waitMinutes}
                durationDisplay={durationDisplay}
                isArriveSoon={isArriveSoon}
                isPickupCountdownSoon={isPickupCountdownSoon}
                pickupCountdownSeconds={pickupCountdownSeconds}
                finishCountdownEnabled={finishCountdownEnabled}
                finishCountdownSeconds={finishCountdownSeconds}
                limitMinutes={limitMinutes}
                handleOpenCancelPopup={handleOpenCancelPopup}
            />
 
            {
                [4, 5, 6, 8, 9].includes(tripStatus) &&
                <View className="car-card">
                    <VehicleInfoCard vehicleInfo={vehicleInfo} />
                    
                    <TemperatureControl tripStatus={tripStatus} orderId={orderId} />
                    
                    <DoorTrunkControl 
                        tripStatus={tripStatus} 
                        orderId={orderId} 
                        orderTrunkStatus={orderTrunkStatus}
                        handleOpenOverRoutePopup={handleOpenOverRoutePopup}
                        handleOpenAnnouncementsPopup={handleOpenAnnouncementsPopup}
                    />
                    
                    <FareDetailCard 
                        tripStatus={tripStatus} 
                        fareBreakdown={fareBreakdown} 
                        orderId={orderId}
                        resetDetailVersion={resetDetailVersion}
                        onToggleDetailFade={onToggleDetailFade}
                        handlePay={handlePay}
                    />
                </View>
            }
 
            <DoorTrunkControl 
                tripStatus={tripStatus === 7 ? 7 : -1} 
                orderId={orderId} 
                orderTrunkStatus={orderTrunkStatus}
                handleOpenOverRoutePopup={handleOpenOverRoutePopup}
                handleOpenAnnouncementsPopup={handleOpenAnnouncementsPopup}
            />
 
            <EvaluationCard 
                tripStatus={tripStatus} 
                orderId={orderId}
                handleOpenEvaluatePopup={handleOpenEvaluatePopup}
                evaluateSubmitVersion={evaluateSubmitVersion}
                evaluateCloseVersion={evaluateCloseVersion}
            />
        </View>
    );
}