feat(robotaxi): 增加路线过期校验并优化蓝牙解锁提示
- 新增 `routeStaleCheck` API 用于下单前校验路线是否过期,若过期则刷新路线并提示用户
- 优化蓝牙车门解锁流程,统一鉴权失败和解锁失败的提示文案,并增加解锁成功提示
- 调整取消叫车弹窗的等待时间文案表述
| | |
| | | }, true); |
| | | } |
| | | |
| | | // 导航-下单前校验路况是否过期 |
| | | export const routeStaleCheck = async () => { |
| | | return request({ |
| | | url: _ROBOTAXI_HOST + '/itinerary/base/v1/mini-program/navigation/route-stale-check', |
| | | method: 'POST' |
| | | }, true); |
| | | } |
| | | |
| | | // 保存订单 |
| | | export const saveOrder = async (payload) => { |
| | | return request({ |
| | |
| | | // 不同取消阶段对应的文案配置 |
| | | const STATUS_MAP = { |
| | | 1: { |
| | | title: `预计${waitMinutesValue}分钟内有车,确定取消吗?`, |
| | | title: `${waitMinutesValue}分钟内预计有车,确定取消吗?`, |
| | | tip: discountAmountValue > 0 ? `本单限时优惠${discountAmountValue}元,重新叫车可能等待更久` : '', |
| | | }, |
| | | 2: { |
| | |
| | | }; |
| | | |
| | | type ConnectStatus = 0 | 1 | 2 | 3; |
| | | const RETRY_UNLOCK_MESSAGE = '请点击解锁按钮解锁车门'; // 鉴权失败/解锁失败统一提示文案 |
| | | const UNLOCK_SUCCESS_MESSAGE = '车门已解锁,请上车'; // 解锁成功提示文案 |
| | | |
| | | /** |
| | | * 解析车辆信息中的蓝牙 MAC。 |
| | |
| | | const [authSuccess, setAuthSuccess] = useState(false); // RtAuth 鉴权是否成功 |
| | | const [isAuthorizing, setIsAuthorizing] = useState(false); // 鉴权流程进行中 |
| | | const [authError, setAuthError] = useState<string>(''); // 鉴权流程错误信息 |
| | | const showUnlockToast = useCallback((title: string) => { |
| | | Taro.showToast({ |
| | | title, |
| | | icon: 'none' |
| | | }); |
| | | }, []); // 统一展示蓝牙解锁结果提示 |
| | | |
| | | const bluetoothMac = useMemo(() => resolveBluetoothMac(vehicleInfo), [vehicleInfo]); // 车辆蓝牙 MAC |
| | | |
| | |
| | | setAuthError(''); |
| | | setConnectStatus(3); |
| | | } else { |
| | | const message = result?.data?.errorDesc || result?.error || '蓝牙鉴权失败'; |
| | | setAuthSuccess(false); |
| | | setAuthError(String(message)); |
| | | setAuthError(RETRY_UNLOCK_MESSAGE); |
| | | showUnlockToast(RETRY_UNLOCK_MESSAGE); |
| | | } |
| | | setIsAuthorizing(false); |
| | | }, |
| | | onRtNotification: (result: any) => { |
| | | console.log('[蓝牙] 解锁通知:', result); |
| | | if (result?.type === 'pollingUnlock') { |
| | | if (result?.success) { |
| | | setAuthError(''); |
| | | showUnlockToast(UNLOCK_SUCCESS_MESSAGE); |
| | | } else { |
| | | setAuthError(RETRY_UNLOCK_MESSAGE); |
| | | showUnlockToast(RETRY_UNLOCK_MESSAGE); |
| | | } |
| | | return; |
| | | } |
| | | if (result?.type === 'error') { |
| | | setAuthError(RETRY_UNLOCK_MESSAGE); |
| | | showUnlockToast(RETRY_UNLOCK_MESSAGE); |
| | | } |
| | | } |
| | | }); |
| | | return managerRef.current; |
| | | }, []); |
| | | }, [showUnlockToast]); |
| | | |
| | | /** |
| | | * 主动断开蓝牙连接并重置状态。 |
| | |
| | | import Taro from '@tarojs/taro'; |
| | | import { formatDateTime, clearOrderTripStorage, debounce, reportEvent } from '../../../../utils/Robotaxi-public-method'; |
| | | import { saveOrder, getOrderPayment, cancelOrder, endOrder } from '../../../api/begin-route'; |
| | | import { saveOrder, getOrderPayment, cancelOrder, endOrder, routeStaleCheck } from '../../../api/begin-route'; |
| | | import { checkOtp } from '../../../../utils/tools'; |
| | | import { jumpTo } from '../../../../utils/jump'; |
| | | import { TripStatus } from '../constants/trip-status'; |
| | |
| | | * 订单动作编排:下单、取消、结束、支付。 |
| | | */ |
| | | export default function useOrderActions(deps: Deps) { |
| | | const ROUTE_STALE_NOTICE_TEXT = '路况已变,价格已更新'; // 路况变化提示文案 |
| | | |
| | | /** |
| | | * 结束下单中状态。 |
| | | */ |
| | |
| | | }; |
| | | |
| | | /** |
| | | * 下单前校验路线是否过期,命中过期时刷新路线并终止本次下单。 |
| | | */ |
| | | const checkRouteStaleBeforeOrder = async (startSite: any) => { |
| | | try { |
| | | const staleCheckRes: any = await routeStaleCheck(); |
| | | const needRefreshNotice = staleCheckRes?.needRefreshNotice === true; // 服务端是否要求刷新路线 |
| | | if (!needRefreshNotice) { |
| | | return true; |
| | | } |
| | | Taro.showToast({ title: ROUTE_STALE_NOTICE_TEXT, icon: 'none' }); |
| | | deps.routeRequestRouteAndFare( |
| | | Number(startSite?.latitude), |
| | | Number(startSite?.longitude), |
| | | Number(deps.endSite?.latitude), |
| | | Number(deps.endSite?.longitude), |
| | | true |
| | | ); |
| | | stopCallSubmitting(); |
| | | return false; |
| | | } catch (error) { |
| | | Taro.showToast({ title: '路线校验失败,请重试', icon: 'none' }); |
| | | stopCallSubmitting(); |
| | | return false; |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * 呼叫车辆。 |
| | | */ |
| | | const callImmediately = debounce(async () => { |
| | |
| | | if (!s) return; |
| | | const openCityId = await deps.checkDistanceAndCityReady(s); |
| | | if (!openCityId) return; |
| | | const routeStalePassed = await checkRouteStaleBeforeOrder(s); |
| | | if (!routeStalePassed) return; |
| | | try { |
| | | const nextOrderId = await submitOrder(s, openCityId); |
| | | if (!nextOrderId) { |