wr: 공통코드 조회 수정

This commit is contained in:
2026-06-05 17:44:51 +09:00
parent 3fee2a781f
commit 6df6e612bc
3 changed files with 294 additions and 8 deletions
+207
View File
@@ -0,0 +1,207 @@
import { SITE_ID } from "@/src/shared/config";
import { NextResponse } from "next/server";
export const revalidate = 60 * 60 * 24;
type SelectDataType = {
text: string;
val: string;
};
type EnvPartSelectDataType = SelectDataType & {
adstDliStrCd: string;
};
const codeMapping = {
WR001: "bdstUsgCd",
WR002: "rswtBdstType",
WR003: "rainFcltCd",
WR004: "bdstGrntchClass",
WR005: "rswtPrscCdMthdCd",
WR006: "orgwtKndCd",
WR007: "ruseMngMtd",
WR008: "rusePrcsMthdCd",
WR009: "erctUswtrPrcsMeth",
WR010: "ruseFcltSpot",
WR011: "pplQulity",
WR012: "pplLenght",
WR013: "bdstFilterYn",
WR014: "rainRswtMng",
WR015: "rainFcltFlowRate",
WR016: "dmdUszCd",
WR017: "sewageInFcltUse",
WR018: "sewageOutFclttUse",
WR019: "htdPowerMthdCd",
WR020: "htdUtztnUsgCd",
} as const;
const defaultHeaders = {
accept: "application/json",
"X-Site-Id": SITE_ID,
};
function getServerBaseUrl() {
const port = process.env.PORT ?? process.env.NEXT_PUBLIC_PORT ?? "3000";
const proxyHost = process.env.NEXT_PUBLIC_PROXY_HOST;
if (process.env.NODE_ENV === "production" && process.env.HOSTNAME) {
return `http://${process.env.HOSTNAME}:${port}`;
}
return proxyHost || `http://localhost:${port}`;
}
async function fetchJson(url: string, cookieHeader?: string) {
const response = await fetch(url, {
method: "GET",
headers: {
...defaultHeaders,
...(cookieHeader ? { cookie: cookieHeader } : {}),
},
next: { revalidate },
});
if (!response.ok) {
throw new Error(`Failed to fetch ${url}: ${response.status}`);
}
return response.json();
}
async function fetchOperationData(path: string, cookieHeader?: string) {
const json = await fetchJson(
`${getServerBaseUrl()}/operation-service${path}`,
cookieHeader
);
return json.data;
}
async function fetchCmsData(path: string, cookieHeader?: string) {
return fetchJson(`${getServerBaseUrl()}${path}`, cookieHeader);
}
async function fetchCommonCodesByKeys(keys: string[], cookieHeader?: string) {
const targets = [...new Set(keys)].filter(
(cd) => Boolean(codeMapping[cd as keyof typeof codeMapping])
);
const entries = await Promise.all(
targets.map(async (cd) => {
const mapping = codeMapping[cd as keyof typeof codeMapping];
const lwCd = await fetchCmsData(
`/cms-service/api/v1/lwpo-cds/up-cd/${cd}`,
cookieHeader
);
const list = Array.isArray(lwCd) ? lwCd : (lwCd.content ?? []);
return [
mapping,
list.map((it: any) => ({
text: it.lwpoCdNm,
val: it.lwpoCd,
})),
] as const;
})
);
return Object.fromEntries(entries) as Record<string, SelectDataType[]>;
}
export async function GET(request: Request) {
try {
const cookieHeader = request.headers.get("cookie") ?? "";
const [sgg, city, rvbsn, mdmbsn, lgbsn, lclgvrnmnt, upCd] =
await Promise.all([
fetchOperationData("/addr/sgg", cookieHeader),
fetchOperationData("/addr/city", cookieHeader),
fetchOperationData("/addr/sarea", cookieHeader),
fetchOperationData("/addr/midArea", cookieHeader),
fetchOperationData("/addr/largeArea", cookieHeader),
fetchOperationData("/addr/govArea", cookieHeader),
fetchCmsData(
"/cms-service/api/v1/up-codes?keyword=&upCd=&cdSe=&useYn=Y&siteId=WR&page=0&size=100&sort=string",
cookieHeader
),
]);
const upWrCode: string[] = (upCd.content ?? [])
.filter((item: any) => item.upCd.slice(0, 2) === "WR")
.map((cd: any) => cd.upCd);
const lwCds = await fetchCommonCodesByKeys(upWrCode, cookieHeader);
const payload = {
sggCd: [
...((sgg ?? []).map((item: any) => ({
text: item.gugun || "",
val: String(item.adstDstrCd) || "",
})) as SelectDataType[]),
],
cityCd: [
{ val: "0", text: "전체" },
...((city ?? []).map((item: any) => ({
val: item.adstDstrCd,
text: item.sido,
})) as SelectDataType[]),
],
rvbsnCd: [
{ val: "0", text: "전체" },
...((rvbsn ?? []).map((item: any) => ({
val: item.rvbsnCd,
text: item.rvbsn,
})) as SelectDataType[]),
],
mdmbsnCd: [
{ val: "0", text: "전체" },
...((mdmbsn ?? []).map((item: any) => ({
val: item.rvbsnCd,
text: item.mdmbsn,
})) as SelectDataType[]),
],
lgbsnCd: [
{ val: "0", text: "전체" },
...((lgbsn ?? []).map((item: any) => ({
val: item.rvbsnCd,
text: item.lgbsn,
})) as SelectDataType[]),
],
lclgvrnmntCd: [
{ val: "0", text: "전체", adstDliStrCd: "" },
...((lclgvrnmnt ?? []).map((item: any) => ({
val: item.lclgvrnmntCd,
text: item.lclgvrnmntNm,
adstDliStrCd: item.adstDliStrCd || "",
})) as EnvPartSelectDataType[]),
],
rainFcltCd: lwCds["rainFcltCd"] ?? [],
bdstUsgCd: lwCds["bdstUsgCd"] ?? [],
orgwtKndCd: lwCds["orgwtKndCd"] ?? [],
pplQulity: lwCds["pplQulity"] ?? [],
pplLenght: lwCds["pplLenght"] ?? [],
dmdUszCd: lwCds["dmdUszCd"] ?? [],
sewageOutFclttUse: lwCds["sewageOutFclttUse"] ?? [],
rainRswtMng: lwCds["rainRswtMng"] ?? [],
rainFcltFlowRate: lwCds["rainFcltFlowRate"] ?? [],
ruseMngMtd: lwCds["ruseMngMtd"] ?? [],
rusePrcsMthdCd: lwCds["rusePrcsMthdCd"] ?? [],
erctUswtrPrcsMeth: lwCds["erctUswtrPrcsMeth"] ?? [],
bdstGrntchClass: lwCds["bdstGrntchClass"] ?? [],
htdPowerMthdCd: lwCds["htdPowerMthdCd"] ?? [],
htdUtztnUsgCd: lwCds["htdUtztnUsgCd"] ?? [],
rswtBdstType: lwCds["rswtBdstType"] ?? [],
bdstTotalUsgType: (lwCds["bdstUsgCd"] ?? []).concat(lwCds["rswtBdstType"] ?? []),
};
return NextResponse.json(payload, {
headers: {
"Cache-Control": "s-maxage=86400, stale-while-revalidate=3600",
},
});
} catch (error) {
console.error("Failed to load common codes:", error);
return NextResponse.json(
{ message: "Failed to load common codes" },
{ status: 500 }
);
}
}
+69 -7
View File
@@ -371,18 +371,80 @@ export const codeActionExport: (set: any, get:any) => comCodeActions = (set: any
},
initCommonCodes: async () => {
if (get().code.isInit) return;
const response = await fetch("/api/common-codes", {
method: "GET",
headers: {
accept: "application/json",
},
});
await getSggCd(set);
await getCityCd(set);
await getRegionCd(set);
await getMiddleRegionCd(set);
await getUnitWaterShedCd(set);
await getEnvPartCd(set);
await getCommonUpCd(set);
if (!response.ok) {
throw new Error(`공통 코드 조회 실패: ${response.status}`);
}
const data = await response.json();
lwCds["rainFcltCd"] = data.rainFcltCd ?? lwCds["rainFcltCd"] ?? [];
lwCds["bdstUsgCd"] = data.bdstUsgCd ?? lwCds["bdstUsgCd"] ?? [];
lwCds["orgwtKndCd"] = data.orgwtKndCd ?? lwCds["orgwtKndCd"] ?? [];
lwCds["pplQulity"] = data.pplQulity ?? lwCds["pplQulity"] ?? [];
lwCds["pplLenght"] = data.pplLenght ?? lwCds["pplLenght"] ?? [];
lwCds["dmdUszCd"] = data.dmdUszCd ?? lwCds["dmdUszCd"] ?? [];
lwCds["sewageOutFclttUse"] =
data.sewageOutFclttUse ?? lwCds["sewageOutFclttUse"] ?? [];
lwCds["rainRswtMng"] = data.rainRswtMng ?? lwCds["rainRswtMng"] ?? [];
lwCds["rainFcltFlowRate"] =
data.rainFcltFlowRate ?? lwCds["rainFcltFlowRate"] ?? [];
lwCds["ruseMngMtd"] = data.ruseMngMtd ?? lwCds["ruseMngMtd"] ?? [];
lwCds["rusePrcsMthdCd"] =
data.rusePrcsMthdCd ?? lwCds["rusePrcsMthdCd"] ?? [];
lwCds["erctUswtrPrcsMeth"] =
data.erctUswtrPrcsMeth ?? lwCds["erctUswtrPrcsMeth"] ?? [];
lwCds["bdstGrntchClass"] =
data.bdstGrntchClass ?? lwCds["bdstGrntchClass"] ?? [];
lwCds["htdPowerMthdCd"] =
data.htdPowerMthdCd ?? lwCds["htdPowerMthdCd"] ?? [];
lwCds["htdUtztnUsgCd"] =
data.htdUtztnUsgCd ?? lwCds["htdUtztnUsgCd"] ?? [];
lwCds["rswtBdstType"] =
data.rswtBdstType ?? lwCds["rswtBdstType"] ?? [];
lwCds["bdstTotalUsgType"] =
data.bdstTotalUsgType ?? lwCds["bdstTotalUsgType"] ?? [];
set((state) => ({
code: {
...state.code,
sggCd: data.sggCd ?? state.code.sggCd,
cityCd: data.cityCd ?? state.code.cityCd,
rvbsnCd: data.rvbsnCd ?? state.code.rvbsnCd,
mdmbsnCd: data.mdmbsnCd ?? state.code.mdmbsnCd,
lgbsnCd: data.lgbsnCd ?? state.code.lgbsnCd,
lclgvrnmntCd: data.lclgvrnmntCd ?? state.code.lclgvrnmntCd,
rainFcltCd: data.rainFcltCd ?? state.code.rainFcltCd,
bdstUsgCd: data.bdstUsgCd ?? state.code.bdstUsgCd,
orgwtKndCd: data.orgwtKndCd ?? state.code.orgwtKndCd,
pplQulity: data.pplQulity ?? state.code.pplQulity,
pplLenght: data.pplLenght ?? state.code.pplLenght,
dmdUszCd: data.dmdUszCd ?? state.code.dmdUszCd,
sewageOutFclttUse:
data.sewageOutFclttUse ?? state.code.sewageOutFclttUse,
rainRswtMng: data.rainRswtMng ?? state.code.rainRswtMng,
rainFcltFlowRate:
data.rainFcltFlowRate ?? state.code.rainFcltFlowRate,
ruseMngMtd: data.ruseMngMtd ?? state.code.ruseMngMtd,
rusePrcsMthdCd:
data.rusePrcsMthdCd ?? state.code.rusePrcsMthdCd,
erctUswtrPrcsMeth:
data.erctUswtrPrcsMeth ?? state.code.erctUswtrPrcsMeth,
bdstGrntchClass:
data.bdstGrntchClass ?? state.code.bdstGrntchClass,
htdPowerMthdCd:
data.htdPowerMthdCd ?? state.code.htdPowerMthdCd,
htdUtztnUsgCd:
data.htdUtztnUsgCd ?? state.code.htdUtztnUsgCd,
rswtBdstType: data.rswtBdstType ?? state.code.rswtBdstType,
bdstTotalUsgType:
data.bdstTotalUsgType ?? state.code.bdstTotalUsgType,
isInit: true,
},
}));
+18 -1
View File
@@ -1,5 +1,6 @@
"use client";
import { useEffect } from "react";
import { DndProvider } from "react-dnd";
import { MultiBackend, getBackendOptions } from "@minoru/react-dnd-treeview";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
@@ -16,7 +17,10 @@ import i18next from "i18next";
import { I18nextProvider } from "react-i18next";
import { Toaster } from "react-hot-toast";
import koBase from "@/public/locales/ko/message.json";
import { StoreProvider as WrStoreProvider } from "@/app/store";
import {
StoreProvider as WrStoreProvider,
useWrStore,
} from "@/app/store";
//import { LoginApi } from "@/src/entities/auth";
//import { useEffect } from "react";
import { setCookie } from "@/src/shared/lib/cookie";
@@ -34,6 +38,18 @@ i18n.init({
},
});
function CommonCodeInitializer() {
const isInit = useWrStore((state) => state.code.isInit);
const initCommonCodes = useWrStore((state) => state.initCommonCodes);
useEffect(() => {
if (isInit) return;
initCommonCodes();
}, [isInit, initCommonCodes]);
return null;
}
const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {
const queryClient = new QueryClient();
return (
@@ -49,6 +65,7 @@ const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {
>
<I18nextProvider i18n={i18n}>
<WrStoreProvider>
<CommonCodeInitializer />
{children}
</WrStoreProvider>
</I18nextProvider>