| src/robotaxi/pages/begin-route/components/modify-destination-fail-popup.tsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/pages/begin-route/hooks/use-modify-destination-flow.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/pages/begin-route/index.tsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/robotaxi/pages/begin-route/components/modify-destination-fail-popup.tsx
New file @@ -0,0 +1,69 @@ import Taro from '@tarojs/taro'; import { View, Image } from '@tarojs/components'; import { useEffect, useState } from 'react'; import './css-folder/over-route.less'; type Props = { show?: boolean; content?: string; onClose?: () => void; onConfirm?: () => void; }; export default function ModifyDestinationFailPopup({ show = false, content = '', onClose, onConfirm }: Props) { const [visible, setVisible] = useState(false); const [animationData, setAnimationData] = useState<any>(); // 确认“我知道了” const handleConfirm = () => { onConfirm?.(); }; // 控制弹窗关闭动画 useEffect(() => { if (!show && visible) { const animation = Taro.createAnimation({ duration: 300, timingFunction: 'ease-in' }); animation.opacity(0).scale(0.8).step(); setAnimationData(animation.export()); setTimeout(() => { setVisible(false); }, 300); } }, [show, visible]); // 控制弹窗打开动画 useEffect(() => { if (!show) { return; } setVisible(true); const animation = Taro.createAnimation({ duration: 300, timingFunction: 'ease-out' }); animation.opacity(1).scale(1).step(); setAnimationData(animation.export()); }, [show]); if (!visible) return null; return ( <View className='over-popup' catchMove> <View className='over-mask' onClick={onClose}></View> <View className='over-content' animation={animationData}> <Image onClick={onClose} className='close-icon' src={require('../../../assets/close-icon.png')} /> <View className='over-title'>修改目的地失败</View> {content ? <View className='over-txt'>{content}</View> : null} <View onClick={handleConfirm} className='reselect-btn'>我知道了</View> </View> </View> ); } src/robotaxi/pages/begin-route/hooks/use-modify-destination-flow.ts
@@ -163,6 +163,16 @@ Taro.removeStorageSync(MODIFY_DESTINATION_OVERRIDE_KEY); }; // 退出修改目的地确认态并清理本地会话缓存 const exitModifyDestinationReview = () => { setPreviewEndSite(null); setPreviousEndSite(null); setPreviousFareEstimate(null); setPreviousRoutePoints([]); clearModifyDestinationSession(); clearLocalDestinationOverride(); }; const handleConfirmModifyDestination = async (selectedRoute?: any) => { if (!isValidSite(previewEndSite)) return; if (isConfirmingModifyDestination) return; @@ -194,12 +204,7 @@ Taro.setStorageSync('endSite', newEndSite); deps.setEndSite(newEndSite); setPreviewEndSite(null); setPreviousEndSite(null); setPreviousFareEstimate(null); setPreviousRoutePoints([]); clearModifyDestinationSession(); clearLocalDestinationOverride(); exitModifyDestinationReview(); Taro.hideLoading(); Taro.showToast({ @@ -212,10 +217,7 @@ } } catch (e: any) { Taro.hideLoading(); Taro.showToast({ title: '修改目的地失败', icon: 'none' }); throw e; } finally { setIsConfirmingModifyDestination(false); } @@ -241,6 +243,7 @@ isModifyDestinationReviewVisible, hasLocalDestinationOverride, clearLocalDestinationOverride, exitModifyDestinationReview, handleStartModifyDestination, handleConfirmModifyDestination }; src/robotaxi/pages/begin-route/index.tsx
@@ -4,6 +4,8 @@ import './index.less'; import BeginRouteView from './components/begin-route-view'; // 修改目的地失败弹窗 import ModifyDestinationFailPopup from './components/modify-destination-fail-popup'; import CouponSelectPopup from '../../components/coupon-select-popup'; // 弹窗状态管理 import usePopupManager from './hooks/use-popup-manager'; @@ -135,6 +137,8 @@ const [evaluateSubmitVersion, setEvaluateSubmitVersion] = useState(0); // 评价提交版本号 const [evaluateCloseVersion, setEvaluateCloseVersion] = useState(0); // 评价关闭版本号 const [showCouponSelectPopup, setShowCouponSelectPopup] = useState(false); // 优惠券选择弹窗展示状态 const [showModifyDestinationFailPopup, setShowModifyDestinationFailPopup] = useState(false); // 修改目的地失败弹窗 const [modifyDestinationFailMessage, setModifyDestinationFailMessage] = useState(''); // 修改目的地失败文案(默认空,避免闪文案) const [orderRouteMetrics, setOrderRouteMetrics] = useState<OrderRouteMetrics>({ distanceMeters: null, durationSeconds: null, @@ -213,6 +217,7 @@ isModifyDestinationReviewVisible, hasLocalDestinationOverride, clearLocalDestinationOverride, exitModifyDestinationReview, handleStartModifyDestination, handleConfirmModifyDestination } = useModifyDestinationFlow({ @@ -830,6 +835,47 @@ isCheckedEnter.current = true; handleStartModifyDestination(fareEstimate, routePoints); }; // 打开修改目的地失败弹窗,先写入文案再展示,避免文案闪烁 const openModifyDestinationFailPopup = (message: string) => { setModifyDestinationFailMessage(message || ''); setShowModifyDestinationFailPopup(true); }; // 失败弹窗确认后退出修改目的地确认态,并清理缓存会话 const handleAcknowledgeModifyDestinationFail = () => { setShowModifyDestinationFailPopup(false); setModifyDestinationFailMessage(''); exitModifyDestinationReview(); }; // 关闭失败弹窗与确认按钮行为一致,统一走清理逻辑 const handleCloseModifyDestinationFailPopup = () => { handleAcknowledgeModifyDestinationFail(); }; // 确认修改前进行阈值校验,命中限制或接口失败都展示失败弹窗 const handleConfirmModifyDestinationWithGuard = async (selectedRoute?: any) => { const currentDistance = Number(orderRouteMetrics?.distanceMeters); const currentDurationSeconds = Number(orderRouteMetrics?.durationSeconds); const distanceLimit = Number(distanceConfig?.xczSyDistance); const durationLimitMinutes = Number(distanceConfig?.xczSyTime); const hitDistanceLimit = Number.isFinite(distanceLimit) && distanceLimit > 0 && Number.isFinite(currentDistance) && currentDistance < distanceLimit; const hitDurationLimit = Number.isFinite(durationLimitMinutes) && durationLimitMinutes > 0 && Number.isFinite(currentDurationSeconds) && (currentDurationSeconds / 60) < durationLimitMinutes; if (hitDistanceLimit || hitDurationLimit) { openModifyDestinationFailPopup('即将到达终点,已无法修改目的地'); return; } try { await handleConfirmModifyDestination(selectedRoute); } catch (error) { openModifyDestinationFailPopup('修改目的地失败,请返回重试'); } }; const handleShareTrip = () => { isCheckedEnter.current = true; }; @@ -955,7 +1001,7 @@ previousEndSite, previousFareEstimate, previewEndSite, handleConfirmModifyDestination, handleConfirmModifyDestination: handleConfirmModifyDestinationWithGuard, bluetoothStatusReady, bluetoothCardDescription, bluetoothCardActionText, @@ -1072,6 +1118,12 @@ onClose={handleCloseCouponSelect} onSelect={handleSelectCoupon} /> <ModifyDestinationFailPopup show={showModifyDestinationFailPopup} content={modifyDestinationFailMessage} onClose={handleCloseModifyDestinationFailPopup} onConfirm={handleAcknowledgeModifyDestinationFail} /> </> ) }