diff --git a/apps/dm/.env.development b/apps/dm/.env.development
index 581a639c5..66f910fbe 100644
--- a/apps/dm/.env.development
+++ b/apps/dm/.env.development
@@ -17,3 +17,6 @@ NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/ap
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.66:8883/sewerage-service/api # 박이정
+
+NEXT_PUBLIC_FINDADRESS_URL=https://business.juso.go.kr/addrlink/addrLinkApi.do
+NEXT_PUBLIC_WR_ADDRESS_KEY = devU01TX0FVVEgyMDI1MDgyNTEwMzkwNDExNjEwNTM=
diff --git a/apps/dm/.env.local b/apps/dm/.env.local
index f6000ca82..1c3474d11 100644
--- a/apps/dm/.env.local
+++ b/apps/dm/.env.local
@@ -20,3 +20,6 @@ NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/ap
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.66:8883/sewerage-service/api # 박이정
+
+NEXT_PUBLIC_FINDADRESS_URL=https://business.juso.go.kr/addrlink/addrLinkApi.do
+NEXT_PUBLIC_WR_ADDRESS_KEY = devU01TX0FVVEgyMDI1MDgyNTEwMzkwNDExNjEwNTM=
diff --git a/apps/dm/.env.production b/apps/dm/.env.production
index 4ce1ba027..358de43c9 100644
--- a/apps/dm/.env.production
+++ b/apps/dm/.env.production
@@ -16,3 +16,6 @@ NEXT_PUBLIC_NGII_URL = http://10.98.25.94:18080/openapi/Gettile.do?apiKey=BDE2BE
NEXT_PUBLIC_SEWERAGE_API_URL = http://apigateway.iipbs-dev.svc.cluster.local:8000/sewerage-service/api
+
+NEXT_PUBLIC_FINDADRESS_URL=https://business.juso.go.kr/addrlink/addrLinkApi.do
+NEXT_PUBLIC_WR_ADDRESS_KEY = U01TXOFVVEgyMDI1MDgyODE0MTAxNzExNjEyMjA=
diff --git a/apps/dm/components/ui/common/utils/utils.ts b/apps/dm/components/ui/common/utils/utils.ts
index f66437553..19c92bff2 100644
--- a/apps/dm/components/ui/common/utils/utils.ts
+++ b/apps/dm/components/ui/common/utils/utils.ts
@@ -15,4 +15,40 @@ export const sanitizeInput = (val: string, allowDecimal = false) => {
// 정수만 허용
return val.replace(/[^0-9]/g, "");
-};
\ No newline at end of file
+};
+
+
+
+// utils: format Date <-> "YYYY-MM-DD" without moment
+export const formatDateToYMD=(value: Date): string => {
+ if (!value) return "";
+ // value can be Date | string ("YYYY-MM-DD")
+ if (typeof value === "string") {
+ // assume already in yyyy-mm-dd
+ if (/^\d{4}-\d{2}-\d{2}$/.test(value)) return value;
+ const d = new Date(value);
+ if (isNaN(d.getTime())) return "";
+ return toYMD(d);
+ }
+ if (value instanceof Date) {
+ if (isNaN(value.getTime())) return "";
+ return toYMD(value);
+ }
+ return "";
+}
+
+const toYMD=(date: Date): string => {
+ // avoid timezone shift by normalizing to local date parts
+ const y = date.getFullYear();
+ const m = String(date.getMonth() + 1).padStart(2, "0");
+ const day = String(date.getDate()).padStart(2, "0");
+ return `${y}-${m}-${day}`;
+}
+
+// const parseYMDToDate=(ymd: string): Date | null => {
+// if (!/^\d{4}-\d{2}-\d{2}$/.test(ymd)) return null;
+// const [y, m, d] = ymd.split("-").map(Number);
+// const date = new Date(y, (m - 1), d);
+// // validate round-trip
+// return (date.getFullYear() === y && date.getMonth() === m - 1 && date.getDate() === d) ? date : null;
+// }
\ No newline at end of file
diff --git a/apps/dm/components/ui/sdmInfoInsertForm/component.tsx b/apps/dm/components/ui/sdmInfoInsertForm/component.tsx
index 69514da41..7c6c13b32 100644
--- a/apps/dm/components/ui/sdmInfoInsertForm/component.tsx
+++ b/apps/dm/components/ui/sdmInfoInsertForm/component.tsx
@@ -2,7 +2,7 @@ import ModalSimilarPage from "@/app/(base-layout)/pages/sdmMng/sdmInfoInsert/mod
import { useDmStore } from "@/app/store";
import {
CANDIDATE,
- DatePicker,
+ // DatePicker,
FormField,
FormLabel,
FormUi,
@@ -10,7 +10,7 @@ import {
UiModal,
} from "@common/business_components";
import { Input } from "@common/components";
-import { Button, Label } from "@common/components/ui";
+import { Button, Label } from "@common/components/ui";
import { useSearchParams } from "next/navigation";
import { useCallback, useEffect, useState } from "react";
import { AccessibleFormField } from "./AccessibleFormField";
@@ -22,7 +22,7 @@ import {
} from "react-hook-form";
import SearchInputText from "../common/searhDemandInput/component";
import React from "react";
-import { sanitizeInput } from "../common/utils/utils";
+import { formatDateToYMD, sanitizeInput } from "../common/utils/utils";
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
import type { SdmInfoFormData } from "@/app/store/sdmMng";
@@ -161,7 +161,9 @@ export function SdmInfoRegForm({
if (defaults) {
Object.entries(defaults).forEach(([field, value]) => {
- form.setValue(field as keyof SdmInfoFormData, value, { shouldDirty: true });
+ form.setValue(field as keyof SdmInfoFormData, value, {
+ shouldDirty: true,
+ });
});
}
}, [form.getValues("usePurpose")]);
@@ -208,8 +210,8 @@ export function SdmInfoRegForm({
formIndex: 0,
required: true,
component: (field) => (
-
-
+ {/* {
@@ -224,8 +226,18 @@ export function SdmInfoRegForm({
},
}}
showOutsideDays={true}
- selectClass={undefined}
- />
+ selectClass={undefined}
+ /> */}
+ {/* 네이티브 input */}
+ {
+ const selectedDate = e.target.value ? new Date(e.target.value) : null;
+ field.onChange(selectedDate);
+ }}
+ value={ formatDateToYMD(field.value as Date) }
+ />
),
},
@@ -363,13 +375,11 @@ export function SdmInfoRegForm({
render={({ field }) =>
name === "money" ? (
-
- { component(field)}
+
+ {component(field)}
- // {component(field)}
) : (
+ // {component(field)}
{
field.onChange(val.toString());
}}
- value={field.value }
+ value={field.value}
readOnly={isDisabled}
onBlur={field.onBlur}
ref={field.ref}
diff --git a/apps/dm/middleware.ts b/apps/dm/middleware.ts
index 8fcfd4167..6b37ac02e 100644
--- a/apps/dm/middleware.ts
+++ b/apps/dm/middleware.ts
@@ -7,6 +7,8 @@ const serverApiUrl = process.env.NEXT_PUBLIC_CS_SERVER_API_URL;
const GEOSERVER_URL = process.env.NEXT_PUBLIC_GEOSERVER_URL || "";
const LX_GEOSERVER_URL = process.env.NEXT_PUBLIC_LX_GEOSERVER_URL || "";
const SEWERAGE_API_URL = process.env.NEXT_PUBLIC_SEWERAGE_API_URL || "";
+const BUSINESS_JUSO_API_URL = process.env.NEXT_PUBLIC_FINDADRESS_URL || "";
+const AdressKey = process.env.NEXT_PUBLIC_WR_ADDRESS_KEY || "";
export function middleware(req: NextRequest) {
const pathname = req.nextUrl.pathname;
@@ -24,8 +26,8 @@ export function middleware(req: NextRequest) {
if (pathname.startsWith("/server")) {
const decodedParams = Array.from(searchParams.entries())
- .map(([key, value]) => `${key}=${decodeURIComponent(value)}`)
- .join("&");
+ .map(([key, value]) => `${key}=${decodeURIComponent(value)}`)
+ .join("&");
const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${
decodedParams ? `?${decodedParams}` : ""
@@ -38,7 +40,6 @@ export function middleware(req: NextRequest) {
return NextResponse.redirect(new URL("/pages/wrStatus", req.url));
}
-
if (pathname.startsWith("/attach-service")) {
const requestHeaders = new Headers(req.headers);
// const token =
@@ -69,7 +70,7 @@ export function middleware(req: NextRequest) {
`[Middleware] Rewriting from '/user-service' path to: ${newUrl}`
);
return NextResponse.rewrite(new URL(newUrl), {
- headers: requestHeaders
+ headers: requestHeaders,
});
}
@@ -81,33 +82,31 @@ export function middleware(req: NextRequest) {
let newUrl = `${GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`;
if (
- typename == "hasudo:tb_il_swage_prcs_fclt" //하수처리시설
- || typename == "hasudo:tb_ms_swage_prcs_zone" //하수처리구역
- || typename == "hasudo:tb_ms_sbmrg_dngr_map" //침수위험지도
- || typename == "hasudo:tb_ms_flood_dngr_map" //도시침수지도
+ typename == "hasudo:tb_il_swage_prcs_fclt" || //하수처리시설
+ typename == "hasudo:tb_ms_swage_prcs_zone" || //하수처리구역
+ typename == "hasudo:tb_ms_sbmrg_dngr_map" || //침수위험지도
+ typename == "hasudo:tb_ms_flood_dngr_map" //도시침수지도
) {
newUrl = `${GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`;
- }
- else if (
- typename == "hasudo:tb_ms_swage_ppl" //관로
- || typename == "hasudo:tb_ms_swage_mhl" //맨홀
- || typename == "hasudo:tb_ms_swage_pmstn" //펌프장
- || typename == "hasudo:tb_ms_stofcbr" //우수토실
+ } else if (
+ typename == "hasudo:tb_ms_swage_ppl" || //관로
+ typename == "hasudo:tb_ms_swage_mhl" || //맨홀
+ typename == "hasudo:tb_ms_swage_pmstn" || //펌프장
+ typename == "hasudo:tb_ms_stofcbr" //우수토실
) {
newUrl = `${LX_GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`;
- }
- else if (
- typename == "hasudo:om_dt_untrt_swg_rain" //중점우수토실
- || typename == "hasudo:om_wqlt_station" //관측소
- || typename == "hasudo:tb_wr_bdst_ruse_fclt" //재이용시설
- || typename == "hasudo:tb_wr_rnwtr_utztn_fclt" //빗물이용시설
- || typename == "hasudo:tb_wr_rswtr_fclt" //중수도시설
- || typename == "hasudo:tb_wr_htdfl_fclt" //온배수시설
- || typename == "hasudo:tb_wr_ruse_fclt_dmd_co" //수요처
- || typename == "hasudo:tb_wr_tmpr_dmd_co" //잠재수요처
- ){
+ } else if (
+ typename == "hasudo:om_dt_untrt_swg_rain" || //중점우수토실
+ typename == "hasudo:om_wqlt_station" || //관측소
+ typename == "hasudo:tb_wr_bdst_ruse_fclt" || //재이용시설
+ typename == "hasudo:tb_wr_rnwtr_utztn_fclt" || //빗물이용시설
+ typename == "hasudo:tb_wr_rswtr_fclt" || //중수도시설
+ typename == "hasudo:tb_wr_htdfl_fclt" || //온배수시설
+ typename == "hasudo:tb_wr_ruse_fclt_dmd_co" || //수요처
+ typename == "hasudo:tb_wr_tmpr_dmd_co" //잠재수요처
+ ) {
const url = req.nextUrl.clone();
- url.searchParams.set('TYPENAME', typename.replace("hasudo:",""));
+ url.searchParams.set("TYPENAME", typename.replace("hasudo:", ""));
queryParams = url.searchParams.toString();
newUrl = `${SEWERAGE_API_URL}/v1/map/geometry${queryParams ? `?${queryParams}` : ""}`;
}
@@ -118,15 +117,41 @@ export function middleware(req: NextRequest) {
if (pathname.startsWith("/sewerage-service")) {
const queryParams = searchParams.toString();
- const newUrl = `${SEWERAGE_API_URL}${pathname.replace("/sewerage-service/api", "")}${queryParams ? `?${queryParams}` : ""
- }`;
+ const newUrl = `${SEWERAGE_API_URL}${pathname.replace("/sewerage-service/api", "")}${
+ queryParams ? `?${queryParams}` : ""
+ }`;
console.log(`[Middleware] Rewriting from '/geoserver' path to: ${newUrl}`);
return NextResponse.rewrite(new URL(newUrl));
}
+ if (pathname.startsWith("/bussiness-juso-service")) {
+ console.log("AdressKey ", AdressKey);
+ const params = new URLSearchParams({
+ currentPage: "1", // 원하는 페이지
+ countPerPage: "5", // 페이지당 결과 수
+ keyword: searchParams.get("keyword") || "", // 검색어(주소)
+ confmKey: AdressKey, // 인증키 인터넷용 패쇄망용은 따로 발급 필요 즉 middleware에서 치환해서 사용해야할듯
+ resultType: "json", // 결과 형식 기본은 xml
+ });
+ const newUrl = `${BUSINESS_JUSO_API_URL}?${params.toString()}`;
+ console.log(`[Middleware] Request to business.juso.go.kr`);
+ console.log(req.url);
+ console.log(
+ `[Middleware] Rewriting from '/business.juso.go.kr' path to: ${newUrl}`
+ );
+ return NextResponse.rewrite(new URL(newUrl));
+ }
return NextResponse.next();
}
export const config = {
- matcher: ["/server/:path*", "/user-service/:path*", "/attach-service/:path*", "/geoserver/:path*", "/sewerage-service/:path*", "/"],
+ matcher: [
+ "/server/:path*",
+ "/user-service/:path*",
+ "/attach-service/:path*",
+ "/geoserver/:path*",
+ "/sewerage-service/:path*",
+ "/bussiness-juso-service/:path*",
+ "/",
+ ],
};
diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx
index 24f9a3f8d..b3db19b1c 100644
--- a/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx
+++ b/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx
@@ -12,8 +12,8 @@ import RdiiChart from './chart/rdiiChart';
import { useInfilChartModalStore, useRdiiChartModalStore } from "./chartModalStore";
import { formatDisplayData } from '@/components/lib/utils/formatDisplayValue';
import { codeMapper } from "../common/codeMapper";
-import { searchUpperPpls } from '@common/business_components/ui/map/Gis';
import LoadingOverlay from '@/components/ui/LoadingBar';
+import { searchUpperPpls } from "./smh";
const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, featureData: any }) => {
@@ -58,7 +58,7 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
const getSelectedLayers = () => {
let result = null;
const layers = gisMap.getLayers().getArray(); // gisMap에서 모든 레이어 가져오기
- let featureLayer: { get: (key: string) => any }; // 피처가 속한 레이어를 찾기 위한 변수
+ let featureLayer: any = null; // 피처가 속한 레이어를 찾기 위한 변수
layers.some((layer: any) => {
const source = layer.getSource();
// if (source && featureData && featureData.fid) {
@@ -77,98 +77,119 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
setIsClicked(true);
console.log('gis data', featureData.values_);
const lyrTyNm = featureData.id_.split('.')[0];
- if (lyrTyNm === 'tb_ms_swage_ppl') {
- result = '하수관로';
- setHeadlist(MsSwagePplCol);
- setLayerSpecificNm(featureData.values_.fclt_mng_no);
- }
- else if (lyrTyNm === 'tb_ms_swage_mhl') {
- result = '하수맨홀';
- setHeadlist(MsSwageMhlCol);
- setLayerSpecificNm(featureData.values_.fclt_mng_no);
- }
- else if (lyrTyNm === 'tb_ms_swage_pmstn') { // 하수펌프장
- const drtwPumpCode = DRTW_SEWAGE_PUMP_USE_CODES.find(code => code.text === '오수펌프장');
- if (drtwPumpCode && featureData.values_.usg_cd.trim() === drtwPumpCode.val) {
- setIsDrtwSewagePump(true);
- setHeadlist(DrtwSewagePumpCol);
+
+ switch (lyrTyNm) {
+ case 'tb_ms_swage_ppl': {
+ result = '하수관로';
+ setHeadlist(MsSwagePplCol);
+ setLayerSpecificNm(featureData.values_.fclt_mng_no);
+ break;
}
- else {
- setIsDrtwSewagePump(false);
- setHeadlist(ExclnSewagePumpCol);
+ case 'tb_ms_swage_mhl': {
+ result = '하수맨홀';
+ setHeadlist(MsSwageMhlCol);
+ setLayerSpecificNm(featureData.values_.fclt_mng_no);
+ break;
+ }
+ case 'tb_ms_swage_pmstn': {
+ const drtwPumpCode = DRTW_SEWAGE_PUMP_USE_CODES.find(code => code.text === '오수펌프장');
+ if (drtwPumpCode && featureData.values_.usg_cd.trim() === drtwPumpCode.val) {
+ setIsDrtwSewagePump(true);
+ setHeadlist(DrtwSewagePumpCol);
+ }
+ else {
+ setIsDrtwSewagePump(false);
+ setHeadlist(ExclnSewagePumpCol);
+ }
+ setLayerSpecificNm(featureData.values_.fclt_mng_no);
+ result = '하수펌프장';
+ break;
+ }
+ case 'tb_il_swage_prcs_fclt': {
+ result = '하수처리시설';
+ setHeadlist(SwtrmtFcltCol);
+ setLayerSpecificNm(featureData.values_.swtrmt_fclt_cd);
+ break;
+ }
+ case 'tb_ms_swage_prcs_zone': {
+ result = '하수처리구역';
+ setHeadlist(SwtrmtPrcsZoneCol);
+ setLayerSpecificNm(featureData.values_.swtrmt_fclt_cd);
+ break;
+ }
+ case 'tb_ms_stofcbr': {
+ result = '우수토실';
+ setHeadlist(stofcbrCol);
+ setLayerSpecificNm(featureData.values_.fclt_mng_no);
+ break;
+ }
+ case 'om_dt_untrt_swg_rain': {
+ result = '중점우수토실';
+ setHeadlist(untrtSwgRainCol1);
+ setHeadlist2(untrtSwgRainCol2);
+ setLayerSpecificNm(featureData.values_.manage_no);
+ break;
+ }
+ default: {
+ result = featureLayer ? featureLayer.get('lyrNm') : null;
+ break;
}
- setLayerSpecificNm(featureData.values_.fclt_mng_no);
- result = '하수펌프장';
}
- else if (lyrTyNm === 'tb_il_swage_prcs_fclt') {
- result = '하수처리시설';
- setHeadlist(SwtrmtFcltCol);
- setLayerSpecificNm(featureData.values_.swtrmt_fclt_cd);
- }
- else if (lyrTyNm === 'tb_ms_swage_prcs_zone') {
- result = '하수처리구역';
- setHeadlist(SwtrmtPrcsZoneCol);
- setLayerSpecificNm(featureData.values_.swtrmt_fclt_cd);
- }
- else if (lyrTyNm === 'tb_ms_stofcbr') {
- result = '우수토실';
- setHeadlist(stofcbrCol);
- setLayerSpecificNm(featureData.values_.fclt_mng_no);
- }
- else if (lyrTyNm === 'om_dt_untrt_swg_rain') {
- result = '중점우수토실';
- setHeadlist(untrtSwgRainCol1);
- setHeadlist2(untrtSwgRainCol2);
- setLayerSpecificNm(featureData.values_.manage_no);
- }
- else result = featureLayer.get('lyrNm');
}
else {
// SearchModal 클릭 이벤트
setIsClicked(false);
console.log('SearchModal data', featureData);
const lyrTyNm = featureData.lyrTypeNm;
- if (featureData.lyrTypeNm === 'tb_ms_swage_ppl') {
- result = '하수관로';
- setHeadlist(MsSwagePplCol2)
- setLayerSpecificNm(featureData.swtrmtFcltCd);
- }
- else if (featureData.lyrTypeNm === 'tb_ms_swage_mhl') {
- result = '하수맨홀';
- setHeadlist(MsSwageMhlCol2)
- setLayerSpecificNm(featureData.fcltMngNo);
- }
- else if (featureData.lyrTypeNm === 'tb_ms_swage_pmstn') { // 하수펌프장
- const drtwPumpCode = DRTW_SEWAGE_PUMP_USE_CODES.find(code => code.text === '오수펌프장');
- if (drtwPumpCode && featureData.usgCd.trim() === drtwPumpCode.val) {
- console.log('오수펌프장');
- setIsDrtwSewagePump(false);
- setHeadlist(ExclnSewagePumpCol2)
+
+ switch (lyrTyNm) {
+ case 'tb_ms_swage_ppl': {
+ result = '하수관로';
+ setHeadlist(MsSwagePplCol2)
+ setLayerSpecificNm(featureData.swtrmtFcltCd);
+ break;
}
- else {
- console.log('빗물펌프장');
- setIsDrtwSewagePump(true);
- setHeadlist(DrtwSewagePumpCol2)
+ case 'tb_ms_swage_mhl': {
+ result = '하수맨홀';
+ setHeadlist(MsSwageMhlCol2)
+ setLayerSpecificNm(featureData.fcltMngNo);
+ break;
+ }
+ case 'tb_ms_swage_pmstn': {
+ const drtwPumpCode = DRTW_SEWAGE_PUMP_USE_CODES.find(code => code.text === '오수펌프장');
+ if (drtwPumpCode && featureData.usgCd.trim() === drtwPumpCode.val) {
+ console.log('오수펌프장');
+ setIsDrtwSewagePump(false);
+ setHeadlist(ExclnSewagePumpCol2)
+ }
+ else {
+ console.log('빗물펌프장');
+ setIsDrtwSewagePump(true);
+ setHeadlist(DrtwSewagePumpCol2)
+ }
+ setLayerSpecificNm(featureData.fcltMngNo);
+ result = '하수펌프장';
+ break;
+ }
+ case 'tb_il_swage_prcs_fclt': {
+ result = '하수처리시설';
+ setHeadlist(SwtrmtFcltCol2)
+ setLayerSpecificNm(featureData.swtrmtFcltCd);
+ break;
+ }
+ case 'tb_ms_swage_prcs_zone': {
+ result = '하수처리구역';
+ setHeadlist(SwtrmtPrcsZoneCol2);
+ setLayerSpecificNm(featureData.swtrmtFcltCd);
+ break;
+ }
+ case 'tb_ms_stofcbr': {
+ result = '우수토실';
+ setHeadlist(stofcbrCol2)
+ setLayerSpecificNm(featureData.fcltMngNo);
+ break;
}
- setLayerSpecificNm(featureData.fcltMngNo);
- result = '하수펌프장';
}
- else if (featureData.lyrTypeNm === 'tb_il_swage_prcs_fclt') {
- result = '하수처리시설';
- setHeadlist(SwtrmtFcltCol2)
- setLayerSpecificNm(featureData.swtrmtFcltCd);
- }
- else if (featureData.lyrTypeNm === 'tb_ms_swage_prcs_zone') {
- result = '하수처리구역';
- setHeadlist(SwtrmtPrcsZoneCol2);
- setLayerSpecificNm(featureData.swtrmtFcltCd);
- }
- else if (featureData.lyrTypeNm === 'tb_ms_stofcbr') {
- result = '우수토실';
- setHeadlist(stofcbrCol2)
- setLayerSpecificNm(featureData.fcltMngNo);
- }
- // else if (featureData.lyrTypeNm === 'om_dt_untrt_swg_rain') result = '중점우수토실';
}
return result;
@@ -424,7 +445,7 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
className="px-2 py-1 text-xl text-gray-600 border border-gray-600 rounded hover:bg-gray-700 mr-4"
onClick={() => {
setIsLoading(true);
- searchUpperPpls(layerSpecificNm).finally(() => setIsLoading(false));
+ searchUpperPpls(gisMap, layerSpecificNm).finally(() => setIsLoading(false));
}}
>
상류관로 보기
diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx
index 848343aad..5d5365834 100644
--- a/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx
+++ b/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx
@@ -1,6 +1,84 @@
// 하수맨홀
import { VerticalTable } from '@/components/ui/verticalTable';
import { useEffect, useState } from 'react';
+import GisApp from "@common/business_components/ui/map/lib/gis.core";
+
+// 상류관로 보기 함수 (FeatureClickEventPopup에서 사용)
+export async function searchUpperPpls(gisMap: any, fcltMngNo: any) {
+ const BASE_URL = process.env.NEXT_PUBLIC_SEWERAGE_API_URL || "";
+ const res = await fetch(`${BASE_URL}/v1/fcltmhl/upperPpls/${fcltMngNo}`, {
+ method: "GET",
+ });
+
+ let data: any = null;
+ if (res.ok) {
+ try {
+ // 응답이 비어있는지 확인
+ const contentLength = res.headers.get("content-length");
+ if (contentLength === "0") {
+ alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`);
+ return;
+ }
+
+ // 응답 텍스트를 먼저 가져와서 빈 문자열인지 확인
+ const text = await res.text();
+ if (!text || text.trim() === "") {
+ alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`);
+ return;
+ }
+
+ // JSON 파싱 시도
+ data = JSON.parse(text);
+ } catch (error) {
+ console.error("JSON parsing error:", error);
+ alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`);
+ return;
+ }
+ } else {
+ alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`);
+ return;
+ }
+
+ const select: any = GisApp.Module.select;
+ let foundFeature: any = null;
+
+ (data || []).forEach((item: any) => {
+ const pplMngNo = item.ppl_mng_no?.trim?.();
+
+ gisMap
+ .getLayers()
+ .getArray()
+ .filter((e: any) => e.get("lyrTyNm") == "tb_ms_swage_ppl")
+ .forEach((layer: any) => {
+ const source = layer.getSource?.();
+ if (source?.getFeatures) {
+ const features = source.getFeatures();
+ for (const f of features) {
+ if (f.values_.fclt_mng_no?.trim?.() === pplMngNo) {
+ foundFeature = f;
+ break;
+ }
+ }
+ }
+ });
+
+ if (foundFeature) select?.selectMultiFeature?.(foundFeature, true);
+ });
+
+ if (!foundFeature) alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`);
+
+ const geometry = foundFeature?.getGeometry();
+ if (geometry) {
+ const extent = geometry.getExtent();
+ gisMap.getView().fit(extent, {
+ duration: 300,
+ padding: [50, 50, 50, 50],
+ maxZoom: 14,
+ constrainResolution: true,
+ nearest: true,
+ });
+ }
+}
const inputColumn = [
{ id: "swtrmtZoneNm", title: "처리구역", type: "input" },
diff --git a/apps/sn/app/(map-layout)/map/page.tsx b/apps/sn/app/(map-layout)/map/page.tsx
index 6e6997267..e1bbc45ad 100644
--- a/apps/sn/app/(map-layout)/map/page.tsx
+++ b/apps/sn/app/(map-layout)/map/page.tsx
@@ -6,7 +6,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
import GisApp from "@common/business_components/ui/map/lib/gis.core";
import SearchModal from "./searchModal/searchModal";
import FeatureClickEventPopup from "./components/popupComponent/featureClickEventPopup";
-import { WaterDepth, WATER_DEPTH_LAYER_TYPES, ORDERED_LAYERS } from "./waterDepth/waterDepth";
+import { WaterDepth, WATER_DEPTH_LAYER_TYPES } from "./waterDepth/waterDepth";
import { ProcSearchBar } from "@common/business_components/ui/map/searchBar";
// 타입 정의 추가
@@ -160,7 +160,6 @@ const Map = () => {
isPlaying={isPlaying}
setIsPlaying={setIsPlaying as any}
targetLayerTypes={WATER_DEPTH_LAYER_TYPES as any}
- orderedLayers={ORDERED_LAYERS as any}
checkInterval={2500}
/>
diff --git a/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx b/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx
index 7fe3bd0f5..d476fedd7 100644
--- a/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx
+++ b/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx
@@ -149,7 +149,6 @@ const ReportTab: React.FC = ({ open, isSearch = true, ctpvNm, sg
// if (gubun !== "") { // 구분검색 (추후 사용할 수도 있을 것 같아 남겨둠)
// filterReportData = filterReportData.filter(item => (item.plantZoneGubun) ? String(item.plantZoneGubun).includes(String(gubun)) : null);
// }
- console.log('report count:', filterReportData.length);
setTableCount(filterReportData.length || 0);
diff --git a/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx b/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx
index 3ec23a850..fdb52a1c2 100644
--- a/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx
+++ b/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx
@@ -80,12 +80,9 @@ const SearchModal: React.FC = ({
const [end2, setEnd2] = useState("");
const [var1, setVar1] = useState("");
const [var2, setVar2] = useState("");
- const [var3, setVar3] = useState("");
- const [var4, setVar4] = useState("");
- // 시작, 종료
const [yearFilter, setYearFilter] = useState({ start: "", end: "" });
- const { ctpv, sgg, BIZ_TY_CD, BIZ_SE_CD } = useStore();
+ const { ctpv, sgg, BIZ_TY_CD } = useStore();
// 오늘 날짜 구하기
@@ -128,8 +125,6 @@ const SearchModal: React.FC = ({
setEnd2("");
setVar1("");
setVar2("");
- setVar3("");
- setVar4("");
setCtpvCd("0");
setSggCd("0");
setYearFilter({
@@ -196,7 +191,6 @@ const SearchModal: React.FC = ({
if (cqlFilters.length > 0) queryParams.append('cqlFiter', cqlFilters.join(' and '));
const res = await axios.get(`${API_URL}/v1/fclts?${queryParams.toString()}`);
- console.log('api:', `${API_URL}/v1/fclts?${queryParams.toString()}`);
// 🎯 각 아이템을 개별적으로 포맷팅하면서 일련번호 추가
const dataWithRowNumber = (res.data.data || []).map((item: any, index: number) => {
@@ -231,7 +225,6 @@ const SearchModal: React.FC = ({
};
});
- console.log("dataWithRowNumber: ", dataWithRowNumber)
setTableData(dataWithRowNumber);
setTableCount(res.data.count || []);
@@ -264,7 +257,6 @@ const SearchModal: React.FC = ({
const params = new URLSearchParams(RequestDTO).toString();
const res = await getData(`v1/bizInfo?${params}`);
- console.log('운영정보 사업 데이터:', res.content);
const mappedContent = (res.content || []).map((item: any, index: number) => {
const formattedItem = formatDisplayData(item);
@@ -512,7 +504,6 @@ const SearchModal: React.FC = ({
RequestDTO.workTypes = JSON.parse(workType.replace(/'/g, '"'));
const res = await getData(`v1/bizInfo/fclts?${new URLSearchParams(RequestDTO).toString()}`);
- console.log('운영정보 cellClick 데이터:', res.data);
const mappedData = (res.data || []).map((item: any, detailIndex: number) => {
const formattedItem = formatDisplayData(item);
@@ -527,7 +518,6 @@ const SearchModal: React.FC = ({
swtrmt_zone_nm: item.swtrmt_zone_nm ? item.swtrmt_zone_nm : '-',
};
});
- console.log('운영정보 cellClick 데이터:', mappedData);
setDetailTableData(mappedData);
setDetailTableCount(res.count || 0);
@@ -565,7 +555,6 @@ const SearchModal: React.FC = ({
swtrmt_zone_nm: item.swtrmt_zone_nm ? item.swtrmt_zone_nm : '-',
};
});
- console.log('운영정보 PageNation 데이터:', mappedData);
setDetailTableData(mappedData);
setDetailTableCount(res.count || 0);
@@ -667,7 +656,6 @@ const SearchModal: React.FC = ({
if (cqlFilters.length > 0) queryParams.append('cqlFiter', cqlFilters.join(' and '));
const res = await axios.get(`${API_URL}/v1/fclts?${queryParams.toString()}`);
- console.log('res.data.data', res.data.data);
@@ -785,7 +773,6 @@ const SearchModal: React.FC = ({
// 선택된 행 데이터를 Excel 다운로드 형식으로 변환
const excelData = mappedContent; // 배열로 감싸서 전달
- console.log('excelData', excelData);
// 파일명 생성 (분석번호 기반)
const label = BASIC_TYPES.find((type) => type.val === basicType)?.text
@@ -929,8 +916,6 @@ const SearchModal: React.FC = ({
const apiStartTime = performance.now();
const res = await getData(`v1/bizInfo/fclts?${new URLSearchParams(RequestDTO).toString()}`);
const apiEndTime = performance.now();
- console.log(`🚀 1. API 호출 시간: ${(apiEndTime - apiStartTime).toFixed(2)}ms`);
- console.log('운영정보 결과 다운로드.data:', res.data);
const mappingStartTime = performance.now();
// 헤더 매핑 정의
@@ -974,13 +959,10 @@ const SearchModal: React.FC = ({
};
});
const mappingEndTime = performance.now();
- console.log(`🔄 2. 데이터 매핑 시간: ${(mappingEndTime - mappingStartTime).toFixed(2)}ms`);
// 선택된 행 데이터를 Excel 다운로드 형식으로 변환
const excelData = mappedData; // 배열로 감싸서 전달
- console.log('excelData', excelData);
-
const excelStartTime = performance.now();
// 파일명 생성 (분석번호 기반)
const label = WORK_TYPES.find((type) => type.val === workType)?.text
@@ -994,7 +976,6 @@ const SearchModal: React.FC = ({
headerMapping: headerMapping
});
const excelEndTime = performance.now();
- console.log(`📊 3. Excel 다운로드 시간: ${(excelEndTime - excelStartTime).toFixed(2)}ms`);
setIsLoading(false);
} catch (error) {
@@ -1023,7 +1004,6 @@ const SearchModal: React.FC = ({
setIsLoading(true);
const row = detailTableData[0];
- console.log('row', row);
const layerNm = row.lyrTypeNm;
const fids = detailTableData.map((item) => item.fid);
const core = GisApp.Module.layer as any;
@@ -1116,6 +1096,7 @@ const SearchModal: React.FC = ({
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
+ curPage={curPage}
headButton={
@@ -1147,6 +1128,7 @@ const SearchModal: React.FC
= ({
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
+ curPage={curPage}
headButton={
}
@@ -1173,6 +1155,7 @@ const SearchModal: React.FC = ({
onPageChange={setDetailCurPage}
resetPageNo={isResetDetailPage}
resetSelection={isResetDetailSelection}
+ curPage={detailCurPage}
headButton={
diff --git a/apps/sn/app/(map-layout)/map/waterDepth/waterDepth.tsx b/apps/sn/app/(map-layout)/map/waterDepth/waterDepth.tsx
index 78849bda2..a1434d895 100644
--- a/apps/sn/app/(map-layout)/map/waterDepth/waterDepth.tsx
+++ b/apps/sn/app/(map-layout)/map/waterDepth/waterDepth.tsx
@@ -7,16 +7,6 @@ export const WATER_DEPTH_LAYER_TYPES: string[] = [
'tb_ms_flood_dngr_map',
'tb_ms_sbmrg_dngr_map'
];
-// 지정된 순서에 따른 lyr_sn 배열
-export const ORDERED_LAYERS: string[] = [
- '27', // 침수위험지도(tb_ms_sbmrg_dngr_map) - 30년 빈도
- '28', // 침수위험지도(tb_ms_sbmrg_dngr_map) - 50년 빈도
- '3', // 침수위험지도(tb_ms_sbmrg_dngr_map) - 80년 빈도
- '4', // 침수위험지도(tb_ms_sbmrg_dngr_map) - 100년 빈도
- '59', // 도시침수지도(tb_ms_flood_dngr_map) - 30년 빈도
- '60', // 도시침수지도(tb_ms_flood_dngr_map) - 50년 빈도
- '58' // 도시침수지도(tb_ms_flood_dngr_map) - 80년 빈도
-];
interface WaterDepthProps {
onClose?: () => void;
diff --git a/apps/sn/app/(with-base-layout)/oper/floodPre/headMakeFloodPre.tsx b/apps/sn/app/(with-base-layout)/oper/floodPre/headMakeFloodPre.tsx
new file mode 100644
index 000000000..f16178003
--- /dev/null
+++ b/apps/sn/app/(with-base-layout)/oper/floodPre/headMakeFloodPre.tsx
@@ -0,0 +1,76 @@
+import { TableHead, TableRow } from "@common/components/ui";
+
+
+export type TableUpperProps = {
+ id: string;
+ title: string;
+ upName?: string;
+ upSequnce?: number;
+ edit?: boolean;
+ visible?: boolean;
+ rowSpan?: number;
+ colSpan?: number;
+ type?: string;
+ selectData?: string; // type 이 seelct 일경우 selectarray 정하기 위해
+ row?: number;
+ mergeCell?: boolean // 셀을 합칠경우
+ maxLength?: number
+ readonly?: boolean
+};
+type chHeadType = {
+ headNm: string;
+ text: string;
+ length: number;
+ rows?: number;
+};
+
+export const HeadMakeFloodPre = (
+ upHeadList: TableUpperProps[],
+ makeHeadNm: chHeadType[]
+) => {
+ return (
+ <>
+
+ {upHeadList
+ .filter((data) => data.visible != false)
+ .map((head: TableUpperProps) =>
+ !head.upSequnce ? (
+
+ {head.title}
+
+ ) : head.upSequnce === 1 ? (
+ ch.headNm === head.upName)?.length
+ }
+ >
+ {makeHeadNm?.find((ch) => ch.headNm === head.upName)?.text}
+
+ ) : null
+ )}
+
+
+
+ {upHeadList
+ .filter((data) => data.visible != false)
+ .map((head: TableUpperProps) =>
+ makeHeadNm?.find((ch) => ch.headNm === head.upName) ? (
+
+ {head.title}
+
+ ) : null
+ )}
+
+ >
+ );
+};
\ No newline at end of file
diff --git a/apps/sn/app/(with-base-layout)/oper/floodPre/inputTableBody.tsx b/apps/sn/app/(with-base-layout)/oper/floodPre/inputTableBody.tsx
new file mode 100644
index 000000000..0058b47d1
--- /dev/null
+++ b/apps/sn/app/(with-base-layout)/oper/floodPre/inputTableBody.tsx
@@ -0,0 +1,200 @@
+import type { TableUpperProps } from "./headMakeFloodPre";
+import { Input, TableCell, TableRow } from "@common/components/ui";
+
+
+// 숫자입력시 , 삽입
+const formatCommaNumber = (
+ value: number | string | undefined | null
+): string => {
+ if (value === undefined || value === null || value === "") return "";
+ const num = Number(value);
+ // 숫자로 변환할 수 없는 값이 들어올 경우 빈 문자열을 반환하여 예상치 못한 "NaN" 출력을 방지합니다.
+ if (isNaN(num)) {
+ return "";
+ }
+ return num.toLocaleString();
+};
+
+// onchange 텍스트를 숫자로 and ,제거
+const handleCommaNumberChange = (
+ e: React.ChangeEvent
,
+ onChange: (value: number | "") => void
+) => {
+ const raw = e.target.value.replace(/,/g, "");
+ if (!/^\d*$/.test(raw)) return;
+ onChange(raw === "" ? "" : Number(raw));
+};
+
+const handleChange = (
+ rowIndex: number,
+ field: any,
+ value: string,
+ setInputData: (data: any) => void
+) => {
+ if (Number(value) < 0 || !Number(value)) {
+ value = "0";
+ }
+ setInputData((prevData: any) =>
+ prevData?.map((row: any, index: number) => {
+ if (index === rowIndex) {
+ return {
+ ...row,
+ [field]: Number(value.replace(/,/g, "")),
+ };
+ }
+ return row;
+ })
+ );
+};
+
+export const InputTableBody = (
+ chgRes: any[] | [],
+ headList: TableUpperProps[],
+ setInputData: (data: any[]) => void,
+ isEditable: boolean = true
+) => {
+ // mergeCell 처리용
+ const getRowSpan = (data: any[], key: string, rowIndex: number) => {
+ if (rowIndex > 0 && data[rowIndex - 1][key] && String(data[rowIndex][key]).trim() === "") {
+ return 0; // 이전과 같으면 셀을 그리지 않음
+ }
+ let span = 1;
+ for (let i = rowIndex + 1; i < data.length; i++) {
+ if (data[i][key] === data[rowIndex][key]) span++;
+ else break;
+ }
+ return span;
+ };
+ return (
+ <>
+ {chgRes.map((data, dataIndex) => {
+ // 소계/총합계 행 판별
+ const isSubTotal = data["용수명"] === "소계";
+ const isTotal = data["구분"] === 0;
+
+ const bgClass = isTotal
+ ? "bg-[#d5e1eb] font-bold"
+ : isSubTotal
+ ? "bg-[#e6eef5] font-semibold"
+ : "";
+
+ return (
+
+ {headList.map((head, headIndex) => {
+ // console.log('head, head.id', head, head.id);
+ const isTextColumn = head.id === "__EMPTY_3";
+ const textAlignClass = isTextColumn
+ ? "text-center"
+ : "text-right";
+
+ // // 총합계 행이면 "구분"에서 colSpan=2로 병합
+ // if (
+ // (data["구분"] === 0 || data["용수명"] === 0) &&
+ // head.id === "구분"
+ // ) {
+ // return (
+ //
+ // 총합계
+ //
+ // );
+ // }
+ // // 총합계(합계) 행이면 "용수명" 컬럼은 렌더링하지 않음
+ // if (
+ // (data["구분"] === 0 || data["용수명"] === 0) &&
+ // head.id === "용수명"
+ // ) {
+ // return null;
+ // }
+
+ // // 총합계 행의 나머지 셀에도 색상 적용
+ // if (data["구분"] === 0 || data["용수명"] === 0) {
+ // return (
+ //
+ // {Number(data[head.id])
+ // ? formatCommaNumber(data[head.id as keyof any])
+ // : (data[head.id as keyof any] ?? "")}
+ //
+ // );
+ // }
+ // mergeCell 처리
+ if (head.mergeCell === true) {
+ const rowSpan = getRowSpan(chgRes, head.id, dataIndex);
+ if (rowSpan === 0) return null;
+ return (
+
+ {Number(data[head.id])
+ ? formatCommaNumber(data[head.id as keyof any])
+ : (data[head.id as keyof any] ?? "")}
+
+ );
+ }
+ // 기본 셀
+ // return head.edit === true && data.edit !== false ? (
+ return isEditable && head.edit === true && data.edit !== false ? (
+
+
+ handleCommaNumberChange(e, (val) =>
+ handleChange(
+ dataIndex,
+ head.id,
+ String(val),
+ setInputData
+ )
+ )
+ }
+ value={formatCommaNumber(data[head.id as keyof any]) ?? ""}
+ maxLength={12}
+ />
+
+ ) : (
+
+
+ {Number(data[head.id])
+ ? formatCommaNumber(data[head.id as keyof any])
+ : (data[head.id as keyof any] ?? "")}
+
+
+ );
+ })}
+
+ );
+ })}
+ {chgRes.length === 0 && (
+
+
+ 조회된 결과가 없습니다.
+
+
+ )}
+ >
+ );
+};
diff --git a/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx b/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx
index 80cd94a0e..a4c7939c8 100644
--- a/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx
+++ b/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx
@@ -2,7 +2,10 @@
import { useState, useEffect } from 'react'
import LoadingOverlay from '@/components/ui/LoadingBar'
import { UITab, UiTable } from '@common/business_components/ui'
+import { Table, TableBody, TableHeader } from "@common/components/ui";
import * as XLSX from 'xlsx';
+import { HeadMakeFloodPre } from './headMakeFloodPre';
+import { InputTableBody } from './inputTableBody';
const TABS = [
{ val: "management", text: "관리SHEET" },
@@ -19,7 +22,7 @@ const TableModal: React.FC = ({ fileNm, atflId }) => {
const [activeTab, setActiveTab] = useState(TABS[0]?.val ?? "management");
const [managementTableHeader, setManagementTableHeader] = useState<{ id: string; title: string }[]>([]) //테이블 헤더
const [managementTableData, setManagementTableData] = useState([{}]) //테이블 데이터
- const [resultTableHeader, setResultTableHeader] = useState<{ id: string; title: string }[]>([]) //테이블 헤더
+ const [resultTableHeader, setResultTableHeader] = useState<{ id: string; title: string, mergeCell?: boolean }[]>([]) //테이블 헤더
const [resultTableData, setResultTableData] = useState([{}]) //테이블 데이터
const [isLoading, setIsLoading] = useState(false) //로딩 상태
@@ -53,13 +56,12 @@ const TableModal: React.FC = ({ fileNm, atflId }) => {
// 관리 SHEET
const managementHeader = jsonDataBySheet['관리SHEET']?.[7] || [];
- // 1번째~47번째, 74번째~80번째 데이터만 필터링
const filteredManagementHeader = Object.entries(managementHeader)
.filter(([key, value]) => {
const match = key.match(/^__EMPTY_(\d+)$/);
if (match) {
const index = parseInt(match[1] ?? '', 10);
- return (index > 0 && index < 47) || (index > 73);
+ return (0 < index && index < 47) || (73 < index);
}
return false;
})
@@ -81,17 +83,20 @@ const TableModal: React.FC = ({ fileNm, atflId }) => {
// 운영관리현황 점검결과
const resultHeader = jsonDataBySheet['운영관리현황 점검결과']?.[2] || [];
- const dynamicInspectionHeader = Object.entries(resultHeader)
+ const dynamicResultHeader = Object.entries(resultHeader)
.map(([key, value]) => ({
id: key,
- title: String(value).replace(/\r\n/g, '\n')
+ title: String(value).replace(/\r\n/g, '\n'),
+ mergeCell: false,
+ ...(key === '__EMPTY_3' && { mergeCell: true }) // __EMPTY_3인 경우 mergeCell: true 추가
}));
- dynamicInspectionHeader.splice(1, 0, {
+ dynamicResultHeader.splice(1, 0, {
id: "__EMPTY_2",
- title: ''
+ title: '',
+ mergeCell: false
});
- setResultTableHeader(dynamicInspectionHeader);
- console.log('resultTableHeader', dynamicInspectionHeader);
+ setResultTableHeader(dynamicResultHeader);
+ console.log('resultTableHeader', dynamicResultHeader);
const resultData = Array.isArray(jsonDataBySheet['운영관리현황 점검결과'])
? jsonDataBySheet['운영관리현황 점검결과'].slice(3)
@@ -225,7 +230,7 @@ const TableModal: React.FC = ({ fileNm, atflId }) => {
)}
{/* 운영관리현황 점검결과 탭 */}
{activeTab === 'Inspection results' && (
-
+
= ({ fileNm, atflId }) => {
cellClick={undefined}
onPageChange={() => { }}
/>
+ {/*
+
+ {HeadMakeFloodPre(resultTableHeader, [])}
+
+
+ {InputTableBody(resultTableData ?? [], resultTableHeader, setResultTableData, false)}
+
+
*/}
)}
diff --git a/apps/sn/app/(with-base-layout)/oper/oldPp/headList.ts b/apps/sn/app/(with-base-layout)/oper/oldPp/headList.ts
new file mode 100644
index 000000000..516302720
--- /dev/null
+++ b/apps/sn/app/(with-base-layout)/oper/oldPp/headList.ts
@@ -0,0 +1,1711 @@
+import { z } from "zod";
+
+export const oldPpHeadListType = z.array(
+ z.object({
+ id: z.string(),
+ title: z.string(),
+ visible: z.boolean(),
+ })
+);
+
+type CommonTableProps = {
+ id: string;
+ title: string;
+ upName?: string;
+ upSequnce?: number;
+ row?: number;
+ rowSpan?: number;
+ colSpan?: number;
+ visible?: boolean;
+};
+
+export const oldPpTable2HeadList: z.infer
= [
+ {
+ id: "rowNumber",
+ title: "일련번호",
+ visible: true,
+ },
+ {
+ id: "__EMPTY",
+ title: "연번",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_1",
+ title: "차수",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_2",
+ title: "정밀조사 사업코드",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_3",
+ title: "시도",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_4",
+ title: "시군구",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_5",
+ title: "사업명",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_6",
+ title: "착수",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_7",
+ title: "준공",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_8",
+ title: "내역사업명",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_9",
+ title: "물량\r\n(결산자료)",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_0",
+ title: "실제조사물량\r\n(보고서,실적보고)",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_10",
+ title: "계",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_11",
+ title: "국고",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_12",
+ title: "지방비",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_13",
+ title: " 총사업비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_14",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_15",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_16",
+ title: " 계 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_17",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_18",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_19",
+ title: " 총사업비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_20",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_21",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_22",
+ title: " 계 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_23",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_24",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_25",
+ title: " 총사업비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_26",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_27",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_28",
+ title: " 계 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_29",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_30",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_31",
+ title: " 총사업비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_32",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_33",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_34",
+ title: " 계 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_35",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_36",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_37",
+ title: " 총사업비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_38",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_39",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_40",
+ title: " 계 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_41",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_42",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_43",
+ title: " 총사업비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_44",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_45",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_46",
+ title: " 계 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_47",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_48",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_49",
+ title: " 총사업비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_50",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_51",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_52",
+ title: " 계 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_53",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_54",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_55",
+ title: " 총사업비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_56",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_57",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_58",
+ title: " 계 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_59",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_60",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_61",
+ title: " 총사업비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_62",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_63",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_64",
+ title: " 계 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_65",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_66",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_67",
+ title: " 총사업비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_68",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_69",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_70",
+ title: " 계 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_71",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_72",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_73",
+ title: " 총사업비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_74",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_75",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_76",
+ title: " 계 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_77",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_78",
+ title: " 지방비 ",
+ visible: true,
+ },
+];
+
+export const oldPpTable2NodeList: CommonTableProps[] = [
+ {
+ id: "rowNumber",
+ title: "일련번호",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY",
+ title: "연번",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_1",
+ title: "차수",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_2",
+ title: "정밀조사 사업코드",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_3",
+ title: "시도",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_4",
+ title: "시군구",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_5",
+ title: "사업명",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_6",
+ title: "착수",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_7",
+ title: "준공",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_8",
+ title: "내역사업명",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_9",
+ title: "물량\r\n(결산자료)",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_0",
+ title: "실제조사물량\r\n(보고서,실적보고)",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_10",
+ title: "총계",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 3,
+ },
+ {
+ id: "2__EMPTY_10",
+ title: "계",
+ upName: "__EMPTY_10",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_11",
+ title: "국고",
+ upName: "__EMPTY_10",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_12",
+ title: "지방비",
+ upName: "__EMPTY_10",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_13",
+ title: " 2015년 ",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 6,
+ },
+ {
+ id: "2__EMPTY_13",
+ title: " 총사업비 ",
+ upName: "__EMPTY_13",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_14",
+ title: " 국고 ",
+ upName: "__EMPTY_13",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_15",
+ title: " 지방비 ",
+ upName: "__EMPTY_13",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_16",
+ title: " 계 ",
+ upName: "__EMPTY_13",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_17",
+ title: " 국고 ",
+ upName: "__EMPTY_13",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_18",
+ title: " 지방비 ",
+ upName: "__EMPTY_13",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+
+ {
+ id: "__EMPTY_19",
+ title: " 2016년 ",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 6,
+ },
+ {
+ id: "2__EMPTY_19",
+ title: " 총사업비 ",
+ upName: "__EMPTY_19",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_20",
+ title: " 국고 ",
+ upName: "__EMPTY_19",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_21",
+ title: " 지방비 ",
+ upName: "__EMPTY_19",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_22",
+ title: " 계 ",
+ upName: "__EMPTY_19",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_23",
+ title: " 국고 ",
+ upName: "__EMPTY_19",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_24",
+ title: " 지방비 ",
+ upName: "__EMPTY_19",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_25",
+ title: "2017년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 6,
+ },
+ {
+ id: "2__EMPTY_25",
+ title: " 총사업비 ",
+ upName: "__EMPTY_25",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_26",
+ title: " 국고 ",
+ upName: "__EMPTY_25",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_27",
+ title: " 지방비 ",
+ upName: "__EMPTY_25",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_28",
+ title: " 계 ",
+ upName: "__EMPTY_25",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_29",
+ title: " 국고 ",
+ upName: "__EMPTY_25",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_30",
+ title: " 지방비 ",
+ upName: "__EMPTY_25",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_31",
+ title: "2018년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 6,
+ },
+ {
+ id: "2__EMPTY_31",
+ title: " 총사업비 ",
+ upName: "__EMPTY_31",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_32",
+ title: " 국고 ",
+ upName: "__EMPTY_25",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_33",
+ title: " 지방비 ",
+ upName: "__EMPTY_31",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_34",
+ title: " 계 ",
+ upName: "__EMPTY_31",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_35",
+ title: " 국고 ",
+ upName: "__EMPTY_31",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_36",
+ title: " 지방비 ",
+ upName: "__EMPTY_31",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_37",
+ title: "2019년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 6,
+ },
+ {
+ id: "2__EMPTY_37",
+ title: " 총사업비 ",
+ upName: "__EMPTY_43",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_38",
+ title: " 국고 ",
+ upName: "__EMPTY_43",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_39",
+ title: " 지방비 ",
+ upName: "__EMPTY_43",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_40",
+ title: " 계 ",
+ upName: "__EMPTY_43",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_41",
+ title: " 국고 ",
+ upName: "__EMPTY_43",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_42",
+ title: " 지방비 ",
+ upName: "__EMPTY_43",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_43",
+ title: "2020년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 6,
+ },
+ {
+ id: "2__EMPTY_43",
+ title: " 총사업비 ",
+ upName: "__EMPTY_49",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_44",
+ title: " 국고 ",
+ upName: "__EMPTY_49",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_45",
+ title: " 지방비 ",
+ upName: "__EMPTY_49",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_46",
+ title: " 계 ",
+ upName: "__EMPTY_49",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_47",
+ title: " 국고 ",
+ upName: "__EMPTY_49",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_48",
+ title: " 지방비 ",
+ upName: "__EMPTY_49",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_49",
+ title: "2021년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 6,
+ },
+ {
+ id: "2__EMPTY_49",
+ title: " 총사업비 ",
+ upName: "__EMPTY_55",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_50",
+ title: " 국고 ",
+ upName: "__EMPTY_55",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_51",
+ title: " 지방비 ",
+ upName: "__EMPTY_55",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_52",
+ title: " 계 ",
+ upName: "__EMPTY_55",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_53",
+ title: " 국고 ",
+ upName: "__EMPTY_55",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_54",
+ title: " 지방비 ",
+ upName: "__EMPTY_55",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_55",
+ title: "2022년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 6,
+ },
+ {
+ id: "2__EMPTY_55",
+ title: " 총사업비 ",
+ upName: "__EMPTY_61",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_56",
+ title: " 국고 ",
+ upName: "__EMPTY_61",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_57",
+ title: " 지방비 ",
+ upName: "__EMPTY_61",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_58",
+ title: " 계 ",
+ upName: "__EMPTY_61",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_59",
+ title: " 국고 ",
+ upName: "__EMPTY_61",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_60",
+ title: " 지방비 ",
+ upName: "__EMPTY_61",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_61",
+ title: "2023년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 6,
+ },
+ {
+ id: "2__EMPTY_61",
+ title: " 총사업비 ",
+ upName: "__EMPTY_67",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_62",
+ title: " 국고 ",
+ upName: "__EMPTY_67",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_63",
+ title: " 지방비 ",
+ upName: "__EMPTY_67",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_64",
+ title: " 계 ",
+ upName: "__EMPTY_67",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_65",
+ title: " 국고 ",
+ upName: "__EMPTY_67",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_66",
+ title: " 지방비 ",
+ upName: "__EMPTY_67",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_67",
+ title: "2024년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 6,
+ },
+ {
+ id: "2__EMPTY_67",
+ title: " 총사업비 ",
+ upName: "__EMPTY_73",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_68",
+ title: " 국고 ",
+ upName: "__EMPTY_73",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_69",
+ title: " 지방비 ",
+ upName: "__EMPTY_73",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_70",
+ title: " 계 ",
+ upName: "__EMPTY_73",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_71",
+ title: " 국고 ",
+ upName: "__EMPTY_73",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_72",
+ title: " 지방비 ",
+ upName: "__EMPTY_73",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_73",
+ title: "2025년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 6,
+ },
+ {
+ id: "2__EMPTY_73",
+ title: " 총사업비 ",
+ upName: "__EMPTY_37",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_74",
+ title: " 국고 ",
+ upName: "__EMPTY_37",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_75",
+ title: " 지방비 ",
+ upName: "__EMPTY_37",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_76",
+ title: " 계 ",
+ upName: "__EMPTY_37",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_77",
+ title: " 국고 ",
+ upName: "__EMPTY_37",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_78",
+ title: " 지방비 ",
+ upName: "__EMPTY_37",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+];
+
+export const oldPpTable6HeadList: z.infer = [
+ {
+ id: "rowNumber",
+ title: "일련번호",
+ visible: true,
+ },
+ {
+ id: "__EMPTY",
+ title: "차수",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_1",
+ title: "기존관리",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_2",
+ title: "연번",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_3",
+ title: "정비사업 사업코드",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_4",
+ title: "착공년도",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_5",
+ title: "준공년도",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_6",
+ title: "유역청",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_7",
+ title: "시도",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_8",
+ title: "시군구",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_9",
+ title: "사업명",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_10",
+ title: "내역사업명",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_11",
+ title: "계획물량\r\n(결산자료)",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_12",
+ title: " 계 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_13",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_14",
+ title: " 지방비 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_19",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_25",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_31",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_37",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_43",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_49",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_55",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_61",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_67",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_73",
+ title: " 국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_75",
+ title: " 총국고 ",
+ visible: true,
+ },
+ {
+ id: "__EMPTY_76",
+ title: " 검토자 ",
+ visible: true,
+ },
+];
+
+export const oldPpTable6NodeList: CommonTableProps[] = [
+ {
+ id: "rowNumber",
+ title: "일련번호",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY",
+ title: "차수",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_1",
+ title: "기존관리",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_2",
+ title: "연번",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_3",
+ title: "정비사업 사업코드",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_4",
+ title: "착공년도",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_5",
+ title: "준공년도",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_6",
+ title: "유역청",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_7",
+ title: "시도",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_8",
+ title: "시군구",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_9",
+ title: "사업명",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_10",
+ title: "내역사업명",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_11",
+ title: "물량",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_11",
+ title: "계획물량\r\n(결산자료)",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_12",
+ title: "총계",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 3,
+ },
+ {
+ id: "__EMPTY_12",
+ title: " 계 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_13",
+ title: " 국고 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_14",
+ title: " 지방비 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_15",
+ title: "2016년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_19",
+ title: " 국고 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_21",
+ title: "2017년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_25",
+ title: " 국고 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_27",
+ title: "2018년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_31",
+ title: " 국고 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_33",
+ title: "2019년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_37",
+ title: " 국고 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_39",
+ title: "2020년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_43",
+ title: " 국고 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_45",
+ title: "2021년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_49",
+ title: " 국고 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_51",
+ title: "2022년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_55",
+ title: " 국고 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_57",
+ title: "2023년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_61",
+ title: " 국고 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_63",
+ title: "2024년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_67",
+ title: " 국고 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "2__EMPTY_69",
+ title: "2025년",
+ visible: true,
+ row: 1,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_73",
+ title: " 국고 ",
+ visible: true,
+ row: 2,
+ rowSpan: 1,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_75",
+ title: " 총국고 ",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+ {
+ id: "__EMPTY_76",
+ title: " 검토자 ",
+ visible: true,
+ row: 1,
+ rowSpan: 2,
+ colSpan: 1,
+ },
+];
\ No newline at end of file
diff --git a/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx b/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx
index 7165188ca..8fc09b5f4 100644
--- a/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx
+++ b/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx
@@ -1,7 +1,7 @@
'use client'
import { deleteData, postData, useCookieAuth } from '@/components/lib/api'
import { searchData } from '@/components/lib/common/apiHelpers'
-import { formatDate, handleDownload, yearOptions } from '@/components/lib/utils'
+import { formatDate, handleDownload } from '@/components/lib/utils'
import LoadingOverlay from '@/components/ui/LoadingBar'
import { SearchDiv, SearchFormLeft, SearchFormRight, UiTable, UiModal } from '@common/business_components/ui'
import ListDiv from '@common/business_components/ui/list_div'
@@ -14,6 +14,7 @@ import { AUTH_USER_ID } from "@/shared/config";
import { useQuery } from "@tanstack/react-query";
import { ENDPOINT } from "@common/components/config";
import { getUserInfo } from "@common/components/api";
+import TableModal from './tableModal';
const Page = () => {
@@ -30,7 +31,8 @@ const Page = () => {
const [curPage, setCurPage] = useState(1)
const [totalData, setTotalData] = useState(0) //총 데이터 수
const [isLoading, setIsLoading] = useState(true) //로딩 상태
- const [isModalOpen, setIsModalOpen] = useState(false) // 모달 상태
+ const [isModalOpen, setIsModalOpen] = useState(false) // 등록 모달 상태
+ const [isTableModalOpen, setIsTableModalOpen] = useState(false) // 테이블 모달 상태
const [resetSelection, setResetSelection] = useState(false); // 선택 초기화 상태
const [isResetPage, setIsResetPage] = useState(false);
@@ -223,6 +225,7 @@ const Page = () => {
setFileNm(fileName);
setAtflId(id);
setDcrpPplMtncBizSn(tableData[index]?.dcrpPplMtncBizSn);
+ setIsTableModalOpen(true);
}
}}
onPageChange={setCurPage}
@@ -245,6 +248,21 @@ const Page = () => {
/>
}
/>
+ {/* 엑셀 데이터 테이블 모달 */}
+ }
+ useDirectRender={true}
+ />
>
)
}
diff --git a/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx b/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx
new file mode 100644
index 000000000..169ae0895
--- /dev/null
+++ b/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx
@@ -0,0 +1,465 @@
+'use client'
+import { useState, useEffect } from 'react'
+import LoadingOverlay from '@/components/ui/LoadingBar'
+import { UITab, UiTable } from '@common/business_components/ui'
+import * as XLSX from 'xlsx';
+import { HeadMakeColSpan } from '@common/business_components/ui/table/HeadMakeColSpan';
+import { oldPpTable2HeadList, oldPpTable2NodeList, oldPpTable6HeadList, oldPpTable6NodeList } from './headList';
+
+const TABS = [
+ { val: "1", text: "row data" },
+ { val: "2", text: "1.정밀조사" },
+ { val: "3", text: "2.정밀조사_정비사업연계" },
+ { val: "4", text: " 3.정비사업" },
+ { val: "5", text: "4.정비사업요약" },
+ { val: "6", text: "4.정비사업최종" },
+];
+
+interface TableModalProps {
+ fileNm: string;
+ atflId: string;
+}
+
+const TableModal: React.FC = ({ fileNm, atflId }) => {
+
+ const [activeTab, setActiveTab] = useState(TABS[0]?.val ?? "1");
+ const [tableHeader1, setTableHeader1] = useState<{ id: string; title: string }[]>([])
+ const [tableHeader2, setTableHeader2] = useState<{ id: string; title: string }[]>([])
+ const [tableHeader4, setTableHeader4] = useState<{ id: string; title: string }[]>([])
+ const [tableHeader5, setTableHeader5] = useState<{ id: string; title: string }[]>([])
+ const [tableData1, setTableData1] = useState([{}])
+ const [tableData2, setTableData2] = useState([{}])
+ const [tableData3, setTableData3] = useState([{}])
+ const [tableData4, setTableData4] = useState([{}])
+ const [tableData5, setTableData5] = useState([{}])
+ const [tableData6, setTableData6] = useState([{}])
+ const [isLoading, setIsLoading] = useState(false)
+
+ useEffect(() => {
+ isChckFile();
+ }, []);
+
+ // 파일 다운로드
+ const isChckFile = async () => {
+ setIsLoading(true);
+ try {
+ if (fileNm === '' || fileNm === undefined) {
+ alert('파일을 선택해주세요');
+ setIsLoading(false);
+ return false;
+ }
+
+ const response = await fetch(`/attach-service/api/v1/download/${atflId}`);
+ if (!response.ok) {
+ throw new Error('파일을 가져오는 중 오류가 발생했습니다.');
+ }
+
+ const blob = await response.blob();
+
+ const file = new File([blob], fileNm, {
+ type: blob.type || 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+ });
+
+ const targetSheets = ['row data', '1.정밀조사', '2.정밀조사_정비사업연계', ' 3.정비사업', '4.정비사업요약', '4.정비사업최종'];
+ const jsonDataBySheet = await filePickedSelectedSheets(file, 0, targetSheets);
+
+ const header1 = jsonDataBySheet['row data']?.[1] || [];
+ const header2 = jsonDataBySheet['1.정밀조사']?.[1] || [];
+ const header4 = jsonDataBySheet[' 3.정비사업']?.[1] || [];
+ const header5 = jsonDataBySheet['4.정비사업요약']?.[2] || [];
+
+ // row data
+ const allEntries1 = Object.entries(header1);
+ const filteredHeader1 = [
+ allEntries1[0],
+ allEntries1[1],
+ allEntries1[2],
+ allEntries1[3],
+ allEntries1[5],
+ allEntries1[6],
+ allEntries1[7],
+ allEntries1[8],
+ allEntries1[9],
+ allEntries1[10],
+ allEntries1[11],
+ allEntries1[12],
+ allEntries1[13],
+ allEntries1[14],
+ allEntries1[15]
+ ].filter((e): e is [string, any] => Boolean(e))
+ .map(([key, value]) => ({
+ id: key,
+ title: String(value).replace(/\r\n/g, '\n')
+ }));
+ filteredHeader1.splice(0, 0, {
+ id: "rowNumber",
+ title: '일련번호'
+ });
+ setTableHeader1(filteredHeader1);
+
+ const data1 = Array.isArray(jsonDataBySheet['row data'])
+ ? jsonDataBySheet['row data'].slice(2)
+ : [];
+ const filteredData1 = filterEmptyRows(data1).map((item: any, index: number) => ({
+ ...item,
+ rowNumber: index + 1,
+ __EMPTY_1: item.__EMPTY_1 || '-'
+ }));
+ setTableData1(filteredData1);
+
+ // 1.정밀조사
+ const allEntries2 = Object.entries(header2);
+ let filteredHeader2 = [
+ allEntries2[0],
+ allEntries2[1],
+ allEntries2[2],
+ allEntries2[3],
+ allEntries2[5],
+ allEntries2[6],
+ allEntries2[7],
+ allEntries2[8],
+ allEntries2[9],
+ allEntries2[10],
+ allEntries2[11],
+ allEntries2[12],
+ allEntries2[13],
+ allEntries2[14],
+ allEntries2[15]
+ ].filter((e): e is [string, any] => Boolean(e))
+ .map(([key, value]) => ({
+ id: key,
+ title: String(value).replace(/\r\n/g, '\n')
+ }));
+ filteredHeader2.splice(0, 0, {
+ id: "rowNumber",
+ title: '일련번호'
+ });
+ setTableHeader2(filteredHeader2);
+
+ const data2 = Array.isArray(jsonDataBySheet['1.정밀조사'])
+ ? jsonDataBySheet['1.정밀조사'].slice(2)
+ : [];
+ const filteredData2 = filterEmptyRows(data2).map((item: any, index: number) => ({
+ ...item,
+ rowNumber: index + 1
+ }));
+ setTableData2(filteredData2);
+
+ // 2.정밀조사_정비사업연계 (헤더는 import)
+ const data3 = Array.isArray(jsonDataBySheet['2.정밀조사_정비사업연계'])
+ ? jsonDataBySheet['2.정밀조사_정비사업연계'].slice(5)
+ : [];
+ const filteredData3 = filterEmptyRows(data3).map((item: any, index: number) => {
+ const newItem = { ...item };
+ // 매핑 에러로 인해 특정 키를 "__EMPTY_0"으로 변경
+ const targetKey = "*1차 출처: 공단자료\r\n*2차 출처: 정산서, 정밀조사보고서 등.\r\n (파랑) 2024년말 기준 실적 제출 자료. 준공 후 재확인 필요\r\n (노랑셀) 준공(또는 정산) 후에 재확인 필요";
+ if (newItem[targetKey] !== undefined) {
+ newItem["__EMPTY_0"] = newItem[targetKey];
+ delete newItem[targetKey];
+ }
+ return {
+ ...newItem,
+ __EMPTY_4: newItem?.__EMPTY_4 || '-',
+ rowNumber: index + 1
+ };
+ });
+ setTableData3(filteredData3);
+
+ // 3.정비사업
+ const allEntries4 = Object.entries(header4);
+ const filteredHeader4 = allEntries4.filter((e): e is [string, any] => Boolean(e))
+ .map(([key, value]) => ({
+ id: key,
+ title: String(value).replace(/\r\n/g, '\n')
+ }));
+
+ filteredHeader4.splice(0, 0, {
+ id: "rowNumber",
+ title: '일련번호'
+ });
+ setTableHeader4(filteredHeader4);
+
+ const data4 = Array.isArray(jsonDataBySheet[' 3.정비사업'])
+ ? jsonDataBySheet[' 3.정비사업'].slice(2)
+ : [];
+ const filteredData4 = filterEmptyRows(data4).map((item: any, index: number) => ({
+ ...item,
+ rowNumber: index + 1,
+ __EMPTY_2: item?.__EMPTY_2 || '-',
+ __EMPTY_11: item?.__EMPTY_11 || '-',
+ }));
+ setTableData4(filteredData4);
+
+ // 4.정비사업요약
+ const allEntries5 = Object.entries(header5);
+ const excludeKeys5 = [
+ ": \"정비사업\"sheet에서 사업코드 ctrl+c, Ctrl+v 한 다음 중복된 데이터 제거실시",
+ "__EMPTY",
+ "__EMPTY_8",
+ "__EMPTY_15"
+ ];
+ const filteredHeader5 = allEntries5
+ .filter(([key]) => !excludeKeys5.includes(key))
+ .filter((e): e is [string, any] => Boolean(e))
+ .map(([key, value]) => ({
+ id: key,
+ title: String(value).replace(/\r\n/g, '\n'),
+ }));
+ filteredHeader5.splice(0, 0, {
+ id: "rowNumber",
+ title: '일련번호'
+ });
+ setTableHeader5(filteredHeader5);
+
+ const data5 = Array.isArray(jsonDataBySheet['4.정비사업요약'])
+ ? jsonDataBySheet['4.정비사업요약'].slice(3)
+ : [];
+ const filteredData5 =
+ filterEmptyRows(data5).map((item: any, index: number) => ({
+ ...item,
+ rowNumber: index + 1,
+ }));
+ setTableData5(filteredData5);
+
+ // 4.정비사업최종 (헤더는 import)
+ const data6 = Array.isArray(jsonDataBySheet['4.정비사업최종'])
+ ? jsonDataBySheet['4.정비사업최종'].slice(6)
+ : [];
+ const filteredData6 =
+ filterEmptyRows(data6).map((item: any, index: number) => ({
+ ...item,
+ rowNumber: index + 1,
+ }));
+ setTableData6(filteredData6);
+ } catch (error) {
+ console.error('파일 처리 중 오류 발생:', error);
+ alert('파일 처리 중 오류가 발생했습니다.');
+ } finally {
+ setIsLoading(false);
+ }
+}
+
+function filterEmptyRows(data: any[]) {
+ return data
+ .filter(row => {
+ return Object.entries(row).some(([key, value]) => {
+ const match = key.match(/^__EMPTY_(\d+)$/);
+ if (!match || parseInt(match[1] ?? '', 10) < 2) return false;
+
+ return value !== undefined &&
+ value !== null &&
+ String(value).trim() !== '' &&
+ String(value).trim() !== '-' &&
+ String(value).trim() !== '';
+ });
+ })
+ .map((row) => {
+ const processedRow = { ...row };
+ const keys = Object.keys(processedRow);
+
+ keys.forEach((key, keyIndex) => {
+ // 마지막 속성(사업 근거)이 아닌 경우에만 빈 값을 '-'으로 변경
+ if (keyIndex !== keys.length - 1) {
+ const value = processedRow[key];
+ if (value === undefined ||
+ value === null ||
+ value === '' ||
+ String(value).trim() === '') {
+ processedRow[key] = '-';
+ }
+ }
+ });
+
+ return processedRow;
+ });
+};
+
+// 특정 시트만 선택적으로 JSON으로 변환하는 함수
+function filePickedSelectedSheets(file: File, headerNum: number = 0, sheetNames: string[]): Promise> {
+ const reader = new FileReader();
+
+ return new Promise((resolve, reject) => {
+ reader.onload = function (e) {
+ const data = e.target?.result;
+ if (!data) {
+ console.error("Failed to read file: e.target.result is null");
+ reject(new Error("Failed to read file"));
+ return;
+ }
+
+ // Excel 파일 읽기
+ const wb = XLSX.read(data, { type: 'binary', cellDates: true });
+ const result: Record = {};
+
+ // 지정된 시트 이름만 찾아서 처리
+ sheetNames.forEach(targetSheetName => {
+ // 대소문자 구분 없이 시트 이름 찾기
+ const sheetName = wb.SheetNames.find(name =>
+ name.toLowerCase() === targetSheetName.toLowerCase()
+ );
+
+ if (sheetName) {
+ const sheet = wb.Sheets[sheetName];
+ if (sheet) {
+ const jsonData = XLSX.utils.sheet_to_json(sheet, { range: headerNum, raw: false });
+ result[targetSheetName] = jsonData;
+ }
+ } else {
+ console.warn(`Sheet "${targetSheetName}" not found in workbook`);
+ result[targetSheetName] = [];
+ }
+ });
+
+ resolve(result);
+ };
+
+ reader.onerror = function () {
+ console.error("Error reading file");
+ reject(new Error("Error reading file"));
+ };
+
+ // 파일 읽기 시작
+ reader.readAsBinaryString(file);
+ });
+};
+
+
+return (
+ <>
+ {/* 탭 영역 */}
+ ({
+ value: tab.val,
+ label: tab.text
+ }))}
+ onValueChange={(value: string) => setActiveTab(value)}
+ />
+ {/* row data 탭 */}
+ {activeTab === '1' && (
+
+ )}
+ {/* 1.정밀조사 탭 */}
+ {activeTab === '2' && (
+
+ )}
+ {/* 2.정밀조사_정비사업연계 탭 */}
+ {activeTab === '3' && (
+
+ )}
+ {/* 3.정비사업 탭 */}
+ {activeTab === '4' && (
+
+ )}
+ {/* 4.정비사업요약 탭 */}
+ {activeTab === '5' && (
+
+ )}
+ {/* 4.정비사업최종 탭 */}
+ {activeTab === '6' && (
+
+ )}
+ >
+)
+};
+
+export default TableModal;
\ No newline at end of file
diff --git a/apps/wr/.env.development b/apps/wr/.env.development
index ceaf190df..d3ec10727 100644
--- a/apps/wr/.env.development
+++ b/apps/wr/.env.development
@@ -27,3 +27,5 @@ NEXT_PUBLIC_ACCESS_TOKEN = access-token
NEXT_PUBLIC_REFRESH_TOKEN = refresh-token
NEXT_PUBLIC_NGII_URL = https://map.ngii.go.kr/openapi/Gettile.do?apiKey=04trYP9_xwLAfALjwZ-B8g
NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/api # 개발 서버 API
+NEXT_PUBLIC_FINDADRESS_URL=https://business.juso.go.kr/addrlink/addrLinkApi.do
+NEXT_PUBLIC_WR_ADDRESS_KEY = devU01TX0FVVEgyMDI1MDgyNTEwMzkwNDExNjEwNTM=
diff --git a/apps/wr/.env.local b/apps/wr/.env.local
index 4d8937ea6..547195433 100644
--- a/apps/wr/.env.local
+++ b/apps/wr/.env.local
@@ -16,6 +16,12 @@ NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver
NEXT_PUBLIC_NGII_URL = https://map.ngii.go.kr/openapi/Gettile.do?apiKey=04trYP9_xwLAfALjwZ-B8g
+
+
+NEXT_PUBLIC_FINDADRESS_URL=https://business.juso.go.kr/addrlink/addrLinkApi.do
+NEXT_PUBLIC_WR_ADDRESS_KEY = devU01TX0FVVEgyMDI1MDgyNTEwMzkwNDExNjEwNTM=
+
+
NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/api # 개발 서버 API
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883/sewerage-service/api # 최용성
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.66:8883/sewerage-service/api # 박이정
diff --git a/apps/wr/.env.production b/apps/wr/.env.production
index 4a0754665..295ba7ea9 100644
--- a/apps/wr/.env.production
+++ b/apps/wr/.env.production
@@ -16,6 +16,9 @@ NEXT_PUBLIC_NGII_URL = http://10.98.25.94:18080/openapi/Gettile.do?apiKey=BDE2BE
NEXT_PUBLIC_SEWERAGE_API_URL = http://apigateway.iipbs-dev.svc.cluster.local:8000/sewerage-service/api
+NEXT_PUBLIC_FINDADRESS_URL=https://business.juso.go.kr/addrlink/addrLinkApi.do
+NEXT_PUBLIC_WR_ADDRESS_KEY = U01TXOFVVEgyMDI1MDgyODE0MTAxNzExNjEyMjA=
+
diff --git a/apps/wr/app/store/common/code/basicCode.tsx b/apps/wr/app/store/common/code/basicCode.tsx
index aa5d1152e..8af04c59f 100644
--- a/apps/wr/app/store/common/code/basicCode.tsx
+++ b/apps/wr/app/store/common/code/basicCode.tsx
@@ -52,7 +52,7 @@ export const ruseBizMthdCd: SelectDataType[] = [
{ val: "자체", text: "자체" },
];
-//공통 건축물 용도
+// 공통 건축물 용도
export const bdstUsgCd: SelectDataType[] = [
{ val: "-1", text: "확인불가" },
{ val: "1", text: "운동장" },
@@ -71,67 +71,67 @@ export const bdstUsgCd: SelectDataType[] = [
{ val: "14", text: "골프장" },
{ val: "15", text: "대규모점포" },
{ val: "16", text: "기타" },
- { text: "숙박업", val: "17" },
- { text: "목욕장업", val: "18" },
- { text: "공장", val: "19" },
- { text: "발전시설", val: "20" },
- { text: "관광단지개발사업", val: "21" },
- { text: "도시개발사업", val: "22" },
- { text: "산업단지개발사업", val: "23" },
- { text: "택지개발사업", val: "24" },
- { text: "대규모점포(대형마트)", val: "25" },
- { text: "대규모점포(전문점)", val: "26" },
- { text: "대규모점포(백화점)", val: "27" },
- { text: "대규모점포(쇼핑센터)", val: "28" },
- { text: "대규모점포(복합쇼핑몰)", val: "29" },
- { text: "물류시설", val: "30" },
- { text: "운수시설(여객자동차터미널)", val: "31" },
- { text: "운수시설(철도시설)", val: "32" },
- { text: "운수시설(공항시설)", val: "33" },
- { text: "운수시설(항만시설)", val: "34" },
- { text: "업무시설(공공업무시설)", val: "35" },
- { text: "업무시설(금융업소)", val: "36" },
- { text: "업무시설(사무소)", val: "37" },
- { text: "업무시설(결혼상담소 등 소개업소)", val: "38" },
- { text: "업무시설(출판사)", val: "39" },
- { text: "업무시설(신문사)", val: "40" },
- { text: "업무시설(오피스텔)", val: "41" },
- { text: "교정시설", val: "42" },
- { text: "방송국", val: "43" },
- { text: "전신전화국", val: "44" },
- { text: "기타", val: "45" },
+ { val: "17", text: "숙박업" },
+ { val: "18", text: "목욕장업" },
+ { val: "19", text: "공장" },
+ { val: "20", text: "발전시설" },
+ { val: "21", text: "관광단지개발사업" },
+ { val: "22", text: "도시개발사업" },
+ { val: "23", text: "산업단지개발사업" },
+ { val: "24", text: "택지개발사업" },
+ { val: "25", text: "대규모점포(대형마트)" },
+ { val: "26", text: "대규모점포(전문점)" },
+ { val: "27", text: "대규모점포(백화점)" },
+ { val: "28", text: "대규모점포(쇼핑센터)" },
+ { val: "29", text: "대규모점포(복합쇼핑몰)" },
+ { val: "30", text: "물류시설" },
+ { val: "31", text: "운수시설(여객자동차터미널)" },
+ { val: "32", text: "운수시설(철도시설)" },
+ { val: "33", text: "운수시설(공항시설)" },
+ { val: "34", text: "운수시설(항만시설)" },
+ { val: "35", text: "업무시설(공공업무시설)" },
+ { val: "36", text: "업무시설(금융업소)" },
+ { val: "37", text: "업무시설(사무소)" },
+ { val: "38", text: "업무시설(결혼상담소 등 소개업소)" },
+ { val: "39", text: "업무시설(출판사)" },
+ { val: "40", text: "업무시설(신문사)" },
+ { val: "41", text: "업무시설(오피스텔)" },
+ { val: "42", text: "교정시설" },
+ { val: "43", text: "방송국" },
+ { val: "44", text: "전신전화국" },
+ { val: "45", text: "기타" },
];
export const rswtBdstType: SelectDataType[] = [
- { text: "숙박업", val: "17" },
- { text: "목욕장업", val: "18" },
- { text: "공장", val: "19" },
- { text: "발전시설", val: "20" },
- { text: "관광단지개발사업", val: "21" },
- { text: "도시개발사업", val: "22" },
- { text: "산업단지개발사업", val: "23" },
- { text: "택지개발사업", val: "24" },
- { text: "대규모점포(대형마트)", val: "25" },
- { text: "대규모점포(전문점)", val: "26" },
- { text: "대규모점포(백화점)", val: "27" },
- { text: "대규모점포(쇼핑센터)", val: "28" },
- { text: "대규모점포(복합쇼핑몰)", val: "29" },
- { text: "물류시설", val: "30" },
- { text: "운수시설(여객자동차터미널)", val: "31" },
- { text: "운수시설(철도시설)", val: "32" },
- { text: "운수시설(공항시설)", val: "33" },
- { text: "운수시설(항만시설)", val: "34" },
- { text: "업무시설(공공업무시설)", val: "35" },
- { text: "업무시설(금융업소)", val: "36" },
- { text: "업무시설(사무소)", val: "37" },
- { text: "업무시설(결혼상담소 등 소개업소)", val: "38" },
- { text: "업무시설(출판사)", val: "39" },
- { text: "업무시설(신문사)", val: "40" },
- { text: "업무시설(오피스텔)", val: "41" },
- { text: "교정시설", val: "42" },
- { text: "방송국", val: "43" },
- { text: "전신전화국", val: "44" },
- { text: "기타", val: "45" },
+ { val: "17", text: "숙박업" },
+ { val: "18", text: "목욕장업" },
+ { val: "19", text: "공장" },
+ { val: "20", text: "발전시설" },
+ { val: "21", text: "관광단지개발사업" },
+ { val: "22", text: "도시개발사업" },
+ { val: "23", text: "산업단지개발사업" },
+ { val: "24", text: "택지개발사업" },
+ { val: "25", text: "대규모점포(대형마트)" },
+ { val: "26", text: "대규모점포(전문점)" },
+ { val: "27", text: "대규모점포(백화점)" },
+ { val: "28", text: "대규모점포(쇼핑센터)" },
+ { val: "29", text: "대규모점포(복합쇼핑몰)" },
+ { val: "30", text: "물류시설" },
+ { val: "31", text: "운수시설(여객자동차터미널)" },
+ { val: "32", text: "운수시설(철도시설)" },
+ { val: "33", text: "운수시설(공항시설)" },
+ { val: "34", text: "운수시설(항만시설)" },
+ { val: "35", text: "업무시설(공공업무시설)" },
+ { val: "36", text: "업무시설(금융업소)" },
+ { val: "37", text: "업무시설(사무소)" },
+ { val: "38", text: "업무시설(결혼상담소 등 소개업소)" },
+ { val: "39", text: "업무시설(출판사)" },
+ { val: "40", text: "업무시설(신문사)" },
+ { val: "41", text: "업무시설(오피스텔)" },
+ { val: "42", text: "교정시설" },
+ { val: "43", text: "방송국" },
+ { val: "44", text: "전신전화국" },
+ { val: "45", text: "기타" },
];
export const orgwtKndCd = [
@@ -186,6 +186,7 @@ export const pplLenght = [
];
export const rainFcltCd = [
+ { val: "10", text: "확인불가" },
{ val: "01", text: "지붕" },
{ val: "02", text: "건물옥상" },
{ val: "03", text: "골프장 연못" },
@@ -195,7 +196,6 @@ export const rainFcltCd = [
{ val: "07", text: "태양광패널" },
{ val: "08", text: "연못" },
{ val: "09", text: "기타" },
- { val: "10", text: "확인불가" },
];
diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx
index add7030fa..28888d042 100644
--- a/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx
+++ b/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx
@@ -17,15 +17,15 @@ const hdtflObjSchema = z.object({
.string()
.min(1, { message: validationMessages.required("에너지원 종류") }),
fclCpct: z
- .number()
- .positive({ message: validationMessages.required("시설 용량") }),
+ .number().nullish(),
+ //.positive({ message: validationMessages.required("시설 용량") }),
plwtYn: z.enum(["Y", "N"]).default("Y"),
orgwtWtritSpt: z
- .string()
- .min(1, { message: validationMessages.required("원수 취수 지점") }),
+ .string().nullish(),
+ // .min(1, { message: validationMessages.required("원수 취수 지점") }),
orgwtOcrnProcs: z
- .string()
- .min(1, { message: validationMessages.required("원수 발생 공정") }),
+ .string().nullish(),
+ // .min(1, { message: validationMessages.required("원수 발생 공정") }),
wtritEntrcTp: z
.number()
.max(100, { message: "온도는 100이상이 될 수 없습니다." })
@@ -33,12 +33,12 @@ const hdtflObjSchema = z.object({
amtgnr: z.number().default(0),
prcsProcsYn: z.enum(["Y", "N"]).default("Y"),
prcsFcltCpct: z
- .number()
- .positive({ message: validationMessages.required("처리시설 용량") }),
+ .number().nullish(),
+ // .positive({ message: validationMessages.required("처리시설 용량") }),
fmYn: z.string().default(""),
utztnCpct: z
- .number()
- .positive({ message: validationMessages.required("이용 용량") }),
+ .number().nullish(),
+ // .positive({ message: validationMessages.required("이용 용량") }),
utztnUsg: z
.string()
.min(1, { message: validationMessages.required("이용 용도") }),
diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/type.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/type.tsx
index 011d29da4..4bf891d87 100644
--- a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/type.tsx
+++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/type.tsx
@@ -19,14 +19,9 @@ export const baseReuseBuildingSchema = z.object({
instlCstSprtYn: z.string().default("Y"),
instlCstSprtAmt: z.number().nullish(),
grntchBdstCertYn: z.string().default("Y"),
- grntchBdstCertYr: z
- .string()
- .max(4, { message: validationMessages.yearFormat })
- .refine(
- (year) => year.length === 0 || /^\d{4}$/.test(year),
- {
- message: validationMessages.yearFormat,
- }
+ grntchBdstCertYr: z.string().refine(
+ (val) => val === "" || /^\d{4}$/.test(val),
+ { message: "연도는 빈값 또는 4자리 숫자여야 합니다." }
),
grntchBdstCertNo: z.string().default(""),
grntchBdstCertGrd: z.string().default(""),
@@ -59,7 +54,7 @@ export const chgBuildingSchema = z.object({
export const htdflReuseBuildingSchema = z.object({
bdstRuseFcltSn: z.number().nullish(),
bdstInfoSn: z.number().nullish(),
- instlCmptnDt: z.coerce.date().default(() => new Date()),
+ //instlCmptnDt: z.coerce.date().default(() => new Date()),
instlCst: z.number().nullish(),
operMngCd: z.string().optional().nullish(),
anlOperCst: z.number().default(0),
diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx
index 7ef9bf0d9..02ea00b19 100644
--- a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx
+++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx
@@ -14,7 +14,7 @@ const rswtrObjSchema = z.object({
//wtrUsqty: z.number({ required_error: validationMessages.required("물사용량(m³)") }).positive({ message: validationMessages.required("물사용량(m³)") }),
//oblgTrgtWtrUsqty: z.number().nullish().default(0),
orgwtKndCd: z.string({ required_error: validationMessages.requiredSelect("원수 종류") }).min(1, { message: validationMessages.requiredSelect("원수 종류") }),
- filtrTrtmfctCpct: z.number({ required_error: validationMessages.required("처리시설 용량") }),
+ filtrTrtmfctCpct: z.number().nullish(),
filtrTrtmfctProcs: z.string({ required_error: validationMessages.required("주요처리공정") }).min(1, { message: validationMessages.required("주요처리공정") }),
filtrTrtmfctUsgCd: z.string().default("").nullish(),
rswtrUsqty: z.number().default(0),
diff --git a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx
index 90ca4e0f5..0b7be34fa 100644
--- a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx
+++ b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx
@@ -21,7 +21,7 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) {
const { userSiSggCd } = code;
const [useCityCd, setUserCityCd] = useState([]);
const [useSggCd, setUserSggCd] = useState([]);
-
+ const [initDaddr, setInitDaddr] = useState();
useEffect(() => {
if (userSiSggCd.length === 2 && code.cityCd.length > 0) {
@@ -56,6 +56,7 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) {
form.setValue("ctpvCd", Number(city[0]?.val));
form.setValue("sggCd", Number(sgg[0]?.val));
}
+
}, [form, userSiSggCd, code.cityCd, code.sggCd]);
@@ -67,9 +68,16 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) {
return () => subscription?.unsubscribe();
}, [form.form]);
+ // useEffect(() => {
+ // console.log("form ", form.watch());
+ // }, [form.formState]);
+
+
useEffect(() => {
- console.log("form.formState ", form.watch("archArea"));
- }, [form.formState]);
+ const bdstInfoSn = form.getValues("bdstInfoSn");
+ if(bdstInfoSn&&bdstInfoSn>0)
+ setInitDaddr(form.getValues("daddr"));
+ }, [form.getValues("bdstInfoSn")]);
return (
<>
@@ -166,7 +174,7 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) {
/> */}
{
console.log("rtnData", rtnData);
field.onChange(rtnData.roadAddrPart1);
diff --git a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx
index dc2c16242..c17dfda04 100644
--- a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx
+++ b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx
@@ -78,6 +78,10 @@ export default function HtdflRegForm({
};
const cleanHtdflData = (raw: any): z.infer => {
+ const buildings =
+ raw?.reuseBuilding && raw.reuseBuilding.length > 0
+ ? raw.reuseBuilding
+ : [{}];
return {
...raw,
frstArchPrmsnDt: new Date(raw?.frstArchPrmsnDt || null),
@@ -92,7 +96,7 @@ export default function HtdflRegForm({
: new Date(item?.archChgPrmsnDt),
bdstChgNm: item?.bdstChgNm ?? "", // null → ""
})),
- reuseBuilding: (raw?.reuseBuilding || []).map((item: any) => ({
+ reuseBuilding:buildings.map((item: any) => ({
...item,
instlCmptnDt: new Date(item?.instlCmptnDt),
htdflObj: {
diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx
index 09acc46e8..fbcae44b0 100644
--- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx
+++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx
@@ -84,13 +84,14 @@ export default function RainRegForm({
typeof item?.grntchBdstCertYr === "string"
? item?.grntchBdstCertYr
: "", // null → ""
+ bdstUsgCd: item?.bdstUsgCd ?? Number("-1"), // null → "-1"
instlCstSprtYn: item?.instlCstSprtYn ?? "Y", // null → "Y"
- grntchBdstCertYn: item?.grntchBdstCertYn ?? "Y",
+ grntchBdstCertYn: item?.grntchBdstCertYn ?? "D",
rainyObj: {
...item?.rainyObj,
- pntfColKnd:item.rainyObj?.pntfColKnd??'확인불가',
+ pntfColKnd:item.rainyObj?.pntfColKnd??rainFcltCd[0]?.val??'',
filtrTrtmfctPrs:item.rainyObj?.filtrTrtmfctPrs??'',
- filtrTrtmfctYn: item?.rainyObj?.filtrTrtmfctYn ?? "Y",
+ filtrTrtmfctYn: item?.rainyObj?.filtrTrtmfctYn ?? "D",
},
})),
};
@@ -98,7 +99,7 @@ export default function RainRegForm({
useEffect(() => {
if (grntchBdstCertYn === "N") {
- form.setValue("reuseBuilding.0.grntchBdstCertYr", "");
+ form.setValue("reuseBuilding.0.grntchBdstCertYr", '');
form.setValue("reuseBuilding.0.grntchBdstCertNo", "");
form.setValue("reuseBuilding.0.grntchBdstCertGrd", "");
} else if (instlCstSprtYn === "N") {
@@ -298,7 +299,10 @@ export default function RainRegForm({
selectClass={selectClass}
label={""}
selectArray={rainFcltCd}
- onSelectValue={readonly ? () => { } : field.onChange}
+ onSelectValue={ (item) =>{
+ if(readonly) return;
+ field.onChange(item)
+ } }
value={field.value ?? rainFcltCd[0]?.val}
readOnly={readonly}
/>
@@ -521,8 +525,7 @@ export default function RainRegForm({
control={form.control}
name="reuseBuilding.0.grntchBdstCertYr"
render={({ field }) => {
- const isUnknown =
- field.value === null || field.value === "0000"; // 또는 Number(value) === -1
+ const isUnknown = field.value === null || field.value === "0000"; // 또는 Number(value) === -1
return (
{
if (readonly) return;
if (e.target.value === "확인불가") {
diff --git a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx
index 5ae5cd264..82aa0227c 100644
--- a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx
+++ b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx
@@ -83,8 +83,10 @@ export default function RswtrRegForm({
const filtrTrtmfctCpct = form.watch('reuseBuilding.0.rswtrObj.filtrTrtmfctCpct')
const cleanRswtData = (raw: any): z.infer => {
-
- console.log('raw ', raw)
+ const buildings =
+ raw?.reuseBuilding && raw.reuseBuilding.length > 0
+ ? raw.reuseBuilding
+ : [{}];
return {
...raw,
frstArchPrmsnDt: raw?.frstArchPrmsnDt
@@ -93,14 +95,15 @@ export default function RswtrRegForm({
archChgPrmsnDt: raw?.archChgPrmsnDt
? new Date(raw?.archChgPrmsnDt)
: null,
- reuseBuilding: (raw?.reuseBuilding || []).map((item: any) => ({
+ reuseBuilding:buildings.map((item: any) => ({
...item,
instlCmptnDt: item?.instlCmptnDt
? new Date(item.instlCmptnDt)
: new Date(), // item?.instlCmptnDt가 유효하지 않으면 현재 날짜로 초기화
operMngCd: item?.operMngCd || "", // null → ""
- instlCstSprtYn: item?.instlCstSprtYn || code.yn[0]?.val, // null → "Y"
- grntchBdstCertYn: item?.grntchBdstCertYn || code.yn[0]?.val,
+ instlCstSprtYn: item?.instlCstSprtYn || 'N', // null → "Y"
+ grntchBdstCertYn: item?.grntchBdstCertYn ||'N',
+ bdstUsgCd: item?.bdstUsgCd ?? Number("-1"), // null → "-1"
rswtrObj: {
...item?.rswtrObj,
filtrTrtmfctYn: item?.rainyObj?.filtrTrtmfctYn || code.yn[0]?.val,
@@ -145,6 +148,9 @@ export default function RswtrRegForm({
if (rswtZod) form.reset(cleanRswtData(rswtForm));
}, [rswtForm, form]);
+
+
+
return (