import Taro from '@tarojs/taro';
|
import { useState, useEffect, useRef } from 'react';
|
import { View, Text, Image, Input } from '@tarojs/components';
|
import './index.less';
|
import { reportEvent, toUnixSeconds } from '../../../utils/Robotaxi-public-method';
|
import { getOrderDistance } from '../../api/select-map-site';
|
import {
|
ensureOrderDistanceConfig,
|
isWithinPickupMaxDistance,
|
isWithinStartEndMinDistance,
|
normalizeOrderDistanceConfig
|
} from '../../utils/order-distance';
|
import { checkOtp } from '../../../utils/tools';
|
import TipPopup from '../../components/tip-popup';
|
import SiteListItem from './components/site-list-item';
|
import FavoritePopup from './components/favorite-popup';
|
import useSiteSearch from './hooks/use-site-search';
|
import usePostLoginResume from './hooks/use-post-login-resume';
|
import {
|
sortSitesByCollectedFirst,
|
sortSitesByNameMatchAndDistance,
|
splitHighlightParts,
|
filterNearbyListByCurrentSite,
|
filterRecommendedDropoffSitesByMinDistance
|
} from './utils/site-search';
|
import {
|
MODIFY_DESTINATION_CANDIDATE_KEY,
|
MODIFY_DESTINATION_PENDING_SAME_SITE_TOAST_KEY,
|
MODIFY_DESTINATION_SKIP_AC_QUERY_ON_RETURN_KEY,
|
MODIFY_DESTINATION_SESSION_KEY,
|
isSameModifyDestinationSite
|
} from '../../constants/modify-destination';
|
import {
|
RECOMMENDED_DROPOFF_STATION_ITEM_EVENT_ID,
|
SEARCH_DROPOFF_RESULT_ITEM_EVENT_ID,
|
SEARCH_PICKUP_RESULT_ITEM_EVENT_ID,
|
SELECT_DROPOFF_LOCATION_PAGE_VIEW_EVENT_ID,
|
SELECT_PICKUP_LOCATION_PAGE_VIEW_EVENT_ID,
|
SELECT_DROPOFF_LOCATION_HISTORY_DROPOFF_ITEM_EVENT_ID,
|
SELECT_DROPOFF_LOCATION_MAP_SELECT_BUTTON_EVENT_ID,
|
SELECT_PICKUP_LOCATION_HISTORY_PICKUP_ITEM_EVENT_ID,
|
SELECT_PICKUP_LOCATION_PIN_PICKUP_LOCATION_BUTTON_EVENT_ID
|
} from '../../constants/report-events';
|
import {
|
createIndexedStationSelectionPayload,
|
createReportStationPayload,
|
createReportUserCurrentLocationPayload
|
} from '../../constants/report-structures';
|
import {
|
HOME_START_SITE_SOURCE_MANUAL_SELECTED,
|
writeHomeStartSiteDisplayState
|
} from '../../hooks/use-home-start-site-display';
|
import {
|
ORDER_DISTANCE_TIP_TYPE_MAX_DISTANCE,
|
ORDER_DISTANCE_TIP_TYPE_MIN_DISTANCE
|
} from '../../constants/order-distance';
|
import {
|
HISTORY_CONFIRM_RIDE_SOURCE_TYPE,
|
RECOMMENDED_CONFIRM_RIDE_SOURCE_TYPE,
|
SEARCH_CONFIRM_RIDE_SOURCE_TYPE,
|
UNKNOWN_CONFIRM_RIDE_SOURCE_TYPE,
|
completeConfirmRideSelectionSession,
|
writeConfirmRideSiteSourceType
|
} from '../../constants/confirm-ride-report';
|
import { hasActiveTripOrderInStorage } from '../../utils/order';
|
import { withRobotaxiWhitelist } from '../../../utils/whitelist';
|
import { showToast } from '../../components/toast';
|
import { withToast } from '../../components/toast/with-toast';
|
import { TripStatus } from '../../constants/trip-status';
|
|
function SiteSearchPage() {
|
const [searchValue, setSearchValue] = useState('') //搜索值
|
// 输入框重置 key:仅在清空/编程式重置时自增以重挂载输入框,
|
// 输入框采用非受控模式(不回填 value),避免 iOS 下 re-render 回填打断输入法导致丢字/输入不进去
|
const [inputResetKey, setInputResetKey] = useState(0)
|
const [showAllHistory, setShowAllHistory] = useState(false) // 是否展示全部历史记录
|
const [showAllRecommend, setShowAllRecommend] = useState(false) // 是否展示全部推荐站点
|
const [distanceConfig, setDistanceConfig] = useState<any>({})
|
const [showTipPopup, setShowTipPopup] = useState(false)
|
const [tipType, setTipType] = useState('')
|
const [showFavoritePopup, setShowFavoritePopup] = useState(false)
|
const hasReportedPickupPageView = useRef(false) // 上车点页页面浏览埋点是否已上报
|
const hasReportedDropoffPageView = useRef(false) // 下车点页页面浏览埋点是否已上报
|
|
const MAX_SHOW_COUNT = 5 // 默认最多显示5条
|
const MAX_EXPANDED_COUNT = 10
|
const MAX_SHOW_HISTORY = 3 // 默认历史记录最多3条
|
const RECOMMEND_SHOW_COUNT = 15 // 推荐站点默认展示数量
|
|
const router = Taro.useRouter();
|
|
const {
|
pageType,
|
siteList,
|
historySite,
|
nonOperationalSite,
|
nearbySiteList,
|
isSearching,
|
lastCompletedKeyword,
|
isInitLoaded,
|
searchSite,
|
debouncedSearch,
|
clearSearchResults,
|
refreshData,
|
cancelDebouncedSearch,
|
flushDebouncedSearch,
|
confirmSearch,
|
} = useSiteSearch({
|
router,
|
searchValue,
|
maxExpandedCount: MAX_EXPANDED_COUNT,
|
maxShowCount: MAX_SHOW_COUNT
|
});
|
|
useEffect(() => {
|
getOrderDistance().then((res: any) => {
|
if (res) {
|
setDistanceConfig(normalizeOrderDistanceConfig(res));
|
}
|
}).catch(() => { });
|
}, []);
|
|
/**
|
* 确保搜索页距离配置可用,避免快速确认时漏掉校验。
|
*/
|
const ensureDistanceConfigReady = async () => ensureOrderDistanceConfig({
|
currentConfig: distanceConfig,
|
fetchConfig: getOrderDistance,
|
onConfigResolved: setDistanceConfig
|
});
|
|
// 处理终点选择后的业务校验与跳转
|
const handleEndSiteSelection = async (
|
item: any,
|
sourceType = UNKNOWN_CONFIRM_RIDE_SOURCE_TYPE
|
) => {
|
// 检查是否有行程订单
|
const modifySession = Taro.getStorageSync(MODIFY_DESTINATION_SESSION_KEY);
|
const hasActiveTrip = hasActiveTripOrderInStorage();
|
// 增加 hasActiveTrip 联合判断,防止上一单异常终止导致 modifySession 缓存残留,污染新下单流程
|
const isModifyDestinationActive = modifySession?.active && hasActiveTrip;
|
|
if (!isModifyDestinationActive && hasActiveTrip) {
|
Taro.reLaunch({
|
url: '/robotaxi/pages/begin-route/index?skipPageFlag=1',
|
});
|
return;
|
}
|
// 检查起终点是否在同一运营区域
|
const resolvedDistanceConfig = await ensureDistanceConfigReady();
|
const startSiteCache = Taro.getStorageSync('startSite');
|
if (startSiteCache?.electronicAreaId && item?.electronicAreaId && startSiteCache.electronicAreaId !== item.electronicAreaId) {
|
showToast({
|
title: '起终点需在同一运营区域',
|
icon: 'none',
|
})
|
return
|
}
|
try {
|
if (!isWithinStartEndMinDistance({
|
startSite: startSiteCache,
|
endSite: item,
|
minDistance: resolvedDistanceConfig?.minDistance
|
})) {
|
setTipType(ORDER_DISTANCE_TIP_TYPE_MIN_DISTANCE);
|
setShowTipPopup(true);
|
return;
|
}
|
} catch { }
|
// 【修改目的地拦截补充】
|
// 正常下单流程在上方已由 isWithinStartEndMinDistance 处理。
|
// 但在“接驾中修改目的地”时,如果后台距离配置(minDistance)未下发或为 0,底层判断会被放行。
|
// 为了防止用户在接驾阶段将目的地改得和原上车点一样(或物理距离极近),此处增加针对 modifySession 活跃状态下的强校验:
|
// 1. isSameSite:坐标、ID或名称一致视为同一站点。
|
// 2. isTooClose:物理直线距离小于后台配置的 minDistance(如有)。
|
// 命中任一条件,即阻断并提示“建议步行前往”。
|
if (isModifyDestinationActive) {
|
const isPickupTripStatus = [TripStatus.VehicleApproaching, TripStatus.VehicleArrivedPickup].includes(modifySession.tripStatus);
|
if (isPickupTripStatus) {
|
const isSameSite = isSameModifyDestinationSite(startSiteCache, item);
|
const isTooClose = !isWithinStartEndMinDistance({
|
startSite: startSiteCache,
|
endSite: item,
|
minDistance: resolvedDistanceConfig?.minDistance
|
});
|
|
if (isSameSite || isTooClose) {
|
setTipType(ORDER_DISTANCE_TIP_TYPE_MIN_DISTANCE);
|
setShowTipPopup(true);
|
return;
|
}
|
}
|
}
|
// 检查是否与上一个选择的终点相同
|
if (isModifyDestinationActive && isSameModifyDestinationSite(modifySession?.previousEndSite, item)) {
|
Taro.setStorageSync(MODIFY_DESTINATION_PENDING_SAME_SITE_TOAST_KEY, 1);
|
}
|
if (isModifyDestinationActive) {
|
Taro.setStorageSync(MODIFY_DESTINATION_CANDIDATE_KEY, item);
|
Taro.setStorageSync(MODIFY_DESTINATION_SKIP_AC_QUERY_ON_RETURN_KEY, 1); // 修改目的地返回行程页时跳过一次空调/温度状态查询
|
} else {
|
Taro.setStorageSync('endSite', item)
|
}
|
writeConfirmRideSiteSourceType('end', sourceType);
|
completeConfirmRideSelectionSession(startSiteCache, item);
|
const returnToBeginRouteUrl = isModifyDestinationActive
|
? '/robotaxi/pages/begin-route/index?skipPageFlag=1&fromModifyDestination=1'
|
: (Taro.getStorageSync('orderId') ? '/robotaxi/pages/begin-route/index?skipPageFlag=1' : '/robotaxi/pages/begin-route/index');
|
Taro.reLaunch({
|
url: returnToBeginRouteUrl,
|
})
|
}
|
|
const { setPostLoginPendingAction } = usePostLoginResume({
|
pageType,
|
handleEndSiteSelection
|
});
|
|
const changeSearchValue = (e: any) => {
|
const val = e.detail.value;
|
setSearchValue(val);
|
debouncedSearch(val);
|
return val;
|
}
|
|
// 切换历史记录展示状态
|
const toggleHistoryShow = () => {
|
setShowAllHistory(!showAllHistory)
|
}
|
|
// 切换推荐站点展示状态
|
const toggleRecommendShow = () => {
|
setShowAllRecommend(!showAllRecommend)
|
}
|
|
/**
|
* 构造地图选点埋点中的用户当前位置字段。
|
*/
|
const createUserCurrentLocationPayload = async () => {
|
const selectedCity = Taro.getStorageSync('selectedCity');
|
try {
|
const location = await Taro.getLocation({ type: 'gcj02' });
|
return createReportUserCurrentLocationPayload({
|
latitude: location?.latitude || router.params?.latitude || 0,
|
longitude: location?.longitude || router.params?.longitude || 0
|
}, String(selectedCity?.name || ''));
|
} catch (error) {
|
return createReportUserCurrentLocationPayload({
|
latitude: router.params?.latitude || 0,
|
longitude: router.params?.longitude || 0
|
}, String(selectedCity?.name || ''));
|
}
|
};
|
|
/**
|
* 点击地图选点时上报埋点。
|
*/
|
const reportSelectPickupLocationEvent = async () => {
|
if (pageType !== 'start' && pageType !== 'end') {
|
return;
|
}
|
const userCurrentLocation = await createUserCurrentLocationPayload();
|
const eventId = pageType === 'start'
|
? SELECT_PICKUP_LOCATION_PIN_PICKUP_LOCATION_BUTTON_EVENT_ID
|
: SELECT_DROPOFF_LOCATION_MAP_SELECT_BUTTON_EVENT_ID;
|
reportEvent(eventId, {
|
user_cur_loc: userCurrentLocation,
|
nearby_pickup_stations: Array.isArray(nearbySiteList) ? nearbySiteList : []
|
});
|
};
|
|
/**
|
* 上报选择上车点页页面浏览埋点。
|
*/
|
const reportSelectPickupLocationPageViewEvent = async () => {
|
const userCurrentLocation = await createUserCurrentLocationPayload();
|
reportEvent(SELECT_PICKUP_LOCATION_PAGE_VIEW_EVENT_ID, {
|
user_cur_loc: userCurrentLocation,
|
nearby_pickup_stations: Array.isArray(nearbySiteList) ? nearbySiteList : []
|
}, 'pageView');
|
};
|
|
/**
|
* 上报选择下车点页页面浏览埋点。
|
*/
|
const reportSelectDropoffLocationPageViewEvent = () => {
|
reportEvent(SELECT_DROPOFF_LOCATION_PAGE_VIEW_EVENT_ID, {}, 'pageView');
|
};
|
|
/**
|
* 点击历史记录站点时上报埋点。
|
*/
|
const reportHistoryPickupSelectEvent = (item: any, listIndex: number, totalResults: number) => {
|
if (pageType !== 'start') {
|
return;
|
}
|
const selectedCity = Taro.getStorageSync('selectedCity');
|
reportEvent(SELECT_PICKUP_LOCATION_HISTORY_PICKUP_ITEM_EVENT_ID, {
|
histroy_pickup_stations: createIndexedStationSelectionPayload({
|
site: item,
|
savedAtTimestamp: toUnixSeconds(item?.createTime),
|
usageCount: 1,
|
listIndex,
|
totalResults,
|
fallbackCity: String(selectedCity?.name || '')
|
})
|
});
|
};
|
|
/**
|
* 点击历史记录下车点时上报埋点。
|
*/
|
const reportHistoryDropoffSelectEvent = (item: any, listIndex: number, totalResults: number) => {
|
if (pageType !== 'end') {
|
return;
|
}
|
const selectedCity = Taro.getStorageSync('selectedCity');
|
reportEvent(SELECT_DROPOFF_LOCATION_HISTORY_DROPOFF_ITEM_EVENT_ID, {
|
selected_history_dropoff: createIndexedStationSelectionPayload({
|
site: item,
|
savedAtTimestamp: toUnixSeconds(item?.createTime),
|
usageCount: 1,
|
listIndex,
|
totalResults,
|
fallbackCity: String(selectedCity?.name || '')
|
})
|
});
|
};
|
|
/**
|
* 选择推荐下车点时上报埋点。
|
*/
|
const reportRecommendedDropoffStationEvent = (item: any, listIndex: number, totalResults: number) => {
|
if (pageType !== 'end' || searchValue.trim()) {
|
return;
|
}
|
const selectedCity = Taro.getStorageSync('selectedCity');
|
reportEvent(RECOMMENDED_DROPOFF_STATION_ITEM_EVENT_ID, {
|
selected_recommended_station: createIndexedStationSelectionPayload({
|
site: item,
|
savedAtTimestamp: toUnixSeconds(item?.createTime),
|
usageCount: 1,
|
listIndex,
|
totalResults,
|
fallbackCity: String(selectedCity?.name || '')
|
})
|
});
|
};
|
|
/**
|
* 点击搜索结果站点时上报埋点。
|
*/
|
const reportSearchResultEvent = (item: any, listIndex: number, totalResults: number) => {
|
const eventId = pageType === 'start'
|
? SEARCH_PICKUP_RESULT_ITEM_EVENT_ID
|
: pageType === 'end'
|
? SEARCH_DROPOFF_RESULT_ITEM_EVENT_ID
|
: '';
|
if (!eventId || !searchValue.trim()) {
|
return;
|
}
|
const selectedCity = Taro.getStorageSync('selectedCity');
|
reportEvent(eventId, {
|
search_selected_station: {
|
query_keyword: String(searchValue || '').trim(),
|
list_idx: Number(listIndex),
|
total_results: Number(totalResults),
|
station: createReportStationPayload(item, String(selectedCity?.name || ''))
|
}
|
});
|
};
|
|
const toSelectSite = async () => {
|
await reportSelectPickupLocationEvent();
|
Taro.navigateTo({
|
url: '/robotaxi/pages/select-map-site/index?pageType=' + pageType + '&fromSiteSearch=1',
|
})
|
}
|
|
const onChangeSelectSite = async (
|
item,
|
isNonOperational = true,
|
sourceType = UNKNOWN_CONFIRM_RIDE_SOURCE_TYPE
|
) => {
|
if (item?.operationStatus === 2) {
|
showToast({
|
title: '当前站点暂未开放',
|
icon: 'none',
|
})
|
return
|
}
|
if (!isNonOperational) {
|
showToast({
|
title: '当前站点暂未开放',
|
icon: 'none',
|
})
|
return
|
}
|
if (pageType == 'start') {
|
const resolvedDistanceConfig = await ensureDistanceConfigReady();
|
const endSiteCache = Taro.getStorageSync('endSite');
|
if (endSiteCache?.electronicAreaId && item?.electronicAreaId && endSiteCache.electronicAreaId !== item.electronicAreaId) {
|
showToast({
|
title: '起终点需在同一运营区域',
|
icon: 'none',
|
})
|
return
|
}
|
try {
|
const loc = await Taro.getLocation({ type: 'gcj02' });
|
if (!isWithinPickupMaxDistance({
|
userLatitude: loc.latitude,
|
userLongitude: loc.longitude,
|
pickupSite: item,
|
maxDistance: resolvedDistanceConfig?.maxDistance
|
})) {
|
setTipType(ORDER_DISTANCE_TIP_TYPE_MAX_DISTANCE);
|
setShowTipPopup(true);
|
return;
|
}
|
if (!isWithinStartEndMinDistance({
|
startSite: item,
|
endSite: endSiteCache,
|
minDistance: resolvedDistanceConfig?.minDistance
|
})) {
|
setTipType(ORDER_DISTANCE_TIP_TYPE_MIN_DISTANCE);
|
setShowTipPopup(true);
|
return;
|
}
|
} catch { }
|
Taro.setStorageSync('startSite', item);
|
writeConfirmRideSiteSourceType('start', sourceType);
|
completeConfirmRideSelectionSession(item, endSiteCache);
|
writeHomeStartSiteDisplayState(item, HOME_START_SITE_SOURCE_MANUAL_SELECTED);
|
Taro.navigateBack()
|
} else if (pageType == 'end') {
|
const otp = await checkOtp(false);
|
if (!otp) {
|
setPostLoginPendingAction(item);
|
Taro.navigateTo({ url: '/pages/user/login?hideBack=1' });
|
return
|
}
|
await handleEndSiteSelection(item, sourceType);
|
}
|
}
|
|
const clearSearchValue = () => {
|
setSearchValue('');
|
clearSearchResults();
|
// 非受控输入框:通过自增 key 重挂载来清空原生输入框内容
|
setInputResetKey((k) => k + 1);
|
}
|
const handleCloseTipPopup = () => {
|
setShowTipPopup(false);
|
setTimeout(() => {
|
setTipType('');
|
}, 600);
|
}
|
|
const handleCloseFavoritePopup = () => {
|
setShowFavoritePopup(false);
|
refreshData(); // 关闭弹窗时刷新列表数据(包括历史记录和附近站点)
|
};
|
|
/**
|
* 收藏站点返回的是“收藏记录对象”,这里统一转换成下单链路使用的站点对象。
|
*/
|
const normalizeFavoriteSelectedSite = (item: any) => {
|
const resolvedPointId = item?.pointId || item?.id || '';
|
const resolvedName = item?.pointName || item?.name || '';
|
const shouldPreserveFavoriteId = item?.pointId && String(item?.id || '') !== String(item?.pointId || '');
|
return {
|
...item,
|
favoriteId: shouldPreserveFavoriteId ? item?.id : item?.favoriteId,
|
id: resolvedPointId,
|
pointId: resolvedPointId,
|
name: resolvedName,
|
pointName: resolvedName,
|
};
|
};
|
|
const handleSelectFavorite = (item) => {
|
setShowFavoritePopup(false);
|
onChangeSelectSite(normalizeFavoriteSelectedSite(item));
|
};
|
|
const renderHighlightedText = (text: string, className: string) => { // 通用高亮渲染
|
const kw = (searchValue || '').trim();
|
if (!kw) {
|
return <View className={className}>{text}</View>;
|
}
|
const parts = splitHighlightParts(String(text || ''), kw);
|
return (
|
<View className={className}>
|
{parts.map((part, idx) => (
|
<Text key={idx} className={part.match ? 'highlight-match' : ''}>
|
{part.text}
|
</Text>
|
))}
|
</View>
|
);
|
}
|
|
const renderSiteItems = (
|
list: any[],
|
onSelect: (item: any, index?: number) => void,
|
showDistance = true,
|
showStationChildren = false
|
) => { // 复用列表项渲染
|
return list.map((item, index) => (
|
<SiteListItem
|
key={item.id || index}
|
itemKey={item.id || index}
|
item={item}
|
iconSrc='https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/address-20260630.png'
|
starSrc='https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/active-star-20260726.png'
|
noStarSrc='https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/no-star-20260726.png'
|
showDistance={showDistance}
|
onSelect={(selectedItem: any) => onSelect(selectedItem, index)}
|
renderHighlightedText={renderHighlightedText}
|
showStationChildren={showStationChildren}
|
/>
|
));
|
};
|
|
const currentSiteCache = pageType === 'start'
|
? Taro.getStorageSync('startSite')
|
: pageType === 'end'
|
? Taro.getStorageSync('endSite')
|
: null;
|
const filteredNearbyList = filterNearbyListByCurrentSite(nearbySiteList, currentSiteCache);
|
const sortedNearbyList = sortSitesByCollectedFirst(filteredNearbyList);
|
const fallbackNearbyList = sortedNearbyList.slice(0, MAX_EXPANDED_COUNT); // 兜底推荐列表(最多展示 MAX_EXPANDED_COUNT 条)
|
const trimmedSearchValue = searchValue.trim();
|
const startSiteCache = Taro.getStorageSync('startSite');
|
const recommendSourceList = trimmedSearchValue
|
? sortSitesByNameMatchAndDistance(siteList, searchValue)
|
: sortedNearbyList;
|
const recommendList = pageType === 'end' && !trimmedSearchValue
|
? filterRecommendedDropoffSitesByMinDistance(recommendSourceList, startSiteCache, distanceConfig?.minDistance)
|
: recommendSourceList;
|
const sortedHistorySite = sortSitesByCollectedFirst(historySite);
|
const visibleHistory = showAllHistory ? sortedHistorySite.slice(0, MAX_EXPANDED_COUNT) : sortedHistorySite.slice(0, MAX_SHOW_HISTORY);
|
const visibleRecommend = showAllRecommend ? recommendList : recommendList.slice(0, RECOMMEND_SHOW_COUNT);
|
const canShowSearchFallback = !searchValue || (!isSearching && lastCompletedKeyword === searchValue.trim());
|
|
useEffect(() => {
|
if (pageType !== 'start' || !isInitLoaded || hasReportedPickupPageView.current) {
|
return;
|
}
|
hasReportedPickupPageView.current = true;
|
void reportSelectPickupLocationPageViewEvent();
|
}, [pageType, isInitLoaded]);
|
|
useEffect(() => {
|
if (pageType !== 'end' || !isInitLoaded || hasReportedDropoffPageView.current) {
|
return;
|
}
|
hasReportedDropoffPageView.current = true;
|
reportSelectDropoffLocationPageViewEvent();
|
}, [pageType, isInitLoaded]);
|
|
// 使用数据截断展示,不再通过高度裁剪内容
|
|
return (
|
<View className='search-page'>
|
{/* 搜索区域 */}
|
<View className='search-card'>
|
<View className={`search-icon ${pageType == 'end' ? 'end-icon' : ''}`}></View>
|
<View className='search-input-box'>
|
<Input className='search-input' placeholder={pageType == 'start' ? '请输入上车点' : '请输入目的地'}
|
key={inputResetKey}
|
defaultValue={searchValue}
|
onInput={(e) => changeSearchValue(e)}
|
onBlur={flushDebouncedSearch}
|
onConfirm={(e) => {
|
const keyword = e?.detail?.value || searchValue; // 确认搜索关键字,优先取输入框事件值
|
confirmSearch(keyword);
|
}}
|
confirmType='search'
|
autoFocus
|
/>
|
{
|
searchValue &&
|
<View onClick={clearSearchValue} className='cancel-icon-box'>
|
<Image className='cancel-icon' src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/clear-icon.png" />
|
</View>
|
}
|
</View>
|
</View>
|
{/* 收藏站点与地图选点 */}
|
<View className='fast-box'>
|
<View className='fast-item' onClick={() => setShowFavoritePopup(true)}>
|
<Image className='fast-item-icon favorite-icon' src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/favorite-v2.png"></Image>
|
<Text className='fast-item-text'>收藏站点</Text>
|
</View>
|
<View className='fast-split'></View>
|
<View onClick={toSelectSite} className='fast-item'>
|
<Image className='fast-item-icon map-icon' src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/map-v2.png"></Image>
|
<Text className='fast-item-text'>地图选点</Text>
|
</View>
|
</View>
|
{/* 推荐站点 */}
|
{
|
recommendList.length > 0 &&
|
<View className='recommend-card'>
|
<Image className='recommend-card-bg' src='https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/seadrch-site-bg-20260714.png' />
|
<View className='recommend-content-box'>
|
<View className='card-header'>{searchValue ? '搜索站点' : '推荐站点'}</View>
|
<View className='card-content recommend-list-content' id='recommend-card-content' key={`recommend-${showAllRecommend ? 'expanded' : 'collapsed'}`}>
|
{
|
renderSiteItems(visibleRecommend, (item, index = 0) => {
|
if (pageType === 'start' && searchValue.trim()) {
|
reportSearchResultEvent(item, index, recommendList.length);
|
}
|
if (pageType === 'end' && trimmedSearchValue) {
|
reportSearchResultEvent(item, index, recommendList.length);
|
}
|
if (pageType === 'end' && !trimmedSearchValue) {
|
reportRecommendedDropoffStationEvent(item, index, recommendList.length);
|
}
|
onChangeSelectSite(
|
item,
|
true,
|
trimmedSearchValue
|
? SEARCH_CONFIRM_RIDE_SOURCE_TYPE
|
: RECOMMENDED_CONFIRM_RIDE_SOURCE_TYPE
|
);
|
}, true, true)
|
}
|
</View>
|
{recommendList.length > RECOMMEND_SHOW_COUNT && (
|
<View className='show-more' hoverClass='none' onClick={toggleRecommendShow}>
|
<Text className='more-text'>{showAllRecommend ? '收起' : '展示更多'}</Text>
|
<Image className={`more-icon ${showAllRecommend ? 'rotate-up' : ''}`} src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/arrow.png"></Image>
|
</View>
|
)}
|
</View>
|
</View>
|
}
|
{/* 历史记录 */}
|
{
|
(sortedHistorySite.length > 0 && !searchValue) &&
|
<View className='history-card'>
|
<View className='card-header'>历史记录</View>
|
<View className='card-content list-content' id='history-card-content' key={`history-${showAllHistory ? 'expanded' : 'collapsed'}`}>
|
{
|
renderSiteItems(visibleHistory, (item, index = 0) => {
|
if (pageType === 'start') {
|
reportHistoryPickupSelectEvent(item, index, visibleHistory.length);
|
}
|
if (pageType === 'end') {
|
reportHistoryDropoffSelectEvent(item, index, visibleHistory.length);
|
}
|
onChangeSelectSite(item, true, HISTORY_CONFIRM_RIDE_SOURCE_TYPE);
|
}, true, true)
|
}
|
</View>
|
{sortedHistorySite.length > MAX_SHOW_HISTORY && (
|
<View className='show-more' hoverClass='none' onClick={toggleHistoryShow}>
|
<Text className='more-text'>{showAllHistory ? '收起' : '展示更多'}</Text>
|
<Image className={`more-icon ${showAllHistory ? 'rotate-up' : ''}`} src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/arrow.png"></Image>
|
</View>
|
)}
|
</View>
|
}
|
{/* 非营运区域 */}
|
{
|
nonOperationalSite.length > 0 &&
|
<View className='nonOperational-card'>
|
<View className='card-header'>暂未开放</View>
|
<View className='card-content'>
|
{
|
renderSiteItems(nonOperationalSite, (item) => onChangeSelectSite(item, false), false)
|
}
|
</View>
|
</View>
|
}
|
{
|
isInitLoaded && canShowSearchFallback && fallbackNearbyList.length > 0 && (!siteList.length && (!searchValue ? !sortedNearbyList.length : true) && !nonOperationalSite.length && (!searchValue ? !sortedHistorySite.length : true)) &&
|
<View className='recommend-card'>
|
<Image className='recommend-card-bg' src='https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/seadrch-site-bg-20260714.png' />
|
<View className='recommend-content-box'>
|
<View className='card-header'>暂无搜索结果,为您推荐附近站点</View>
|
<View className='card-content recommend-list-content'>
|
{
|
renderSiteItems(
|
fallbackNearbyList,
|
(item) => onChangeSelectSite(item, true, RECOMMENDED_CONFIRM_RIDE_SOURCE_TYPE),
|
true
|
)
|
}
|
</View>
|
</View>
|
</View>
|
}
|
<TipPopup
|
show={showTipPopup}
|
onClose={handleCloseTipPopup}
|
tipType={tipType}
|
isMap={false}
|
/>
|
<FavoritePopup
|
show={showFavoritePopup}
|
onClose={handleCloseFavoritePopup}
|
onSelect={handleSelectFavorite}
|
pageType={pageType}
|
/>
|
</View>
|
)
|
}
|
|
export default withRobotaxiWhitelist(withToast(SiteSearchPage));
|