222 lines
7.3 KiB
TypeScript
222 lines
7.3 KiB
TypeScript
"use client";
|
|
|
|
import type { SelectDataType } from "@common/business_components";
|
|
import { formatDisplayData } from "@/components/lib/utils/formatDisplayValue";
|
|
import {
|
|
MS_SWAGE_PPL_CODES,
|
|
MS_SWAGE_PPL_USE_CODES,
|
|
MsSwagePplCol,
|
|
} from "../map/components/common/table";
|
|
|
|
export type AgedPipeFilters = {
|
|
elapsedYears: number;
|
|
ctpvCd: string;
|
|
sggCd: string;
|
|
};
|
|
|
|
export type AgedPipeRow = {
|
|
fid: string;
|
|
lyrTypeNm: string;
|
|
rowNumber: number;
|
|
fcltMngNo: string;
|
|
instlYmd: string;
|
|
pdmtVl: string | number;
|
|
prlgVl: string | number;
|
|
usgCd: string;
|
|
mqltCd: string;
|
|
elapsedYears: number | string;
|
|
ctpvNm?: string;
|
|
sggNm?: string;
|
|
[key: string]: unknown;
|
|
};
|
|
|
|
type PipeSource = Record<string, unknown>;
|
|
|
|
const useMap = new Map(MS_SWAGE_PPL_USE_CODES.map((item) => [item.val.trim(), item.text]));
|
|
const materialMap = new Map(MS_SWAGE_PPL_CODES.map((item) => [item.val.trim(), item.text]));
|
|
|
|
export const AGED_PIPE_DEFAULT_FILTERS: AgedPipeFilters = {
|
|
elapsedYears: 20,
|
|
ctpvCd: "0",
|
|
sggCd: "0",
|
|
};
|
|
|
|
export const AGED_PIPE_LIST_HEADLIST = [
|
|
{ id: "rowNumber", title: "NO", widthPercent: 6 },
|
|
{ id: "fcltMngNo", title: "시설관리번호", widthPercent: 18 },
|
|
{ id: "instlYmd", title: "설치일자", widthPercent: 12 },
|
|
{ id: "pdmtVl", title: "관경(mm)", widthPercent: 10 },
|
|
{ id: "prlgVl", title: "연장(m)", widthPercent: 10 },
|
|
{ id: "usgCd", title: "용도", widthPercent: 14 },
|
|
{ id: "mqltCd", title: "재질", widthPercent: 18 },
|
|
{ id: "elapsedYears", title: "경과년도", widthPercent: 12, align: "right" },
|
|
];
|
|
|
|
export const AGED_PIPE_EXCEL_HEADER = {
|
|
rowNumber: "NO",
|
|
fcltMngNo: "시설관리번호",
|
|
instlYmd: "설치일자",
|
|
pdmtVl: "관경(mm)",
|
|
prlgVl: "연장(m)",
|
|
usgCd: "용도",
|
|
mqltCd: "재질",
|
|
elapsedYears: "경과년도",
|
|
};
|
|
|
|
export const AGED_PIPE_DETAIL_FIELDS = MsSwagePplCol;
|
|
|
|
const getToday = () => new Date();
|
|
|
|
const pad2 = (value: number) => String(value).padStart(2, "0");
|
|
|
|
export const getCutoffYmd = (elapsedYears: number) => {
|
|
const today = getToday();
|
|
const cutoff = new Date(today.getFullYear() - elapsedYears, today.getMonth(), today.getDate());
|
|
return `${cutoff.getFullYear()}${pad2(cutoff.getMonth() + 1)}${pad2(cutoff.getDate())}`;
|
|
};
|
|
|
|
const normalizeYmd = (value: unknown) => String(value ?? "").replace(/[^0-9]/g, "").slice(0, 8);
|
|
|
|
const getCodePrefix = (source: PipeSource) =>
|
|
String(source.pbadmsEmdCd ?? source.pbadms_emd_cd ?? "").trim();
|
|
|
|
const resolveRegionName = (
|
|
code: string,
|
|
directName: unknown,
|
|
options: SelectDataType[],
|
|
prefixLength: number,
|
|
) => {
|
|
if (String(directName ?? "").trim()) return String(directName);
|
|
const prefix = code.slice(0, prefixLength);
|
|
return options.find((item) => String(item.val).trim() === prefix)?.text ?? "";
|
|
};
|
|
|
|
export const getElapsedYears = (value: unknown) => {
|
|
const normalized = normalizeYmd(value);
|
|
if (normalized.length < 4) return null;
|
|
|
|
const year = Number(normalized.slice(0, 4));
|
|
const month = Number(normalized.slice(4, 6) || "1");
|
|
const day = Number(normalized.slice(6, 8) || "1");
|
|
if (!year) return null;
|
|
|
|
const today = getToday();
|
|
let elapsed = today.getFullYear() - year;
|
|
if (
|
|
today.getMonth() + 1 < month ||
|
|
(today.getMonth() + 1 === month && today.getDate() < day)
|
|
) {
|
|
elapsed -= 1;
|
|
}
|
|
|
|
return Math.max(elapsed, 0);
|
|
};
|
|
|
|
export const buildAgedPipeCqlFilters = (filters: AgedPipeFilters) => {
|
|
const cqlFilters: string[] = [];
|
|
cqlFilters.push(`instl_ymd <= '${getCutoffYmd(filters.elapsedYears)}'`);
|
|
|
|
if (filters.sggCd !== "0") {
|
|
cqlFilters.push(`pbadms_emd_cd LIKE '${filters.sggCd}%'`);
|
|
} else if (filters.ctpvCd !== "0") {
|
|
cqlFilters.push(`pbadms_emd_cd LIKE '${filters.ctpvCd}%'`);
|
|
}
|
|
|
|
return cqlFilters;
|
|
};
|
|
|
|
export const matchesAgedPipeFilters = (source: PipeSource, filters: AgedPipeFilters) => {
|
|
const instlYmd = normalizeYmd(source.instl_ymd ?? source.instlYmd);
|
|
if (!instlYmd || instlYmd > getCutoffYmd(filters.elapsedYears)) return false;
|
|
|
|
const regionCode = getCodePrefix(source);
|
|
if (filters.sggCd !== "0") return regionCode.startsWith(filters.sggCd);
|
|
if (filters.ctpvCd !== "0") return regionCode.startsWith(filters.ctpvCd);
|
|
return true;
|
|
};
|
|
|
|
export const toDisplayPipeRow = (
|
|
source: PipeSource,
|
|
index: number,
|
|
page: number,
|
|
ctpvOptions: SelectDataType[],
|
|
sggOptions: SelectDataType[],
|
|
): AgedPipeRow => {
|
|
const formatted = formatDisplayData(source) as PipeSource;
|
|
const codePrefix = getCodePrefix(source);
|
|
const instlYmd = formatted.instlYmd ?? source.instlYmd ?? formatted.instl_ymd ?? source.instl_ymd;
|
|
const trimmedUse = String(source.usgCd ?? source.usg_cd ?? "").trim();
|
|
const trimmedMaterial = String(source.mqltCd ?? source.mqlt_cd ?? "").trim();
|
|
const pdmtVl = formatted.pdmtVl ?? source.pdmtVl ?? source.pdmt_vl ?? "-";
|
|
const prlgVl = formatted.prlgVl ?? source.prlgVl ?? source.prlg_vl ?? "-";
|
|
|
|
return {
|
|
...source,
|
|
...formatted,
|
|
fid: String(source.fid ?? ""),
|
|
lyrTypeNm: String(source.lyrTypeNm ?? "tb_ms_swage_ppl"),
|
|
rowNumber: (page - 1) * 10 + index + 1,
|
|
fcltMngNo: String(formatted.fcltMngNo ?? source.fcltMngNo ?? source.fclt_mng_no ?? "-"),
|
|
instlYmd: String(instlYmd ?? "-"),
|
|
pdmtVl: typeof pdmtVl === "number" ? pdmtVl : String(pdmtVl),
|
|
prlgVl: typeof prlgVl === "number" ? prlgVl : String(prlgVl),
|
|
usgCd: useMap.get(trimmedUse) ?? String(formatted.usgCd ?? source.usgCd ?? source.usg_cd ?? "-"),
|
|
mqltCd:
|
|
materialMap.get(trimmedMaterial) ??
|
|
String(formatted.mqltCd ?? source.mqltCd ?? source.mqlt_cd ?? "-"),
|
|
elapsedYears: getElapsedYears(source.instlYmd ?? source.instl_ymd) ?? "-",
|
|
ctpvNm: resolveRegionName(
|
|
codePrefix,
|
|
formatted.ctpvNm ?? source.ctpvNm ?? source.ctpv_nm,
|
|
ctpvOptions,
|
|
2,
|
|
),
|
|
sggNm: resolveRegionName(
|
|
codePrefix,
|
|
formatted.sggNm ?? source.sggNm ?? source.sgg_nm,
|
|
sggOptions,
|
|
5,
|
|
),
|
|
};
|
|
};
|
|
|
|
export const getPipeDisplayValue = (source: PipeSource, key: string) => {
|
|
const formatted = formatDisplayData(source) as PipeSource;
|
|
const keyMap: Record<string, string[]> = {
|
|
fclt_mng_no: ["fclt_mng_no", "fcltMngNo"],
|
|
inst_mng_no: ["inst_mng_no", "instMngNo"],
|
|
instl_ymd: ["instl_ymd", "instlYmd"],
|
|
mapsht_no: ["mapsht_no", "mapshtNo"],
|
|
pdmt_vl: ["pdmt_vl", "pdmtVl"],
|
|
prlg_vl: ["prlg_vl", "prlgVl"],
|
|
usg_cd: ["usg_cd", "usgCd"],
|
|
mqlt_cd: ["mqlt_cd", "mqltCd"],
|
|
avg_grdn: ["avg_grdn", "avgGrdn"],
|
|
drtw_mltv_area: ["drtw_mltv_area", "drtwMltvArea"],
|
|
excln_mltv_area: ["excln_mltv_area", "exclnMltvArea"],
|
|
tmpt_dpth: ["tmpt_dpth", "tmptDpth"],
|
|
tmpt_mhl_mng_no: ["tmpt_mhl_mng_no", "tmptMhlMngNo"],
|
|
scend_dpth: ["scend_dpth", "scendDpth"],
|
|
scend_mhl_mng_no: ["scend_mhl_mng_no", "scendMhlMngNo"],
|
|
trfln_cnt: ["trfln_cnt", "trflnCnt"],
|
|
vrtc_len: ["vrtc_len", "vrtcLen"],
|
|
wdth_len: ["wdth_len", "wdthLen"],
|
|
};
|
|
|
|
const candidates = keyMap[key] ?? [key];
|
|
for (const candidate of candidates) {
|
|
const value = formatted[candidate] ?? source[candidate];
|
|
if (value !== undefined && value !== null && value !== "") {
|
|
if (candidate === "usg_cd" || candidate === "usgCd") {
|
|
return useMap.get(String(source.usg_cd ?? source.usgCd ?? "").trim()) ?? value;
|
|
}
|
|
if (candidate === "mqlt_cd" || candidate === "mqltCd") {
|
|
return materialMap.get(String(source.mqlt_cd ?? source.mqltCd ?? "").trim()) ?? value;
|
|
}
|
|
return value;
|
|
}
|
|
}
|
|
|
|
return "-";
|
|
};
|