Files
frontend/apps/sn/app/(map-layout)/map/components/water-risk/water-risk-client.ts
T

114 lines
4.5 KiB
TypeScript

/** 통수위험 분석 대상과 결과를 조회하는 API 함수를 제공한다. */
import { getData } from "@/shared/api/sewerage-api";
import type { UiTableSort } from "@common/business_components/ui/table";
import type {
WaterRiskAreaOption,
WaterRiskMapView,
WaterRiskResultPage,
WaterRiskResultRow,
WaterRiskStatus,
} from "./water-risk-types";
export type WaterRiskResultQuery = {
startDate: string;
endDate: string;
/** 현재 탭 분석기준시간(정시) 정확 일치 조건. 분석시각 기간과 함께 보내지 않는다. */
analysisBaseAt?: string;
/** 과거이력 분석시각 기간 시작(yyyy-MM-ddTHH:00:00, 포함). 종료와 함께 보낸다. */
analysisBaseFrom?: string;
/** 과거이력 분석시각 기간 종료(yyyy-MM-ddTHH:00:00, 포함). 시작과 함께 보낸다. */
analysisBaseTo?: string;
/**
* 과거이력 강우시각(강우 시작 일시) 기간 시작(yyyy-MM-ddTHH:00:00, 포함). 종료와 함께 보낸다.
* 보내면 백엔드가 startDate·endDate보다 이 기간을 우선한다.
*/
rainStartedFrom?: string;
/** 과거이력 강우시각(강우 시작 일시) 기간 종료(yyyy-MM-ddTHH:00:00, 포함). 시작과 함께 보낸다. */
rainStartedTo?: string;
ctpvCd?: string;
sggCd?: string;
areaId?: string;
riskStatus?: WaterRiskStatus;
rainEventStatus?: "IN_PROGRESS" | "ENDED";
sort?: UiTableSort;
page: number;
size: number;
};
type WaterRiskApiResultRow = Omit<WaterRiskResultRow, "sidoName"> & {
ctpvName: string;
};
/** 통수위험 결과 API 응답을 기존 화면 표시 모델로 정규화한다. */
const normalizeResultRow = (row: WaterRiskApiResultRow): WaterRiskResultRow => ({
...row,
sidoName: row.ctpvName,
currentAccumRainQty: row.currentAccumRainQty ?? null,
pipeSummaries: Array.isArray(row.pipeSummaries) ? row.pipeSummaries : [],
});
/** 등록된 중점관리지역 검색조건을 조회한다. */
export const fetchWaterRiskAreas = async (): Promise<WaterRiskAreaOption[]> => {
const response = await getData("v1/waterRisk/areas");
return Array.isArray(response) ? response : [];
};
/** 기간·행정구역·지역·위험상태에 맞는 결과 페이지를 조회한다. */
export const fetchWaterRiskResults = async (
query: WaterRiskResultQuery,
): Promise<WaterRiskResultPage> => {
const params = new URLSearchParams({
startDate: query.startDate,
endDate: query.endDate,
page: String(query.page),
size: String(query.size),
});
if (query.ctpvCd) params.set("ctpvCd", query.ctpvCd);
if (query.analysisBaseAt) params.set("analysisBaseAt", query.analysisBaseAt);
if (query.analysisBaseFrom && query.analysisBaseTo) {
params.set("analysisBaseFrom", query.analysisBaseFrom);
params.set("analysisBaseTo", query.analysisBaseTo);
}
if (query.rainStartedFrom && query.rainStartedTo) {
params.set("rainStartedFrom", query.rainStartedFrom);
params.set("rainStartedTo", query.rainStartedTo);
}
if (query.sggCd) params.set("sggCd", query.sggCd);
if (query.areaId) params.set("areaId", query.areaId);
if (query.riskStatus) params.set("riskStatus", query.riskStatus);
if (query.rainEventStatus) params.set("rainEventStatus", query.rainEventStatus);
if (query.sort) params.set("sort", `${query.sort.key},${query.sort.direction}`);
const response = await getData(`v1/waterRisk/results?${params.toString()}`);
const items = Array.isArray(response?.items)
? response.items.map((row: WaterRiskApiResultRow) => normalizeResultRow(row))
: [];
return {
items,
analysisBaseAt: response?.analysisBaseAt ?? null,
total: Number(response?.total ?? 0),
page: Number(response?.page ?? query.page),
size: Number(response?.size ?? query.size),
totalPages: Number(response?.totalPages ?? 0),
};
};
/** 결과 행과 연결된 중점관리지역·유출관로 도형을 조회한다. */
export const fetchWaterRiskMapView = async (
row: WaterRiskResultRow,
): Promise<WaterRiskMapView> => {
// 날짜·지역이 아니라 누른 행의 SWMM 실행 ID로 조회해야 같은 날 같은 지역 결과가 여러 건이어도 같은 결과를 그린다.
if (!row.executionId) {
throw new Error("지도 조회에 필요한 SWMM 실행 ID가 없습니다.");
}
const response = await getData(
`v1/waterRisk/executions/${encodeURIComponent(row.executionId)}/mapView`,
);
return {
...response,
pipes: Array.isArray(response?.pipes) ? response.pipes : [],
manholes: Array.isArray(response?.manholes) ? response.manholes : [],
};
};