import Taro, { useDidShow, useRouter } from '@tarojs/taro';
|
import { useEffect, useMemo, useState } from 'react';
|
import './index.less';
|
import useMapMarkers from './hooks/use-map-markers';
|
import useVehicleTracking from './hooks/use-vehicle-tracking';
|
import useRouteManager from './hooks/use-route-manager';
|
import useMapViewport from './hooks/use-map-viewport';
|
import useViewDelegates from './hooks/use-view-delegates';
|
import useShareTripRuntime from './hooks/use-share-trip-runtime';
|
import ShareTripView from './components/share-trip-view';
|
import { TripStatus } from '../../constants/trip-status';
|
import { isWhiteList } from '../../api/home';
|
import { subscribeShareTripByTap } from '../../../utils/subscribe';
|
import { checkOtp } from '../../../utils/tools';
|
import { jumpToHome } from '../../../utils/jump';
|
import { safeMakePhoneCall } from '../../../utils/Robotaxi-public-method';
|
import { withRobotaxiWhitelist } from '../../../utils/whitelist';
|
|
type StatusRule = {
|
showPickup: boolean;
|
showDropoff: boolean;
|
showCar: boolean;
|
showRoute: boolean;
|
showWalking: boolean;
|
viewport: string;
|
translateCar: boolean;
|
};
|
|
function ShareTrip() {
|
const router = useRouter();
|
const { orderId = '' } = router.params || {}; // 分享订单 ID
|
const [tripData, setTripData] = useState<any>(null); // 行程详情数据
|
const [longitude, setLongitude] = useState(113.32452); // 地图中心经度
|
const [latitude, setLatitude] = useState(23.10229); // 地图中心纬度
|
const [startSite, setStartSite] = useState<any>(null); // 上车点
|
const [endSite, setEndSite] = useState<any>({}); // 下车点
|
const [isExpired, setIsExpired] = useState(false); // 是否超 24h 过期
|
const [showReminder, setShowReminder] = useState(true); // 是否展示提醒
|
const [tripStatus, setTripStatus] = useState<TripStatus>(TripStatus.PublishRoute); // 当前行程状态
|
const [authReady, setAuthReady] = useState(false); // 登录校验通过后才允许加载分享页
|
const [isRobotaxiWhiteList, setIsRobotaxiWhiteList] = useState(false); // 用户是否命中 Robotaxi 白名单
|
|
useDidShow(() => {
|
// 分享页需要先登录,登录成功后小程序会返回当前页并再次触发校验
|
void checkOtp(true).then((otp) => {
|
const hasLogin = Boolean(otp);
|
setAuthReady(hasLogin);
|
if (!hasLogin) {
|
setIsRobotaxiWhiteList(false);
|
return;
|
}
|
// 登录成功后校验白名单,控制左上角 home 返回落点
|
void isWhiteList()
|
.then((res: boolean) => {
|
setIsRobotaxiWhiteList(res);
|
})
|
.catch(() => {
|
setIsRobotaxiWhiteList(false);
|
});
|
});
|
});
|
|
const STATUS_RULES: Record<TripStatus, StatusRule> = {
|
[TripStatus.PublishRoute]: { showPickup: true, showDropoff: true, showCar: false, showRoute: true, showWalking: true, viewport: 'route_walking', translateCar: false },
|
[TripStatus.Publishing]: { showPickup: true, showDropoff: false, showCar: false, showRoute: false, showWalking: false, viewport: 'pickup', translateCar: false },
|
[TripStatus.CallingCar]: { showPickup: true, showDropoff: false, showCar: false, showRoute: false, showWalking: false, viewport: 'pickup', translateCar: false },
|
[TripStatus.VehicleApproaching]: { showPickup: true, showDropoff: false, showCar: true, showRoute: true, showWalking: false, viewport: 'route', translateCar: true },
|
[TripStatus.VehicleArrivedPickup]: { showPickup: true, showDropoff: false, showCar: true, showRoute: false, showWalking: false, viewport: 'car_user', translateCar: true },
|
[TripStatus.InService]: { showPickup: false, showDropoff: true, showCar: true, showRoute: true, showWalking: false, viewport: 'route', translateCar: true },
|
[TripStatus.ArrivedDestination]: { showPickup: false, showDropoff: true, showCar: false, showRoute: true, showWalking: false, viewport: 'order_detail', translateCar: false },
|
[TripStatus.TripFinished]: { showPickup: true, showDropoff: true, showCar: false, showRoute: true, showWalking: false, viewport: 'order_detail', translateCar: false },
|
[TripStatus.PaymentSuccess]: { showPickup: true, showDropoff: true, showCar: false, showRoute: true, showWalking: false, viewport: 'order_detail', translateCar: false },
|
[TripStatus.CancelOnlyPickup]: { showPickup: true, showDropoff: false, showCar: false, showRoute: false, showWalking: false, viewport: 'pickup', translateCar: false },
|
}; // 行程状态显示规则
|
|
const statusRule = useMemo(
|
() => STATUS_RULES[tripStatus] || STATUS_RULES[TripStatus.PublishRoute],
|
[tripStatus],
|
); // 当前状态渲染规则
|
const shouldShowRoute = statusRule.showRoute; // 是否展示主路线
|
|
const isAndroid = useMemo(() => {
|
try {
|
const info = Taro.getSystemInfoSync();
|
return info?.platform === 'android' || /android/i.test(info?.system || '');
|
} catch (error) {
|
return false;
|
}
|
}, []); // 平台标记
|
|
const mapLongitude = longitude ?? 116.397128; // 地图兜底经度
|
const mapLatitude = latitude ?? 39.916527; // 地图兜底纬度
|
const vehicleMarkerId = !isAndroid && tripStatus === TripStatus.InService ? 30 : 3; // 车辆 marker ID
|
|
const { vehicleLocation, vehicleDirection, setVehicleDirection, updateVehicleLocationThrottled } = useVehicleTracking({
|
statusRule,
|
vehicleMarkerId,
|
}); // 车辆追踪状态容器
|
|
const { markers } = useMapMarkers({
|
tripStatus,
|
statusRule,
|
isAndroid,
|
startSite,
|
endSite,
|
vehicleLocation,
|
vehicleDirection,
|
vehicleMarkerId,
|
}); // 地图 marker 状态容器
|
|
const {
|
polyline,
|
applyRoutePoints,
|
routePoints,
|
walkingPoints,
|
routeDistance,
|
routeDuration,
|
setRouteDistance,
|
setRouteDuration,
|
} = useRouteManager({
|
isAndroid,
|
tripStatus,
|
statusRule,
|
shouldShowRoute,
|
}); // 路线状态容器
|
const displayRouteDuration = useMemo(() => {
|
if (routeDuration === null) {
|
return null;
|
}
|
const normalizedDuration = Number(routeDuration);
|
if (!Number.isFinite(normalizedDuration)) {
|
return null;
|
}
|
// 分享行程统一按分钟展示,不展示秒数;不足 1 分钟时按 1 分钟兜底。
|
return Math.max(60, normalizedDuration);
|
}, [routeDuration]);
|
|
const { mapScale, updateMapViewportPadding } = useMapViewport({
|
tripStatus,
|
statusRule,
|
routePoints,
|
walkingPoints,
|
startSite,
|
endSite,
|
vehicleLocation,
|
longitude,
|
latitude,
|
setLongitude,
|
setLatitude,
|
}); // 视口状态容器
|
|
useShareTripRuntime({
|
authReady,
|
orderId,
|
tripStatus,
|
startSite,
|
endSite,
|
setTripStatus,
|
setTripData,
|
setStartSite,
|
setEndSite,
|
setIsExpired,
|
setShowReminder,
|
setLongitude,
|
setLatitude,
|
setRouteDistance,
|
setRouteDuration,
|
applyRoutePoints,
|
updateVehicleLocationThrottled,
|
setVehicleDirection,
|
}); // 分享页业务流程编排
|
|
useEffect(() => {
|
const timer = setTimeout(() => {
|
updateMapViewportPadding();
|
}, 80);
|
return () => clearTimeout(timer);
|
}, [tripStatus, showReminder, tripData?.startPointName, tripData?.endPointName, tripData?.plateNumber, updateMapViewportPadding]); // UI 数据变化后二次修正留白
|
|
const { renderMapOverlays } = useViewDelegates({
|
isAndroid,
|
tripStatus,
|
mapScale,
|
markers,
|
shouldShowWaitingRadar: false,
|
waitingRadarVisible: false,
|
waitingRadarStyle: {},
|
waitingRadarSrc: '',
|
carCalloutVisible: false,
|
carCalloutStyle: {},
|
arriveCalloutVisible: false,
|
arriveCalloutStyle: {},
|
routeDistance,
|
routeDuration: displayRouteDuration,
|
customCalloutIconSrc: 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/maker-tooltip-right.png',
|
}); // 地图浮层视图委托
|
|
const goHome = () => {
|
if (isRobotaxiWhiteList) {
|
Taro.reLaunch({ url: '/pages/robotaxi/home/index' });
|
return;
|
}
|
// 非白名单用户先回到小鹏汽车首页,页面内容后续再补充
|
// jumpToHome();
|
Taro.switchTab({
|
url: '/pages/home/index',
|
});
|
}; // 返回首页
|
|
const handleContactService = () => {
|
safeMakePhoneCall();
|
}; // 联系客服动作
|
|
const handleEnableReminder = async () => {
|
// 用户主动点击时直接拉起订阅,避免被本地频控缓存拦截
|
await subscribeShareTripByTap(orderId);
|
setShowReminder(false);
|
}; // 开启提醒订阅
|
|
if (!authReady) {
|
return null;
|
}
|
|
return (
|
<ShareTripView
|
isExpired={isExpired}
|
showReminder={showReminder}
|
handleEnableReminder={handleEnableReminder}
|
tripData={tripData}
|
mapLongitude={mapLongitude}
|
mapLatitude={mapLatitude}
|
mapScale={mapScale}
|
markers={markers}
|
polyline={polyline}
|
routeDuration={displayRouteDuration}
|
renderMapOverlays={renderMapOverlays}
|
goHome={goHome}
|
handleContactService={handleContactService}
|
/>
|
);
|
}
|
|
export default withRobotaxiWhitelist(ShareTrip);
|