feat(platform): advance vehicle operations center
This commit is contained in:
@@ -27,6 +27,7 @@ type AMapMap = {
|
||||
|
||||
type AMapOverlay = {
|
||||
setMap?: (map: AMapMap | null) => void;
|
||||
on?: (eventName: string, handler: () => void) => void;
|
||||
};
|
||||
|
||||
let amapLoaderPromise: Promise<AMapLike> | null = null;
|
||||
@@ -93,6 +94,8 @@ export function VehicleMap({
|
||||
heightClassName = 'vp-map-monitor',
|
||||
fallbackLabel,
|
||||
maxFallbackPoints = 120,
|
||||
selectedId,
|
||||
onPointSelect,
|
||||
children
|
||||
}: {
|
||||
points: VehicleMapPoint[];
|
||||
@@ -100,6 +103,8 @@ export function VehicleMap({
|
||||
heightClassName?: string;
|
||||
fallbackLabel?: string;
|
||||
maxFallbackPoints?: number;
|
||||
selectedId?: string;
|
||||
onPointSelect?: (point: VehicleMapPoint) => void;
|
||||
children?: ReactNode;
|
||||
}) {
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
@@ -129,12 +134,16 @@ export function VehicleMap({
|
||||
mapRef.current.addControl(new AMap.Scale());
|
||||
}
|
||||
overlaysRef.current.forEach((overlay) => overlay.setMap?.(null));
|
||||
const markers = validPoints.slice(0, 500).map((point, index) => new AMap.Marker({
|
||||
position: [point.longitude, point.latitude],
|
||||
title: point.title || point.label,
|
||||
zIndex: mode === 'track' ? 100 + index : 100,
|
||||
content: `<div class="vp-amap-marker ${point.online === false ? 'vp-amap-marker-offline' : 'vp-amap-marker-online'}">${mode === 'track' ? index + 1 : ''}</div>`
|
||||
}));
|
||||
const markers = validPoints.slice(0, 500).map((point, index) => {
|
||||
const marker = new AMap.Marker({
|
||||
position: [point.longitude, point.latitude],
|
||||
title: point.title || point.label,
|
||||
zIndex: point.id === selectedId ? 300 : mode === 'track' ? 100 + index : 100,
|
||||
content: `<div class="vp-amap-marker ${point.online === false ? 'vp-amap-marker-offline' : 'vp-amap-marker-online'} ${point.id === selectedId ? 'vp-amap-marker-selected' : ''}">${mode === 'track' ? index + 1 : ''}</div>`
|
||||
});
|
||||
marker.on?.('click', () => onPointSelect?.(point));
|
||||
return marker;
|
||||
});
|
||||
const nextOverlays: AMapOverlay[] = [...markers];
|
||||
if (mode === 'track' && validPoints.length > 1) {
|
||||
nextOverlays.push(new AMap.Polyline({
|
||||
@@ -156,7 +165,7 @@ export function VehicleMap({
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [config.webJsKey, config.securityJsCode, config.securityServiceHost, mode, validPoints]);
|
||||
}, [config.webJsKey, config.securityJsCode, config.securityServiceHost, mode, onPointSelect, selectedId, validPoints]);
|
||||
|
||||
useEffect(() => () => {
|
||||
mapRef.current?.destroy();
|
||||
@@ -173,11 +182,14 @@ export function VehicleMap({
|
||||
{showFallback ? (
|
||||
<div className="vp-map-fallback">
|
||||
{fallbackPoints.map((point, index) => (
|
||||
<span
|
||||
<button
|
||||
key={`${point.id}-${index}`}
|
||||
className={`vp-map-dot ${mode === 'track' && index === 0 ? 'vp-map-dot-start' : mode === 'track' && index === fallbackPoints.length - 1 ? 'vp-map-dot-end' : point.online === false ? 'vp-map-dot-offline' : 'vp-map-dot-online'}`}
|
||||
type="button"
|
||||
aria-label={`选择地图车辆 ${point.label}`}
|
||||
className={`vp-map-dot ${mode === 'track' && index === 0 ? 'vp-map-dot-start' : mode === 'track' && index === fallbackPoints.length - 1 ? 'vp-map-dot-end' : point.online === false ? 'vp-map-dot-offline' : 'vp-map-dot-online'} ${point.id === selectedId ? 'vp-map-dot-selected' : ''}`}
|
||||
title={point.title || point.label}
|
||||
style={pointToPixelStyle(point, index)}
|
||||
onClick={() => onPointSelect?.(point)}
|
||||
/>
|
||||
))}
|
||||
<Tag className="vp-map-fallback-status" color={isAMapConfigured(config) ? 'blue' : 'orange'}>
|
||||
|
||||
Reference in New Issue
Block a user