import { View, Map, Text, Image, ScrollView } from '@tarojs/components';
|
import CustomerServicePopup from '../../../components/customer-service';
|
import TipPopup from '../../../components/tip-popup';
|
import { formatTripDistance, formatTripDurationFromSeconds } from '../../../../utils/Robotaxi-public-method';
|
import { SELECT_SITE_RANGE_STATUS, type SelectSiteRangeStatus } from '../hooks/use-select-map-site-state';
|
|
type Deps = {
|
longitude: number | null;
|
latitude: number | null;
|
mapScale: number;
|
markers: any[];
|
mapPolylines: any[];
|
polygons: any[];
|
handleRegionChange: (e: any) => void;
|
handleMarkerTap: (e: any) => void;
|
toBack: () => void;
|
backIcon: string;
|
openService: () => void;
|
toCoupon: () => void;
|
personalCenter: string;
|
coupon: string;
|
contactService: string;
|
nearbyLoading: boolean;
|
isAndroid: boolean;
|
waitingRadarSrc: string;
|
showToolTip: boolean;
|
selectedSite: any;
|
selectionMode: 'point' | 'station';
|
selectedStation: any;
|
stationSiteList: any[];
|
rangeStatus: SelectSiteRangeStatus;
|
tooltipBgSrc: string;
|
pageType: string;
|
bounce: boolean;
|
pointer: string;
|
toOrigin: () => void;
|
originIcon: string;
|
walkingDuration: number | null;
|
walkingDistance: number | null;
|
nearbySites: any[];
|
handleCollect: (e: any) => void;
|
changeStationSite: (site: any) => void;
|
activeStar: string;
|
noStar: string;
|
confirmSite: () => void;
|
confirmButtonText: string;
|
confirmButtonDisabled: boolean;
|
crossOperatingAreaHintText: string;
|
showViewOperatingAreaButton: boolean;
|
handleViewOperatingArea: () => void;
|
showCustomerService: boolean;
|
handleCloseCustomerService: () => void;
|
showTipPopup: boolean;
|
handleCloseTipPopup: () => void;
|
tipType: string;
|
toPersonalCenter: () => void;
|
toSiteSearch: () => void;
|
hideSearchBox?: boolean;
|
};
|
|
/**
|
* 选点页视图组件:仅负责渲染地图与页面 UI,不包含业务状态编排。
|
*/
|
export default function SelectMapSiteView(deps: Deps) {
|
const isOutOfOperatingArea = deps.rangeStatus === SELECT_SITE_RANGE_STATUS.outOfOperatingArea;
|
const isCrossOperatingArea = deps.rangeStatus === SELECT_SITE_RANGE_STATUS.crossOperatingArea;
|
const showRangeWarning = isOutOfOperatingArea || isCrossOperatingArea;
|
const shouldShowSelectedSiteEcho = !showRangeWarning && Boolean(deps.selectedSite.name);
|
const shouldShowStationSelection = deps.selectionMode === 'station' && !showRangeWarning;
|
const garyToolTipBg = 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/tooltip-bg-gray-20260714.png';
|
|
return (
|
<View className="home-container">
|
<Map
|
id="select-site-map"
|
longitude={deps.longitude}
|
latitude={deps.latitude}
|
scale={deps.mapScale}
|
markers={deps.markers.map((m) => ({ ...m, title: '', name: '' }))}
|
polyline={deps.mapPolylines}
|
polygons={deps.polygons}
|
showLocation={!!deps.longitude}
|
onRegionChange={deps.handleRegionChange}
|
onMarkerTap={deps.handleMarkerTap}
|
style={{ width: '100%', height: '100%' }}
|
>
|
{/* 返回 */}
|
<View onClick={deps.toBack} className="select-city">
|
<Image className="select-city-icon" src={deps.backIcon} />
|
</View>
|
{/* 搜索框 */}
|
{!deps.hideSearchBox && (
|
<View onClick={deps.toSiteSearch} className="search-card">
|
<View className={`search-icon ${deps.pageType == 'end' ? 'end-icon' : ''}`}></View>
|
<View className="search-input-box">
|
<View className="search-input-placeholder">{deps.pageType == 'start' ? '请输入上车点' : '请输入目的地'}</View>
|
</View>
|
</View>
|
)}
|
{/* 地图浮层入口 - 选点页不展示 */}
|
{deps.nearbyLoading && deps.isAndroid && (
|
<Image className="waiting-radar-img" src={deps.waitingRadarSrc} />
|
)}
|
{/* 指针 */}
|
<View className="pointer-box">
|
{deps.nearbyLoading && !deps.isAndroid && (
|
<Image className="waiting-radar" src={deps.waitingRadarSrc} />
|
)}
|
{((deps.showToolTip && shouldShowSelectedSiteEcho) || showRangeWarning) && (
|
<View className="toolTip">
|
{(showRangeWarning || deps.selectedSite.time) && (
|
<View className="toolTip-bg">
|
<Image className="toolTip-bg-img" src={(isOutOfOperatingArea || isCrossOperatingArea) ? garyToolTipBg : deps.tooltipBgSrc } />
|
{!showRangeWarning && (
|
<Image className="toolTip-bg-icon" src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/map-time-icon-20260708.png" />
|
)}
|
<Text className="toolTip-bg-text">
|
{isOutOfOperatingArea ? '不在运营区' : isCrossOperatingArea ? '不在同一运营区' : `限停${deps.selectedSite.time}分钟`}
|
</Text>
|
</View>
|
)}
|
<View className="toolTip-txt">
|
<View className="toolTip-txt-content">
|
{isOutOfOperatingArea
|
? `请拖动至${deps.pageType == 'end' ? '目的地' : '上车点'}`
|
: isCrossOperatingArea
|
? '请在同一运营区内选择'
|
: deps.selectedSite.name}
|
</View>
|
<Image className="toolTip-diamond-icon" src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/diamond-icon-20260708.png" />
|
</View>
|
</View>
|
)}
|
{/* 黑色站点名浮窗(toolTip)显示时隐藏中心大头针 */}
|
<Image className={`pointer-icon ${deps.bounce ? 'bounce' : ''} ${(deps.showToolTip && shouldShowSelectedSiteEcho) || showRangeWarning ? 'hidden-pointer' : ''}`} src={deps.pointer} />
|
</View>
|
<View className="container">
|
<View className="container-inner">
|
{/* 复位按钮 */}
|
<View className="origin-box">
|
<Image onClick={deps.toOrigin} className="origin-icon" src={deps.originIcon} />
|
</View>
|
<View className="content-box-wrap" catchMove onClick={(e) => e.stopPropagation()}>
|
{deps.showViewOperatingAreaButton && (
|
<View onClick={deps.handleViewOperatingArea} className="select-operating-area-entry">
|
查看运营区域
|
</View>
|
)}
|
{/* 确认站点 */}
|
<View className="content-box">
|
<Image className="content-box-top-bg" src='https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/top-card-bg-20260722.png' />
|
<View className="content-box-coantainer">
|
<View className="content-box-item">
|
<View className='content-box-item-title'>
|
<View className="content-title">{shouldShowStationSelection ? deps.selectedStation?.name : (deps.pageType === 'start' ? '确认上车点' : '确认目的地')}</View>
|
{deps.pageType === 'start' && deps.walkingDuration !== null && deps.walkingDistance !== null && (
|
<View className="limit-tip">
|
从当前位置出发步行{formatTripDurationFromSeconds(deps.walkingDuration)}({formatTripDistance(deps.walkingDistance)})上车
|
</View>
|
)}
|
{(deps.nearbySites.length > 0 && deps.pageType === 'end') && (
|
<View className="limit-tip">点击金色圆点或拖动大头针,可修改目的地</View>
|
)}
|
</View>
|
{shouldShowStationSelection && (
|
<Image
|
onClick={deps.handleCollect}
|
className='collect-icon'
|
src={deps.selectedStation?.isCollect ? deps.activeStar : deps.noStar}
|
/>
|
)}
|
</View>
|
<View className='site-list-wrap'>
|
<ScrollView
|
className="site-list"
|
scrollY
|
enhanced
|
showScrollbar={true}
|
>
|
<View className='site-list-inner'>
|
{shouldShowStationSelection ? (
|
deps.stationSiteList.length > 0 ? deps.stationSiteList.map((item) => (
|
<View
|
key={item.id || item.pointId || `${item.latitude}_${item.longitude}`}
|
className={`site-item ${String(item.id || item.pointId || '') === String(deps.selectedSite?.id || deps.selectedSite?.pointId || '') ? 'site-active' : ''}`}
|
onClick={() => deps.changeStationSite(item)}
|
>
|
<View>{item.name}</View>
|
</View>
|
)) : <View className="no-service">当前场站暂无可选站点</View>
|
) : shouldShowSelectedSiteEcho ? (
|
<View className='site-item site-active'>
|
<View>{deps.selectedSite.name}</View>
|
{deps.selectionMode === 'point' && (
|
<Image onClick={deps.handleCollect} className='collect-icon' src={deps.selectedSite.isCollect === 1 ? deps.activeStar : deps.noStar} />
|
)}
|
</View>
|
) : showRangeWarning ? (
|
<View className="no-service">{isCrossOperatingArea ? deps.crossOperatingAreaHintText : '超出服务范围,请在运营区内选择'}</View>
|
) : <View className="no-service">附近无可选站点</View>
|
}
|
</View>
|
</ScrollView>
|
</View>
|
<View onClick={deps.confirmButtonDisabled ? undefined : deps.confirmSite} className={`site-confirm ${deps.confirmButtonDisabled ? 'no-confirm' : ''}`}>
|
{deps.confirmButtonText}
|
</View>
|
</View>
|
</View>
|
</View>
|
</View>
|
</View>
|
</Map>
|
{/* 客服弹窗 */}
|
<CustomerServicePopup
|
show={deps.showCustomerService}
|
onClose={deps.handleCloseCustomerService}
|
/>
|
{/* 提示弹窗 */}
|
<TipPopup
|
show={deps.showTipPopup}
|
onClose={deps.handleCloseTipPopup}
|
tipType={deps.tipType}
|
/>
|
</View>
|
);
|
}
|