diff --git a/frontend/src/api/gisApi.ts b/frontend/src/api/gisApi.ts index fd7129d..c1d260a 100644 --- a/frontend/src/api/gisApi.ts +++ b/frontend/src/api/gisApi.ts @@ -51,7 +51,7 @@ export const gisApi = { }, getVesselTracks(mmsiList: string[], startTime: string, endTime: string): Promise { - return postJson('/api/v2/tracks/vessels', { mmsiList, startTime, endTime }) + return postJson('/api/v2/tracks/vessels', { vessels: mmsiList, startTime, endTime }) }, getRecentPositions(minutes = 10): Promise { diff --git a/frontend/src/features/viewport-replay/components/ReplaySetupPanel.tsx b/frontend/src/features/viewport-replay/components/ReplaySetupPanel.tsx index d4c4199..a102561 100644 --- a/frontend/src/features/viewport-replay/components/ReplaySetupPanel.tsx +++ b/frontend/src/features/viewport-replay/components/ReplaySetupPanel.tsx @@ -40,9 +40,10 @@ export default function ReplaySetupPanel({ map }: ReplaySetupPanelProps) { const handleQuery = () => { if (!map) return const bounds = getViewportBounds(map) - const zoom = map.getZoom() - const startISO = startTime.replace('T', ' ') + ':00' - const endISO = endTime.replace('T', ' ') + ':00' + const zoom = Math.round(map.getZoom()) + // 백엔드 @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") 형식 유지 + const startISO = startTime + ':00' + const endISO = endTime + ':00' replayWebSocket.executeQuery(startISO, endISO, bounds, zoom) } diff --git a/frontend/src/features/viewport-replay/services/replayWebSocket.ts b/frontend/src/features/viewport-replay/services/replayWebSocket.ts index cc47c16..1be5ae6 100644 --- a/frontend/src/features/viewport-replay/services/replayWebSocket.ts +++ b/frontend/src/features/viewport-replay/services/replayWebSocket.ts @@ -94,12 +94,16 @@ class ReplayWebSocketService { }, onStompError: (frame) => { - console.error('[ReplayWS] STOMP error:', frame.headers.message) + console.error('[ReplayWS] STOMP error:', frame.headers.message, frame.body) + if (replayStore.querying) { + replayStore.completeQuery() + } replayStore.setConnectionState('error') reject(new Error(frame.headers.message)) }, - onWebSocketError: () => { + onWebSocketError: (evt) => { + console.error('[ReplayWS] WebSocket error:', evt) replayStore.setConnectionState('error') reject(new Error('WebSocket connection failed')) }, @@ -158,6 +162,7 @@ class ReplayWebSocketService { zoomLevel, } + console.log('[ReplayWS] Sending query:', request.startTime, '~', request.endTime, 'zoom:', request.zoomLevel) this.client.publish({ destination: '/app/tracks/query', body: JSON.stringify(request), @@ -196,9 +201,15 @@ class ReplayWebSocketService { this.client.subscribe('/user/queue/tracks/response', (msg: IMessage) => { try { const data = JSON.parse(msg.body) + console.log('[ReplayWS] Response:', data.status, data.queryId) if (data.queryId) { this.currentQueryId = data.queryId } + if (data.status === 'ERROR') { + console.error('[ReplayWS] Query error:', data.message) + this.clearQueryTimeout() + useReplayStore.getState().completeQuery() + } } catch { /* ignore */ } }) }