perf(monitor): aggregate realtime workspace

This commit is contained in:
lingniu
2026-07-16 03:26:14 +08:00
parent 01150844df
commit cad39d6326
12 changed files with 147 additions and 28 deletions

View File

@@ -67,10 +67,13 @@ GET /api/dashboard/summary
GET /api/v2/monitor/summary?keyword=A&protocol=JT808&status=driving
GET /api/v2/monitor/map?zoom=5
GET /api/v2/monitor/map?zoom=13&bounds=113,22,114,24&status=online
GET /api/v2/monitor/workspace?zoom=13&bounds=113,22,114,24&railLimit=200
```
`summary` and `map` share keyword, protocol and `online|offline|driving|idle` status semantics. `map` accepts `bounds=minLongitude,minLatitude,maxLongitude,maxLatitude`; malformed, non-finite, reversed or out-of-world bounds return `MONITOR_BOUNDS_INVALID`. Below zoom 11 the response remains clustered or mixed. At zoom 11 and above it returns lightweight MassMarks only when the visible point set is at most 2,000; otherwise it adaptively coarsens cells until no more than 2,000 clusters remain. It never returns full telemetry JSON in a point. The browser keeps the normal list at 200 rows, requests map data independently, waits 300ms after `moveend/zoomend`, and drops stale viewport bounds when a direct vehicle search must locate and focus its unique result.
`workspace` is the production map-screen BFF response. It executes one bounded realtime snapshot read, then derives `summary`, the first `railLimit` realtime vehicle rows (hard-capped at 200), and the viewport-aware `map` payload from that same snapshot. The standalone `summary`, `map`, and realtime-vehicle APIs remain available for list mode and external compatibility, but the browser must not fan them out concurrently for one map refresh.
Returns vehicle service KPIs, source distribution, vehicle service status distribution, link health, and realtime backlog.
### Vehicle Service

View File

@@ -96,6 +96,8 @@ The Alert Center previously mounted every tab's data dependencies together: the
Vite previously copied the ignored developer-local `public/app-config.js` into `dist` unchanged. The API correctly intercepted production `/app-config.js` requests, but a local AMap security code still entered release archives and would become exposed if that interception ever regressed. The production build now overwrites the copied file with the credential-free example and verifies an exact byte match. The ECS release smoke gate independently requires the server-side `/_AMapService` host and rejects the security-code property, so both the artifact and the served runtime surface fail closed. This matches AMap's production guidance, which strongly recommends server proxy forwarding and explicitly classifies browser plaintext configuration as unsafe: <https://lbs.amap.com/api/javascript-api-v2/guide/abc/jscode>.
The monitor map screen previously fanned one refresh into three independent requests: summary, a 200-row rail and a map snapshot of up to 10,000 vehicles. Each server path repeated the realtime snapshot count and row query, and the browser created three overlapping payload lifecycles. `/api/v2/monitor/workspace` now reads the bounded snapshot once and derives all three coherent views from it; the client owns one abortable, zero-retention high-volume query. This applies the gateway aggregation/BFF pattern to a single data-heavy screen and follows Grafana's recommendation to share results instead of repeating data-source queries: <https://learn.microsoft.com/en-us/azure/architecture/patterns/gateway-aggregation>, <https://grafana.com/docs/grafana/latest/visualizations/panels-visualizations/query-transform-data/share-query/>.
The navigation and progressive-loading direction follows mature observability systems: persistent global controls, collapsible sections and loading only the content needed for the current task. Elastic documents these dashboard interaction and panel-organization patterns here: <https://www.elastic.co/docs/explore-analyze/dashboards/using> and <https://www.elastic.co/docs/explore-analyze/dashboards/arrange-panels>.
### Remaining audit queue