기본정보 눌렀을때 뜨는 오류해결

This commit is contained in:
leeheejin
2025-12-10 16:47:48 +09:00
parent 6707e2afd2
commit 65c1855eba
5 changed files with 159 additions and 32 deletions

View File

@@ -230,15 +230,115 @@ export default function MapTestWidgetV2({ element }: MapTestWidgetV2Props) {
...prev,
[identifier]: result.data.rows[0],
}));
} else {
// 데이터가 없는 경우에도 "로드 완료" 상태로 표시 (빈 객체 저장)
setTripInfo((prev) => ({
...prev,
[identifier]: { _noData: true },
}));
}
} else {
// API 실패 시에도 "로드 완료" 상태로 표시
setTripInfo((prev) => ({
...prev,
[identifier]: { _noData: true },
}));
}
} catch (err) {
console.error("공차/운행 정보 로드 실패:", err);
// 에러 시에도 "로드 완료" 상태로 표시
setTripInfo((prev) => ({
...prev,
[identifier]: { _noData: true },
}));
}
setTripInfoLoading(null);
}, [tripInfo]);
// 마커 로드 시 운행/공차 정보 미리 일괄 조회
const preloadTripInfo = useCallback(async (loadedMarkers: MarkerData[]) => {
if (!loadedMarkers || loadedMarkers.length === 0) return;
// 마커에서 identifier 추출 (user_id 또는 vehicle_number)
const identifiers: string[] = [];
loadedMarkers.forEach((marker) => {
try {
const parsed = JSON.parse(marker.description || "{}");
const identifier = parsed.user_id || parsed.vehicle_number || parsed.id;
if (identifier && !tripInfo[identifier]) {
identifiers.push(identifier);
}
} catch {
// 파싱 실패 시 무시
}
});
if (identifiers.length === 0) return;
try {
// 모든 마커의 운행/공차 정보를 한 번에 조회
const placeholders = identifiers.map((_, i) => `$${i + 1}`).join(", ");
const query = `SELECT
id, vehicle_number, user_id,
last_trip_start, last_trip_end, last_trip_distance, last_trip_time,
last_empty_start, last_empty_end, last_empty_distance, last_empty_time,
departure, arrival, status
FROM vehicles
WHERE user_id IN (${identifiers.map(id => `'${id}'`).join(", ")})
OR vehicle_number IN (${identifiers.map(id => `'${id}'`).join(", ")})`;
const response = await fetch(getApiUrl("/api/dashboards/execute-query"), {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${typeof window !== "undefined" ? localStorage.getItem("authToken") || "" : ""}`,
},
body: JSON.stringify({ query }),
});
if (response.ok) {
const result = await response.json();
if (result.success && result.data.rows.length > 0) {
const newTripInfo: Record<string, any> = {};
// 조회된 데이터를 identifier별로 매핑
result.data.rows.forEach((row: any) => {
const hasData = row.last_trip_start || row.last_trip_end ||
row.last_trip_distance || row.last_trip_time ||
row.last_empty_start || row.last_empty_end ||
row.last_empty_distance || row.last_empty_time;
if (row.user_id) {
newTripInfo[row.user_id] = hasData ? row : { _noData: true };
}
if (row.vehicle_number) {
newTripInfo[row.vehicle_number] = hasData ? row : { _noData: true };
}
});
// 조회되지 않은 identifier는 _noData로 표시
identifiers.forEach((id) => {
if (!newTripInfo[id]) {
newTripInfo[id] = { _noData: true };
}
});
setTripInfo((prev) => ({ ...prev, ...newTripInfo }));
} else {
// 결과가 없으면 모든 identifier를 _noData로 표시
const noDataInfo: Record<string, any> = {};
identifiers.forEach((id) => {
noDataInfo[id] = { _noData: true };
});
setTripInfo((prev) => ({ ...prev, ...noDataInfo }));
}
}
} catch (err) {
console.error("운행/공차 정보 미리 로드 실패:", err);
}
}, [tripInfo]);
// 다중 데이터 소스 로딩
const loadMultipleDataSources = useCallback(async () => {
if (!dataSources || dataSources.length === 0) {
@@ -311,6 +411,9 @@ export default function MapTestWidgetV2({ element }: MapTestWidgetV2Props) {
setMarkers(markersWithHeading);
setPolygons(allPolygons);
setLastRefreshTime(new Date());
// 마커 로드 후 운행/공차 정보 미리 일괄 조회
preloadTripInfo(markersWithHeading);
} catch (err: any) {
setError(err.message);
} finally {
@@ -1856,6 +1959,12 @@ export default function MapTestWidgetV2({ element }: MapTestWidgetV2Props) {
return mins > 0 ? `${hours}시간 ${mins}` : `${hours}시간`;
};
// 이미 로드했는데 데이터가 없는 경우 (버튼 숨김)
const loadedInfo = tripInfo[identifier];
if (loadedInfo && loadedInfo._noData) {
return null; // 데이터 없음 - 버튼도 정보도 표시 안 함
}
// 데이터가 없고 아직 로드 안 했으면 로드 버튼 표시
if (!hasEmptyTripInfo && !hasTripInfo && !tripInfo[identifier]) {
return (