| src/robotaxi/pages/begin-route/components/calling-car.tsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/pages/begin-route/components/css-folder/calling-car.less | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/pages/begin-route/hooks/use-view-delegates.tsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/robotaxi/pages/begin-route/components/calling-car.tsx
@@ -26,6 +26,8 @@ tripStatus?: TripStatus; /** 是否在本次挂载时播放"派单成功"转场(由父层捕捉首次进入派单成功(4)边沿传入,因本组件被 key 重挂载无法自判) */ playDispatchTransition?: boolean; /** 是否在本次挂载时播放"直达待评价"入场(由父层捕捉 送驾中(6)→待评价(9) 边沿传入,内部免费订单跳过待支付时使用) */ playEvaluateEnter?: boolean; /** 派单成功转场动效完成(或本次不播放转场)时回调,用于放行页面级蓝牙初始化 */ onDispatchTransitionSettled?: () => void; /** 打开取消弹窗,入参为预计到达展示文案 */ @@ -119,6 +121,7 @@ export default function CallingCar({ tripStatus = TripStatus.CallingCar, playDispatchTransition = false, playEvaluateEnter = false, onDispatchTransitionSettled, handleOpenCancelPopup, handleCancelTimeout, @@ -197,6 +200,12 @@ const isTripFinished = tripStatus === TripStatus.TripFinished; const isCallingCar = tripStatus === TripStatus.CallingCar; /** * 「直达待评价」入场快照:与 useDispatchTransition 里的 shouldPlayEnter 同理, * 父层的 playEvaluateEnter 在下一次渲染即翻 false,直接绑定会把动画类中途卸掉、动效被扼杀, * 故在挂载时快照一次,组件生命周期内不变(本组件由 key={tripStatus} 保证每次状态切换都重挂载)。 */ const [shouldPlayEvaluateEnter] = useState(playEvaluateEnter); /** * 车控(空调 / 音乐 / 香氛):卡片与弹窗分开挂载。 * 卡片放进横向滑动的 ScrollView;弹窗是 fixed 全屏浮层,必须挂在 ScrollView 之外, * 否则 iOS(WKWebView)下滚动容器会成为 fixed 的包含块,弹窗被限制在卡片滑动区内。 @@ -255,8 +264,8 @@ } return <Image className='calling-car-bg' src={CARD_BG_IMG} /> } // 根节点状态类:呼叫中覆盖 + 待支付态 + 明细展开态 + 派单转场阶段 + 整卡升起入场 const rootClassName = `calling-car${isCallingCar ? ' calling-status-car' : ''}${isTripFinished ? ' calling-car--finished' : ''}${isTripFinished && detailExpanded ? ' is-detail-expanded' : ''}${dispatchPhase !== 'idle' ? ` dispatch-${dispatchPhase}` : ''}${shouldPlayEnter ? ' calling-car--enter' : ''}${!contentReady ? ' dispatch-defer-content' : ''}`; // 根节点状态类:呼叫中覆盖 + 待支付态 + 明细展开态 + 派单转场阶段 + 整卡升起入场 + 直达待评价入场 const rootClassName = `calling-car${isCallingCar ? ' calling-status-car' : ''}${isTripFinished ? ' calling-car--finished' : ''}${isTripFinished && detailExpanded ? ' is-detail-expanded' : ''}${dispatchPhase !== 'idle' ? ` dispatch-${dispatchPhase}` : ''}${shouldPlayEnter ? ' calling-car--enter' : ''}${shouldPlayEvaluateEnter ? ' calling-car--evaluate-enter' : ''}${!contentReady ? ' dispatch-defer-content' : ''}`; // 按状态组合渲染行程卡片模块 return ( src/robotaxi/pages/begin-route/components/css-folder/calling-car.less
@@ -136,6 +136,53 @@ transform: translateY(0); } } // 「送驾中(6) 直达待评价(9)」整卡入场:内部免费订单跳过待支付(8),原本是无动效硬切。 // 卡片容器为底部锚定(.container position:fixed bottom:0),待评价态内容更高会瞬间向上顶, // 故从「相当于送驾态卡顶」的位置升起,用运动吃掉高度差;同时做轻微透明度渐变,柔化内容替换。 // // 起升距离 = 待评价态与送驾态的卡片高度差。 // 实测依据(同机型两态截图,designWidth 750 下 px 即设计稿单位):以两态共有的首个内容块 // VehicleInfoCard(“小鹏GX”行)到屏幕底部的距离比对,送驾态约 288px、待评价态约 659px, // 即待评价态多出约 370px(新增费用明细两行 + 评价卡,减去状态条 + 操作栏)。 // 用 LESS 变量而非 CSS 自定义属性:keyframes 内的 var() 在旧版 WKWebView 上存在不生效的风险, // LESS 变量在编译期就展开为字面量,按真机观感调这一处即可。 @evaluate-enter-rise: 380px; @keyframes calling-car-evaluate-rise { from { transform: translateY(@evaluate-enter-rise); opacity: 0.4; } to { transform: translateY(0); opacity: 1; } } // 待评价态新增内容(费用明细卡 / 评价卡)分层浮现:轻微上移淡入,手法对齐 finished-distance-fade。 @keyframes calling-car-evaluate-content-fade { from { transform: translateY(16px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } .calling-car--evaluate-enter { // 位移行程约 380px(大于派单入场的 170px),时长相应放到 0.7s,保持速度感与派单入场一致。 animation: calling-car-evaluate-rise 0.7s cubic-bezier(0.22, 0.61, 0.36, 1) both; will-change: transform; // 分层:整卡升起过半后,新增的费用明细卡与评价卡再依次浮现,进一步掩盖高度差。 .fare-box-card { animation: calling-car-evaluate-content-fade 600ms ease-out 420ms both; } .car-card-evaluate { animation: calling-car-evaluate-content-fade 600ms ease-out 560ms both; } } // 派单成功转场期间:蓝牙卡 / 车控卡 / 底部操作栏隐藏但保留占位(opacity),逻辑另在各组件延迟执行; // 动效完成后移除 .dispatch-defer-content,随 opacity 过渡淡入。用 opacity 而非 visibility,保证淡入过渡生效。 .calling-car { src/robotaxi/pages/begin-route/hooks/use-view-delegates.tsx
@@ -321,6 +321,15 @@ const playDispatchTransition = deps.tripStatus === TripStatus.VehicleApproaching && prevTripStatusRef.current !== TripStatus.VehicleApproaching; // 捕捉「送驾中(6) 直达待评价(9)」边沿:内部免费订单无需支付,行程结束后跳过待支付(8)直接进入待评价。 // 该路径原本没有任何入场动效,且待评价态内容比送驾态更高(多出费用明细卡与评价卡), // 底部锚定容器(.container position:fixed bottom:0)会瞬间向上顶,观感生硬。 // 与 playDispatchTransition 同理:CallingCar 被 key 重挂载无法自判边沿,由父层捕捉后传入, // 组件内做挂载快照,再用挂载即播的 keyframes 实现整卡升起 + 内容分层浮现。 // 限定上一态为 InService:不影响支付后 8→9 的既有表现;冷启动恢复时 prev 为 undefined 也不会误播。 const playEvaluateEnter = deps.tripStatus === TripStatus.PaymentSuccess && prevTripStatusRef.current === TripStatus.InService; useEffect(() => { prevTripStatusRef.current = deps.tripStatus; }, [deps.tripStatus]); @@ -1035,6 +1044,7 @@ <CallingCar key={deps.tripStatus} playDispatchTransition={playDispatchTransition} playEvaluateEnter={playEvaluateEnter} onDispatchTransitionSettled={deps.onDispatchTransitionSettled} orderId={deps.orderId} hasBeforeUserEndSite={deps.hasBeforeUserEndSite}