205 lines
6.6 KiB
TypeScript
205 lines
6.6 KiB
TypeScript
/** 처리구역 관로분석정보와 보수이력을 조회·다운로드하는 API를 제공한다. */
|
|
import { getBlobDataWithHeaders, getData } from "@/components/lib/api";
|
|
|
|
export type SwtrmtPrcsZoneAnalysisMetric = {
|
|
avgInstlYear?: number | string | null;
|
|
oldestInstlYear?: number | string | null;
|
|
latestInstlYear?: number | string | null;
|
|
pipeCount?: number | string | null;
|
|
pipeLength?: number | string | null;
|
|
};
|
|
|
|
export type SwtrmtPrcsZoneAnalysisResponse = {
|
|
zone?: {
|
|
zoneId?: string | number | null;
|
|
swtrmtZoneNm?: string | null;
|
|
ctpvCd?: string | null;
|
|
ctpvNm?: string | null;
|
|
sggCd?: string | null;
|
|
sggNm?: string | null;
|
|
swtrmtFcltCd?: string | null;
|
|
swtrmtFcltNm?: string | null;
|
|
};
|
|
analysis?: {
|
|
total?: SwtrmtPrcsZoneAnalysisMetric | null;
|
|
combined?: SwtrmtPrcsZoneAnalysisMetric | null;
|
|
rain?: SwtrmtPrcsZoneAnalysisMetric | null;
|
|
sewage?: SwtrmtPrcsZoneAnalysisMetric | null;
|
|
};
|
|
excluded?: {
|
|
missingInstlYearCount?: number | string | null;
|
|
};
|
|
};
|
|
|
|
type ZoneAnalysisSource = Record<string, any> | null | undefined;
|
|
|
|
export type RepairHistoryFilters = {
|
|
useCd?: string;
|
|
materialCode?: string;
|
|
diameterFrom?: string;
|
|
diameterTo?: string;
|
|
};
|
|
|
|
export type RepairHistoryRow = {
|
|
rowNo: number;
|
|
fid: string;
|
|
lyrTypeNm?: string | null;
|
|
fcltMngNo?: string | null;
|
|
repairCount: number;
|
|
latestRepairYmd?: string | null;
|
|
latestRepairYear?: number | null;
|
|
elapsedYearsSinceRepair?: number | null;
|
|
useCd?: string | null;
|
|
useNm?: string | null;
|
|
installationYear?: number | null;
|
|
burialDepth?: number | null;
|
|
materialCode?: string | null;
|
|
materialName?: string | null;
|
|
pdmtVl?: number | null;
|
|
prlgVl?: number | null;
|
|
geometryJson?: string | null;
|
|
};
|
|
|
|
export type RepairHistoryResponse = {
|
|
totalElements: number;
|
|
totalPages: number;
|
|
page: number;
|
|
size: number;
|
|
data: RepairHistoryRow[];
|
|
};
|
|
|
|
const ANALYSIS_ENDPOINT_PREFIX = "v1/swagePrcsZones";
|
|
const REPAIR_HISTORY_PAGE_SIZE = 200;
|
|
|
|
const firstValue = (...values: unknown[]) => {
|
|
const value = values.find((item) => {
|
|
if (item === null || item === undefined) return false;
|
|
const text = String(item).trim();
|
|
return text !== "" && text !== "-";
|
|
});
|
|
|
|
return value === undefined ? "" : String(value).trim();
|
|
};
|
|
|
|
export const getSwtrmtPrcsZoneId = (rawFeatureData: any, featureData: ZoneAnalysisSource) => {
|
|
const rawValues = rawFeatureData?.values_ ?? rawFeatureData ?? {};
|
|
|
|
return firstValue(
|
|
rawFeatureData?.getId?.(),
|
|
rawFeatureData?.id_,
|
|
rawFeatureData?.fid,
|
|
rawValues?.fid,
|
|
featureData?.fid,
|
|
rawValues?.swtrmt_zone_sn,
|
|
rawValues?.swtrmtZoneSn,
|
|
featureData?.swtrmt_zone_sn,
|
|
featureData?.swtrmtZoneSn,
|
|
rawValues?.zoneId,
|
|
featureData?.zoneId,
|
|
rawValues?.swtrmt_fclt_cd,
|
|
rawValues?.swtrmtFcltCd,
|
|
featureData?.swtrmt_fclt_cd,
|
|
featureData?.swtrmtFcltCd
|
|
);
|
|
};
|
|
|
|
export const getSwtrmtPrcsZoneAnalysisParams = (rawFeatureData: any, featureData: ZoneAnalysisSource) => {
|
|
const rawValues = rawFeatureData?.values_ ?? rawFeatureData ?? {};
|
|
const params = new URLSearchParams();
|
|
|
|
const entries = {
|
|
ctpvCd: firstValue(rawValues?.ctpv_cd, rawValues?.ctpvCd, featureData?.ctpv_cd, featureData?.ctpvCd),
|
|
sggCd: firstValue(rawValues?.sgg_cd, rawValues?.sggCd, featureData?.sgg_cd, featureData?.sggCd),
|
|
swtrmtFcltCd: firstValue(rawValues?.swtrmt_fclt_cd, rawValues?.swtrmtFcltCd, featureData?.swtrmt_fclt_cd, featureData?.swtrmtFcltCd),
|
|
swtrmtZoneNm: firstValue(rawValues?.swtrmt_zone_nm, rawValues?.swtrmtZoneNm, featureData?.swtrmt_zone_nm, featureData?.swtrmtZoneNm),
|
|
};
|
|
|
|
Object.entries(entries).forEach(([key, value]) => {
|
|
if (value) params.append(key, value);
|
|
});
|
|
|
|
return params;
|
|
};
|
|
|
|
export const fetchSwtrmtPrcsZoneAnalysis = async (
|
|
rawFeatureData: any,
|
|
featureData: ZoneAnalysisSource
|
|
): Promise<SwtrmtPrcsZoneAnalysisResponse | null> => {
|
|
const zoneId = getSwtrmtPrcsZoneId(rawFeatureData, featureData);
|
|
if (!zoneId) return null;
|
|
|
|
const params = getSwtrmtPrcsZoneAnalysisParams(rawFeatureData, featureData);
|
|
const query = params.toString();
|
|
const path = `${ANALYSIS_ENDPOINT_PREFIX}/${encodeURIComponent(zoneId)}/pplAnalysis${query ? `?${query}` : ""}`;
|
|
|
|
return (await getData(path)) ?? {};
|
|
};
|
|
|
|
const appendRepairHistoryFilters = (params: URLSearchParams, filters: RepairHistoryFilters) => {
|
|
Object.entries(filters).forEach(([key, value]) => {
|
|
const normalized = String(value ?? "").trim();
|
|
if (normalized) params.append(key, normalized);
|
|
});
|
|
};
|
|
|
|
const getRepairHistoryPath = (
|
|
zoneId: string,
|
|
filters: RepairHistoryFilters,
|
|
suffix = "",
|
|
extraParams: Record<string, string> = {},
|
|
) => {
|
|
const params = new URLSearchParams();
|
|
appendRepairHistoryFilters(params, filters);
|
|
Object.entries(extraParams).forEach(([key, value]) => {
|
|
const normalized = value.trim();
|
|
if (normalized) params.append(key, normalized);
|
|
});
|
|
const query = params.toString();
|
|
return `${ANALYSIS_ENDPOINT_PREFIX}/${encodeURIComponent(zoneId)}/repairHistories${suffix}${query ? `?${query}` : ""}`;
|
|
};
|
|
|
|
/** 윈도우 팝업과 부모 지도가 같은 전체 결과를 사용하도록 서버 페이지를 끝까지 합친다. */
|
|
export const fetchAllRepairHistoriesByZoneId = async (
|
|
zoneId: string,
|
|
filters: RepairHistoryFilters,
|
|
): Promise<RepairHistoryResponse> => {
|
|
if (!zoneId.trim()) throw new Error("처리구역 식별값이 없습니다.");
|
|
|
|
const firstParams = new URLSearchParams();
|
|
appendRepairHistoryFilters(firstParams, filters);
|
|
firstParams.set("page", "0");
|
|
firstParams.set("size", String(REPAIR_HISTORY_PAGE_SIZE));
|
|
const first = (await getData(
|
|
`${ANALYSIS_ENDPOINT_PREFIX}/${encodeURIComponent(zoneId)}/repairHistories?${firstParams.toString()}`,
|
|
)) as RepairHistoryResponse;
|
|
|
|
const pages: RepairHistoryResponse[] = [first];
|
|
for (let page = 1; page < (first.totalPages ?? 0); page += 1) {
|
|
const params = new URLSearchParams(firstParams);
|
|
params.set("page", String(page));
|
|
pages.push((await getData(
|
|
`${ANALYSIS_ENDPOINT_PREFIX}/${encodeURIComponent(zoneId)}/repairHistories?${params.toString()}`,
|
|
)) as RepairHistoryResponse);
|
|
}
|
|
|
|
const data = pages.flatMap((page) => page?.data ?? []);
|
|
return {
|
|
...first,
|
|
totalElements: data.length,
|
|
totalPages: 1,
|
|
page: 0,
|
|
size: data.length,
|
|
data,
|
|
};
|
|
};
|
|
|
|
/** 현재 조회 조건의 화면 목록 항목 파일을 내려받는다. */
|
|
export const downloadRepairHistoriesByZoneId = async (
|
|
zoneId: string,
|
|
filters: RepairHistoryFilters,
|
|
zoneName: string,
|
|
) => {
|
|
if (!zoneId.trim()) throw new Error("처리구역 식별값이 없습니다.");
|
|
return getBlobDataWithHeaders(getRepairHistoryPath(zoneId, filters, "/download", { zoneName }));
|
|
};
|