From bd8d850a78c321eabf51b549474dd238dec7dfcd Mon Sep 17 00:00:00 2001 From: dongsilove Date: Fri, 2 Jan 2026 23:17:59 +0900 Subject: [PATCH 01/34] =?UTF-8?q?dm:=20=EC=97=B0=EB=85=B9=EC=83=89=20?= =?UTF-8?q?=EC=8A=A4=ED=82=A8=20=EB=B0=8F=20=EB=A9=94=EB=89=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dm/app/layout.tsx | 3 +++ packages/common/components/src/ui/header/index.tsx | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/dm/app/layout.tsx b/apps/dm/app/layout.tsx index 462537e09..7224c9dc2 100644 --- a/apps/dm/app/layout.tsx +++ b/apps/dm/app/layout.tsx @@ -1,5 +1,8 @@ "use client"; import "./globals.css"; +import { setCookie } from "../src/shared/lib"; + +setCookie("site-id-key", process.env.NEXT_PUBLIC_SITE_ID || "DM"); export default function RootLayout({ children, diff --git a/packages/common/components/src/ui/header/index.tsx b/packages/common/components/src/ui/header/index.tsx index 97ed4c151..ddd5e0c21 100644 --- a/packages/common/components/src/ui/header/index.tsx +++ b/packages/common/components/src/ui/header/index.tsx @@ -153,10 +153,10 @@ export function Header({ viewOnly }: { viewOnly?: boolean }) {

{mounted ? ( - logo { if (logoRef.current) { @@ -167,7 +167,7 @@ export function Header({ viewOnly }: { viewOnly?: boolean }) { ) : ( )} - 0 ? `${(logoWidth - 120) / (siteInfo?.siteNm?.length || 1)}px` : '0.05em' From 94b640d5664490c9de2543d099911f978d0e0015 Mon Sep 17 00:00:00 2001 From: dongsilove Date: Sat, 3 Jan 2026 14:50:26 +0900 Subject: [PATCH 02/34] =?UTF-8?q?dm:=20experimental=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dm/.env.local | 11 +++++------ apps/dm/next.config.ts | 3 +++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/dm/.env.local b/apps/dm/.env.local index 44e7072c3..e73fe4485 100644 --- a/apps/dm/.env.local +++ b/apps/dm/.env.local @@ -4,17 +4,16 @@ NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token NEXT_PUBLIC_PORT = 3005 -#NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11035 NEXT_PUBLIC_PROXY_HOST = http://localhost:3005 -NEXT_PUBLIC_DM_SERVER_API_URL = http://con.mind-one.co.kr:11083/reuse-service/api/v1 -NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 -NEXT_PUBLIC_FO_SERVER_API_URL = http://con.mind-one.co.kr:11083/operation-service/api/v1 -# NEXT_PUBLIC_FO_SERVER_API_URL = http://192.168.1.222:8883/operation-service/api/v1 NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000 +NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 +NEXT_PUBLIC_DM_SERVER_API_URL = http://con.mind-one.co.kr:11083/reuse-service/api/v1 +# NEXT_PUBLIC_FO_SERVER_API_URL = http://192.168.1.222:8883/operation-service/api/v1 +NEXT_PUBLIC_FO_SERVER_API_URL = http://con.mind-one.co.kr:11083/operation-service/api/v1 +NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11083/reuse-service/api/v1 NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver NEXT_PUBLIC_CS_TUS_UPLOAD = /attach-service/api/v1/tus/upload -NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11083/reuse-service/api/v1 NEXT_PUBLIC_NGII_URL = https://map.ngii.go.kr NEXT_PUBLIC_NGII_PARAM = 04trYP9_xwLAfALjwZ-B8g&service=WMTS&request=GetTile&version=1.0.0&format=image/png&layer=korean_map&style=korean&tilematrixset=korean&tilematrix={z}&tilecol={x}&tilerow={y} NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service # 개발 서버 API diff --git a/apps/dm/next.config.ts b/apps/dm/next.config.ts index bc21e16a4..5e1533ec9 100644 --- a/apps/dm/next.config.ts +++ b/apps/dm/next.config.ts @@ -5,6 +5,9 @@ const subDomain = const nextConfig: NextConfig = { output: "standalone", + experimental: { + proxyTimeout: 600000, + }, async rewrites() { return { beforeFiles: [ From 897ce3eb242848d46db1f3e8622c0c47223f08cc Mon Sep 17 00:00:00 2001 From: dongsilove Date: Sat, 3 Jan 2026 15:52:41 +0900 Subject: [PATCH 03/34] =?UTF-8?q?wr:=20=EC=A3=BC=EC=84=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/(map-layout)/map/mainMap/page.tsx | 228 +++++++++--------- apps/wr/components/lib/func/mapUtil.ts | 88 +++---- 2 files changed, 157 insertions(+), 159 deletions(-) diff --git a/apps/wr/app/(map-layout)/map/mainMap/page.tsx b/apps/wr/app/(map-layout)/map/mainMap/page.tsx index 362d45cb8..927703ad9 100644 --- a/apps/wr/app/(map-layout)/map/mainMap/page.tsx +++ b/apps/wr/app/(map-layout)/map/mainMap/page.tsx @@ -21,7 +21,7 @@ import WrOverLay from "@/components/ui/map/wrOverLay/wrOverLay"; const Map = () => { - const {code, comMap ,rainMapDetile ,rswtMapDetile,getRuseMaplListReturn,pbnMapDetaile,ldrmntMapDetile,htdfMapDetile,coSttnMapDetail} = useWrStore((state) => state); + const { code, comMap, rainMapDetile, rswtMapDetile, getRuseMaplListReturn, pbnMapDetaile, ldrmntMapDetile, htdfMapDetile, coSttnMapDetail } = useWrStore((state) => state); const { isFeatured } = comMap; const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정 const gisMaps = useRef(null); @@ -93,7 +93,6 @@ const Map = () => { return; } - // 항상 같은 select 객체 사용 const select = GisApp.Module.select as any; if (!select) return; @@ -109,7 +108,6 @@ const Map = () => { const layerName = getWrLayerNm(data); const featurePk = getWrFeaturePk(layerName ?? ""); - // 재이용시설 if (featurePk) { const lastPk = @@ -254,139 +252,139 @@ const Map = () => { const OVERLAY_MIN_ZOOM = 16; -const OVERLAY_COORD_PRECISION = 5; -const OVERLAY_MAX_PER_VIEW = 800; + const OVERLAY_COORD_PRECISION = 5; + const OVERLAY_MAX_PER_VIEW = 800; -const overlayManagersRef = useRef([]); -const overlayActiveRef = useRef(false); -const moveEndDebounceRef = useRef(null); + const overlayManagersRef = useRef([]); + const overlayActiveRef = useRef(false); + const moveEndDebounceRef = useRef(null); -// 반환: Promise -const overlayFormatter = async (feature: any, props: any) => { - const p = props || {}; - const featureId = - feature.getId?.() ?? p?.id ?? p?.fid ?? p?.ftrIdn ?? ''; - if (!featureId) return null; + // 반환: Promise + const overlayFormatter = async (feature: any, props: any) => { + const p = props || {}; + const featureId = + feature.getId?.() ?? p?.id ?? p?.fid ?? p?.ftrIdn ?? ''; + if (!featureId) return null; - const tableId = String(featureId).split('.')[0]??''; - const fcltCd = getFeatureCd(props, tableId); + const tableId = String(featureId).split('.')[0] ?? ''; + const fcltCd = getFeatureCd(props, tableId); - if (!fcltCd) return null; + if (!fcltCd) return null; - let data: any = null; - let title = ''; + let data: any = null; + let title = ''; - if (tableId === 'tb_il_swage_prcs_fclt') { data = await pbnMapDetaile(fcltCd); title = '하수처리시설'; } - else if (tableId === 'tb_wr_bdst_ruse_fclt') { data = await getRuseMaplListReturn(fcltCd); title = '하수재이용시설'; } - else if (tableId === 'tb_wr_rnwtr_utztn_fclt'){ data = await rainMapDetile(fcltCd); title = '빗물이용시설'; } - else if (tableId === 'tb_wr_rswtr_fclt') { data = await rswtMapDetile(fcltCd); title = '중수도시설'; } - else if (tableId === 'tb_wr_htdfl_fclt') { data = await htdfMapDetile(fcltCd); title = '온배수시설'; } - else if (tableId === 'tb_wr_ruse_fclt_dmd_co'){ data = await coSttnMapDetail(fcltCd); title = '수요처'; } - else if (tableId === 'tb_wr_tmpr_dmd_co') { data = await ldrmntMapDetile(fcltCd); title = '잠재수요처'; } + if (tableId === 'tb_il_swage_prcs_fclt') { data = await pbnMapDetaile(fcltCd); title = '하수처리시설'; } + else if (tableId === 'tb_wr_bdst_ruse_fclt') { data = await getRuseMaplListReturn(fcltCd); title = '하수재이용시설'; } + else if (tableId === 'tb_wr_rnwtr_utztn_fclt') { data = await rainMapDetile(fcltCd); title = '빗물이용시설'; } + else if (tableId === 'tb_wr_rswtr_fclt') { data = await rswtMapDetile(fcltCd); title = '중수도시설'; } + else if (tableId === 'tb_wr_htdfl_fclt') { data = await htdfMapDetile(fcltCd); title = '온배수시설'; } + else if (tableId === 'tb_wr_ruse_fclt_dmd_co') { data = await coSttnMapDetail(fcltCd); title = '수요처'; } + else if (tableId === 'tb_wr_tmpr_dmd_co') { data = await ldrmntMapDetile(fcltCd); title = '잠재수요처'; } - const empty = - data == null || - (Array.isArray(data) && data.length === 0) || - (typeof data === 'object' && !Array.isArray(data) && Object.keys(data).length === 0); + const empty = + data == null || + (Array.isArray(data) && data.length === 0) || + (typeof data === 'object' && !Array.isArray(data) && Object.keys(data).length === 0); - if (empty) return null; + if (empty) return null; - const div = document.createElement('div'); - const root = createRoot(div); - (div as any).__dispose = () => { try { root.unmount(); } catch {} }; - root.render(); - return div; // ← 데이터 있을 때만 HTMLElement 반환 -}; -const destroyAllManagers = () => { - overlayManagersRef.current.forEach(m => { try { m.destroy(); } catch {} }); - overlayManagersRef.current = []; - overlayActiveRef.current = false; -}; + const div = document.createElement('div'); + const root = createRoot(div); + (div as any).__dispose = () => { try { root.unmount(); } catch { } }; + root.render(); + return div; // ← 데이터 있을 때만 HTMLElement 반환 + }; + const destroyAllManagers = () => { + overlayManagersRef.current.forEach(m => { try { m.destroy(); } catch { } }); + overlayManagersRef.current = []; + overlayActiveRef.current = false; + }; -const mountOverlayManagers = () => { - const map = gisMaps.current; - if (!map) return; + const mountOverlayManagers = () => { + const map = gisMaps.current; + if (!map) return; - // 이전 것 정리 - destroyAllManagers(); + // 이전 것 정리 + destroyAllManagers(); - // 체크된 벡터 레이어만 골라 매니저 생성 - const checkedSet = new Set(checkedLayers.map(String)); - const layers: any[] = map.getLayers().getArray(); - const targets = layers.filter((layer: any) => { - const src = layer.getSource?.(); - const isVector = src && typeof src.getFeatures === "function"; - const id = String(layer.get?.("lyrSn") ?? layer.get?.("id") ?? ""); - return isVector && layer.getVisible?.() && checkedSet.has(id); - }); - - targets.forEach((layer: any) => { - const mgr = createOverlayManager(map, layer, overlayFormatter, { - coordPrecision: OVERLAY_COORD_PRECISION, - maxOverlaysPerViewport: OVERLAY_MAX_PER_VIEW, + // 체크된 벡터 레이어만 골라 매니저 생성 + const checkedSet = new Set(checkedLayers.map(String)); + const layers: any[] = map.getLayers().getArray(); + const targets = layers.filter((layer: any) => { + const src = layer.getSource?.(); + const isVector = src && typeof src.getFeatures === "function"; + const id = String(layer.get?.("lyrSn") ?? layer.get?.("id") ?? ""); + return isVector && layer.getVisible?.() && checkedSet.has(id); }); - mgr.mount(); // 리스너 1회 등록 - mgr.enable(); // 표시 + 1회 sync - overlayManagersRef.current.push(mgr); - }); - overlayActiveRef.current = overlayManagersRef.current.length > 0; -}; + targets.forEach((layer: any) => { + const mgr = createOverlayManager(map, layer, overlayFormatter, { + coordPrecision: OVERLAY_COORD_PRECISION, + maxOverlaysPerViewport: OVERLAY_MAX_PER_VIEW, + }); + mgr.mount(); // 리스너 1회 등록 + mgr.enable(); // 표시 + 1회 sync + overlayManagersRef.current.push(mgr); + }); -useEffect(() => { - const map = gisMaps.current; - if (!map) return; - - const z = map.getView()?.getZoom?.() ?? 0; - if (z < OVERLAY_MIN_ZOOM) { - // 저줌에선 그냥 안 보이게만 - overlayManagersRef.current.forEach(m => { try { m.disable({ clear:true, delayed:true }); } catch {} }); - return; - } - mountOverlayManagers(); - - return () => { destroyAllManagers(); }; -}, [checkedLayers]); - - -useEffect(() => { - const map = gisMaps.current; - if (!map) return; - - const onMoveStart = () => { - // 숨기기만 (리스너/DOM 대량 제거 X) - overlayManagersRef.current.forEach(m => { try { m.disable({ clear:false }); } catch {} }); - if (moveEndDebounceRef.current) { clearTimeout(moveEndDebounceRef.current); moveEndDebounceRef.current = null; } + overlayActiveRef.current = overlayManagersRef.current.length > 0; }; - const onMoveEnd = () => { + useEffect(() => { + const map = gisMaps.current; + if (!map) return; + const z = map.getView()?.getZoom?.() ?? 0; - const active = overlayActiveRef.current; + if (z < OVERLAY_MIN_ZOOM) { + // 저줌에선 그냥 안 보이게만 + overlayManagersRef.current.forEach(m => { try { m.disable({ clear: true, delayed: true }); } catch { } }); + return; + } + mountOverlayManagers(); - if (moveEndDebounceRef.current) clearTimeout(moveEndDebounceRef.current); - moveEndDebounceRef.current = window.setTimeout(() => { - if (z < OVERLAY_MIN_ZOOM) { - if (active) overlayManagersRef.current.forEach(m => { try { m.disable({ clear:true, delayed:true }); } catch {} }); - return; - } - if (!active) { - mountOverlayManagers(); - } else { - // 다시 보이고 1회만 동기화 - overlayManagersRef.current.forEach(m => { try { m.enable(); m.syncOverlays(); } catch {} }); - } - }, 180) as unknown as number; - }; + return () => { destroyAllManagers(); }; + }, [checkedLayers]); - map.on("movestart", onMoveStart); - map.on("moveend", onMoveEnd); - return () => { - map.un("movestart", onMoveStart); - map.un("moveend", onMoveEnd); - if (moveEndDebounceRef.current) { clearTimeout(moveEndDebounceRef.current); moveEndDebounceRef.current = null; } - }; -}, [checkedLayers]); + + useEffect(() => { + const map = gisMaps.current; + if (!map) return; + + const onMoveStart = () => { + // 숨기기만 (리스너/DOM 대량 제거 X) + overlayManagersRef.current.forEach(m => { try { m.disable({ clear: false }); } catch { } }); + if (moveEndDebounceRef.current) { clearTimeout(moveEndDebounceRef.current); moveEndDebounceRef.current = null; } + }; + + const onMoveEnd = () => { + const z = map.getView()?.getZoom?.() ?? 0; + const active = overlayActiveRef.current; + + if (moveEndDebounceRef.current) clearTimeout(moveEndDebounceRef.current); + moveEndDebounceRef.current = window.setTimeout(() => { + if (z < OVERLAY_MIN_ZOOM) { + if (active) overlayManagersRef.current.forEach(m => { try { m.disable({ clear: true, delayed: true }); } catch { } }); + return; + } + if (!active) { + mountOverlayManagers(); + } else { + // 다시 보이고 1회만 동기화 + overlayManagersRef.current.forEach(m => { try { m.enable(); m.syncOverlays(); } catch { } }); + } + }, 180) as unknown as number; + }; + + map.on("movestart", onMoveStart); + map.on("moveend", onMoveEnd); + return () => { + map.un("movestart", onMoveStart); + map.un("moveend", onMoveEnd); + if (moveEndDebounceRef.current) { clearTimeout(moveEndDebounceRef.current); moveEndDebounceRef.current = null; } + }; + }, [checkedLayers]); return (
{ const featureCd = - layerNm === "tb_wr_bdst_ruse_fclt" + layerNm === "tb_wr_bdst_ruse_fclt" //하수재이용시설 ? featurePropertise?.swtrmt_fclt_cd : [ - "tb_wr_rswtr_fclt", - "tb_wr_htdfl_fclt", - "tb_wr_rnwtr_utztn_fclt", - "tb_wr_tmpr_dmd_co", - ].includes(layerNm) + "tb_wr_rswtr_fclt", // 중수도시설 + "tb_wr_htdfl_fclt", // 온배수시설 + "tb_wr_rnwtr_utztn_fclt", // 빗물이용시설 + "tb_wr_tmpr_dmd_co", // 잠재수요처 + ].includes(layerNm) ? featurePropertise?.bdst_nm - : layerNm === "tb_il_swage_prcs_fclt" + : layerNm === "tb_il_swage_prcs_fclt" //하수처리시설 ? featurePropertise?.swtrmt_fclt_cd - : layerNm === "tb_wr_ruse_fclt_dmd_co" + : layerNm === "tb_wr_ruse_fclt_dmd_co" //수요처 ? featurePropertise?.bdst_info_sn : null; @@ -71,9 +71,9 @@ export const getSelectedLayers = (isFeature: any, gisMaps: any) => { let result = null; const layers = map ? map - .getLayers() - .getArray() - .filter((l: any) => l.getVisible()) + .getLayers() + .getArray() + .filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기 let featureLayer: { get: (key: string) => any } = { get: () => null }; @@ -119,12 +119,12 @@ export const getClickFeatureId = (data: any) => { } else if (layerName == "수요처") { //수요처 featureId = `${layerName}.${data.dmdInfoId.replaceAll("-", "")}`; - }else if (layerName == "잠재수요처") { + } else if (layerName == "잠재수요처") { //잠재수요처 featureId = data.id_ - } else { - + } else { + featureId = data.id_ } @@ -160,7 +160,7 @@ export function featurePopUpOpen( ); } -export const getOverLayObj = (fclType: string, data: any,code?:any) => { +export const getOverLayObj = (fclType: string, data: any, code?: any) => { let newObj = {}; let title = ""; @@ -169,11 +169,11 @@ export const getOverLayObj = (fclType: string, data: any,code?:any) => { if (fclType === "하수재이용시설") { newObj = { - "시설용량(톤/일)": formatCommaNumber(data?.fcltCpct) ??'확인불가', - "재이용률(%)": (data?.fcltCpct / data?.bscFctCpc)||0, + "시설용량(톤/일)": formatCommaNumber(data?.fcltCpct) ?? '확인불가', + "재이용률(%)": (data?.fcltCpct / data?.bscFctCpc) || 0, "장내용수(m³/년)": formatCommaNumber(data?.inUsage) ?? '확인불가', - "장외용수(m3/년)":formatCommaNumber(data?.outUsage) ?? '확인불가', - // 수요처: data?.reuseBuilding[0]?.rainyObj.pntfColArea ?? '확인불가', + "장외용수(m3/년)": formatCommaNumber(data?.outUsage) ?? '확인불가', + // 수요처: data?.reuseBuilding[0]?.rainyObj.pntfColArea ?? '확인불가', }; title = data?.bdstNm ?? '확인불가'; } else if (fclType === "하수처리시설") { @@ -184,9 +184,9 @@ export const getOverLayObj = (fclType: string, data: any,code?:any) => { "재이용시설 등록여부": data?.ruse ?? '확인불가', }; title = data?.bscFctNm ?? '확인불가'; - } else if (fclType === "빗물이용시설" ) { + } else if (fclType === "빗물이용시설") { newObj = { - 건물용도: code?.bdstUsgCd.find((item) => item.val=== String(data?.reuseBuilding[0].bdstUsgCd) )?.text ?? '확인불가', + 건물용도: code?.bdstUsgCd.find((item) => item.val === String(data?.reuseBuilding[0].bdstUsgCd))?.text ?? '확인불가', 설치완료일: data?.reuseBuilding[0]?.instlCmptnDt ?? '확인불가', 처리시설유무: data?.reuseBuilding[0]?.rainyObj.filtrTrtmfctYn ?? '확인불가', "처리시설용량(m³/일)": formatCommaNumber(data?.reuseBuilding[0]?.rainyObj.filtrTrtmfctCpct) ?? '확인불가', @@ -195,25 +195,25 @@ export const getOverLayObj = (fclType: string, data: any,code?:any) => { title = data?.bdstNm ?? '확인불가'; } else if (fclType === "중수도시설") { newObj = { - 건물용도: code?.bdstUsgCd.find((item) => item.val===String(data?.reuseBuilding[0].bdstUsgCd) )?.text ?? '확인불가', + 건물용도: code?.bdstUsgCd.find((item) => item.val === String(data?.reuseBuilding[0].bdstUsgCd))?.text ?? '확인불가', 설치완료일: data?.reuseBuilding[0]?.instlCmptnDt ?? '확인불가', - "주요 처리공정": data?.reuseBuilding[0]?.rswtrObj.filtrTrtmfctProcs ?? '확인불가', - 원수종류: code?.orgwtKndCd.find((item) => item.val === data?.reuseBuilding[0]?.rswtrObj.orgwtKndCd)?.text ?? '확인불가', + "주요 처리공정": data?.reuseBuilding[0]?.rswtrObj.filtrTrtmfctProcs ?? '확인불가', + 원수종류: code?.orgwtKndCd.find((item) => item.val === data?.reuseBuilding[0]?.rswtrObj.orgwtKndCd)?.text ?? '확인불가', //이용용도: isCode.filtrTrtmfctUsgCd data?.reuseBuilding[0]?.rswtrObj.altUswtrKndCd ?? '확인불가', }; title = data?.bdstNm ?? '확인불가'; } else if (fclType === "온배수시설") { newObj = { - '발전유형': data?.reuseBuilding[0]?.htdflObj.etgtType??'', - '설비용량': data?.reuseBuilding[0]?.htdflObj.fclCpct??'', - '담수화 여부': data?.reuseBuilding[0]?.htdflObj.plwtYn??'', + '발전유형': data?.reuseBuilding[0]?.htdflObj.etgtType ?? '', + '설비용량': data?.reuseBuilding[0]?.htdflObj.fclCpct ?? '', + '담수화 여부': data?.reuseBuilding[0]?.htdflObj.plwtYn ?? '', }; title = data?.bdstNm ?? '확인불가'; } else if (fclType === "수요처") { newObj = { - '사업자등록번호': data?.dmdInfoId??'', - '주소': data?.daddr??'', - '전화번호': formatPhoneNumber(data?.telno)??'', + '사업자등록번호': data?.dmdInfoId ?? '', + '주소': data?.daddr ?? '', + '전화번호': formatPhoneNumber(data?.telno) ?? '', }; title = data?.dmdCoNm ?? '확인불가'; From ac3acbb0f43264329fe6c0d1fc7f00cd636025c2 Mon Sep 17 00:00:00 2001 From: dongsilove Date: Sun, 4 Jan 2026 20:45:08 +0900 Subject: [PATCH 04/34] =?UTF-8?q?fo:=20dashboard=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/store/dashboard/index.tsx | 160 ++++++++++++++++++-------- apps/fo/app/store/store.tsx | 41 +++---- 2 files changed, 136 insertions(+), 65 deletions(-) diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index b2778e3d8..081da3839 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -699,6 +699,7 @@ const drainageEquipmentList: DrainageEquipmentListProps[] = [ } ]; +type ApiRes = { data: any; count: any; } /**==================================== * Store - api (데이터 호출) ====================================*/ @@ -722,7 +723,7 @@ const fetchFacilityPlan = async (targetYear: string | undefined, fcltyCd: string }; /* 시설정보 및 운영현황 - 운영실태 */ -const fetchOperationStatus = async (searchYear: string | undefined, fcltyCd: string | undefined) => { +const fetchOperationStatus = async (searchYear: string | undefined, fcltyCd: string | undefined): Promise => { try { const url = '/dashBoard/mngInfo/' + (searchYear ? searchYear : '2023') + '/' + (fcltyCd ? fcltyCd : ''); const res = await getFetch('fo', url); @@ -746,14 +747,15 @@ const fetchMainGraph = async (searchYear: string | undefined, fcltyCd: string | } // 수질 데이터 청천시, 강우시 재계산 -const calcWaterQltyData = async (data: any[], searchYear: string | undefined, fcltyCd: string | undefined) => { +const calcWaterQltyData = async (data: any[], searchYear: string | undefined, fcltyCd: string | undefined, mainGraphData: any) => { const nullToZero = (value: any) => { return value === null || value === undefined || value === '' ? 0 : Number(value); }; const orgData = data; - const res = await fetchMainGraph(searchYear, fcltyCd); + // const res = await fetchMainGraph(searchYear, fcltyCd); // /fclt/qlty/hist/{year}/{fcltyCd} + const res = mainGraphData; if (res.data.wqltObjs.length > 0) { // const clone = (arr: any[]) => arr?.map(v => ({ ...v })) ?? []; const qltyData = res.data.wqltObjs; @@ -761,7 +763,7 @@ const calcWaterQltyData = async (data: any[], searchYear: string | undefined, fc // 강우시 변수 const rainEffectDayArray: string[] = []; - + // (0) 전체변수 let summerDay = 0, noNullSummerDay = 0; let totalInflBodAvgSummer = 0, totalInflTnAvgSummer = 0, totalInflTpAvgSummer = 0; @@ -1064,6 +1066,9 @@ export type DashBoardType = { rainManageList: RainManageListProps[]; excelList: RainManageExcelType[]; isLoadingRainManage: boolean; + mainGraphData: any; + mainGraphYear: string; + mainGraphFcltyCd: string; }, DrainageEquipment: { @@ -1127,6 +1132,9 @@ export const dashBoardInitState: DashBoardType = { rainManageList: rainManageList, excelList: [], isLoadingRainManage: false, + mainGraphData: null, + mainGraphYear: '', + mainGraphFcltyCd: '', }, DrainageEquipment: { @@ -1251,7 +1259,8 @@ const searchWaterUsage = async (searchYear: string, fcltyCd: string) => { } export const dashBoardReducer = ( - set: (fn: (state: DashBoardType) => DashBoardType) => void + set: (fn: (state: DashBoardType) => DashBoardType) => void, + get: () => DashBoardType ): DashBoardActions => { return { initializeDashBoardData: async () => { @@ -1275,7 +1284,7 @@ export const dashBoardReducer = ( })); let waterUsage = [0, 0, 0]; waterUsage = await searchWaterUsage(targetYear, fcltyCd); // /fclt/flow/{fcltyCd}/{year} -console.log(waterUsage); + set((state: DashBoardType) => ({ ...state, PlanFclty: { @@ -1355,6 +1364,26 @@ console.log(waterUsage); /** 시설정보 및 운영현황 - 운영실태 */ searchOperationStatus: async (isExcel: boolean, searchYear: string, fcltyCd: string) => { + const state = get(); + let mainGraphData: ApiRes = { data: [], count: 0 }; + + // 이미 조회된 데이터가 있는지 확인 (연도와 시설코드가 같을 때만) + if (state.RainManage.mainGraphYear === searchYear && state.RainManage.mainGraphFcltyCd === fcltyCd && state.RainManage.mainGraphData) { + mainGraphData = state.RainManage.mainGraphData; + } else { + mainGraphData = await fetchMainGraph(searchYear, fcltyCd); + // 조회된 데이터 저장 + set((state: DashBoardType) => ({ + ...state, + RainManage: { + ...state.RainManage, + mainGraphData: mainGraphData, + mainGraphYear: searchYear, + mainGraphFcltyCd: fcltyCd, + } + })); + } + set((state: DashBoardType) => ({ ...state, OperationStatus: { @@ -1630,52 +1659,55 @@ console.log(waterUsage); // 오염물질 // RDII 추정 = 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) - const resp = await fetchMainGraph(searchYear, fcltyCd); - const wqltData = resp.data.wqltObjs; - const wqltDataTot = CalcRainEffect(clone(wqltData)); - const wqltDataSunny = CalcRainEffect(clone(wqltData), 'SUNNY'); + // const resp = await fetchMainGraph(searchYear, fcltyCd); + const resp = mainGraphData; + if (resp && resp.data && resp.data.wqltObjs) { + const wqltData = resp.data.wqltObjs; + const wqltDataTot = CalcRainEffect(clone(wqltData)); + const wqltDataSunny = CalcRainEffect(clone(wqltData), 'SUNNY'); - let minSummerBod = 99999999; - let minSummerBodInfl = 99999999; - let winterCnt = 0; - let winterBodSunny = 0; - let rdiRain = 0; + let minSummerBod = 99999999; + let minSummerBodInfl = 99999999; + let winterCnt = 0; + let winterBodSunny = 0; + let rdiRain = 0; - const summerMonth = ['06', '07', '08']; - const winterMonth = ['01', '02']; + const summerMonth = ['06', '07', '08']; + const winterMonth = ['01', '02']; - wqltDataTot.filter(item => summerMonth.includes(item.msrDt.toString().replaceAll('-', '').substring(4, 6))).forEach(item2 => { - if (Number(item2.infoRnDay) >= 3) { - const inflBod = Number(item2.inflAssctBfrWqltBod); - const infl = Number(item2.inflAmnt); - const rain = Number(item2.infoRnDay); - if (inflBod < minSummerBod) { - minSummerBodInfl = infl; - minSummerBod = inflBod; - rdiRain = rain; + wqltDataTot.filter(item => summerMonth.includes(item.msrDt.toString().replaceAll('-', '').substring(4, 6))).forEach(item2 => { + if (Number(item2.infoRnDay) >= 3) { + const inflBod = Number(item2.inflAssctBfrWqltBod); + const infl = Number(item2.inflAmnt); + const rain = Number(item2.infoRnDay); + if (inflBod < minSummerBod) { + minSummerBodInfl = infl; + minSummerBod = inflBod; + rdiRain = rain; + } } - } - }); + }); - wqltDataSunny.filter(item => winterMonth.includes(item.msrDt.toString().replaceAll('-', '').substring(4, 6))).forEach(item2 => { - winterBodSunny += Number(item2.inflAssctBfrWqltBod); - winterCnt += 1; - }); + wqltDataSunny.filter(item => winterMonth.includes(item.msrDt.toString().replaceAll('-', '').substring(4, 6))).forEach(item2 => { + winterBodSunny += Number(item2.inflAssctBfrWqltBod); + winterCnt += 1; + }); - const roundMinSummerBodInfl = Number(roundNumber(minSummerBodInfl, 0).toString().replaceAll(',', '')); - const roundMinSummerBod = Number(roundNumber(minSummerBod, 1).toString().replaceAll(',', '')); - const roundWinterBodSunny = Number(roundNumber(winterBodSunny, 1).toString().replaceAll(',', '')); + const roundMinSummerBodInfl = Number(roundNumber(minSummerBodInfl, 0).toString().replaceAll(',', '')); + const roundMinSummerBod = Number(roundNumber(minSummerBod, 1).toString().replaceAll(',', '')); + const roundWinterBodSunny = Number(roundNumber(winterBodSunny, 1).toString().replaceAll(',', '')); - const winterBodAvg = Number(roundNumber((roundWinterBodSunny / winterCnt), 1).toString().replaceAll(',', '')); - // 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) - const winMinusSum = winterBodAvg - roundMinSummerBod; + const winterBodAvg = Number(roundNumber((roundWinterBodSunny / winterCnt), 1).toString().replaceAll(',', '')); + // 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) + const winMinusSum = winterBodAvg - roundMinSummerBod; - const rdiValue = winMinusSum === 0 ? 0 : roundMinSummerBodInfl * (winMinusSum / winterBodAvg); + const rdiValue = winMinusSum === 0 ? 0 : roundMinSummerBodInfl * (winMinusSum / winterBodAvg); - rdiPercent = (rdiValue / minSummerBodInfl) * 100; + rdiPercent = (rdiValue / minSummerBodInfl) * 100; - operationalStatusList[0].rdi = rdiValue; - operationalStatusList[0].rdiRain = rdiRain; + operationalStatusList[0].rdi = rdiValue; + operationalStatusList[0].rdiRain = rdiRain; + } /* const summerLowFlow = data.summerBod&&data.summerBod.INFL_AMNT&&data.summerBod.INFL_AMNT!='null'?Number(data.summerBod.INFL_AMNT):0; const winterAvgBod = data.winterSunny&&data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD&&data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD!='null'?Number(data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD):0; const summerLowBod = data.summerBod&&data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD&&data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD!='null'?Number(data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD):0; @@ -1792,7 +1824,7 @@ console.log(waterUsage); } } - const rtnData = await calcWaterQltyData(operationalStatusList, searchYear, fcltyCd); // 수질 데이터 청천시, 강우시 재계산 + const rtnData = await calcWaterQltyData(operationalStatusList, searchYear, fcltyCd, mainGraphData); // 수질 데이터 청천시, 강우시 재계산 // 총인설비가 없을 경우 제외 // console.log('총인시설 여부 : ', data.yearData?.TP_FCT_YN); @@ -1815,6 +1847,26 @@ console.log(waterUsage); }, searchMainGraph: async (searchYear: string, fcltyCd: string) => { + const state = get(); + let res: any = null; + + // 이미 조회된 데이터가 있는지 확인 + if (state.RainManage.mainGraphYear === searchYear && state.RainManage.mainGraphFcltyCd === fcltyCd && state.RainManage.mainGraphData) { + res = state.RainManage.mainGraphData; + } else { + res = await fetchMainGraph(searchYear, fcltyCd); + // 데이터 저장 + set((state: DashBoardType) => ({ + ...state, + RainManage: { + ...state.RainManage, + mainGraphData: res, + mainGraphYear: searchYear, + mainGraphFcltyCd: fcltyCd, + } + })); + } + set((state: DashBoardType) => ({ ...state, MainGraph: { @@ -1822,7 +1874,7 @@ console.log(waterUsage); isLoadingMainGraph: true, }, })); - const res = await fetchMainGraph(searchYear, fcltyCd); + // const res = await fetchMainGraph(searchYear, fcltyCd); const res2 = await fetchFacilityWaterQltyInfo(fcltyCd); let chungcunSumFlow = 0; @@ -1944,6 +1996,24 @@ console.log(waterUsage); }, searchRainManage: async (searchYear: string, fcltyCd: string, isExcel: boolean) => { + const state = get(); + let res: any = null; + + if (state.RainManage.mainGraphYear === searchYear && state.RainManage.mainGraphFcltyCd === fcltyCd && state.RainManage.mainGraphData) { + res = state.RainManage.mainGraphData; + } else { + res = await fetchMainGraph(searchYear, fcltyCd); + set((state: DashBoardType) => ({ + ...state, + RainManage: { + ...state.RainManage, + mainGraphData: res, + mainGraphYear: searchYear, + mainGraphFcltyCd: fcltyCd, + } + })); + } + set((state: DashBoardType) => ({ ...state, RainManage: { @@ -1951,7 +2021,7 @@ console.log(waterUsage); isLoadingRainManage: true, }, })); - const res = await fetchMainGraph(searchYear, fcltyCd); + // const res = await fetchMainGraph(searchYear, fcltyCd); if (res == null || res.data.wqltObjs == null || res.data.wqltObjs.length === 0) { set((state: DashBoardType) => ({ ...state, diff --git a/apps/fo/app/store/store.tsx b/apps/fo/app/store/store.tsx index f7f2222c6..c7064a40e 100644 --- a/apps/fo/app/store/store.tsx +++ b/apps/fo/app/store/store.tsx @@ -42,8 +42,9 @@ import { export type FoStore = CommonStore & tableType & DashBoardStore & ProcessFacilityStore & ProcessAreaStore & FlowRateSearchStore & FacilityPrecipitationStore & FacilityWaterQltyStore & PlanSewageStore & SewageOccurStore & UnderWaterStore & RdiStore; export type FoState = CommonType & tableState & ProcessFacilityType & ProcessAreaType & FacilityPrecipitationType & FlowRateSearchType & DashBoardType & FacilityWaterQltyType & PlanSewageType & SewageOccurType & UnderWaterType & RdiType; -export const StoreZus = - (initState: FoState = { ...commonState, +export const StoreZus = + (initState: FoState = { + ...commonState, ...tableStateExport , ...processFacilityInitState , ...processAreaInitState @@ -57,22 +58,22 @@ export const StoreZus = , ...rdiInitState } ) => { - return createStore()((set) => { - return { - ...initState, - ...CommonReducer(set), - ...tableActionsExport(set), - ...dashBoardReducer(set), - ...processFacilityReducer(set), - ...processAreaReducer(set), - ...facilityPrecipitationReducer(set), - ...flowRateSearchReducer(set), - ...facilityWaterQltyReducer(set), - ...planSewageReducer(set), - ...sewageOccurReducer(set), - ...underWaterReducer(set), - ...rdiReducer(set), - } - }) -} + return createStore()((set, get) => { + return { + ...initState, + ...CommonReducer(set), + ...tableActionsExport(set), + ...dashBoardReducer(set, get), + ...processFacilityReducer(set), + ...processAreaReducer(set), + ...facilityPrecipitationReducer(set), + ...flowRateSearchReducer(set), + ...facilityWaterQltyReducer(set), + ...planSewageReducer(set), + ...sewageOccurReducer(set), + ...underWaterReducer(set), + ...rdiReducer(set), + } + }) + } //store 등록하는 부분 \ No newline at end of file From 955c969fc58527c2ec983fabf9c60d2b99beb7b3 Mon Sep 17 00:00:00 2001 From: dongsilove Date: Mon, 5 Jan 2026 06:50:18 +0900 Subject: [PATCH 05/34] =?UTF-8?q?fo:=EC=A3=BC=EC=84=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/store/dashboard/index.tsx | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index 081da3839..38df4f7b7 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -53,21 +53,21 @@ export type planFcltyListProps = { export type OperationalStatusListProps = { flowRate: string, waterQlty: string, - yearAvg: number | '', - yearMax: number | '', - yearMin: number | '', - summerAll: number | string | '', - summerThree: number | string | '', - summerRain: number | string | '', - winterAll: number | string | '', - winterSunnyAvg: number | string | '', - winterSunnyMax: number | string | '', - winterSunnyMin: number | string | '', - groundWaterAvg: number | string | '', - groundWaterSummer: number | string | '', - groundWaterWinter: number | string | '', - rdi: number | string | '', - rdiRain: number | string | '', + yearAvg: number | '', // 평균 + yearMax: number | '', // 최대 + yearMin: number | '', // 최소 + summerAll: number | string | '', // 하절기 전체 + summerThree: number | string | '', // 하절기 3mm이상 + summerRain: number | string | '', // 하절기 강우 + winterAll: number | string | '', // 동절기 전체 + winterSunnyAvg: number | string | '', // 동절기 청천시 평균 + winterSunnyMax: number | string | '', // 동절기 청천시 최대 + winterSunnyMin: number | string | '', // 동절기 청천시 최소 + groundWaterAvg: number | string | '', // 지하수 유입량 연평균 + groundWaterSummer: number | string | '',// 지하수 유입량 하절기 평균 + groundWaterWinter: number | string | '',// 지하수 유입량 동절기 평균 + rdi: number | string | '', // RDII 추정 + rdiRain: number | string | '', // RDII 추정시 일강수량(mm) } export interface operationalStatusListProps { @@ -345,7 +345,7 @@ const planFcltyList: planFcltyListProps[] = [ }, ] -const upHeadListOperationStatus: TableUpperProps[] = [ +const upHeadListOperationStatus: TableUpperProps[] = [ // 시설정보 및 운영현황 { id: "flowRate", title: "유량 및 수질", upName: "upChangeRe1", upSequnce: 1 }, { id: "waterQlty", title: "유량 및 수질", upName: "upChangeRe1", upSequnce: 2 }, { id: "yearAvg", title: "평균", upName: "upChangeRe2", upSequnce: 1 }, @@ -365,7 +365,7 @@ const upHeadListOperationStatus: TableUpperProps[] = [ { id: "rdiRain", title: "RDII 추정시\n일강수량(mm)" }, ] -const upHeadListRainManage: TableUpperProps[] = [ +const upHeadListRainManage: TableUpperProps[] = [ // 강우일 운영현황 { id: "rainItem", title: "강우량", row: 0, rowSpan: 2, widthPercent: 8 }, { id: "rainRate", title: "강우조건\n비율(%)", row: 0, rowSpan: 2, align: "right", widthPercent: 5 }, { id: "rainDay", title: "일수", row: 0, rowSpan: 2, align: "right", widthPercent: 5 }, From 69c068e82342b745c96244fa8d6009bc1165a310 Mon Sep 17 00:00:00 2001 From: ljpark Date: Mon, 5 Jan 2026 15:55:45 +0900 Subject: [PATCH 06/34] =?UTF-8?q?fo:=20dashboard=20=EC=A3=BC=EC=84=9D2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/store/dashboard/index.tsx | 32 +++++++++++++-------------- apps/fo/app/store/flowRate/index.tsx | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index 38df4f7b7..b017e2b6f 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -1420,17 +1420,17 @@ export const dashBoardReducer = ( // 연간 const yearAvg = data.yearData === null ? '' : ( (data.yearData.AVG_INFL_AMNT ? data.yearData.AVG_INFL_AMNT : 0) + // 실제유입량(반류수제거)(m³/일) 평균 - (data.yearData.AVG_SUM_FLOW ? data.yearData.AVG_SUM_FLOW : 0) + // api 주석처리되어 있음. + (data.yearData.AVG_SUM_FLOW ? data.yearData.AVG_SUM_FLOW : 0) + // 연계처리량 api 주석처리되어 있음. (data.yearData.AVG_RETURN_AMNT ? data.yearData.AVG_RETURN_AMNT : 0) // 반류수유량(m³/일) 평균 ); const yearMax = data.yearData === null ? '' : ( (data.yearData.MAX_INFL_AMNT ? data.yearData.MAX_INFL_AMNT : 0) + // 실제유입량(반류수제거)(m³/일) 최대 - (data.yearData.MAX_SUM_FLOW ? data.yearData.MAX_SUM_FLOW : 0) + // api 주석처리되어 있음. + (data.yearData.MAX_SUM_FLOW ? data.yearData.MAX_SUM_FLOW : 0) + // 연계처리량 api 주석처리되어 있음. (data.yearData.MAX_RETURN_AMNT ? data.yearData.MAX_RETURN_AMNT : 0) // 반류수유량(m³/일) 최대 ); const yearMin = data.yearData === null ? '' : ( (data.yearData.MIN_INFL_AMNT ? data.yearData.MIN_INFL_AMNT : 0) + // 실제유입량(반류수제거)(m³/일) 최소 - (data.yearData.MIN_SUM_FLOW ? data.yearData.MIN_SUM_FLOW : 0) + // api 주석처리되어 있음. + (data.yearData.MIN_SUM_FLOW ? data.yearData.MIN_SUM_FLOW : 0) + // 연계처리량 api 주석처리되어 있음. (data.yearData.MIN_RETURN_AMNT ? data.yearData.MIN_RETURN_AMNT : 0) // 반류수유량(m³/일) 최소 ); operationalStatusList[0].yearAvg = yearAvg; // 연간유입평균 @@ -1484,7 +1484,7 @@ export const dashBoardReducer = ( // 연계처리수,지하수유입량 const bscFctCd = fcltyCd; - const res2 = await fetchFlowRateModalList(bscFctCd, searchYear); // /fclt/flow/ + const res2 = await fetchFlowRateModalList(bscFctCd, searchYear); // /fclt/flow/ - 일별 유량 조회 //const calData = CalcRainEffect(clone(res2.data), 'SUNNY'); //const calRainData = CalcRainEffect(clone(res2.data), 'RAIN'); @@ -1506,7 +1506,7 @@ export const dashBoardReducer = ( let rainEffectDay = 0; yearDay = res2.data ? res2.data.length : 1; - res2.data.forEach((item: any) => { + res2.data.forEach((item: any) => { //fetchFlowRateModalList const month = item.msrDt.substring(4, 6); // 월 추출 const sumFlow = item.sumFlow && item.sumFlow !== 'x' ? Number(item.sumFlow.toString().trim()) : 0; @@ -1545,7 +1545,7 @@ export const dashBoardReducer = ( } else if (month === '01' || month === '02') { // 동절기 winterChungchuDay += 1; - winterChungchunSumFlow += sumFlow; + winterChungchunSumFlow += sumFlow; // 연계처리수 sumWinterChungcunFlow += inflAmnt; winterChungchunDayReturnAvg += returnAmnt; winterChungchunDayEfflAvg += efflAmnt; @@ -1632,16 +1632,16 @@ export const dashBoardReducer = ( // 방류량 (청천시) 최소 winterChungchunEfflMin = winterChungchunDayEfflMin - operationalStatusList[0].yearAvg = roundUp(Number(operationalStatusList[0].yearAvg), 0) + roundUp(yearAvgSumFlow, 0); - operationalStatusList[0].yearMax = roundUp(totFlowMax, 0); // + roundUp(yearMaxSumFlow, 0); - operationalStatusList[0].yearMin = roundUp(totFlowMin, 0); - operationalStatusList[0].summerAll = roundUp(Number(operationalStatusList[0].summerAll), 0) + roundUp(summerAll, 0); - operationalStatusList[0].summerThree = roundUp(Number(operationalStatusList[0].summerThree), 0) + roundUp(summerThree, 0); - operationalStatusList[0].summerRain = roundUp(Number(operationalStatusList[0].summerRain), 0) + roundUp(summerRain, 0); - operationalStatusList[0].winterAll = roundUp(Number(operationalStatusList[0].winterAll), 0) + roundUp(winterAll, 0); - operationalStatusList[0].winterSunnyMin = roundUp(winterChungchunTotalInflAmntMin, 0); - operationalStatusList[0].winterSunnyMax = roundUp(winterChungchunTotalInflAmntMax, 0); - operationalStatusList[0].winterSunnyAvg = roundUp(Number(operationalStatusList[0].winterSunnyAvg), 0) + roundUp(winterSunnyAvg, 0); + operationalStatusList[0].yearAvg = roundUp(Number(operationalStatusList[0].yearAvg), 0) + roundUp(yearAvgSumFlow, 0); // 연간 유입 평균 = 하수유입량(순수하수유입량) + 연계처리량 + 반류수유량(m³/일) + operationalStatusList[0].yearMax = roundUp(totFlowMax, 0); // 연간 유입 최대 + operationalStatusList[0].yearMin = roundUp(totFlowMin, 0); // 연간 유입 최소 + operationalStatusList[0].summerAll = roundUp(Number(operationalStatusList[0].summerAll), 0) + roundUp(summerAll, 0); // 하절기 유입 전기간 + operationalStatusList[0].summerThree = roundUp(Number(operationalStatusList[0].summerThree), 0) + roundUp(summerThree, 0); // 하절기 유입 강우시(강우영향일) + operationalStatusList[0].summerRain = roundUp(Number(operationalStatusList[0].summerRain), 0) + roundUp(summerRain, 0); // 하절기 유입 청천시 + operationalStatusList[0].winterAll = roundUp(Number(operationalStatusList[0].winterAll), 0) + roundUp(winterAll, 0); // 동절기 유입 전기간 + operationalStatusList[0].winterSunnyMin = roundUp(winterChungchunTotalInflAmntMin, 0); // 동절기 유입 최소 + operationalStatusList[0].winterSunnyMax = roundUp(winterChungchunTotalInflAmntMax, 0); // 동절기 유입 최대 + operationalStatusList[0].winterSunnyAvg = roundUp(Number(operationalStatusList[0].winterSunnyAvg), 0) + roundUp(winterSunnyAvg, 0); // 동절기 유입 평균 // 지하수유입량 const usage = chungcunSumFlow / cntSunnyDay; //calData.length; diff --git a/apps/fo/app/store/flowRate/index.tsx b/apps/fo/app/store/flowRate/index.tsx index 66d639fb8..94d4b9326 100644 --- a/apps/fo/app/store/flowRate/index.tsx +++ b/apps/fo/app/store/flowRate/index.tsx @@ -283,7 +283,7 @@ export const flowRateSearchReducer:(set:(fn: (state: FlowRateSearchType) => Flow const excelDownList: ExcelType[] = []; const rtnData = data.map((item: flowRateListProps) => { item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, '')); - item.totInflAmnt = Number(item.inflAmnt || 0) + Number(item.sumFlow || 0) + Number(item.returnAmnt || 0) + item.totInflAmnt = Number(item.inflAmnt || 0) + Number(item.sumFlow || 0) + Number(item.returnAmnt || 0); // 하수유입량 + 연계처리량 + 반류수유량(m³/일) dataFormSetting(item); return item; }); From a0ad12af492fc6d40bf7adca03a59932c45e23b4 Mon Sep 17 00:00:00 2001 From: ljpark Date: Tue, 6 Jan 2026 16:08:36 +0900 Subject: [PATCH 07/34] fo: api /dashboard/mngInfo --- apps/fo/app/store/dashboard/index.tsx | 787 ++++++++++++-------------- 1 file changed, 360 insertions(+), 427 deletions(-) diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index b017e2b6f..09097d6e4 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -723,16 +723,16 @@ const fetchFacilityPlan = async (targetYear: string | undefined, fcltyCd: string }; /* 시설정보 및 운영현황 - 운영실태 */ -const fetchOperationStatus = async (searchYear: string | undefined, fcltyCd: string | undefined): Promise => { - try { - const url = '/dashBoard/mngInfo/' + (searchYear ? searchYear : '2023') + '/' + (fcltyCd ? fcltyCd : ''); - const res = await getFetch('fo', url); - return { data: res.data, count: res.count } - } catch (error) { - console.error('운영실태 데이터를 가져오는데 실패했습니다:', error); - return { data: [], count: 0 }; - } -} +// const fetchOperationStatus = async (searchYear: string | undefined, fcltyCd: string | undefined): Promise => { +// try { +// const url = '/dashBoard/mngInfo/' + (searchYear ? searchYear : '2023') + '/' + (fcltyCd ? fcltyCd : ''); +// const res = await getFetch('fo', url); +// return { data: res.data, count: res.count } +// } catch (error) { +// console.error('운영실태 데이터를 가져오는데 실패했습니다:', error); +// return { data: [], count: 0 }; +// } +// } // 주요그래프 데이터 const fetchMainGraph = async (searchYear: string | undefined, fcltyCd: string | undefined) => { @@ -749,6 +749,15 @@ const fetchMainGraph = async (searchYear: string | undefined, fcltyCd: string | // 수질 데이터 청천시, 강우시 재계산 const calcWaterQltyData = async (data: any[], searchYear: string | undefined, fcltyCd: string | undefined, mainGraphData: any) => { + const operList = { + inflBod: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, // 유입BOD + inflTN: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, // 유입TN + inflTP: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, // 유입TP + efflBod: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, // 방류BOD + efflTN: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, // 방류TN + efflTP: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, // 방류TP + tpInflTp: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, //총인 유입수질 TP(mg/L) + }; const nullToZero = (value: any) => { return value === null || value === undefined || value === '' ? 0 : Number(value); }; @@ -775,6 +784,7 @@ const calcWaterQltyData = async (data: any[], searchYear: string | undefined, fc // (1) 청천시 변수 // (1-1) 날짜 count + let chungchunSummerDay = 0, noNullChungchunSummerDay = 0; let chungchunWinterDay = 0, noNullChungchunWinterDay = 0; @@ -804,6 +814,8 @@ const calcWaterQltyData = async (data: any[], searchYear: string | undefined, fc let rainEffectDay = 0; // 전체 대상 + const totalDay = qltyData.length; + let noNullYearDay = 0; qltyData.forEach((item: any) => { if (item.infoRnDay == null) item.infoRnDay = 0; const month = item.msrDt.substring(4, 6); // 월 추출 @@ -898,7 +910,7 @@ const calcWaterQltyData = async (data: any[], searchYear: string | undefined, fc totalEfflBodAvgWinter += nullToZero(item.efflWqltBod); totalEfflTnAvgWinter += nullToZero(item.efflWqltTn); totalEfflTpAvgWinter += nullToZero(item.efflWqltTp); - totalTpInflAvgWinter += nullToZero(item.tpInflWqltTp); + totalTpInflAvgWinter += nullToZero(item.tpInflWqltTp); //총인 유입수질 TP(mg/L) } else if (month === '06' || month === '07' || month === '08') { summerDay += 1; if (item.tpInflWqltTp != null && item.tpInflWqltTp != 0) { @@ -912,74 +924,81 @@ const calcWaterQltyData = async (data: any[], searchYear: string | undefined, fc totalEfflTpAvgSummer += nullToZero(item.efflWqltTp); totalTpInflAvgSummer += nullToZero(item.tpInflWqltTp); } + + if (item.tpInflWqltTp != null && item.tpInflWqltTp != 0) { + noNullYearDay += 1; + } + operList.inflBod.yearTot += nullToZero(item.inflAssctBfrWqltBod); + operList.inflTN.yearTot += nullToZero(item.inflAssctBfrWqltTn); + operList.inflTP.yearTot += nullToZero(item.inflAssctBfrWqltTp); + operList.efflBod.yearTot += nullToZero(item.efflWqltBod); + operList.efflTN.yearTot += nullToZero(item.efflWqltTn); + operList.efflTP.yearTot += nullToZero(item.efflWqltTp); + operList.tpInflTp.yearTot += nullToZero(item.tpInflWqltTp); + // 최대 최소 + operList.inflBod.yearMax = Math.max(operList.inflBod.yearMax, nullToZero(item.inflAssctBfrWqltBod)); + operList.inflBod.yearMin = Math.min(operList.inflBod.yearMin, nullToZero(item.inflAssctBfrWqltBod)); + operList.inflTN.yearMax = Math.max(operList.inflTN.yearMax, nullToZero(item.inflAssctBfrWqltTn)); + operList.inflTN.yearMin = Math.min(operList.inflTN.yearMin, nullToZero(item.inflAssctBfrWqltTn)); + operList.inflTP.yearMax = Math.max(operList.inflTP.yearMax, nullToZero(item.inflAssctBfrWqltTp)); + operList.inflTP.yearMin = Math.min(operList.inflTP.yearMin, nullToZero(item.inflAssctBfrWqltTp)); + operList.efflBod.yearMax = Math.max(operList.efflBod.yearMax, nullToZero(item.efflWqltBod)); + operList.efflBod.yearMin = Math.min(operList.efflBod.yearMin, nullToZero(item.efflWqltBod)); + operList.efflTN.yearMax = Math.max(operList.efflTN.yearMax, nullToZero(item.efflWqltTn)); + operList.efflTN.yearMin = Math.min(operList.efflTN.yearMin, nullToZero(item.efflWqltTn)); + operList.efflTP.yearMax = Math.max(operList.efflTP.yearMax, nullToZero(item.efflWqltTp)); + operList.efflTP.yearMin = Math.min(operList.efflTP.yearMin, nullToZero(item.efflWqltTp)); + operList.tpInflTp.yearMax = Math.max(operList.tpInflTp.yearMax, nullToZero(item.tpInflWqltTp)); + operList.tpInflTp.yearMin = Math.min(operList.tpInflTp.yearMin, nullToZero(item.tpInflWqltTp)); + }); - orgData[5].winterAll = qltyDataSetting(totalInflBodAvgWinter, winterDay, 1); // 동절기 유입BOD - orgData[6].winterAll = qltyDataSetting(totalEfflBodAvgWinter, winterDay, 1); // 동절기 방류BOD - orgData[7].winterAll = qltyDataSetting(totalInflTnAvgWinter, winterDay, 3); // 동절기 유입TN - orgData[8].winterAll = qltyDataSetting(totalEfflTnAvgWinter, winterDay, 3); // 동절기 방류TN - orgData[9].winterAll = qltyDataSetting(totalInflTpAvgWinter, winterDay, 3); // 동절기 유입TP - orgData[10].winterAll = qltyDataSetting(totalEfflTpAvgWinter, winterDay, 3); // 동절기 방류TP + operList.inflBod.yearAvg = operList.inflBod.yearTot / totalDay; + operList.inflTN.yearAvg = operList.inflTN.yearTot / totalDay; + operList.inflTP.yearAvg = operList.inflTP.yearTot / totalDay; + operList.efflBod.yearAvg = operList.efflBod.yearTot / totalDay; + operList.efflTN.yearAvg = operList.efflTN.yearTot / totalDay; + operList.efflTP.yearAvg = operList.efflTP.yearTot / totalDay; + operList.tpInflTp.yearAvg = operList.tpInflTp.yearTot / totalDay; + orgData[5].yearAvg = qltyDataSetting(operList.inflBod.yearTot, totalDay, 1); // 연간 유입BOD + orgData[6].yearAvg = qltyDataSetting(operList.efflBod.yearTot,totalDay, 1); // 연간 방류BOD + orgData[7].yearAvg = qltyDataSetting(operList.inflTN.yearTot,totalDay, 3); // 연간 유입TN + orgData[8].yearAvg = qltyDataSetting(operList.efflTN.yearTot,totalDay, 3); // 연간 방류TN + orgData[9].yearAvg = qltyDataSetting(operList.inflTP.yearTot,totalDay, 3); // 연간 유입TP + orgData[10].yearAvg = qltyDataSetting(operList.efflTP.yearTot,totalDay, 3); // 연간 방류TP //총인설비 - orgData[11].winterAll = qltyDataSetting(totalTpInflAvgWinter, noNullWinterDay, 3); - orgData[12].winterAll = qltyDataSetting(totalEfflTpAvgWinter, winterDay, 3); + orgData[11].yearAvg = qltyDataSetting(operList.tpInflTp.yearTot, noNullYearDay, 3); // 연간 총인 유입수질 TP + orgData[12].yearAvg = qltyDataSetting(operList.efflTP.yearTot, totalDay, 3); // 연간 총인 유입수질 TP - orgData[5].summerAll = qltyDataSetting(totalInflBodAvgSummer, summerDay, 1); // 하절기 유입BOD - orgData[6].summerAll = qltyDataSetting(totalEfflBodAvgSummer, summerDay, 1); // 하절기 방류BOD - orgData[7].summerAll = qltyDataSetting(totalInflTnAvgSummer, summerDay, 3); // 하절기 유입TN - orgData[8].summerAll = qltyDataSetting(totalEfflTnAvgSummer, summerDay, 3); // 하절기 방류TN - orgData[9].summerAll = qltyDataSetting(totalInflTpAvgSummer, summerDay, 3); // 하절기 유입TP - orgData[10].summerAll = qltyDataSetting(totalEfflTpAvgSummer, summerDay, 3); // 하절기 방류TP + orgData[5].yearMax = roundUp(operList.inflBod.yearMax, 1); // 연간 유입BOD + orgData[6].yearMax = roundUp(operList.efflBod.yearMax, 1); // 연간 방류BOD + orgData[7].yearMax = roundUp(operList.inflTN.yearMax, 3).toFixed(3); // 연간 유입TN + orgData[8].yearMax = roundUp(operList.efflTN.yearMax, 3).toFixed(3); // 연간 방류TN + orgData[9].yearMax = roundUp(operList.inflTP.yearMax, 3).toFixed(3); // 연간 유입TP + orgData[10].yearMax = roundUp(operList.efflTP.yearMax, 3).toFixed(3); // 연간 방류TP + orgData[11].yearMax = roundUp(operList.tpInflTp.yearMax, 3).toFixed(3); // 연간 총인 유입수질 TP + orgData[12].yearMax = roundUp(operList.efflTP.yearMax, 3).toFixed(3); // 연간 총인 유입수질 TP + orgData[5].yearMin = roundUp(operList.inflBod.yearMin, 1); // 연간 유입BOD + orgData[6].yearMin = roundUp(operList.efflBod.yearMin, 1); // 연간 방류BOD + orgData[7].yearMin = roundUp(operList.inflTN.yearMin, 3).toFixed(3); // 연간 유입TN + orgData[8].yearMin = roundUp(operList.efflTN.yearMin, 3).toFixed(3); // 연간 방류TN + orgData[9].yearMin = roundUp(operList.inflTP.yearMin, 3).toFixed(3); // 연간 유입TP + orgData[10].yearMin = roundUp(operList.efflTP.yearMin, 3).toFixed(3); // 연간 방류TP + orgData[11].yearMin = roundUp(operList.tpInflTp.yearMin, 3).toFixed(3); // 연간 총인 유입수질 TP + orgData[12].yearMin = roundUp(operList.efflTP.yearMin, 3).toFixed(3); // 연간 총인 유입수질 TP + + orgData[5].summerAll = qltyDataSetting(totalInflBodAvgSummer, summerDay, 1); // 하절기 전기간 유입BOD + orgData[6].summerAll = qltyDataSetting(totalEfflBodAvgSummer, summerDay, 1); // 하절기 전기간 방류BOD + orgData[7].summerAll = qltyDataSetting(totalInflTnAvgSummer, summerDay, 3); // 하절기 전기간 유입TN + orgData[8].summerAll = qltyDataSetting(totalEfflTnAvgSummer, summerDay, 3); // 하절기 전기간 방류TN + orgData[9].summerAll = qltyDataSetting(totalInflTpAvgSummer, summerDay, 3); // 하절기 전기간 유입TP + orgData[10].summerAll = qltyDataSetting(totalEfflTpAvgSummer, summerDay, 3); // 하절기 전기간 방류TP //총인설비 orgData[11].summerAll = qltyDataSetting(totalTpInflAvgSummer, noNullSummerDay, 3); orgData[12].summerAll = qltyDataSetting(totalEfflTpAvgSummer, summerDay, 3); - - // 청천시 수질 데이터 수정 - // 하절기 - orgData[5].summerRain = qltyDataSetting(chungchunInflBodAvgSummer, chungchunSummerDay, 1); - orgData[6].summerRain = qltyDataSetting(chungchunEfflBodAvgSummer, chungchunSummerDay, 1); - orgData[7].summerRain = qltyDataSetting(chungchunInflTnAvgSummer, chungchunSummerDay, 3); - orgData[8].summerRain = qltyDataSetting(chungchunEfflTnAvgSummer, chungchunSummerDay, 3); - orgData[9].summerRain = qltyDataSetting(chungchunInflTpAvgSummer, chungchunSummerDay, 3); - orgData[10].summerRain = qltyDataSetting(chungchunEfflTpAvgSummer, chungchunSummerDay, 3); - - // 총인설비 - orgData[11].summerRain = qltyDataSetting(chungchunTpInflAvgSummer, noNullChungchunSummerDay, 3); - orgData[12].summerRain = qltyDataSetting(chungchunEfflTpAvgSummer, chungchunSummerDay, 3); - - // 동절기 - orgData[5].winterSunnyAvg = qltyDataSetting(chungchunInflBodAvg, chungchunWinterDay, 1); - orgData[6].winterSunnyAvg = qltyDataSetting(chungchunEfflBodAvg, chungchunWinterDay, 1); - orgData[7].winterSunnyAvg = qltyDataSetting(chungchunInflTnAvg, chungchunWinterDay, 3); - orgData[8].winterSunnyAvg = qltyDataSetting(chungchunEfflTnAvg, chungchunWinterDay, 3); - orgData[9].winterSunnyAvg = qltyDataSetting(chungchunInflTpAvg, chungchunWinterDay, 3); - orgData[10].winterSunnyAvg = qltyDataSetting(chungchunEfflTpAvg, chungchunWinterDay, 3); - - // 총인설비 - orgData[11].winterSunnyAvg = qltyDataSetting(chungchunTpInflAvg, noNullChungchunWinterDay, 3); - orgData[12].winterSunnyAvg = qltyDataSetting(chungchunInflTpAvg, chungchunWinterDay, 3); - - orgData[5].winterSunnyMax = roundUp(chungchunInflBodMax, 1).toFixed(1); - orgData[6].winterSunnyMax = roundUp(chungchunEfflBodMax, 1).toFixed(1); - orgData[7].winterSunnyMax = roundUp(chungchunInflTnMax, 3).toFixed(3); - orgData[8].winterSunnyMax = roundUp(chungchunEfflTnMax, 3).toFixed(3); - orgData[9].winterSunnyMax = roundUp(chungchunInflTpMax, 3).toFixed(3); - orgData[10].winterSunnyMax = roundUp(chungchunEfflTpMax, 3).toFixed(3); - orgData[11].winterSunnyMax = roundUp(chungchunTpInflMax, 3).toFixed(3); - orgData[12].winterSunnyMax = roundUp(chungchunInflTpMax, 3).toFixed(3); - - orgData[5].winterSunnyMin = chungchunInflBodMin === 99999999 ? '0.0' : roundUp(chungchunInflBodMin, 1).toFixed(1); - orgData[6].winterSunnyMin = chungchunEfflBodMin === 99999999 ? '0.0' : roundUp(chungchunEfflBodMin, 1).toFixed(1); - orgData[7].winterSunnyMin = chungchunInflTnMin === 99999999 ? '0.000' : roundUp(chungchunInflTnMin, 3).toFixed(3); - orgData[8].winterSunnyMin = chungchunEfflTnMin === 99999999 ? '0.000' : roundUp(chungchunEfflTnMin, 3).toFixed(3); - orgData[9].winterSunnyMin = chungchunInflTpMin === 99999999 ? '0.000' : roundUp(chungchunInflTpMin, 3).toFixed(3); - orgData[10].winterSunnyMin = chungchunEfflTpMin === 99999999 ? '0.000' : roundUp(chungchunEfflTpMin, 3).toFixed(3); - orgData[11].winterSunnyMin = chungchunTpInflMin === 99999999 ? '0.000' : roundUp(chungchunTpInflMin, 3).toFixed(3); - orgData[12].winterSunnyMin = chungchunInflTpMin === 99999999 ? '0.000' : roundUp(chungchunInflTpMin, 3).toFixed(3); - // 강우시 수질 데이터 수정 orgData[5].summerThree = qltyDataSetting(rainInflBodAvg, rainSummerDay, 1); orgData[6].summerThree = qltyDataSetting(rainEfflBodAvg, rainSummerDay, 1); @@ -987,12 +1006,61 @@ const calcWaterQltyData = async (data: any[], searchYear: string | undefined, fc orgData[8].summerThree = qltyDataSetting(rainEfflTnAvg, rainSummerDay, 3); orgData[9].summerThree = qltyDataSetting(rainInflTpAvg, rainSummerDay, 3); orgData[10].summerThree = qltyDataSetting(rainEfflTpAvg, rainSummerDay, 3); - // 총인설비 orgData[11].summerThree = qltyDataSetting(rainTpInflAvg, noNullRainSummerDay, 3); - orgData[12].summerThree = qltyDataSetting(rainInflTpAvg, rainSummerDay, 3); - // console.log(rainEffectDayArray); - // console.log("000000000", rainSummerDay, noNullRainSummerDay, rainInflBodAvg, rainInflTnAvg, rainInflTpAvg, rainEfflBodAvg, rainEfflTnAvg, rainEfflTpAvg, rainTpInflAvg); + orgData[12].summerThree = qltyDataSetting(rainEfflTpAvg, rainSummerDay, 3); + + // 하절기 청천시 수질 데이터 + orgData[5].summerRain = qltyDataSetting(chungchunInflBodAvgSummer, chungchunSummerDay, 1); + orgData[6].summerRain = qltyDataSetting(chungchunEfflBodAvgSummer, chungchunSummerDay, 1); + orgData[7].summerRain = qltyDataSetting(chungchunInflTnAvgSummer, chungchunSummerDay, 3); + orgData[8].summerRain = qltyDataSetting(chungchunEfflTnAvgSummer, chungchunSummerDay, 3); + orgData[9].summerRain = qltyDataSetting(chungchunInflTpAvgSummer, chungchunSummerDay, 3); + orgData[10].summerRain = qltyDataSetting(chungchunEfflTpAvgSummer, chungchunSummerDay, 3); + // 총인설비 + orgData[11].summerRain = qltyDataSetting(chungchunTpInflAvgSummer, noNullChungchunSummerDay, 3); + orgData[12].summerRain = qltyDataSetting(chungchunEfflTpAvgSummer, chungchunSummerDay, 3); + + orgData[5].winterAll = qltyDataSetting(totalInflBodAvgWinter, winterDay, 1); // 동절기 전기간 유입BOD + orgData[6].winterAll = qltyDataSetting(totalEfflBodAvgWinter, winterDay, 1); // 동절기 전기간 방류BOD + orgData[7].winterAll = qltyDataSetting(totalInflTnAvgWinter, winterDay, 3); // 동절기 전기간 유입TN + orgData[8].winterAll = qltyDataSetting(totalEfflTnAvgWinter, winterDay, 3); // 동절기 전기간 방류TN + orgData[9].winterAll = qltyDataSetting(totalInflTpAvgWinter, winterDay, 3); // 동절기 전기간 유입TP + orgData[10].winterAll = qltyDataSetting(totalEfflTpAvgWinter, winterDay, 3); // 동절기 전기간 방류TP + //총인설비 + orgData[11].winterAll = qltyDataSetting(totalTpInflAvgWinter, noNullWinterDay, 3); + orgData[12].winterAll = qltyDataSetting(totalEfflTpAvgWinter, winterDay, 3); + + // 동절기 청천시 수질 데이터 + orgData[5].winterSunnyAvg = qltyDataSetting(chungchunInflBodAvg, chungchunWinterDay, 1); + orgData[6].winterSunnyAvg = qltyDataSetting(chungchunEfflBodAvg, chungchunWinterDay, 1); + orgData[7].winterSunnyAvg = qltyDataSetting(chungchunInflTnAvg, chungchunWinterDay, 3); + orgData[8].winterSunnyAvg = qltyDataSetting(chungchunEfflTnAvg, chungchunWinterDay, 3); + orgData[9].winterSunnyAvg = qltyDataSetting(chungchunInflTpAvg, chungchunWinterDay, 3); + orgData[10].winterSunnyAvg = qltyDataSetting(chungchunEfflTpAvg, chungchunWinterDay, 3); + // 총인설비 + orgData[11].winterSunnyAvg = qltyDataSetting(chungchunTpInflAvg, noNullChungchunWinterDay, 3); + orgData[12].winterSunnyAvg = qltyDataSetting(chungchunEfflTpAvg, chungchunWinterDay, 3); + + orgData[5].winterSunnyMax = roundUp(chungchunInflBodMax, 1).toFixed(1); + orgData[6].winterSunnyMax = roundUp(chungchunEfflBodMax, 1).toFixed(1); + orgData[7].winterSunnyMax = roundUp(chungchunInflTnMax, 3).toFixed(3); + orgData[8].winterSunnyMax = roundUp(chungchunEfflTnMax, 3).toFixed(3); + orgData[9].winterSunnyMax = roundUp(chungchunInflTpMax, 3).toFixed(3); + orgData[10].winterSunnyMax = roundUp(chungchunEfflTpMax, 3).toFixed(3); + orgData[11].winterSunnyMax = roundUp(chungchunTpInflMax, 3).toFixed(3); + orgData[12].winterSunnyMax = roundUp(chungchunEfflTpMax, 3).toFixed(3); + + orgData[5].winterSunnyMin = chungchunInflBodMin === 99999999 ? '0.0' : roundUp(chungchunInflBodMin, 1).toFixed(1); + orgData[6].winterSunnyMin = chungchunEfflBodMin === 99999999 ? '0.0' : roundUp(chungchunEfflBodMin, 1).toFixed(1); + orgData[7].winterSunnyMin = chungchunInflTnMin === 99999999 ? '0.000' : roundUp(chungchunInflTnMin, 3).toFixed(3); + orgData[8].winterSunnyMin = chungchunEfflTnMin === 99999999 ? '0.000' : roundUp(chungchunEfflTnMin, 3).toFixed(3); + orgData[9].winterSunnyMin = chungchunInflTpMin === 99999999 ? '0.000' : roundUp(chungchunInflTpMin, 3).toFixed(3); + orgData[10].winterSunnyMin = chungchunEfflTpMin === 99999999 ? '0.000' : roundUp(chungchunEfflTpMin, 3).toFixed(3); + orgData[11].winterSunnyMin = chungchunTpInflMin === 99999999 ? '0.000' : roundUp(chungchunTpInflMin, 3).toFixed(3); + orgData[12].winterSunnyMin = chungchunEfflTpMin === 99999999 ? '0.000' : roundUp(chungchunEfflTpMin, 3).toFixed(3); + + return orgData; } else { @@ -1193,46 +1261,47 @@ export const dataFormSettingWqlty = (item: OperationalStatusListProps) => { DataForm({ type: 'float1', column: 'rdi', item: item as unknown as Record }); }; -const changeValue = (operationalStatus, data, keyTxt = 'INFL_AMNT') => { - operationalStatus.yearAvg = data.yearData ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.yearData ? Number(Math.round(data.yearData['AVG_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.yearData['AVG_' + keyTxt] : ''; - operationalStatus.yearMax = data.yearData ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.yearData ? Number(Math.round(data.yearData['MAX_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.yearData['MAX_' + keyTxt] : ''; - operationalStatus.yearMin = data.yearData ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.yearData ? Number(Math.round(data.yearData['MIN_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.yearData['MIN_' + keyTxt] : ''; - // 여름 - operationalStatus.summerAll = data.summer ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.summer ? Number(Math.round(data.summer['AVG_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.summer['AVG_' + keyTxt] : ''; - operationalStatus.summerThree = data.summerRainy ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.summerRainy ? Number(Math.round(data.summerRainy["AVG_" + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.summerRainy["AVG_" + keyTxt] : ''; - operationalStatus.summerRain = data.summerSunny ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.summerSunny ? Number(Math.round(data.summerSunny["AVG_" + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.summerSunny["AVG_" + keyTxt] : ''; - // 겨울 - operationalStatus.winterAll = data.winter ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.winter ? Number(Math.round(data.winter["AVG_" + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.winter["AVG_" + keyTxt] : ''; - operationalStatus.winterSunnyMin = data.winterSunny ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.winterSunny ? Number(Math.round(data.winterSunny["MIN_" + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.winterSunny["MIN_" + keyTxt] : ''; - operationalStatus.winterSunnyAvg = data.winterSunny ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.winterSunny ? Number(Math.round(data.winterSunny["AVG_" + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.winterSunny["AVG_" + keyTxt] : ''; - operationalStatus.winterSunnyMax = data.winterSunny ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.winterSunny ? Number(Math.round(data.winterSunny["MAX_" + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.winterSunny["MAX_" + keyTxt] : ''; - // 지하수 +// const changeValue = (operationalStatus, data, keyTxt = 'INFL_AMNT') => { +// //console.log('data.yearData', data.yearData); +// operationalStatus.yearAvg = data.yearData ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.yearData ? Number(Math.round(data.yearData['AVG_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.yearData['AVG_' + keyTxt] : ''; +// operationalStatus.yearMax = data.yearData ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.yearData ? Number(Math.round(data.yearData['MAX_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.yearData['MAX_' + keyTxt] : ''; +// operationalStatus.yearMin = data.yearData ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.yearData ? Number(Math.round(data.yearData['MIN_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.yearData['MIN_' + keyTxt] : ''; +// // 여름 +// operationalStatus.summerAll = data.summer ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.summer ? Number(Math.round(data.summer['AVG_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.summer['AVG_' + keyTxt] : ''; +// operationalStatus.summerThree = data.summerRainy ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.summerRainy ? Number(Math.round(data.summerRainy["AVG_" + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.summerRainy["AVG_" + keyTxt] : ''; +// operationalStatus.summerRain = data.summerSunny ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.summerSunny ? Number(Math.round(data.summerSunny["AVG_" + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.summerSunny["AVG_" + keyTxt] : ''; +// // 겨울 +// operationalStatus.winterAll = data.winter ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.winter ? Number(Math.round(data.winter["AVG_" + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.winter["AVG_" + keyTxt] : ''; +// operationalStatus.winterSunnyMin = data.winterSunny ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.winterSunny ? Number(Math.round(data.winterSunny["MIN_" + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.winterSunny["MIN_" + keyTxt] : ''; +// operationalStatus.winterSunnyAvg = data.winterSunny ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.winterSunny ? Number(Math.round(data.winterSunny["AVG_" + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.winterSunny["AVG_" + keyTxt] : ''; +// operationalStatus.winterSunnyMax = data.winterSunny ? (keyTxt.includes('_TP') || keyTxt.includes("_TN")) ? data.winterSunny ? Number(Math.round(data.winterSunny["MAX_" + keyTxt] * 1000) / 1000).toFixed(3).toString() : '' : data.winterSunny["MAX_" + keyTxt] : ''; +// // 지하수 - // 오염물질 - // RDII 추정 = 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) - const summerLowFlow = data.summerBod && data.summerBod.INFL_AMNT && data.summerBod.INFL_AMNT != 'null' ? Number(data.summerBod.INFL_AMNT) : 0; - const winterAvgBod = data.winterSunny && data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD && data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD != 'null' ? Number(data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD) : 0; - const summerLowBod = data.summerBod && data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD && data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD != 'null' ? Number(data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD) : 0; - const summerLowRain = data.summerBod && data.summerBod.INFO_RN_DAY && data.summerBod.INFO_RN_DAY != 'null' ? Number(data.summerBod.INFO_RN_DAY) : 0; - operationalStatus.rdi = winterAvgBod === 0 ? 0 : roundUp(summerLowFlow * ((winterAvgBod - summerLowBod) / winterAvgBod), 1); - operationalStatus.rdiRain = summerLowRain; -} +// // 오염물질 +// // RDII 추정 = 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) +// const summerLowFlow = data.summerBod && data.summerBod.INFL_AMNT && data.summerBod.INFL_AMNT != 'null' ? Number(data.summerBod.INFL_AMNT) : 0; +// const winterAvgBod = data.winterSunny && data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD && data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD != 'null' ? Number(data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD) : 0; +// const summerLowBod = data.summerBod && data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD && data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD != 'null' ? Number(data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD) : 0; +// const summerLowRain = data.summerBod && data.summerBod.INFO_RN_DAY && data.summerBod.INFO_RN_DAY != 'null' ? Number(data.summerBod.INFO_RN_DAY) : 0; +// operationalStatus.rdi = winterAvgBod === 0 ? 0 : roundUp(summerLowFlow * ((winterAvgBod - summerLowBod) / winterAvgBod), 1); +// operationalStatus.rdiRain = summerLowRain; +// } -const calcValue = (operationalStatus, data, keyTxt = 'INFL_ASSCT_BFR_WQLT_TP') => { - // 연간 - operationalStatus.yearAvg = data.yearData && data.yearData['AVG_' + keyTxt] ? Number(Math.round(data.yearData['AVG_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : ''; - operationalStatus.yearMax = data.yearData && data.yearData['MAX_' + keyTxt] ? Number(Math.round(data.yearData['MAX_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : ''; - operationalStatus.yearMin = data.yearData && data.yearData['MIN_' + keyTxt] ? Number(Math.round(data.yearData['MIN_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : ''; - // 여름 - operationalStatus.summerAll = data.summer && data.summer['AVG_' + keyTxt] ? Number(Math.round(data.summer['AVG_' + keyTxt] * 0.8 * 1000) / 1000).toFixed(3).toString() : ''; - operationalStatus.summerThree = data.summerRainy && data.summerRainy['AVG_' + keyTxt] ? Number(Math.round(data.summerRainy['AVG_' + keyTxt] * 0.82 * 1000) / 1000).toFixed(3).toString() : ''; - operationalStatus.summerRain = data.summerSunny && data.summerSunny['AVG_' + keyTxt] ? Number(Math.round(data.summerSunny['AVG_' + keyTxt] * 0.74 * 1000) / 1000).toFixed(3).toString() : ''; - // 겨울 - operationalStatus.winterAll = data.winter && data.winter['AVG_' + keyTxt] ? Number(Math.round(data.winter['AVG_' + keyTxt] * 1.16 * 1000) / 1000).toFixed(3).toString() : ''; - operationalStatus.winterSunnyMin = data.winterSunny && data.winterSunny['MIN_' + keyTxt] ? Number(Math.round(data.winterSunny['MIN_' + keyTxt] * 1.2 * 1000) / 1000).toFixed(3).toString() : ''; - operationalStatus.winterSunnyAvg = data.winterSunny && data.winterSunny['AVG_' + keyTxt] ? Number(Math.round(data.winterSunny['AVG_' + keyTxt] * 1.25 * 1000) / 1000).toFixed(3).toString() : ''; - operationalStatus.winterSunnyMax = data.winterSunny && data.winterSunny['MAX_' + keyTxt] ? Number(Math.round(data.winterSunny['MAX_' + keyTxt] * 1.3 * 1000) / 1000).toFixed(3).toString() : ''; -} +// const calcValue = (operationalStatus, data, keyTxt = 'INFL_ASSCT_BFR_WQLT_TP') => { +// // 연간 +// operationalStatus.yearAvg = data.yearData && data.yearData['AVG_' + keyTxt] ? Number(Math.round(data.yearData['AVG_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : ''; +// operationalStatus.yearMax = data.yearData && data.yearData['MAX_' + keyTxt] ? Number(Math.round(data.yearData['MAX_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : ''; +// operationalStatus.yearMin = data.yearData && data.yearData['MIN_' + keyTxt] ? Number(Math.round(data.yearData['MIN_' + keyTxt] * 1000) / 1000).toFixed(3).toString() : ''; +// // 여름 +// operationalStatus.summerAll = data.summer && data.summer['AVG_' + keyTxt] ? Number(Math.round(data.summer['AVG_' + keyTxt] * 0.8 * 1000) / 1000).toFixed(3).toString() : ''; +// operationalStatus.summerThree = data.summerRainy && data.summerRainy['AVG_' + keyTxt] ? Number(Math.round(data.summerRainy['AVG_' + keyTxt] * 0.82 * 1000) / 1000).toFixed(3).toString() : ''; +// operationalStatus.summerRain = data.summerSunny && data.summerSunny['AVG_' + keyTxt] ? Number(Math.round(data.summerSunny['AVG_' + keyTxt] * 0.74 * 1000) / 1000).toFixed(3).toString() : ''; +// // 겨울 +// operationalStatus.winterAll = data.winter && data.winter['AVG_' + keyTxt] ? Number(Math.round(data.winter['AVG_' + keyTxt] * 1.16 * 1000) / 1000).toFixed(3).toString() : ''; +// operationalStatus.winterSunnyMin = data.winterSunny && data.winterSunny['MIN_' + keyTxt] ? Number(Math.round(data.winterSunny['MIN_' + keyTxt] * 1.2 * 1000) / 1000).toFixed(3).toString() : ''; +// operationalStatus.winterSunnyAvg = data.winterSunny && data.winterSunny['AVG_' + keyTxt] ? Number(Math.round(data.winterSunny['AVG_' + keyTxt] * 1.25 * 1000) / 1000).toFixed(3).toString() : ''; +// operationalStatus.winterSunnyMax = data.winterSunny && data.winterSunny['MAX_' + keyTxt] ? Number(Math.round(data.winterSunny['MAX_' + keyTxt] * 1.3 * 1000) / 1000).toFixed(3).toString() : ''; +// } type wtrUsgYearsType = { YEAR: string; @@ -1391,97 +1460,43 @@ export const dashBoardReducer = ( isLoadingOperationStatus: true, }, })); - const res = await fetchOperationStatus(searchYear, fcltyCd); // /dashBoard/mngInfo/ - const data = res.data; - - let yearMaxSumFlow = 1, yearMinSumFlow = 1, yearAvgSumFlow = 1; // 연간 최대, 최소, 평균 - let summerAll = 1; // 하절기 전기간 - let summerThree = 1; // 하절기 - let summerRain = 1; // 하절기 - let winterAll = 1; // 동절기 전기간 - let winterSunnyMin = 1, winterSunnyAvg = 1, winterSunnyMax = 1; // 동절기 청천 최소, 평균, 최대 - - // 최대, 최소 총 유입량 (1년 하루 합계의 최대, 최소) - // 하절기 청천시, 강우시 재계산 리턴값 - let summerChungchunFlow = 1, summerChungchunReturnAmnt = 1, summerChungchunEfflAmnt = 1; // 하절기 청천 - let summerRainInflAmnt = 1, summerRainReturnAmnt = 1, summerRainEfflAmnt = 1; // 하절기 강우시 - // 동절기 청천시 최대, 최소, 평균 리턴값 - let winterChungchunFlowAvg = 1, winterChungchunFlowMax = 1, winterChungchunFlowMin = 1; // 동절기 청천 하수유입량 평균, 최대, 최소 - let winterChungchunReturnAvg = 1, winterChungchunReturnMax = 1, winterChungchunReturnMin = 1; // 동절기 청천 총인반류수 평균, 최대, 최소 - let winterChungchunEfflAvg = 1, winterChungchunEfflMax = 1, winterChungchunEfflMin = 1; // 동절기 청천 방류량 평균, 최대, 최소 + // const res = await fetchOperationStatus(searchYear, fcltyCd); // /dashBoard/mngInfo/ + // const data = res.data; + const operList = { + inFlow : {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 + , summerTot: 0, summerAvg: 0, summerRainy: 0, summerSunny: 0 + , winterTot: 0, winterAvg: 0, winterSunny: 0, winterSunnyMax: 0, winterSunnyMin: 9999999 + , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0}, + inflAmt: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999, yearSunny: 0 + , summerTot: 0, summerAvg: 0, summerRainy: 0, summerSunny: 0 + , winterTot: 0, winterAvg: 0, winterSunny: 0, winterSunnyMax: 0, winterSunnyMin: 9999999 + , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0}, + sumFlow: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 + , summerTot: 0, summerAvg: 0, summerRainy: 0, summerSunny: 0 + , winterTot: 0, winterAvg: 0, winterSunny: 0, winterSunnyMax: 0, winterSunnyMin: 9999999 + , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0}, + returnFlow: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 + , summerTot: 0, summerAvg: 0, summerRainy: 0, summerSunny: 0 + , winterTot: 0, winterAvg: 0, winterSunny: 0, winterSunnyMax: 0, winterSunnyMin: 9999999 + , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0}, + efflFlow: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 + , summerTot: 0, summerAvg: 0, summerRainy: 0, summerSunny: 0 + , winterTot: 0, winterAvg: 0, winterSunny: 0, winterSunnyMax: 0, winterSunnyMin: 9999999 + , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0}, + }; const clone = (arr: any[]) => arr?.map(v => ({ ...v })) ?? []; let rdiPercent = 0; let operationalStatusList = clone(operationalStatusListOrg); - if (data && operationalStatusList) { + if (operationalStatusList) { // 유량 - 유입 if (operationalStatusList?.[0]) { - // 연간 - const yearAvg = data.yearData === null ? '' : ( - (data.yearData.AVG_INFL_AMNT ? data.yearData.AVG_INFL_AMNT : 0) + // 실제유입량(반류수제거)(m³/일) 평균 - (data.yearData.AVG_SUM_FLOW ? data.yearData.AVG_SUM_FLOW : 0) + // 연계처리량 api 주석처리되어 있음. - (data.yearData.AVG_RETURN_AMNT ? data.yearData.AVG_RETURN_AMNT : 0) // 반류수유량(m³/일) 평균 - ); - const yearMax = data.yearData === null ? '' : ( - (data.yearData.MAX_INFL_AMNT ? data.yearData.MAX_INFL_AMNT : 0) + // 실제유입량(반류수제거)(m³/일) 최대 - (data.yearData.MAX_SUM_FLOW ? data.yearData.MAX_SUM_FLOW : 0) + // 연계처리량 api 주석처리되어 있음. - (data.yearData.MAX_RETURN_AMNT ? data.yearData.MAX_RETURN_AMNT : 0) // 반류수유량(m³/일) 최대 - ); - const yearMin = data.yearData === null ? '' : ( - (data.yearData.MIN_INFL_AMNT ? data.yearData.MIN_INFL_AMNT : 0) + // 실제유입량(반류수제거)(m³/일) 최소 - (data.yearData.MIN_SUM_FLOW ? data.yearData.MIN_SUM_FLOW : 0) + // 연계처리량 api 주석처리되어 있음. - (data.yearData.MIN_RETURN_AMNT ? data.yearData.MIN_RETURN_AMNT : 0) // 반류수유량(m³/일) 최소 - ); - operationalStatusList[0].yearAvg = yearAvg; // 연간유입평균 - operationalStatusList[0].yearMax = yearMax; // 연간유입최대 - operationalStatusList[0].yearMin = yearMin; // 연간유입최소 - // 하절기 - operationalStatusList[0].summerAll = data.summer === null ? '' : ( // 하절기전기간 - (data.summer.AVG_INFL_AMNT ? data.summer.AVG_INFL_AMNT : 0) + - (data.summer.AVG_SUM_FLOW ? data.summer.AVG_SUM_FLOW : 0) - ); - operationalStatusList[0].summerThree = data.summerRainy === null ? '' : ( // 하절기 강우시 - (data.summerRainy.AVG_INFL_AMNT ? data.summerRainy.AVG_INFL_AMNT : 0) + - (data.summerRainy.AVG_SUM_FLOW ? data.summerRainy.AVG_SUM_FLOW : 0) - ); - operationalStatusList[0].summerRain = data.summerSunny === null ? '' : ( // 하절기 청천시 - (data.summerSunny.AVG_INFL_AMNT ? data.summerSunny.AVG_INFL_AMNT : 0) + - (data.summerSunny.AVG_SUM_FLOW ? data.summerSunny.AVG_SUM_FLOW : 0) - ); - // 동절기 - operationalStatusList[0].winterAll = data.winter === null ? '' : ( // 동절기 전기간 - (data.winter.AVG_INFL_AMNT ? data.winter.AVG_INFL_AMNT : 0) + - (data.winter.AVG_SUM_FLOW ? data.winter.AVG_SUM_FLOW : 0) + - (data.winter.AVG_TP_INFL_WQLT_TP ? data.winter.AVG_TP_INFL_WQLT_TP : 0) - ); - operationalStatusList[0].winterSunnyMin = data.winterSunny === null ? '' : (// 동절기 청천 최소 - (data.winterSunny.MIN_INFL_AMNT ? data.winterSunny.MIN_INFL_AMNT : 0) + - (data.winterSunny.MIN_SUM_FLOW ? data.winterSunny.MIN_SUM_FLOW : 0) + - (data.winterSunny.MIN_TP_INFL_WQLT_TP ? data.winterSunny.MIN_TP_INFL_WQLT_TP : 0) - ); - operationalStatusList[0].winterSunnyAvg = data.winterSunny === null ? '' : (// 동절기 청천 평균 - (data.winterSunny.AVG_INFL_AMNT ? data.winterSunny.AVG_INFL_AMNT : 0) + - (data.winterSunny.AVG_SUM_FLOW ? data.winterSunny.AVG_SUM_FLOW : 0) + - (data.winterSunny.AVG_TP_INFL_WQLT_TP ? data.winterSunny.AVG_TP_INFL_WQLT_TP : 0) - ); - operationalStatusList[0].winterSunnyMax = data.winterSunny === null ? '' : (// 동절기 청천 최대 - (data.winterSunny.MAX_INFL_AMNT ? data.winterSunny.MAX_INFL_AMNT : 0) + - (data.winterSunny.MAX_SUM_FLOW ? data.winterSunny.MAX_SUM_FLOW : 0) + - (data.winterSunny.MAX_TP_INFL_WQLT_TP ? data.winterSunny.MAX_TP_INFL_WQLT_TP : 0) - ); - + // 연계처리수 let yearDay = 0, summerDay = 0, winterDay = 0; // 연간 일수, 하절기 일수, 동절기 일수 let summerRainDay = 0, summerChungchunDay = 0, winterChungchuDay = 0; // 하절기 강우 일수, 하절기 청천 일수, 동절기 청천 일수 - let totFlowMax = 0, totFlowMin = 9999999; - let yearSumFlow = 0, maxYearSumFlow = 0, minYearSumFlow = 9999999; - let summerSumFlow = 0, summerChungchunSumFlow = 0, summerRainDaySumFlow = 0; // 하절기 유입량 합, 하절기 청천 유입량 합, 하절기 강우 유입량 합 - let summerRainDayFlow = 0, summerRainDayReturnFlow = 0, summerRainDayEfflFlow = 0; // 하절기 강우 유입량, 하절기 강우 반류량, 하절기 강우 방류량 - let winterSumFlow = 0; // 동절기 유입량 합 - let winterChungchunSumFlow = 0; // 동절기 청천 유입량 합 - let maxWinterChungchunSumFlow = 0, minWinterChungchunSumFlow = 9999999; - + // 연계처리수,지하수유입량 const bscFctCd = fcltyCd; const res2 = await fetchFlowRateModalList(bscFctCd, searchYear); // /fclt/flow/ - 일별 유량 조회 @@ -1490,30 +1505,18 @@ export const dashBoardReducer = ( //const calRainData = CalcRainEffect(clone(res2.data), 'RAIN'); let cntSunnyDay = 0; // 청천일 수 - // 지하수유입량 - 청천시 기준 - let chungcunSumFlow = 0; - let sumSummerChungcunFlow = 0; - let sumWinterChungcunFlow = 0; - let summerChungchunDayReturnAmnt = 0; // 하절기 청천시 총인설비 반류수 - let summerChungchunDayEfflAmnt = 0; // 하절기 청천시 총인설비 방류수 - - let winterChungchunTotalInflAmntMax = 0, winterChungchunTotalInflAmntMin = 9999999; // 동절기 총 유입량 최대, 최소 - let winterChungchunDayFlowMax = 0, winterChungchunDayFlowMin = 9999999; // 동절기 청천시 하수유입량 최대, 최소 - let winterChungchunDayReturnMax = 0, winterChungchunDayReturnMin = 9999999; // 동절기 청천시 총인반류수 최대, 최소, 평균 - let winterChungchunDayReturnAvg = 0; - // 동절기 청천시 방류량 최대, 최소, 평균 - let winterChungchunDayEfflMax = 0, winterChungchunDayEfflMin = 9999999, winterChungchunDayEfflAvg = 0; - + // let chungcunSumFlow = 0; // 연간 청천 순수하수 + let rainEffectDay = 0; yearDay = res2.data ? res2.data.length : 1; - res2.data.forEach((item: any) => { //fetchFlowRateModalList + res2.data.forEach((item: any) => { // --일별 유량 start const month = item.msrDt.substring(4, 6); // 월 추출 const sumFlow = item.sumFlow && item.sumFlow !== 'x' ? Number(item.sumFlow.toString().trim()) : 0; const inflAmnt = item.inflAmnt && item.inflAmnt !== 'x' ? Number(item.inflAmnt.toString().trim()) : 0; const returnAmnt = item.returnAmnt && item.returnAmnt !== 'x' ? Number(item.returnAmnt.toString().trim()) : 0; const efflAmnt = item.efflAmnt && item.efflAmnt !== 'x' ? Number(item.efflAmnt.toString().trim()) : 0; - + if (item.infoRnDay == null) item.infoRnDay = 0; if (item.infoRnDay >= 3) { rainEffectDay = 2; @@ -1524,135 +1527,141 @@ export const dashBoardReducer = ( if (rainEffectDay >= 0) { // 강우영향일 - if (month === '06' || month === '07' || month === '08') { // 하절기 + if (month === '06' || month === '07' || month === '08') { // 하절기 강우영향일 summerRainDay += 1; - summerRainDaySumFlow += sumFlow; - summerRainDayFlow += inflAmnt; - summerRainDayReturnFlow += returnAmnt; - summerRainDayEfflFlow += efflAmnt; + operList.inFlow.summerRainy += inflAmnt + sumFlow + returnAmnt; + operList.inflAmt.summerRainy += inflAmnt; + operList.sumFlow.summerRainy += sumFlow; + operList.returnFlow.summerRainy += returnAmnt; + operList.efflFlow.summerRainy += efflAmnt; } } else if (rainEffectDay < 0) { cntSunnyDay += 1; // 청천일수 // 청천시 - chungcunSumFlow += inflAmnt; + // chungcunSumFlow += inflAmnt; // 연간 청천 순수하수 + operList.inflAmt.yearSunny += inflAmnt; // 연간 청천 순수하수 - if (month === '06' || month === '07' || month === '08') { // 하절기 + if (month === '06' || month === '07' || month === '08') { // 하절기 청천 summerChungchunDay += 1; - summerChungchunSumFlow += sumFlow; - sumSummerChungcunFlow += inflAmnt; - summerChungchunDayReturnAmnt += returnAmnt; - summerChungchunDayEfflAmnt += efflAmnt; - - } else if (month === '01' || month === '02') { // 동절기 + operList.inFlow.summerSunny += inflAmnt + sumFlow + returnAmnt; + operList.inflAmt.summerSunny += inflAmnt; + operList.sumFlow.summerSunny += sumFlow; + operList.returnFlow.summerSunny += returnAmnt; + operList.efflFlow.summerSunny += efflAmnt; + } else if (month === '01' || month === '02') { // 동절기 청천 winterChungchuDay += 1; - winterChungchunSumFlow += sumFlow; // 연계처리수 - sumWinterChungcunFlow += inflAmnt; - winterChungchunDayReturnAvg += returnAmnt; - winterChungchunDayEfflAvg += efflAmnt; + const inflowOne = inflAmnt + sumFlow + returnAmnt; + operList.inFlow.winterSunny += inflAmnt + sumFlow + returnAmnt; + operList.inflAmt.winterSunny += inflAmnt; + operList.sumFlow.winterSunny += sumFlow; + operList.returnFlow.winterSunny += returnAmnt; + operList.efflFlow.winterSunny += efflAmnt; - let totWinterTotalInflAmnt = 0; - totWinterTotalInflAmnt = inflAmnt + sumFlow + returnAmnt; - if (winterChungchunTotalInflAmntMax < totWinterTotalInflAmnt) winterChungchunTotalInflAmntMax = totWinterTotalInflAmnt; - if (winterChungchunTotalInflAmntMin > totWinterTotalInflAmnt || winterChungchunTotalInflAmntMin === 0) winterChungchunTotalInflAmntMin = totWinterTotalInflAmnt; + if (operList.inFlow.winterSunnyMax < inflowOne) operList.inFlow.winterSunnyMax = inflowOne; + if (operList.inflAmt.winterSunnyMax < inflAmnt) operList.inflAmt.winterSunnyMax = inflAmnt; + if (operList.sumFlow.winterSunnyMax < sumFlow) operList.sumFlow.winterSunnyMax = sumFlow; + if (operList.returnFlow.winterSunnyMax < returnAmnt) operList.returnFlow.winterSunnyMax = returnAmnt; + if (operList.efflFlow.winterSunnyMax < efflAmnt) operList.efflFlow.winterSunnyMax = efflAmnt; - if (winterChungchunDayFlowMin > inflAmnt) winterChungchunDayFlowMin = inflAmnt; - if (winterChungchunDayFlowMax < inflAmnt) winterChungchunDayFlowMax = inflAmnt; - - if (minWinterChungchunSumFlow > sumFlow) minWinterChungchunSumFlow = sumFlow; - if (maxWinterChungchunSumFlow < sumFlow) maxWinterChungchunSumFlow = sumFlow; - - if (winterChungchunDayReturnMin > returnAmnt) winterChungchunDayReturnMin = returnAmnt; - if (winterChungchunDayReturnMax < returnAmnt) winterChungchunDayReturnMax = returnAmnt; - - if (winterChungchunDayEfflMin > efflAmnt) winterChungchunDayEfflMin = efflAmnt; - if (winterChungchunDayEfflMax < efflAmnt) winterChungchunDayEfflMax = efflAmnt; + if (operList.inFlow.winterSunnyMin > inflowOne) operList.inFlow.winterSunnyMin = inflowOne; + if (operList.inflAmt.winterSunnyMin > inflAmnt) operList.inflAmt.winterSunnyMin = inflAmnt; + if (operList.sumFlow.winterSunnyMin > sumFlow) operList.sumFlow.winterSunnyMin = sumFlow; + if (operList.returnFlow.winterSunnyMin > returnAmnt) operList.returnFlow.winterSunnyMin = returnAmnt; + if (operList.efflFlow.winterSunnyMin > efflAmnt) operList.efflFlow.winterSunnyMin = efflAmnt; } } + const inflowOne = inflAmnt + sumFlow + returnAmnt; + operList.inFlow.yearTot += inflAmnt + sumFlow + returnAmnt; + operList.inflAmt.yearTot += inflAmnt; + operList.sumFlow.yearTot += sumFlow; + operList.returnFlow.yearTot += returnAmnt; + operList.efflFlow.yearTot += efflAmnt; - yearSumFlow += sumFlow; - if (maxYearSumFlow < sumFlow) maxYearSumFlow = sumFlow; - if (minYearSumFlow > sumFlow) minYearSumFlow = sumFlow; + if (operList.inFlow.yearMax < inflowOne) operList.inFlow.yearMax = inflowOne; + if (operList.inflAmt.yearMax < inflAmnt) operList.inflAmt.yearMax = inflAmnt; + if (operList.sumFlow.yearMax < sumFlow) operList.sumFlow.yearMax = sumFlow; + if (operList.returnFlow.yearMax < returnAmnt) operList.returnFlow.yearMax = returnAmnt; + if (operList.efflFlow.yearMax < efflAmnt) operList.efflFlow.yearMax = efflAmnt; - // 1년 최대 총 하수유입량 - let totYearFlow = 0; - totYearFlow = inflAmnt + sumFlow + returnAmnt; - if (totFlowMax < totYearFlow) totFlowMax = totYearFlow; - if (totFlowMin > totYearFlow || totFlowMin === 0) { - totFlowMin = totYearFlow; - } + if (operList.inFlow.yearMin > inflowOne) operList.inFlow.yearMin = inflowOne; + if (operList.inflAmt.yearMin > inflAmnt) operList.inflAmt.yearMin = inflAmnt; + if (operList.sumFlow.yearMin > sumFlow) operList.sumFlow.yearMin = sumFlow; + if (operList.returnFlow.yearMin > returnAmnt) operList.returnFlow.yearMin = returnAmnt; + if (operList.efflFlow.yearMin > efflAmnt) operList.efflFlow.yearMin = efflAmnt; if (month === '06' || month === '07' || month === '08') { summerDay += 1; - summerSumFlow += sumFlow; + operList.inFlow.summerTot += inflAmnt + sumFlow + returnAmnt; + operList.inflAmt.summerTot += inflAmnt; + operList.sumFlow.summerTot += sumFlow; + operList.returnFlow.summerTot += returnAmnt; + operList.efflFlow.summerTot += efflAmnt; } else if (month === '01' || month === '02') { winterDay += 1; - winterSumFlow += sumFlow; + operList.inFlow.winterTot += inflAmnt + sumFlow + returnAmnt; + operList.inflAmt.winterTot += inflAmnt; + operList.sumFlow.winterTot += sumFlow; + operList.returnFlow.winterTot += returnAmnt; + operList.efflFlow.winterTot += efflAmnt; } - }); + }); // --일별 유량 end + // 연간 평균 + operList.inFlow.yearAvg = (yearDay > 0)? operList.inFlow.yearTot / yearDay : 0; + operList.inflAmt.yearAvg = (yearDay > 0)? operList.inflAmt.yearTot / yearDay : 0; + operList.sumFlow.yearAvg = (yearDay > 0)? operList.sumFlow.yearTot / yearDay : 0; + operList.returnFlow.yearAvg = (yearDay > 0)? operList.returnFlow.yearTot / yearDay : 0; + operList.efflFlow.yearAvg = (yearDay > 0)? operList.efflFlow.yearTot / yearDay : 0; + // 하절기 전기간 평균 + operList.inFlow.summerAvg = (summerDay > 0)? operList.inFlow.summerTot / summerDay : 0; + operList.inflAmt.summerAvg = (summerDay > 0)? operList.inflAmt.summerTot / summerDay : 0; + operList.sumFlow.summerAvg = (summerDay > 0)? operList.sumFlow.summerTot / summerDay : 0; + operList.returnFlow.summerAvg = (summerDay > 0)? operList.returnFlow.summerTot / summerDay : 0; + operList.efflFlow.summerAvg = (summerDay > 0)? operList.efflFlow.summerTot / summerDay : 0; + // 하절기 강우시 평균 + operList.inFlow.summerRainy = (summerRainDay > 0)? operList.inFlow.summerRainy / summerRainDay : 0; + operList.inflAmt.summerRainy = (summerRainDay > 0)? operList.inflAmt.summerRainy / summerRainDay : 0; + operList.sumFlow.summerRainy = (summerRainDay > 0)? operList.sumFlow.summerRainy / summerRainDay : 0; + operList.returnFlow.summerRainy = (summerRainDay > 0)? operList.returnFlow.summerRainy / summerRainDay : 0; + operList.efflFlow.summerRainy = (summerRainDay > 0)? operList.efflFlow.summerRainy / summerRainDay : 0; + // 하절기 청천시 평균 + operList.inFlow.summerSunny = (summerChungchunDay > 0)? operList.inFlow.summerSunny / summerChungchunDay : 0; + operList.inflAmt.summerSunny = (summerChungchunDay > 0)? operList.inflAmt.summerSunny / summerChungchunDay : 0; + operList.sumFlow.summerSunny = (summerChungchunDay > 0)? operList.sumFlow.summerSunny / summerChungchunDay : 0; + operList.returnFlow.summerSunny = (summerChungchunDay > 0)? operList.returnFlow.summerSunny / summerChungchunDay : 0; + operList.efflFlow.summerSunny = (summerChungchunDay > 0)? operList.efflFlow.summerSunny / summerChungchunDay : 0; + // 동절기 전기간 평균 + operList.inFlow.winterAvg = (winterDay > 0)? operList.inFlow.winterTot / winterDay : 0; + operList.inflAmt.winterAvg = (winterDay > 0)? operList.inflAmt.winterTot / winterDay : 0; + operList.sumFlow.winterAvg = (winterDay > 0)? operList.sumFlow.winterTot / winterDay : 0; + operList.returnFlow.winterAvg = (winterDay > 0)? operList.returnFlow.winterTot / winterDay : 0; + operList.efflFlow.winterAvg = (winterDay > 0)? operList.efflFlow.winterTot / winterDay : 0; + // 동절기 청천시 평균 + operList.inFlow.winterSunny = (winterChungchuDay > 0)? operList.inFlow.winterSunny / winterChungchuDay : 0; + operList.inflAmt.winterSunny = (winterChungchuDay > 0)? operList.inflAmt.winterSunny / winterChungchuDay : 0; + operList.sumFlow.winterSunny = (winterChungchuDay > 0)? operList.sumFlow.winterSunny / winterChungchuDay : 0; + operList.returnFlow.winterSunny = (winterChungchuDay > 0)? operList.returnFlow.winterSunny / winterChungchuDay : 0; + operList.efflFlow.winterSunny = (winterChungchuDay > 0)? operList.efflFlow.winterSunny / winterChungchuDay : 0; - // 연계처리수 - yearAvgSumFlow = Number((yearSumFlow && Number(yearSumFlow) != 0) ? (yearSumFlow / yearDay) : ''); - yearMaxSumFlow = maxYearSumFlow; - yearMinSumFlow = minYearSumFlow; - summerAll = summerSumFlow && Number(summerSumFlow) != 0 ? Number(summerSumFlow / summerDay) : 0 - summerThree = summerRainDaySumFlow && Number(summerRainDaySumFlow) != 0 ? Number(summerRainDaySumFlow / summerRainDay) : 0; - summerRain = summerChungchunSumFlow && Number(summerChungchunSumFlow) != 0 ? Number(summerChungchunSumFlow / summerChungchunDay) : 0; - winterAll = winterSumFlow && Number(winterSumFlow) != 0 ? Number(winterSumFlow / winterDay) : 0; - winterSunnyMin = minWinterChungchunSumFlow; - winterSunnyAvg = winterChungchunSumFlow && Number(winterChungchunSumFlow) != 0 ? (winterChungchunSumFlow / winterChungchuDay) : 0; - winterSunnyMax = maxWinterChungchunSumFlow; - - // 하절기 강우시 계산 - // 하수유입량 (강우시) - summerRainInflAmnt = summerRainDayFlow && Number(summerRainDayFlow) != 0 ? Number(summerRainDayFlow / summerRainDay) : 0; - // 총인설비방류수 (강우시) - summerRainReturnAmnt = summerRainDayReturnFlow && Number(summerRainDayReturnFlow) != 0 ? Number(summerRainDayReturnFlow / summerRainDay) : 0; - // 방루량 (강우시) - summerRainEfflAmnt = summerRainDayEfflFlow && summerRainDayEfflFlow != 0 ? summerRainDayEfflFlow / summerRainDay : 0; - - // 동절기 청천시 계산 - // 하수유입량 (청천시) 평균 - winterChungchunFlowAvg = sumWinterChungcunFlow && Number(sumWinterChungcunFlow) != 0 ? (sumWinterChungcunFlow / winterChungchuDay) : 0; - // 총인반류수 (청천시) 평균 - winterChungchunReturnAvg = winterChungchunDayReturnAvg && Number(winterChungchunDayReturnAvg) != 0 ? (winterChungchunDayReturnAvg / winterChungchuDay) : 0; - // 방류량 (청천시) 평균 - winterChungchunEfflAvg = winterChungchunDayEfflAvg && Number(winterChungchunDayEfflAvg) != 0 ? (winterChungchunDayEfflAvg / winterChungchuDay) : 0; - // 하수유입량 (청천시) 최대 - winterChungchunFlowMax = winterChungchunDayFlowMax; - // 총인반류수 (청천시) 최대 - winterChungchunReturnMax = winterChungchunDayReturnMax; - // 방류량 (청천시) 최대 - winterChungchunEfflMax = winterChungchunDayEfflMax; - // 하수유입량 (청천시) 최소 - winterChungchunFlowMin = winterChungchunDayFlowMin; - // 총인반류수 (청천시) 최소 - winterChungchunReturnMin = winterChungchunDayReturnMin; - // 방류량 (청천시) 최소 - winterChungchunEfflMin = winterChungchunDayEfflMin - - operationalStatusList[0].yearAvg = roundUp(Number(operationalStatusList[0].yearAvg), 0) + roundUp(yearAvgSumFlow, 0); // 연간 유입 평균 = 하수유입량(순수하수유입량) + 연계처리량 + 반류수유량(m³/일) - operationalStatusList[0].yearMax = roundUp(totFlowMax, 0); // 연간 유입 최대 - operationalStatusList[0].yearMin = roundUp(totFlowMin, 0); // 연간 유입 최소 - operationalStatusList[0].summerAll = roundUp(Number(operationalStatusList[0].summerAll), 0) + roundUp(summerAll, 0); // 하절기 유입 전기간 - operationalStatusList[0].summerThree = roundUp(Number(operationalStatusList[0].summerThree), 0) + roundUp(summerThree, 0); // 하절기 유입 강우시(강우영향일) - operationalStatusList[0].summerRain = roundUp(Number(operationalStatusList[0].summerRain), 0) + roundUp(summerRain, 0); // 하절기 유입 청천시 - operationalStatusList[0].winterAll = roundUp(Number(operationalStatusList[0].winterAll), 0) + roundUp(winterAll, 0); // 동절기 유입 전기간 - operationalStatusList[0].winterSunnyMin = roundUp(winterChungchunTotalInflAmntMin, 0); // 동절기 유입 최소 - operationalStatusList[0].winterSunnyMax = roundUp(winterChungchunTotalInflAmntMax, 0); // 동절기 유입 최대 - operationalStatusList[0].winterSunnyAvg = roundUp(Number(operationalStatusList[0].winterSunnyAvg), 0) + roundUp(winterSunnyAvg, 0); // 동절기 유입 평균 + // 연간 유입 평균 = 하수유입량(순수하수유입량) + 연계처리량 + 반류수유량(m³/일) + operationalStatusList[0].yearAvg = roundUp(operList.inFlow.yearAvg, 0); // 연간 유입 평균 = 하수유입량(순수하수유입량) + 연계처리량 + 반류수유량(m³/일) + operationalStatusList[0].yearMax = roundUp(operList.inFlow.yearMax, 0); // 연간 유입 최대 + operationalStatusList[0].yearMin = roundUp(operList.inFlow.yearMin, 0); // 연간 유입 최소 + operationalStatusList[0].summerAll = roundUp(operList.inFlow.summerAvg, 0); // 하절기 유입 전기간 + operationalStatusList[0].summerThree = roundUp(operList.inFlow.summerRainy, 0); // 하절기 유입 강우시(강우영향일) + operationalStatusList[0].summerRain = roundUp(operList.inFlow.summerSunny, 0); // 하절기 유입 청천시 + operationalStatusList[0].winterAll = roundUp(operList.inFlow.winterAvg, 0); // 동절기 유입 전기간 + operationalStatusList[0].winterSunnyMin = roundUp(operList.inFlow.winterSunnyMin, 0); // 동절기 유입 최소 + operationalStatusList[0].winterSunnyMax = roundUp(operList.inFlow.winterSunnyMax, 0); // 동절기 유입 최대 + operationalStatusList[0].winterSunnyAvg = roundUp(operList.inFlow.winterAvg, 0); // 동절기 유입 평균 // 지하수유입량 - const usage = chungcunSumFlow / cntSunnyDay; //calData.length; - const summerUsage = sumSummerChungcunFlow / summerChungchunDay; - const winterUsage = sumWinterChungcunFlow / winterChungchuDay; + const usage = operList.inflAmt.yearSunny / cntSunnyDay; // 연간 청천 순수하수 평균 + const summerUsage = operList.inflAmt.summerSunny; // 하절기 청천 순수하수 평균 + const winterUsage = operList.inflAmt.winterSunny; // 동절기 청천 순수하수 평균 // 임시 계산변수값들 메인에 대입 - summerChungchunFlow = summerUsage; - summerChungchunReturnAmnt = summerChungchunDayReturnAmnt / summerChungchunDay; - summerChungchunEfflAmnt = summerChungchunDayEfflAmnt / summerChungchunDay; - operationalStatusList[0].groundWaterAvg = Math.round((usage - (usage * 0.65 * OSU_PERCENT)) * 100) / 100; operationalStatusList[0].groundWaterSummer = Math.round((summerUsage - (summerUsage * 0.65 * OSU_PERCENT)) * 100) / 100; operationalStatusList[0].groundWaterWinter = Math.round((winterUsage - (winterUsage * 0.65 * OSU_PERCENT)) * 100) / 100; @@ -1676,20 +1685,20 @@ export const dashBoardReducer = ( const winterMonth = ['01', '02']; wqltDataTot.filter(item => summerMonth.includes(item.msrDt.toString().replaceAll('-', '').substring(4, 6))).forEach(item2 => { - if (Number(item2.infoRnDay) >= 3) { - const inflBod = Number(item2.inflAssctBfrWqltBod); - const infl = Number(item2.inflAmnt); - const rain = Number(item2.infoRnDay); + if (Number(item2.infoRnDay) >= 3) { // 3mm 이상 강우일 + const inflBod = Number(item2.inflAssctBfrWqltBod); //유입연계전수질_BOD(mg/L) + const infl = Number(item2.inflAmnt); //실제유입량(반류수제거)(m³/일) + const rain = Number(item2.infoRnDay); //강우량 if (inflBod < minSummerBod) { minSummerBodInfl = infl; minSummerBod = inflBod; - rdiRain = rain; + rdiRain = rain; // 하절기 최소 bod일때의 일강수량 } } }); wqltDataSunny.filter(item => winterMonth.includes(item.msrDt.toString().replaceAll('-', '').substring(4, 6))).forEach(item2 => { - winterBodSunny += Number(item2.inflAssctBfrWqltBod); + winterBodSunny += Number(item2.inflAssctBfrWqltBod); // 동절기 청천시 유입BOD(mg/L) winterCnt += 1; }); @@ -1705,132 +1714,56 @@ export const dashBoardReducer = ( rdiPercent = (rdiValue / minSummerBodInfl) * 100; - operationalStatusList[0].rdi = rdiValue; - operationalStatusList[0].rdiRain = rdiRain; + operationalStatusList[0].rdi = rdiValue; // RDII 추정 + operationalStatusList[0].rdiRain = rdiRain; // RDII 추정시 일강수량(mm) } - /* const summerLowFlow = data.summerBod&&data.summerBod.INFL_AMNT&&data.summerBod.INFL_AMNT!='null'?Number(data.summerBod.INFL_AMNT):0; - const winterAvgBod = data.winterSunny&&data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD&&data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD!='null'?Number(data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD):0; - const summerLowBod = data.summerBod&&data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD&&data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD!='null'?Number(data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD):0; - const summerLowRain = data.summerBod&&data.summerBod.INFO_RN_DAY&&data.summerBod.INFO_RN_DAY!='null'?Number(data.summerBod.INFO_RN_DAY):0; - operationalStatusList[0].rdi = winterAvgBod===0?0:roundUp(summerLowFlow * ((winterAvgBod - summerLowBod) / winterAvgBod), 2); - operationalStatusList[0].rdiRain = summerLowRain; */ } if (operationalStatusList[0] && operationalStatusList[7]) { - operationalStatusList[7].groundWaterAvg = operationalStatusList[0].groundWaterAvg === null ? '' : data.yearData && data.yearData.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterAvg.toString().replaceAll(',', '')) / (data.yearData && data.yearData.AVG_INFL_AMNT ? Number(data.yearData.AVG_INFL_AMNT.toString().replaceAll(',', '')) : 0) * 100) * 10) / 10 + '%'; - operationalStatusList[7].groundWaterSummer = operationalStatusList[0].groundWaterSummer === null ? '' : data.summer && data.summer.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterSummer.toString().replaceAll(',', '')) / (data.summer && data.summer.AVG_INFL_AMNT ? Number(data.summer.AVG_INFL_AMNT.toString().replaceAll(',', '')) : 0) * 100) * 10) / 10 + '%'; - operationalStatusList[7].groundWaterWinter = operationalStatusList[0].groundWaterWinter === null ? '' : data.winter && data.winter.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterWinter.toString().replaceAll(',', '')) / (data.winter && data.winter.AVG_INFL_AMNT ? Number(data.winter.AVG_INFL_AMNT.toString().replaceAll(',', '')) : 0) * 100) * 10) / 10 + '%'; + // operationalStatusList[7].groundWaterAvg = operationalStatusList[0].groundWaterAvg === null ? '' : operList.inFlow.yearTot && data.yearData.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterAvg.toString().replaceAll(',', '')) / (data.yearData && data.yearData.AVG_INFL_AMNT ? Number(data.yearData.AVG_INFL_AMNT.toString().replaceAll(',', '')) : 0) * 100) * 10) / 10 + '%'; + // operationalStatusList[7].groundWaterSummer = operationalStatusList[0].groundWaterSummer === null ? '' : data.summer && data.summer.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterSummer.toString().replaceAll(',', '')) / (data.summer && data.summer.AVG_INFL_AMNT ? Number(data.summer.AVG_INFL_AMNT.toString().replaceAll(',', '')) : 0) * 100) * 10) / 10 + '%'; + // operationalStatusList[7].groundWaterWinter = operationalStatusList[0].groundWaterWinter === null ? '' : data.winter && data.winter.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterWinter.toString().replaceAll(',', '')) / (data.winter && data.winter.AVG_INFL_AMNT ? Number(data.winter.AVG_INFL_AMNT.toString().replaceAll(',', '')) : 0) * 100) * 10) / 10 + '%'; + operationalStatusList[7].groundWaterAvg = operList.inflAmt.yearAvg === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterAvg.toString().replaceAll(',', '')) / operList.inflAmt.yearAvg * 100) * 10) / 10 + '%'; + operationalStatusList[7].groundWaterSummer = operList.inflAmt.summerAvg === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterSummer.toString().replaceAll(',', '')) / operList.inflAmt.summerAvg * 100) * 10) / 10 + '%'; + operationalStatusList[7].groundWaterWinter = operList.inflAmt.winterAvg === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterWinter.toString().replaceAll(',', '')) / operList.inflAmt.winterAvg * 100) * 10) / 10 + '%'; operationalStatusList[7].rdi = roundNumber(rdiPercent, 1) + '%'; - /* operationalStatusList[7].groundWaterAvg = operationalStatusList[0].groundWaterAvg === null ? '' : Number(Number(operationalStatusList[0].groundWaterAvg) / Number(data.yearData.AVG_INFL_AMNT)) * 100; - operationalStatusList[7].groundWaterSummer = operationalStatusList[0].groundWaterSummer === null ? '' : Number(Number(operationalStatusList[0].groundWaterSummer) / Number(data.summer.AVG_INFL_AMNT)) * 100; - operationalStatusList[7].groundWaterWinter = operationalStatusList[0].groundWaterWinter === null ? '' : Number(Number(operationalStatusList[0].groundWaterWinter) / Number(data.winter.AVG_INFL_AMNT)) * 100;*/ } - for (let i = 1; i < operationalStatusList.length; i++) { - const txtArray = ['1', 'INFL_AMNT', 'SUM_FLOW', 'RETURN_AMNT', 'EFFL_AMNT', 'INFL_ASSCT_BFR_WQLT_BOD', 'EFFL_WQLT_BOD', 'INFL_ASSCT_BFR_WQLT_TN', 'EFFL_WQLT_TN', 'INFL_ASSCT_BFR_WQLT_TP', 'EFFL_WQLT_TP', 'TP_INFL_WQLT_TP', 'EFFL_WQLT_TP']; - if (operationalStatusList[i]) { - if (i < 7) { - changeValue(operationalStatusList[i], data, txtArray[i]); - if (i < 5) { - dataFormSetting(operationalStatusList[i]!); - } else { - dataFormSettingWqlty(operationalStatusList[i]!); - } - - } else { - calcValue(operationalStatusList[i], data, txtArray[i]); - } + // 순수하수량(1), 연계처리수(2), 총인설비방류수(3), 방류수(4) 데이터 매핑 + const flowMappings = [ + { index: 0, source: operList.inFlow }, + { index: 1, source: operList.inflAmt }, + { index: 2, source: operList.sumFlow }, + { index: 3, source: operList.returnFlow }, + { index: 4, source: operList.efflFlow }, + ]; + flowMappings.forEach(({ index, source }) => { + const item = operationalStatusList[index]; + if (item) { + item.yearAvg = source.yearAvg; + item.yearMax = source.yearMax; + item.yearMin = source.yearMin; + item.summerAll = source.summerAvg; + item.summerThree = source.summerRainy; + item.summerRain = source.summerSunny; + item.winterSunnyAvg = source.winterSunny; + item.winterSunnyMax = source.winterSunnyMax; + item.winterSunnyMin = source.winterSunnyMin; + item.winterAll = source.winterAvg; + dataFormSetting(item); } - } + }); - // 순수하수량 - if (operationalStatusList[1]) { - operationalStatusList[1].summerThree = summerRainInflAmnt; - operationalStatusList[1].summerRain = summerChungchunFlow; - operationalStatusList[1].winterSunnyAvg = winterChungchunFlowAvg; - operationalStatusList[1].winterSunnyMax = winterChungchunFlowMax; - operationalStatusList[1].winterSunnyMin = winterChungchunFlowMin; - dataFormSetting(operationalStatusList[1]); - } - - // 연계처리수 - if (operationalStatusList[2]) { - operationalStatusList[2].yearAvg = yearAvgSumFlow; - operationalStatusList[2].yearMax = yearMaxSumFlow; - operationalStatusList[2].yearMin = yearMinSumFlow; - operationalStatusList[2].summerAll = summerAll; - operationalStatusList[2].summerThree = summerThree; - operationalStatusList[2].summerRain = summerRain; - operationalStatusList[2].winterAll = winterAll; - operationalStatusList[2].winterSunnyMin = winterSunnyMin; - operationalStatusList[2].winterSunnyAvg = winterSunnyAvg; - operationalStatusList[2].winterSunnyMax = winterSunnyMax; - dataFormSetting(operationalStatusList[2]); - } - - // 총인설비방류수 - if (operationalStatusList[3]) { - operationalStatusList[3].summerThree = summerRainReturnAmnt; - operationalStatusList[3].summerRain = summerChungchunReturnAmnt; - operationalStatusList[3].winterSunnyAvg = winterChungchunReturnAvg; - operationalStatusList[3].winterSunnyMax = winterChungchunReturnMax; - operationalStatusList[3].winterSunnyMin = winterChungchunReturnMin; - dataFormSetting(operationalStatusList[3]); - } - - // 방류수 - if (operationalStatusList[4]) { - operationalStatusList[4].summerThree = summerRainEfflAmnt; - operationalStatusList[4].summerRain = summerChungchunEfflAmnt; - operationalStatusList[4].winterSunnyAvg = winterChungchunEfflAvg; - operationalStatusList[4].winterSunnyMax = winterChungchunEfflMax; - operationalStatusList[4].winterSunnyMin = winterChungchunEfflMin; - dataFormSetting(operationalStatusList[4]); - } - - if (operationalStatusList[0]) { - // 안전하게 숫자 변환하는 함수 - const toNum = (val) => { - if (val === null || val === undefined || val === '' || val === '0') return 0; - return Number(val.toString().replaceAll(',', '')) || 0; - }; - - operationalStatusList[0].summerAll = - toNum(operationalStatusList[1]?.summerAll) + - toNum(operationalStatusList[2]?.summerAll) + - toNum(operationalStatusList[3]?.summerAll); - - operationalStatusList[0].summerThree = - toNum(operationalStatusList[1]?.summerThree) + - toNum(operationalStatusList[2]?.summerThree) + - toNum(operationalStatusList[3]?.summerThree); - - operationalStatusList[0].summerRain = - toNum(operationalStatusList[1]?.summerRain) + - toNum(operationalStatusList[2]?.summerRain) + - toNum(operationalStatusList[3]?.summerRain); - - operationalStatusList[0].winterAll = - toNum(operationalStatusList[1]?.winterAll) + - toNum(operationalStatusList[2]?.winterAll) + - toNum(operationalStatusList[3]?.winterAll); - - operationalStatusList[0].winterSunnyAvg = - toNum(operationalStatusList[1]?.winterSunnyAvg) + - toNum(operationalStatusList[2]?.winterSunnyAvg) + - toNum(operationalStatusList[3]?.winterSunnyAvg); - - dataFormSetting(operationalStatusList[0]); - } } const rtnData = await calcWaterQltyData(operationalStatusList, searchYear, fcltyCd, mainGraphData); // 수질 데이터 청천시, 강우시 재계산 // 총인설비가 없을 경우 제외 - // console.log('총인시설 여부 : ', data.yearData?.TP_FCT_YN); + console.log('총인시설 여부 : ', mainGraphData.data.wqltObjs?.tpFctYn); + const tpFctYn = mainGraphData.data.wqltObjs?.tpFctYn; // console.log('rtnData : ', rtnData); - if (data.yearData?.TP_FCT_YN !== 'Y') { + if (tpFctYn !== 'Y') { operationalStatusList = rtnData.slice(0, 11); } else { operationalStatusList = rtnData; @@ -1840,7 +1773,7 @@ export const dashBoardReducer = ( OperationStatus: { ...state.OperationStatus, operationalStatusList: operationalStatusList, - operationalStatusCount: res.count, + operationalStatusCount: 0, isLoadingOperationStatus: false, }, })) From b57858c5efce9734de32ca8edac9465e349c1f41 Mon Sep 17 00:00:00 2001 From: dongsilove Date: Wed, 7 Jan 2026 11:15:43 +0900 Subject: [PATCH 08/34] =?UTF-8?q?fo:=20=EC=B4=9D=EC=9D=B8=EC=8B=9C?= =?UTF-8?q?=EC=84=A4=EC=97=AC=EB=B6=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/store/dashboard/index.tsx | 133 ++++++++++++++------------ 1 file changed, 72 insertions(+), 61 deletions(-) diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index 09097d6e4..0e7dc8597 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -749,14 +749,14 @@ const fetchMainGraph = async (searchYear: string | undefined, fcltyCd: string | // 수질 데이터 청천시, 강우시 재계산 const calcWaterQltyData = async (data: any[], searchYear: string | undefined, fcltyCd: string | undefined, mainGraphData: any) => { - const operList = { - inflBod: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, // 유입BOD - inflTN: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, // 유입TN - inflTP: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, // 유입TP - efflBod: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, // 방류BOD - efflTN: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, // 방류TN - efflTP: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, // 방류TP - tpInflTp: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999}, //총인 유입수질 TP(mg/L) + const operList = { + inflBod: { yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 }, // 유입BOD + inflTN: { yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 }, // 유입TN + inflTP: { yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 }, // 유입TP + efflBod: { yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 }, // 방류BOD + efflTN: { yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 }, // 방류TN + efflTP: { yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 }, // 방류TP + tpInflTp: { yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 }, //총인 유입수질 TP(mg/L) }; const nullToZero = (value: any) => { return value === null || value === undefined || value === '' ? 0 : Number(value); @@ -962,11 +962,11 @@ const calcWaterQltyData = async (data: any[], searchYear: string | undefined, fc operList.tpInflTp.yearAvg = operList.tpInflTp.yearTot / totalDay; orgData[5].yearAvg = qltyDataSetting(operList.inflBod.yearTot, totalDay, 1); // 연간 유입BOD - orgData[6].yearAvg = qltyDataSetting(operList.efflBod.yearTot,totalDay, 1); // 연간 방류BOD - orgData[7].yearAvg = qltyDataSetting(operList.inflTN.yearTot,totalDay, 3); // 연간 유입TN - orgData[8].yearAvg = qltyDataSetting(operList.efflTN.yearTot,totalDay, 3); // 연간 방류TN - orgData[9].yearAvg = qltyDataSetting(operList.inflTP.yearTot,totalDay, 3); // 연간 유입TP - orgData[10].yearAvg = qltyDataSetting(operList.efflTP.yearTot,totalDay, 3); // 연간 방류TP + orgData[6].yearAvg = qltyDataSetting(operList.efflBod.yearTot, totalDay, 1); // 연간 방류BOD + orgData[7].yearAvg = qltyDataSetting(operList.inflTN.yearTot, totalDay, 3); // 연간 유입TN + orgData[8].yearAvg = qltyDataSetting(operList.efflTN.yearTot, totalDay, 3); // 연간 방류TN + orgData[9].yearAvg = qltyDataSetting(operList.inflTP.yearTot, totalDay, 3); // 연간 유입TP + orgData[10].yearAvg = qltyDataSetting(operList.efflTP.yearTot, totalDay, 3); // 연간 방류TP //총인설비 orgData[11].yearAvg = qltyDataSetting(operList.tpInflTp.yearTot, noNullYearDay, 3); // 연간 총인 유입수질 TP orgData[12].yearAvg = qltyDataSetting(operList.efflTP.yearTot, totalDay, 3); // 연간 총인 유입수질 TP @@ -1060,7 +1060,7 @@ const calcWaterQltyData = async (data: any[], searchYear: string | undefined, fc orgData[11].winterSunnyMin = chungchunTpInflMin === 99999999 ? '0.000' : roundUp(chungchunTpInflMin, 3).toFixed(3); orgData[12].winterSunnyMin = chungchunEfflTpMin === 99999999 ? '0.000' : roundUp(chungchunEfflTpMin, 3).toFixed(3); - + return orgData; } else { @@ -1463,27 +1463,37 @@ export const dashBoardReducer = ( // const res = await fetchOperationStatus(searchYear, fcltyCd); // /dashBoard/mngInfo/ // const data = res.data; - const operList = { - inFlow : {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 + const operList = { + inFlow: { + yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 , summerTot: 0, summerAvg: 0, summerRainy: 0, summerSunny: 0 , winterTot: 0, winterAvg: 0, winterSunny: 0, winterSunnyMax: 0, winterSunnyMin: 9999999 - , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0}, - inflAmt: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999, yearSunny: 0 + , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0 + }, + inflAmt: { + yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999, yearSunny: 0 , summerTot: 0, summerAvg: 0, summerRainy: 0, summerSunny: 0 , winterTot: 0, winterAvg: 0, winterSunny: 0, winterSunnyMax: 0, winterSunnyMin: 9999999 - , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0}, - sumFlow: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 + , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0 + }, + sumFlow: { + yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 , summerTot: 0, summerAvg: 0, summerRainy: 0, summerSunny: 0 , winterTot: 0, winterAvg: 0, winterSunny: 0, winterSunnyMax: 0, winterSunnyMin: 9999999 - , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0}, - returnFlow: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 + , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0 + }, + returnFlow: { + yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 , summerTot: 0, summerAvg: 0, summerRainy: 0, summerSunny: 0 , winterTot: 0, winterAvg: 0, winterSunny: 0, winterSunnyMax: 0, winterSunnyMin: 9999999 - , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0}, - efflFlow: {yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 + , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0 + }, + efflFlow: { + yearTot: 0, yearAvg: 0, yearMax: 0, yearMin: 9999999 , summerTot: 0, summerAvg: 0, summerRainy: 0, summerSunny: 0 , winterTot: 0, winterAvg: 0, winterSunny: 0, winterSunnyMax: 0, winterSunnyMin: 9999999 - , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0}, + , groundTot: 0, groundSummer: 0, groundWinter: 0, rdii: 0, rdiiRainAmt: 0 + }, }; const clone = (arr: any[]) => arr?.map(v => ({ ...v })) ?? []; @@ -1492,11 +1502,11 @@ export const dashBoardReducer = ( if (operationalStatusList) { // 유량 - 유입 if (operationalStatusList?.[0]) { - + // 연계처리수 let yearDay = 0, summerDay = 0, winterDay = 0; // 연간 일수, 하절기 일수, 동절기 일수 let summerRainDay = 0, summerChungchunDay = 0, winterChungchuDay = 0; // 하절기 강우 일수, 하절기 청천 일수, 동절기 청천 일수 - + // 연계처리수,지하수유입량 const bscFctCd = fcltyCd; const res2 = await fetchFlowRateModalList(bscFctCd, searchYear); // /fclt/flow/ - 일별 유량 조회 @@ -1506,7 +1516,7 @@ export const dashBoardReducer = ( let cntSunnyDay = 0; // 청천일 수 // let chungcunSumFlow = 0; // 연간 청천 순수하수 - + let rainEffectDay = 0; yearDay = res2.data ? res2.data.length : 1; res2.data.forEach((item: any) => { // --일별 유량 start @@ -1516,7 +1526,7 @@ export const dashBoardReducer = ( const inflAmnt = item.inflAmnt && item.inflAmnt !== 'x' ? Number(item.inflAmnt.toString().trim()) : 0; const returnAmnt = item.returnAmnt && item.returnAmnt !== 'x' ? Number(item.returnAmnt.toString().trim()) : 0; const efflAmnt = item.efflAmnt && item.efflAmnt !== 'x' ? Number(item.efflAmnt.toString().trim()) : 0; - + if (item.infoRnDay == null) item.infoRnDay = 0; if (item.infoRnDay >= 3) { rainEffectDay = 2; @@ -1608,41 +1618,41 @@ export const dashBoardReducer = ( }); // --일별 유량 end // 연간 평균 - operList.inFlow.yearAvg = (yearDay > 0)? operList.inFlow.yearTot / yearDay : 0; - operList.inflAmt.yearAvg = (yearDay > 0)? operList.inflAmt.yearTot / yearDay : 0; - operList.sumFlow.yearAvg = (yearDay > 0)? operList.sumFlow.yearTot / yearDay : 0; - operList.returnFlow.yearAvg = (yearDay > 0)? operList.returnFlow.yearTot / yearDay : 0; - operList.efflFlow.yearAvg = (yearDay > 0)? operList.efflFlow.yearTot / yearDay : 0; + operList.inFlow.yearAvg = (yearDay > 0) ? operList.inFlow.yearTot / yearDay : 0; + operList.inflAmt.yearAvg = (yearDay > 0) ? operList.inflAmt.yearTot / yearDay : 0; + operList.sumFlow.yearAvg = (yearDay > 0) ? operList.sumFlow.yearTot / yearDay : 0; + operList.returnFlow.yearAvg = (yearDay > 0) ? operList.returnFlow.yearTot / yearDay : 0; + operList.efflFlow.yearAvg = (yearDay > 0) ? operList.efflFlow.yearTot / yearDay : 0; // 하절기 전기간 평균 - operList.inFlow.summerAvg = (summerDay > 0)? operList.inFlow.summerTot / summerDay : 0; - operList.inflAmt.summerAvg = (summerDay > 0)? operList.inflAmt.summerTot / summerDay : 0; - operList.sumFlow.summerAvg = (summerDay > 0)? operList.sumFlow.summerTot / summerDay : 0; - operList.returnFlow.summerAvg = (summerDay > 0)? operList.returnFlow.summerTot / summerDay : 0; - operList.efflFlow.summerAvg = (summerDay > 0)? operList.efflFlow.summerTot / summerDay : 0; + operList.inFlow.summerAvg = (summerDay > 0) ? operList.inFlow.summerTot / summerDay : 0; + operList.inflAmt.summerAvg = (summerDay > 0) ? operList.inflAmt.summerTot / summerDay : 0; + operList.sumFlow.summerAvg = (summerDay > 0) ? operList.sumFlow.summerTot / summerDay : 0; + operList.returnFlow.summerAvg = (summerDay > 0) ? operList.returnFlow.summerTot / summerDay : 0; + operList.efflFlow.summerAvg = (summerDay > 0) ? operList.efflFlow.summerTot / summerDay : 0; // 하절기 강우시 평균 - operList.inFlow.summerRainy = (summerRainDay > 0)? operList.inFlow.summerRainy / summerRainDay : 0; - operList.inflAmt.summerRainy = (summerRainDay > 0)? operList.inflAmt.summerRainy / summerRainDay : 0; - operList.sumFlow.summerRainy = (summerRainDay > 0)? operList.sumFlow.summerRainy / summerRainDay : 0; - operList.returnFlow.summerRainy = (summerRainDay > 0)? operList.returnFlow.summerRainy / summerRainDay : 0; - operList.efflFlow.summerRainy = (summerRainDay > 0)? operList.efflFlow.summerRainy / summerRainDay : 0; + operList.inFlow.summerRainy = (summerRainDay > 0) ? operList.inFlow.summerRainy / summerRainDay : 0; + operList.inflAmt.summerRainy = (summerRainDay > 0) ? operList.inflAmt.summerRainy / summerRainDay : 0; + operList.sumFlow.summerRainy = (summerRainDay > 0) ? operList.sumFlow.summerRainy / summerRainDay : 0; + operList.returnFlow.summerRainy = (summerRainDay > 0) ? operList.returnFlow.summerRainy / summerRainDay : 0; + operList.efflFlow.summerRainy = (summerRainDay > 0) ? operList.efflFlow.summerRainy / summerRainDay : 0; // 하절기 청천시 평균 - operList.inFlow.summerSunny = (summerChungchunDay > 0)? operList.inFlow.summerSunny / summerChungchunDay : 0; - operList.inflAmt.summerSunny = (summerChungchunDay > 0)? operList.inflAmt.summerSunny / summerChungchunDay : 0; - operList.sumFlow.summerSunny = (summerChungchunDay > 0)? operList.sumFlow.summerSunny / summerChungchunDay : 0; - operList.returnFlow.summerSunny = (summerChungchunDay > 0)? operList.returnFlow.summerSunny / summerChungchunDay : 0; - operList.efflFlow.summerSunny = (summerChungchunDay > 0)? operList.efflFlow.summerSunny / summerChungchunDay : 0; + operList.inFlow.summerSunny = (summerChungchunDay > 0) ? operList.inFlow.summerSunny / summerChungchunDay : 0; + operList.inflAmt.summerSunny = (summerChungchunDay > 0) ? operList.inflAmt.summerSunny / summerChungchunDay : 0; + operList.sumFlow.summerSunny = (summerChungchunDay > 0) ? operList.sumFlow.summerSunny / summerChungchunDay : 0; + operList.returnFlow.summerSunny = (summerChungchunDay > 0) ? operList.returnFlow.summerSunny / summerChungchunDay : 0; + operList.efflFlow.summerSunny = (summerChungchunDay > 0) ? operList.efflFlow.summerSunny / summerChungchunDay : 0; // 동절기 전기간 평균 - operList.inFlow.winterAvg = (winterDay > 0)? operList.inFlow.winterTot / winterDay : 0; - operList.inflAmt.winterAvg = (winterDay > 0)? operList.inflAmt.winterTot / winterDay : 0; - operList.sumFlow.winterAvg = (winterDay > 0)? operList.sumFlow.winterTot / winterDay : 0; - operList.returnFlow.winterAvg = (winterDay > 0)? operList.returnFlow.winterTot / winterDay : 0; - operList.efflFlow.winterAvg = (winterDay > 0)? operList.efflFlow.winterTot / winterDay : 0; + operList.inFlow.winterAvg = (winterDay > 0) ? operList.inFlow.winterTot / winterDay : 0; + operList.inflAmt.winterAvg = (winterDay > 0) ? operList.inflAmt.winterTot / winterDay : 0; + operList.sumFlow.winterAvg = (winterDay > 0) ? operList.sumFlow.winterTot / winterDay : 0; + operList.returnFlow.winterAvg = (winterDay > 0) ? operList.returnFlow.winterTot / winterDay : 0; + operList.efflFlow.winterAvg = (winterDay > 0) ? operList.efflFlow.winterTot / winterDay : 0; // 동절기 청천시 평균 - operList.inFlow.winterSunny = (winterChungchuDay > 0)? operList.inFlow.winterSunny / winterChungchuDay : 0; - operList.inflAmt.winterSunny = (winterChungchuDay > 0)? operList.inflAmt.winterSunny / winterChungchuDay : 0; - operList.sumFlow.winterSunny = (winterChungchuDay > 0)? operList.sumFlow.winterSunny / winterChungchuDay : 0; - operList.returnFlow.winterSunny = (winterChungchuDay > 0)? operList.returnFlow.winterSunny / winterChungchuDay : 0; - operList.efflFlow.winterSunny = (winterChungchuDay > 0)? operList.efflFlow.winterSunny / winterChungchuDay : 0; + operList.inFlow.winterSunny = (winterChungchuDay > 0) ? operList.inFlow.winterSunny / winterChungchuDay : 0; + operList.inflAmt.winterSunny = (winterChungchuDay > 0) ? operList.inflAmt.winterSunny / winterChungchuDay : 0; + operList.sumFlow.winterSunny = (winterChungchuDay > 0) ? operList.sumFlow.winterSunny / winterChungchuDay : 0; + operList.returnFlow.winterSunny = (winterChungchuDay > 0) ? operList.returnFlow.winterSunny / winterChungchuDay : 0; + operList.efflFlow.winterSunny = (winterChungchuDay > 0) ? operList.efflFlow.winterSunny / winterChungchuDay : 0; // 연간 유입 평균 = 하수유입량(순수하수유입량) + 연계처리량 + 반류수유량(m³/일) operationalStatusList[0].yearAvg = roundUp(operList.inFlow.yearAvg, 0); // 연간 유입 평균 = 하수유입량(순수하수유입량) + 연계처리량 + 반류수유량(m³/일) @@ -1759,8 +1769,9 @@ export const dashBoardReducer = ( const rtnData = await calcWaterQltyData(operationalStatusList, searchYear, fcltyCd, mainGraphData); // 수질 데이터 청천시, 강우시 재계산 // 총인설비가 없을 경우 제외 - console.log('총인시설 여부 : ', mainGraphData.data.wqltObjs?.tpFctYn); - const tpFctYn = mainGraphData.data.wqltObjs?.tpFctYn; + console.log('총인시설 여부 : ', mainGraphData.data.wqltObjs?.[0].tpFctYn); + + const tpFctYn = mainGraphData.data.wqltObjs?.[0].tpFctYn; // console.log('rtnData : ', rtnData); if (tpFctYn !== 'Y') { From 9b1342b2030041541fa4317364201edf80bb8ffc Mon Sep 17 00:00:00 2001 From: dongsilove Date: Wed, 7 Jan 2026 21:46:16 +0900 Subject: [PATCH 09/34] =?UTF-8?q?fo:=20=EC=B2=98=EB=A6=AC=EA=B5=AC?= =?UTF-8?q?=EC=97=AD=EC=A0=95=EB=B3=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/(with-layout)/processArea/page.tsx | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/apps/fo/app/pages/(with-layout)/processArea/page.tsx b/apps/fo/app/pages/(with-layout)/processArea/page.tsx index 91bdb6ab0..adad3ea67 100644 --- a/apps/fo/app/pages/(with-layout)/processArea/page.tsx +++ b/apps/fo/app/pages/(with-layout)/processArea/page.tsx @@ -6,6 +6,7 @@ "use client" import { useFoStore } from "@/app/store"; +import { useShallow } from 'zustand/react/shallow'; import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; import { useCallback, useEffect, useRef, useState } from "react"; @@ -13,19 +14,22 @@ import ProcessFacilityInfoModal from "./modal/page"; import LoadingOverlay from "@common/business_components/ui/loadingBar"; export default function ProcessArea() { - const {Common, + const { + Common, ProcessArea, ProcessAreaSearch, initializeCommonData, searchProcessAreaList - } = useFoStore((state) => state) || { - Common: { isInit: false, selectSidoData: [], selectSigunData: [], selectRegionData: [], selectUnitWaterShedData: [], selectMiddleRegionData: [], selectEnvPartData: [], selectSearchYear: [{ val: "0" }], btnClass: "" }, - ProcessArea: { processAreaList: [], processAreaCount: 0, excelList: [], upHeadList1: [] }, - ProcessAreaSearch: { processFacilityLabelArray: [] }, - initializeCommonData: () => {}, - searchProcessAreaList: () => {} - }; - + } = useFoStore( + useShallow((state) => ({ // 다른 무관한 상태가 변경되어도 이 컴포넌트는 불필요하게 다시 렌더링 되지 않음. + Common: state.Common, + ProcessArea: state.ProcessArea, + ProcessAreaSearch: state.ProcessAreaSearch, + initializeCommonData: state.initializeCommonData, + searchProcessAreaList: state.searchProcessAreaList, + })) + ); + const { isInit, selectSidoData, @@ -37,7 +41,7 @@ export default function ProcessArea() { selectSearchYear, btnClass, } = Common; - + const { processFacilityLabelArray, } = ProcessAreaSearch; @@ -54,11 +58,11 @@ export default function ProcessArea() { // 그리드 관련 const searchInputRef = useRef(null); - // 모달 상태 추가 + // 모달 상태 추가 const [selectedRow, setSelectedRow] = useState(null); const [fcltyNm, setFcltyNm] = useState(""); const [fcltyCd, setFcltyCd] = useState(""); - + const [resetPage, setResetPage] = useState(false); const [searchYearValue, setSearchYearValue] = useState(selectSearchYear[0]?.val || "0"); @@ -74,7 +78,7 @@ export default function ProcessArea() { sigunText: '', }); - const searchProcessArea = useCallback(({ sidoText, sigunText}: ReturnType, pageNo: number, pageCnt:number=20) => { + const searchProcessArea = useCallback(({ sidoText, sigunText }: ReturnType, pageNo: number, pageCnt: number = 20) => { searchProcessAreaList(pageNo, pageCnt, sidoText, sigunText, searchYearValue); }, [searchProcessAreaList, searchYearValue]); @@ -118,11 +122,11 @@ export default function ProcessArea() { useEffect(() => { if (excelList && excelList.length > 0) { - downloadExcel({ - data: excelList as unknown as JSON[], - fileName: '처리구역정보', - sheetNameArray: ['처리구역정보'], - headerRange: 'A1:W1' + downloadExcel({ + data: excelList as unknown as JSON[], + fileName: '처리구역정보', + sheetNameArray: ['처리구역정보'], + headerRange: 'A1:W1' }); } }, [excelList]); @@ -143,7 +147,7 @@ export default function ProcessArea() { - setSearchYearValue(val.toString())} value={searchYearValue} selectClass={undefined}/> + setSearchYearValue(val.toString())} value={searchYearValue} selectClass={undefined} /> } rightChildren={undefined} selectSidoData={selectSidoData} @@ -169,8 +173,8 @@ export default function ProcessArea() { {selectedRow !== null && ( - } + } bodyClass="sm:max-w-[90vw] w-[1200px] h-[900px]" open={selectedRow !== null} onOpenChange={(open: boolean) => !open && closeModal()} From 5b76d02e0b9bee53ce65eb5453934087a445d064 Mon Sep 17 00:00:00 2001 From: ljpark Date: Thu, 8 Jan 2026 13:57:29 +0900 Subject: [PATCH 10/34] =?UTF-8?q?fo:=20=EA=B0=95=EC=88=98=ED=98=84?= =?UTF-8?q?=ED=99=A9=20excel=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/components/common/DataForm.tsx | 9 +++++-- .../facilityPrecipitation/modal/page.tsx | 27 +++++++++++-------- .../src/ui/excel/index.tsx | 10 +++++++ 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/apps/fo/app/components/common/DataForm.tsx b/apps/fo/app/components/common/DataForm.tsx index 48b428e32..d9e78c268 100644 --- a/apps/fo/app/components/common/DataForm.tsx +++ b/apps/fo/app/components/common/DataForm.tsx @@ -7,9 +7,14 @@ export const roundNumber = (value : any, decimals: number) => { if (typeof value === 'number') { return addCommas((Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals)).toFixed(decimals)); - } else if (typeof value === 'string' && !isNaN(Number(value))) { - return addCommas(Number(value).toFixed(decimals)); + } else if (typeof value === 'string') { + // 콤마가 포함된 문자열 처리 ('1,083.0' 같은 경우) + const cleanedValue = value.replace(/,/g, ''); + if (!isNaN(Number(cleanedValue))) { + return addCommas(Number(cleanedValue).toFixed(decimals)); + } } + return value; // 변환 불가능한 경우 원래 값 반환 } export const addCommas = (value: string | number): any => { diff --git a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx index 1bd8a6c89..061d1738d 100644 --- a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx @@ -9,7 +9,7 @@ import CalcRainEffect from "@/app/components/common/CalcRainEffect"; import { roundNumber } from "@/app/components/common/DataForm"; import { useFoStore } from "@/app/store"; import type { PrecipitationPropsDetailProps } from "@/app/store/facilityPrecipitation"; -import { DatePickerRange, downloadExcel, UiTable } from "@common/business_components/ui"; +import { DatePickerRange, downloadExcelHeaders, UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; import { Button, Table, TableCell, TableHead, TableRow } from "@common/components/ui"; import { useEffect, useRef, useState } from "react"; @@ -45,7 +45,7 @@ export default function PrecipitationModal(props: PrecipitationModalProps) { const standYear = parseInt(props.searchYear); return [{ start: new Date(standYear, 0, 1), - end: new Date(standYear, 11, 31) + end: new Date(standYear, 11, 31) //월의 index는 0부터 시작 }]; }; @@ -112,7 +112,6 @@ export default function PrecipitationModal(props: PrecipitationModalProps) { const getTableData = () => { const totals = calculateTotals(); totals.infoRnDay = roundNumber(totals.infoRnDay, 1); - return [ { bscFctCd: "", @@ -157,19 +156,25 @@ export default function PrecipitationModal(props: PrecipitationModalProps) { const excelDownload = () => { const totData = getTableData(); - const excelDownList: any[] = []; + + // 헤더 순서를 명시적으로 정의 + const headers = ["날짜", "강수량(mm/일)", "강우일(일)", "강우영향일(일)"] as const; + + const excelDownList: Record[] = []; if(totData.length > 0){ totData.forEach((item) => { - excelDownList.push({ - "날짜": item.rainDt, - "강수량(mm/일)": roundNumber(item.infoRnDay, 1), - "강우일(일)": roundNumber(item.rainDay, 0), - "강우영향일(일)": roundNumber(item.rainEffectDay, 0), - }); + // 순서를 보장하기 위해 헤더 순서대로 객체 생성 + const row: Record = {}; + row[headers[0]] = item.rainDt; + row[headers[1]] = roundNumber(item.infoRnDay, 1); + row[headers[2]] = roundNumber(item.rainDay, 0); + row[headers[3]] = roundNumber(item.rainEffectDay, 0); + excelDownList.push(row); }); } + if (excelDownList && excelDownList.length > 0) { - downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 강수현황', sheetNameArray: ['지하수유입량'], headerRange: 'A1:D1' }); + downloadExcelHeaders({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 강수현황', sheetNameArray: ['지하수유입량'], headerRange: 'A1:D1' }); } else if (totData.length == 0) { alert('다운받을 데이터가 없습니다.'); } diff --git a/packages/common/business_components/src/ui/excel/index.tsx b/packages/common/business_components/src/ui/excel/index.tsx index aedb32256..0b2659b69 100644 --- a/packages/common/business_components/src/ui/excel/index.tsx +++ b/packages/common/business_components/src/ui/excel/index.tsx @@ -6,6 +6,7 @@ type ExcelDownloadProps = { fileName: string; sheetNameArray: string[]; headerRange?: string; + headers?: string[]|undefined; decimalArray0? : number[]; decimalArray1? : number[]; decimalArray2? : number[]; @@ -19,6 +20,15 @@ export const downloadExcel = ({ data, fileName = new Date().getTime().toString() excelStyle(XLSX.write(workbook, { bookType: "xlsx", type: "buffer" }), headerRange, fileName); }; +export const downloadExcelHeaders = ({ data, fileName = new Date().getTime().toString() + '.xlsx', sheetNameArray = ["Sheet1"], headerRange='A1:V3', headers}: ExcelDownloadProps) => { + const dataArray = Array.isArray(data) ? data : [data]; + // headers가 제공되면 열 순서를 강제함 + const worksheet = XLSX.utils.json_to_sheet(dataArray, headers ? { header: headers } : undefined); + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, sheetNameArray[0]); + excelStyle(XLSX.write(workbook, { bookType: "xlsx", type: "buffer" }), headerRange, fileName); +}; + export const downloadExcelFormat = ({ data, fileName = new Date().getTime().toString() + '.xlsx', sheetNameArray = ["Sheet1"], headerRange='A1:V3', decimalArray0=[], decimalArray1=[], decimalArray2=[], decimalArray3=[]}: ExcelDownloadProps) => { const worksheet = XLSX.utils.json_to_sheet(Array.isArray(data) ? data : [data]); const workbook = XLSX.utils.book_new(); From 295247845c2a5c2572796fd35930e03dd9edd032 Mon Sep 17 00:00:00 2001 From: ljpark Date: Thu, 8 Jan 2026 17:58:38 +0900 Subject: [PATCH 11/34] =?UTF-8?q?fo:=20=EC=A7=80=ED=95=98=EC=88=98?= =?UTF-8?q?=EC=9C=A0=EC=9E=85=EB=9F=89=20=EC=B5=9C=EB=8C=80,=20=EC=B5=9C?= =?UTF-8?q?=EC=86=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/components/common/DataForm.tsx | 22 +++ .../pages/(with-layout)/processArea/page.tsx | 2 +- .../(with-layout)/processFacility/page.tsx | 2 +- .../pages/(with-layout)/sewageOccur/page.tsx | 2 +- .../(with-layout)/underWaterInput/page.tsx | 2 +- apps/fo/app/store/dashboard/index.tsx | 34 +++-- apps/fo/app/store/sewageOccur/index.tsx | 133 ++++-------------- apps/fo/app/store/underWaterInput/index.tsx | 49 ++----- 8 files changed, 86 insertions(+), 160 deletions(-) diff --git a/apps/fo/app/components/common/DataForm.tsx b/apps/fo/app/components/common/DataForm.tsx index d9e78c268..b58322458 100644 --- a/apps/fo/app/components/common/DataForm.tsx +++ b/apps/fo/app/components/common/DataForm.tsx @@ -4,6 +4,28 @@ item: Record; } +/** + * yyyymm 형태의 문자열을 받아 해당 월의 일수를 반환 + * @param {string} yyyymm - 예: "202502", "202412" + * @returns {number} 해당 월의 일수 (예: 28, 29, 30, 31) + */ +export const getDaysInMonth = (yyyymm: string) => { + if (typeof yyyymm !== 'string' || yyyymm.length !== 6) { + throw new Error("입력은 'yyyymm' 형식의 문자열이어야 합니다. 예: '202502'"); + } + + const year = parseInt(yyyymm.slice(0, 4), 10); // "2025" -> 2025 + const month = parseInt(yyyymm.slice(4, 6), 10); // "02" -> 2 + + if (isNaN(year) || isNaN(month) || month < 1 || month > 12) { + throw new Error("유효한 년/월이 아닙니다."); + } + + // Date(year, month, 0) -> 전달의 마지막 날 + // month에 '다음달'을 넣고, 일(day)에 0을 주면 해당 월의 마지막 날짜가 됨 + return new Date(year, month, 0).getDate(); +} + export const roundNumber = (value : any, decimals: number) => { if (typeof value === 'number') { return addCommas((Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals)).toFixed(decimals)); diff --git a/apps/fo/app/pages/(with-layout)/processArea/page.tsx b/apps/fo/app/pages/(with-layout)/processArea/page.tsx index adad3ea67..009d72c9f 100644 --- a/apps/fo/app/pages/(with-layout)/processArea/page.tsx +++ b/apps/fo/app/pages/(with-layout)/processArea/page.tsx @@ -175,7 +175,7 @@ export default function ProcessArea() { {selectedRow !== null && ( } - bodyClass="sm:max-w-[90vw] w-[1200px] h-[900px]" + bodyClass="sm:max-w-[90vw] w-[1200px] h-[100dvh] max-h-[900px] overflow-y-auto" open={selectedRow !== null} onOpenChange={(open: boolean) => !open && closeModal()} /> diff --git a/apps/fo/app/pages/(with-layout)/processFacility/page.tsx b/apps/fo/app/pages/(with-layout)/processFacility/page.tsx index 856ab4631..9c3c612b5 100644 --- a/apps/fo/app/pages/(with-layout)/processFacility/page.tsx +++ b/apps/fo/app/pages/(with-layout)/processFacility/page.tsx @@ -292,7 +292,7 @@ export default function ProcessFacilitySearch() { {selectedRow !== null && ( } - bodyClass="sm:max-w-[70vw] sm:max-h-[95vh]" + bodyClass="sm:max-w-[70vw] h-[100dvh] max-h-[800px]" open={selectedRow !== null} onOpenChange={(open) => !open && closeModal()} /> diff --git a/apps/fo/app/pages/(with-layout)/sewageOccur/page.tsx b/apps/fo/app/pages/(with-layout)/sewageOccur/page.tsx index 001e816ae..31862e362 100644 --- a/apps/fo/app/pages/(with-layout)/sewageOccur/page.tsx +++ b/apps/fo/app/pages/(with-layout)/sewageOccur/page.tsx @@ -250,7 +250,7 @@ export default function PlanSewage() { facilityCd={fcltyCd} searchYear={searchYear} />} - bodyClass="sm:max-w-[90vw] w-[1000px] h-[770px]" + bodyClass="sm:max-w-[90vw] w-[1000px] h-[100dvh] max-h-[770px]" open={selectedRow !== null} onOpenChange={(open) => !open && closeModal()} noHeaderYn="Y" diff --git a/apps/fo/app/pages/(with-layout)/underWaterInput/page.tsx b/apps/fo/app/pages/(with-layout)/underWaterInput/page.tsx index 47e9ec912..a2ad7bfd6 100644 --- a/apps/fo/app/pages/(with-layout)/underWaterInput/page.tsx +++ b/apps/fo/app/pages/(with-layout)/underWaterInput/page.tsx @@ -251,7 +251,7 @@ export default function UnderWaterInput() { {selectedRow !== null && ( } - bodyClass="sm:max-w-[90vw] w-[1000px] h-[770px]" + bodyClass="sm:max-w-[90vw] w-[1000px] h-[100dvh] max-h-[770px]" open={selectedRow !== null} onOpenChange={(open) => !open && closeModal()} noHeaderYn="Y" diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index 0e7dc8597..94c0ab78e 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -2,9 +2,10 @@ * Store - 타입 */ -import { getFetch } from "@/app/components/api"; +import { getFetch, postFetch } from "@/app/components/api"; import CalcRainEffect from "@/app/components/common/CalcRainEffect"; import DataForm, { roundNumber } from "@/app/components/common/DataForm"; +import { getDaysInMonth } from "@/app/components/common/DataForm"; import { fetchPlanInfo, OSU_PERCENT, qltyDataSetting, roundUp } from "../common"; import { type FacilityWaterQltyProps } from "../facilityWaterQlty"; import { fetchFlowRateModalList } from "../flowRate"; @@ -216,6 +217,11 @@ export interface DrainageEquipmentExcelType { stepFourSep: number | '', } +type WtrUsgYmProps = { + bscFctCd : string, // 처리구역시설코드 + levyYm : string, // 부과년월 + wtrUsg : number, // 월별 물사용량(m³/월) +} /** * Store - data */ @@ -722,17 +728,16 @@ const fetchFacilityPlan = async (targetYear: string | undefined, fcltyCd: string } }; -/* 시설정보 및 운영현황 - 운영실태 */ -// const fetchOperationStatus = async (searchYear: string | undefined, fcltyCd: string | undefined): Promise => { -// try { -// const url = '/dashBoard/mngInfo/' + (searchYear ? searchYear : '2023') + '/' + (fcltyCd ? fcltyCd : ''); -// const res = await getFetch('fo', url); -// return { data: res.data, count: res.count } -// } catch (error) { -// console.error('운영실태 데이터를 가져오는데 실패했습니다:', error); -// return { data: [], count: 0 }; -// } -// } +// 시설들 월별 물사용량 정보 조회 +const fetchWtrUsgYmList = async (searchYear: string|undefined, fcltCdList: string[]): Promise => { + try { + const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/'+searchYear, fcltCdList); + return res; + } catch (error) { + console.error('시설들 월별 물사용량 데이터를 가져오는데 실패했습니다:', error); + return null; + } +}; // 주요그래프 데이터 const fetchMainGraph = async (searchYear: string | undefined, fcltyCd: string | undefined) => { @@ -1460,8 +1465,9 @@ export const dashBoardReducer = ( isLoadingOperationStatus: true, }, })); - // const res = await fetchOperationStatus(searchYear, fcltyCd); // /dashBoard/mngInfo/ - // const data = res.data; + + const fcltCdList = [fcltyCd]; + const wtrUsgRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList); // 수용가의 실제 물사용량 const operList = { inFlow: { diff --git a/apps/fo/app/store/sewageOccur/index.tsx b/apps/fo/app/store/sewageOccur/index.tsx index e9857af71..becb5016b 100644 --- a/apps/fo/app/store/sewageOccur/index.tsx +++ b/apps/fo/app/store/sewageOccur/index.tsx @@ -29,7 +29,7 @@ export type SewageOccurProps = { mdmbsn: string, msrDt: string, } -export type modalTableType = { msrDt: string, waterUsage: number, swageChangePercent: number, estimationSewage: number }; +export type modalTableType = { msrDt: string, waterUsage: number, swageChangePercent: number, estimationSewage: number, } export type SewageOccurDetailProps = { cnt: number, sum: number, @@ -39,6 +39,8 @@ export type SewageOccurDetailProps = { sumWtrUsg: number, // 물사용량 합 avgWtrUsg: number, // 일평균 물사용량 monWtrUsg: number, // 월 물사용량 + maxEstSewerage: number, // 최대 오수발생량 추정 + minEstSewerage: number, // 최소 오수발생량 추정 } export type WtrUsgYmProps = { bscFctCd: string, // 처리구역시설코드 @@ -332,6 +334,7 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) = // wtrUsgRes.data.forEach(fclt => { // wtrUsgMap[fclt.bscFctCd] = fclt.wtrUsg; // }); + let maxEstimationSewage = 0, minEstimationSewage = 999999999; for (const item of sewageOccurPropsList) { const detailList = soccurDetailRes?.data[item.bscFctCd]; @@ -368,17 +371,15 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) = // console.log("totWaterUsage:", totWaterUsage); const count = detailList ? detailList.length : 0; const avg = count == 0 ? 0 : totWaterUsage / count; // 일평균 유입량 - item.waterUsage = parseFloat((avg * 0.65).toFixed(2)); // 물사용량 = 일평균 유입량 * 65% + item.waterUsage = parseFloat((avg * 0.65).toFixed(2)); // 물사용량 = 일평균 유입량 * 65% : 실제 수용가의 물사용량 없는 경우 if (wtrUsgYearTotal > 0 && wtrUsgYearDays > 0) { - item.waterUsage = wtrUsgYearDays > 0 ? wtrUsgYearTotal / wtrUsgYearDays : 0; // 일평균 물사용량 + item.waterUsage = wtrUsgYearDays > 0 ? wtrUsgYearTotal / wtrUsgYearDays : 0; // 일평균 물사용량: 실제 수용가의 물사용량 } item.sewageInputYear = parseFloat(avg.toFixed(2)); // 연간 하수유입량(m³/일) item.sewageInputChungchun = parseFloat((chungcunSumFlow === 0 ? 0 : (chungcunSumFlow / sumChungcunDay)).toFixed(2)); // 청천시 하수유입량 item.estimationSewage = parseFloat((item.waterUsage * OSU_PERCENT).toFixed(2)); // 오수발생량 추정(m³/일) - if (item.bscFctCd === '11200PB001R') { - console.log('chungcunSumFlow:', chungcunSumFlow); - console.log('sumChungcunDay:', sumChungcunDay); - } + if (item.estimationSewage > maxEstimationSewage) maxEstimationSewage = item.estimationSewage; + if (item.estimationSewage < minEstimationSewage) minEstimationSewage = item.estimationSewage; // 반올림 처리 ["fctCpc", "waterUsage", "swageChangePercent", "estimationSewage", "sewageInputYear", "sewageInputChungchun"].forEach( (key) => (item[key] = roundNumber(item[key], 0)) @@ -427,93 +428,11 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) = })); } - /* fetchSewageOccurList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm).then(async (res) => { - const excelDownList: ExcelType[] = []; - const data = res.data; - // Promise.all을 사용하여 모든 비동기 작업이 완료될 때까지 기다림 - const calData = await Promise.all(data.map(async (item: SewageOccurProps) => { - item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || ''; - item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || ''; - item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, '')); - item.swageChangePercent = 90; - - const bscFctCd = item.bscFctCd; - const res2 = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear) as FlowResponse; - - let sumChungcunDay = 0; - let chungcunSumFlow = 0; - let totWaterUsage = 0; - - // 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일) - const rainEffectData = CalcRainEffect(res2.data); - - rainEffectData.forEach((item: FlowDataItem) => { - - if(Number(item.rainEffectDay) === 0){ - chungcunSumFlow += Number(item.inflAmnt); - sumChungcunDay += 1; - } - - totWaterUsage += Number(item.inflAmnt); - }); - const avg = totWaterUsage /res2.count; - item.waterUsage = parseFloat((avg * 0.65).toFixed(2)); - item.sewageInputYear = parseFloat(avg.toFixed(2)); - item.sewageInputChungchun = parseFloat((chungcunSumFlow===0?0:(chungcunSumFlow / sumChungcunDay)).toFixed(2)); - item.estimationSewage = parseFloat((item.waterUsage * (item.swageChangePercent/100)).toFixed(2)); - return item; - })); - - calData.forEach((item: SewageOccurProps) => { - DataForm({ type: 'float0', column: 'fctCpc', item: item as unknown as Record }); - DataForm({ type: 'float0', column: 'waterUsage', item: item as unknown as Record }); - DataForm({ type: 'float0', column: 'swageChangePercent', item: item as unknown as Record }); - DataForm({ type: 'float0', column: 'estimationSewage', item: item as unknown as Record }); - DataForm({ type: 'float0', column: 'sewageInputYear', item: item as unknown as Record }); - DataForm({ type: 'float0', column: 'sewageInputChungchun', item: item as unknown as Record }); - }); - - if(pageSize>5000){ - calData.forEach((item: SewageOccurProps) => { - excelDownList.push({ - 시설코드: item.bscFctCd, - 권역: item.rvbsn, - 단위유역: item.lgbsn, - 중권역: item.mdmbsn, - 환경청: item.rgnNm, - 시설명: item.bscFctNm, - 시도: item.sidoNm, - 시군구: item.sggNm, - 주소: item.daddr, - "시설용량(m³/일)": item.fctCpc, - "물사용량(m³/일)": item.waterUsage, - "오수전환율(%)": item.swageChangePercent, - "오수발생량추정(m³/일)": item.estimationSewage, - "연간하수유입량(m³/일)": item.sewageInputYear, - "청천시하수유입량(m³/일)": item.sewageInputChungchun, - }); - }); - } - // 조회 데이터 설정 - set((state: any) => ({ - ...state, - SewageOccur: pageSize<5000?{ - ...state.SewageOccur, - sewageOccurList: calData, - sewageOccurCount: res.count, - isLoading : false, - }:{ - ...state.SewageOccur, - excelList: excelDownList, - isLoading : false, - }, - })) - }); */ }, searchSewageOccurDetailList: async (bscFctCd: string, searchYear: string, startYm?: string, endYm?: string) => { const fcltCdList = [bscFctCd]; - const wtrUsgRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList); + const wtrUsgRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList); // 수용가의 실제 물사용량 const res = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear); const monthData: SewageOccurDetailProps[] = []; let tot = 0, cnt = 0; @@ -554,15 +473,15 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) = } else { monthData[monthIdx] = { cnt: 1, sum: Number(item.inflAmnt), yr: item.msrDt.substring(0, 4) - , usage: 0, cntWtrUsg: 0, sumWtrUsg: 0, avgWtrUsg: 0, monWtrUsg: 0 + , usage: 0, cntWtrUsg: 0, sumWtrUsg: 0, avgWtrUsg: 0, monWtrUsg: 0, maxEstSewerage: 0, minEstSewerage: 999999999 }; } } - tot += Number(item.inflAmnt) + tot += Number(item.inflAmnt); // 연간 유입량 cnt++ }); - // 물사용량 + // 수용가 실제 물사용량 let totWtrUsg = 0; let cntWtrUsg = 0; if (wtrUsgRes && wtrUsgRes.data && wtrUsgRes.data[bscFctCd]) { @@ -582,25 +501,23 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) = const tableData: modalTableType[] = [] - let maxWaterUsage = 0; - let minWaterUsage = 9999999999; + let maxWaterUsage = 0, minWaterUsage = 9999999999; + let maxEstSewage = 0, minEstSewage = 9999999999; let avgWaterUsage = 0; monthData.forEach((item, index) => { - item.avgWtrUsg = item.sum / item.cnt * 0.65; // 일평균 물사용량 = 일평균유입수 * 0.65 - if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg; + item.avgWtrUsg = item.sum / item.cnt * 0.65; // 일평균 물사용량 = 일평균유입수 * 0.65 : 수용가 실제 물사용량이 없으면 + if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg; //수용가 실제 물사용량이 있는 경우 + const estSewage = Math.round(item.avgWtrUsg * OSU_PERCENT * 1) / 1; // 오수발생량 추정 tableData.push({ msrDt: item.yr + '-' + (index + 1 >= 10 ? String(index + 1) : '0' + (index + 1)), waterUsage: Math.round(item.avgWtrUsg * 1) / 1, - swageChangePercent: OSU_PERCENT * 100,//(Math.round((item.usage/item.usage*OSU_PERCENT) * 100) / 100) * 100, - estimationSewage: Math.round(item.avgWtrUsg * OSU_PERCENT * 1) / 1 + swageChangePercent: OSU_PERCENT * 100, //오수전환율 (Math.round((item.usage/item.usage*OSU_PERCENT) * 100) / 100) * 100, + estimationSewage: estSewage, }) - if (item.avgWtrUsg > maxWaterUsage) { - maxWaterUsage = item.avgWtrUsg; - } - - if (item.avgWtrUsg < minWaterUsage) { - minWaterUsage = item.avgWtrUsg; - } + if (item.avgWtrUsg > maxWaterUsage) maxWaterUsage = item.avgWtrUsg; // 물사용량 최대 + if (item.avgWtrUsg < minWaterUsage) minWaterUsage = item.avgWtrUsg; // 물사용량 최소 + if (maxEstSewage < estSewage) maxEstSewage = estSewage; // 오수발생량 최대 + if (minEstSewage > estSewage) minEstSewage = estSewage; // 오수발생량 최소 }); avgWaterUsage = tot / cnt * 0.65 @@ -617,13 +534,13 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) = msrDt: '최대', waterUsage: roundNumber(Math.round(maxWaterUsage * 100) / 100, 0), swageChangePercent: OSU_PERCENT * 100, - estimationSewage: roundNumber(Math.round(maxWaterUsage * OSU_PERCENT * 1) / 1, 0), + estimationSewage: roundNumber(maxEstSewage / 1, 0), }, { msrDt: '최소', waterUsage: roundNumber(Math.round(minWaterUsage * 100) / 100, 0), swageChangePercent: OSU_PERCENT * 100, - estimationSewage: roundNumber(Math.round(minWaterUsage * OSU_PERCENT * 1) / 1, 0), + estimationSewage: roundNumber(minEstSewage / 1, 0), }, ...tableData ] diff --git a/apps/fo/app/store/underWaterInput/index.tsx b/apps/fo/app/store/underWaterInput/index.tsx index c6a2167d8..93745baf9 100644 --- a/apps/fo/app/store/underWaterInput/index.tsx +++ b/apps/fo/app/store/underWaterInput/index.tsx @@ -5,6 +5,7 @@ import type { ExcelType, UnderWaterInputModalProps, UnderWaterProps, WtrUsgYmPro // import CalcRainEffect from "@/app/components/common/CalcRainEffect"; import { OSU_PERCENT } from "../common"; import { fetchFacilityListInit } from "../processFacility"; +import { getDaysInMonth } from "@/app/components/common/DataForm"; export type { TableUpperProps }; // SewageOccurDetailProps 타입을 여기에 정의 @@ -241,7 +242,7 @@ export const fetchWtrUsgYmList = async (searchYear: string|undefined, fcltCdList ====================================*/ export type UnderWaterActions = { searchUnderWaterList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void; - unserWaterModal:(bscFctCd:string, searchYear:string, startYm:string, endYm:string)=>void + underWaterModal:(bscFctCd:string, searchYear:string, startYm:string, endYm:string)=>void } export type UnderWaterType = { @@ -310,27 +311,6 @@ const dataFormSetting=(item : UnderWaterProps)=> { // } // return results; // } -/** - * yyyymm 형태의 문자열을 받아 해당 월의 일수를 반환 - * @param {string} yyyymm - 예: "202502", "202412" - * @returns {number} 해당 월의 일수 (예: 28, 29, 30, 31) - */ -function getDaysInMonth(yyyymm) { - if (typeof yyyymm !== 'string' || yyyymm.length !== 6) { - throw new Error("입력은 'yyyymm' 형식의 문자열이어야 합니다. 예: '202502'"); - } - - const year = parseInt(yyyymm.slice(0, 4), 10); // "2025" -> 2025 - const month = parseInt(yyyymm.slice(4, 6), 10); // "02" -> 2 - - if (isNaN(year) || isNaN(month) || month < 1 || month > 12) { - throw new Error("유효한 년/월이 아닙니다."); - } - - // Date(year, month, 0) -> 전달의 마지막 날 - // month에 '다음달'을 넣고, 일(day)에 0을 주면 해당 월의 마지막 날짜가 됨 - return new Date(year, month, 0).getDate(); -} export type UnderWaterStore = UnderWaterType & UnderWaterActions; @@ -547,7 +527,7 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy } }, - unserWaterModal:async (bscFctCd, searchYear, startYm, endYm)=>{ + underWaterModal:async (bscFctCd, searchYear, startYm, endYm)=>{ const fcltCdList = [bscFctCd]; const wtrUsgRes : any = await fetchWtrUsgYmList(searchYear, fcltCdList); const res = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear); @@ -639,27 +619,28 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy const tableData:UnderWaterInputModalProps[] = [] - let maxWaterUsage = 0; - let minWaterUsage = 9999999999; - let avgWaterUsage = 0; - let maxSunnyInflAmnt = 0; - let minSunnyInflAmnt = 9999999999; - let avgSunnyInflAmnt = 0; + let maxWaterUsage = 0, minWaterUsage = 9999999999, avgWaterUsage = 0; // 물사용량 + let maxSunnyInflAmnt = 0, minSunnyInflAmnt = 9999999999, avgSunnyInflAmnt = 0; // 청천 유입량 + let maxUnderWaterInput = 0, minUnderWaterInput = 9999999999; // 지하수 유입량 monthData.forEach((item, index) => { item.usage = item.sum/item.cnt; // 일평균 유입량 - item.avgWtrUsg = item.sum/item.cnt * 0.65; // 일평균 물사용량 - if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg; // 일평균 물사용량 + item.avgWtrUsg = item.sum/item.cnt * 0.65; // 일평균 물사용량 : 수용가 물사용량이 없는 경우 + // 일평균 물사용량 : 수용가 물사용량이 있는 경우 + if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg; item.sunnyAvgInflAmnt = item.sunnyInflAmnt / item.sunnyCnt; // 청천 일평균 유입량 + const underWtrInput = Math.round((item.sunnyAvgInflAmnt-(item.avgWtrUsg*OSU_PERCENT)) * 1) / 1; // 지하수 유입량 평균 tableData.push({ msrDt: item.yr+'-'+(index+1>=10?String(index+1):'0'+(index+1)), realSewageInput:Math.round(item.sunnyAvgInflAmnt*1) /1, // 청천 실제 하수유입량 sewageOccur:Math.round(item.avgWtrUsg*OSU_PERCENT * 1) / 1,// 오수발생량 - underWaterInput:Math.round((item.sunnyAvgInflAmnt-(item.avgWtrUsg*OSU_PERCENT)) * 1) / 1, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) + underWaterInput: underWtrInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) }) if (item.avgWtrUsg > maxWaterUsage) maxWaterUsage = item.avgWtrUsg; if (item.sunnyAvgInflAmnt > maxSunnyInflAmnt) maxSunnyInflAmnt = item.sunnyAvgInflAmnt; if (item.avgWtrUsg < minWaterUsage) minWaterUsage = item.avgWtrUsg; if (item.sunnyAvgInflAmnt < minSunnyInflAmnt) minSunnyInflAmnt = item.sunnyAvgInflAmnt; + if (underWtrInput > maxUnderWaterInput) maxUnderWaterInput = underWtrInput; + if (underWtrInput < minUnderWaterInput) minUnderWaterInput = underWtrInput; }); if(monthData.length == 0){ @@ -683,13 +664,13 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy msrDt: '최대', realSewageInput: Math.round(maxSunnyInflAmnt*1) /1, // 청천시 실제 하수유입량 sewageOccur: Math.round(maxWaterUsage*OSU_PERCENT * 1) / 1, // 오수발생량 - underWaterInput: Math.round((maxSunnyInflAmnt-(maxWaterUsage*OSU_PERCENT)) * 1) / 1, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) + underWaterInput: maxUnderWaterInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) }, { msrDt: '최소', realSewageInput: Math.round(minSunnyInflAmnt*1) /1, // 청천시 실제 하수유입량 sewageOccur: Math.round(minWaterUsage*OSU_PERCENT * 1) / 1, // 오수발생량 - underWaterInput: Math.round((minSunnyInflAmnt-(minWaterUsage*OSU_PERCENT)) * 1) / 1, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) + underWaterInput: minUnderWaterInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) }, ...tableData ] From 6a5c7c301f82d562c6d8cc9d4e0ebe981475156c Mon Sep 17 00:00:00 2001 From: dongsilove Date: Thu, 8 Jan 2026 22:24:32 +0900 Subject: [PATCH 12/34] =?UTF-8?q?fo:=20dashboard=20=EC=A7=80=ED=95=98?= =?UTF-8?q?=EC=88=98=EC=9C=A0=EC=9E=85=EB=9F=89=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/store/dashboard/index.tsx | 25 +- apps/fo/app/store/sewageOccur/index.tsx | 4 +- apps/fo/app/store/underWaterInput/index.tsx | 552 ++++++++++---------- 3 files changed, 294 insertions(+), 287 deletions(-) diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index 94c0ab78e..fcddcc77b 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -218,9 +218,9 @@ export interface DrainageEquipmentExcelType { } type WtrUsgYmProps = { - bscFctCd : string, // 처리구역시설코드 - levyYm : string, // 부과년월 - wtrUsg : number, // 월별 물사용량(m³/월) + bscFctCd: string, // 처리구역시설코드 + levyYm: string, // 부과년월 + wtrUsg: number, // 월별 물사용량(m³/월) } /** * Store - data @@ -729,9 +729,9 @@ const fetchFacilityPlan = async (targetYear: string | undefined, fcltyCd: string }; // 시설들 월별 물사용량 정보 조회 -const fetchWtrUsgYmList = async (searchYear: string|undefined, fcltCdList: string[]): Promise => { +const fetchWtrUsgYmList = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { try { - const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/'+searchYear, fcltCdList); + const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/' + searchYear, fcltCdList); return res; } catch (error) { console.error('시설들 월별 물사용량 데이터를 가져오는데 실패했습니다:', error); @@ -1672,15 +1672,18 @@ export const dashBoardReducer = ( operationalStatusList[0].winterSunnyMax = roundUp(operList.inFlow.winterSunnyMax, 0); // 동절기 유입 최대 operationalStatusList[0].winterSunnyAvg = roundUp(operList.inFlow.winterAvg, 0); // 동절기 유입 평균 - // 지하수유입량 + // 청천시 유입(순수하수) 평균 const usage = operList.inflAmt.yearSunny / cntSunnyDay; // 연간 청천 순수하수 평균 const summerUsage = operList.inflAmt.summerSunny; // 하절기 청천 순수하수 평균 const winterUsage = operList.inflAmt.winterSunny; // 동절기 청천 순수하수 평균 - - // 임시 계산변수값들 메인에 대입 - operationalStatusList[0].groundWaterAvg = Math.round((usage - (usage * 0.65 * OSU_PERCENT)) * 100) / 100; - operationalStatusList[0].groundWaterSummer = Math.round((summerUsage - (summerUsage * 0.65 * OSU_PERCENT)) * 100) / 100; - operationalStatusList[0].groundWaterWinter = Math.round((winterUsage - (winterUsage * 0.65 * OSU_PERCENT)) * 100) / 100; + // 물사용량 = 유입평균 * 0.65 + const wtrUsg = operList.inflAmt.yearAvg * 0.65; // 연간 물사용량 평균 + const wtrUsgSummer = operList.inflAmt.summerAvg * 0.65; // 하절기 물사용량 평균 + const wtrUsgWinter = operList.inflAmt.winterAvg * 0.65; // 동절기 물사용량 평균 + // 지하수유입량 + operationalStatusList[0].groundWaterAvg = Math.round((usage - (wtrUsg * OSU_PERCENT)) * 100) / 100; + operationalStatusList[0].groundWaterSummer = Math.round((summerUsage - (wtrUsgSummer * OSU_PERCENT)) * 100) / 100; + operationalStatusList[0].groundWaterWinter = Math.round((winterUsage - (wtrUsgWinter * OSU_PERCENT)) * 100) / 100; // 오염물질 // RDII 추정 = 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) diff --git a/apps/fo/app/store/sewageOccur/index.tsx b/apps/fo/app/store/sewageOccur/index.tsx index becb5016b..1f4e8ce7e 100644 --- a/apps/fo/app/store/sewageOccur/index.tsx +++ b/apps/fo/app/store/sewageOccur/index.tsx @@ -370,8 +370,8 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) = // console.log("totWaterUsage:", totWaterUsage); const count = detailList ? detailList.length : 0; - const avg = count == 0 ? 0 : totWaterUsage / count; // 일평균 유입량 - item.waterUsage = parseFloat((avg * 0.65).toFixed(2)); // 물사용량 = 일평균 유입량 * 65% : 실제 수용가의 물사용량 없는 경우 + const avg = count == 0 ? 0 : totWaterUsage / count; // 연간 하수유입량(m³/일) + item.waterUsage = parseFloat((avg * 0.65).toFixed(2)); // 물사용량 = 연간 하수유입량(m³/일) * 65% : 실제 수용가의 물사용량 없는 경우 if (wtrUsgYearTotal > 0 && wtrUsgYearDays > 0) { item.waterUsage = wtrUsgYearDays > 0 ? wtrUsgYearTotal / wtrUsgYearDays : 0; // 일평균 물사용량: 실제 수용가의 물사용량 } diff --git a/apps/fo/app/store/underWaterInput/index.tsx b/apps/fo/app/store/underWaterInput/index.tsx index 93745baf9..0a0ce9537 100644 --- a/apps/fo/app/store/underWaterInput/index.tsx +++ b/apps/fo/app/store/underWaterInput/index.tsx @@ -10,16 +10,16 @@ export type { TableUpperProps }; // SewageOccurDetailProps 타입을 여기에 정의 export type SewageOccurDetailProps = { - cnt : number, - sum : number, - yr:string, - usage:number, // 일평균 유입량 - sunnyCnt : number, - sunnyInflAmnt : number, - sunnyAvgInflAmnt : number, // 청천시 일평균 유입량 - cntWtrUsg : number, // 물사용량 일자수 - sumWtrUsg : number, // 물사용량 합 - avgWtrUsg:number, // 일평균 물사용량 + cnt: number, + sum: number, + yr: string, + usage: number, // 일평균 유입량 + sunnyCnt: number, + sunnyInflAmnt: number, + sunnyAvgInflAmnt: number, // 청천시 일평균 유입량 + cntWtrUsg: number, // 물사용량 일자수 + sumWtrUsg: number, // 물사용량 합 + avgWtrUsg: number, // 일평균 물사용량 } /**==================================== * Store - 타입 @@ -36,145 +36,145 @@ export type SewageOccurDetailProps = { /** * (1) 메인페이지 - */ + */ // 검색단 -const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별']; +const LabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별']; // 리스트 헤더 -const upHeadList1:TableUpperProps[] = [ - { id: "A", title: "행정구역", row:0, colSpan:2 }, - { id: "sidoNm", title: "시도", row:1, widthPercent: 8 }, - { id: "sggNm", title: "시군구", row:1, widthPercent: 8 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, - { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, - { id: "inflAmnt", title: "연평균유입하수량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 10 }, - { id: "C", title: "지하수 유입량 추정", align:"right", row:0, colSpan:3 }, - { id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1, widthPercent: 8 }, - { id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1, widthPercent: 8 }, - { id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1, widthPercent: 8 }, - { id: "properYn", title: "적정여부", row:0, rowSpan:2, widthPercent: 8 }, +const upHeadList1: TableUpperProps[] = [ + { id: "A", title: "행정구역", row: 0, colSpan: 2 }, + { id: "sidoNm", title: "시도", row: 1, widthPercent: 8 }, + { id: "sggNm", title: "시군구", row: 1, widthPercent: 8 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "inflAmnt", title: "연평균유입하수량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "C", title: "지하수 유입량 추정", align: "right", row: 0, colSpan: 3 }, + { id: "underWaterInputYear", title: "연간\n(m³/일)", align: "right", row: 1, widthPercent: 8 }, + { id: "underWaterInputSummer", title: "하절기\n(m³/일)", align: "right", row: 1, widthPercent: 8 }, + { id: "underWaterInputWinter", title: "동절기\n(m³/일)", align: "right", row: 1, widthPercent: 8 }, + { id: "properYn", title: "적정여부", row: 0, rowSpan: 2, widthPercent: 8 }, ]; -const upHeadList2:TableUpperProps[] = [ - { id: "A", title: "유역", row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", row:1, widthPercent: 5 }, - { id: "lgbsn", title: "단위유역", row:1, widthPercent: 5 }, - { id: "mdmbsn", title: "중권역", row:1, widthPercent: 5 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, - { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, - { id: "inflAmnt", title: "연평균유입하수량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 10 }, - { id: "C", title: "지하수 유입량 추정", align:"right", row:0, colSpan:3 }, - { id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1, widthPercent: 8 }, - { id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1, widthPercent: 8 }, - { id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1, widthPercent: 8 }, - { id: "properYn", title: "적정여부", row:0, rowSpan:2, widthPercent: 8 }, +const upHeadList2: TableUpperProps[] = [ + { id: "A", title: "유역", row: 0, colSpan: 3 }, + { id: "rvbsn", title: "권역", row: 1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", row: 1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", row: 1, widthPercent: 5 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "inflAmnt", title: "연평균유입하수량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "C", title: "지하수 유입량 추정", align: "right", row: 0, colSpan: 3 }, + { id: "underWaterInputYear", title: "연간\n(m³/일)", align: "right", row: 1, widthPercent: 8 }, + { id: "underWaterInputSummer", title: "하절기\n(m³/일)", align: "right", row: 1, widthPercent: 8 }, + { id: "underWaterInputWinter", title: "동절기\n(m³/일)", align: "right", row: 1, widthPercent: 8 }, + { id: "properYn", title: "적정여부", row: 0, rowSpan: 2, widthPercent: 8 }, ]; -const upHeadList3:TableUpperProps[] = [ - { id: "A", title: "유역", row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1, row:1, widthPercent: 5 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2, row:1, widthPercent: 5 }, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3, row:1, widthPercent: 5 }, - { id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 8 }, - { id: "B", title: "행정구역", row:0, colSpan:2 }, - { id: "sidoNm", title: "시도", row:1, widthPercent: 6 }, - { id: "sggNm", title: "시군구", row:1, widthPercent: 6 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, - { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, - { id: "inflAmnt", title: "연평균유입하수량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 10 }, - { id: "C", title: "지하수 유입량 추정", align:"right", row:0, colSpan:3 }, - { id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1, widthPercent: 6}, - { id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1, widthPercent: 6 }, - { id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1, widthPercent: 6 }, - { id: "properYn", title: "적정여부", row:0, rowSpan:2, widthPercent: 6 }, +const upHeadList3: TableUpperProps[] = [ + { id: "A", title: "유역", row: 0, colSpan: 3 }, + { id: "rvbsn", title: "권역", upName: "upChangeRe1", upSequnce: 1, row: 1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", upName: "upChangeRe1", upSequnce: 2, row: 1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", upName: "upChangeRe1", upSequnce: 3, row: 1, widthPercent: 5 }, + { id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "B", title: "행정구역", row: 0, colSpan: 2 }, + { id: "sidoNm", title: "시도", row: 1, widthPercent: 6 }, + { id: "sggNm", title: "시군구", row: 1, widthPercent: 6 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 6 }, + { id: "inflAmnt", title: "연평균유입하수량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "C", title: "지하수 유입량 추정", align: "right", row: 0, colSpan: 3 }, + { id: "underWaterInputYear", title: "연간\n(m³/일)", align: "right", row: 1, widthPercent: 6 }, + { id: "underWaterInputSummer", title: "하절기\n(m³/일)", align: "right", row: 1, widthPercent: 6 }, + { id: "underWaterInputWinter", title: "동절기\n(m³/일)", align: "right", row: 1, widthPercent: 6 }, + { id: "properYn", title: "적정여부", row: 0, rowSpan: 2, widthPercent: 6 }, ]; // 모달 -const upHeadListUnderWaterDetail:TableUpperProps[] = [ +const upHeadListUnderWaterDetail: TableUpperProps[] = [ { id: "msrDt", title: "날짜" }, - { id: "realSewageInput", title: "청천시 실제 하수유입량\n(m³/일)", align:"right" }, - { id: "sewageOccur", title: "오수발생량\n(m³/일)", align:"right" }, - { id: "underWaterInput", title: "지하수 유입량\n(m³/일)", align:"right" }, + { id: "realSewageInput", title: "청천시 실제 하수유입량\n(m³/일)", align: "right" }, + { id: "sewageOccur", title: "오수발생량\n(m³/일)", align: "right" }, + { id: "underWaterInput", title: "지하수 유입량\n(m³/일)", align: "right" }, ]; -const underWaterList:UnderWaterProps[] = [ +const underWaterList: UnderWaterProps[] = [ ] -const underWaterDetailList:UnderWaterInputModalProps[] = [ +const underWaterDetailList: UnderWaterInputModalProps[] = [ { - msrDt : "2024-01", - realSewageInput : 178007, - sewageOccur : 10.5, - underWaterInput : 80.6, + msrDt: "2024-01", + realSewageInput: 178007, + sewageOccur: 10.5, + underWaterInput: 80.6, }, { - msrDt : "2024-02", - realSewageInput : 123007, - sewageOccur : 10.7, - underWaterInput : 80.6, + msrDt: "2024-02", + realSewageInput: 123007, + sewageOccur: 10.7, + underWaterInput: 80.6, }, { - msrDt : "2024-03", - realSewageInput : 213007, - sewageOccur : 10.1, - underWaterInput : 80.6, + msrDt: "2024-03", + realSewageInput: 213007, + sewageOccur: 10.1, + underWaterInput: 80.6, }, { - msrDt : "2024-04", - realSewageInput : 83007, - sewageOccur : 9.57, - underWaterInput : 80.6, + msrDt: "2024-04", + realSewageInput: 83007, + sewageOccur: 9.57, + underWaterInput: 80.6, }, { - msrDt : "2024-05", - realSewageInput : 15007, - sewageOccur : 3.57, - underWaterInput : 80.6, + msrDt: "2024-05", + realSewageInput: 15007, + sewageOccur: 3.57, + underWaterInput: 80.6, }, { - msrDt : "2024-06", - realSewageInput : 123007, - sewageOccur : '', - underWaterInput : 80.6, + msrDt: "2024-06", + realSewageInput: 123007, + sewageOccur: '', + underWaterInput: 80.6, }, { - msrDt : "2024-07", - realSewageInput : 101007, - sewageOccur : 1, - underWaterInput : 80.6, + msrDt: "2024-07", + realSewageInput: 101007, + sewageOccur: 1, + underWaterInput: 80.6, }, { - msrDt : "2024-08", - realSewageInput : 103807, - sewageOccur : 10.57, - underWaterInput : '', + msrDt: "2024-08", + realSewageInput: 103807, + sewageOccur: 10.57, + underWaterInput: '', }, { - msrDt : "2024-09", - realSewageInput : 9007, - sewageOccur : 10.57, - underWaterInput : 80.6, + msrDt: "2024-09", + realSewageInput: 9007, + sewageOccur: 10.57, + underWaterInput: 80.6, }, { - msrDt : "2024-10", - realSewageInput : 163007, - sewageOccur : 10.57, - underWaterInput : 80.6, + msrDt: "2024-10", + realSewageInput: 163007, + sewageOccur: 10.57, + underWaterInput: 80.6, }, { - msrDt : "2024-11", - realSewageInput : 123007, - sewageOccur : 10.57, - underWaterInput : 80.6, + msrDt: "2024-11", + realSewageInput: 123007, + sewageOccur: 10.57, + underWaterInput: 80.6, }, { - msrDt : "2024-12", - realSewageInput : 1007, - sewageOccur : 10.57, - underWaterInput : 80.6, + msrDt: "2024-12", + realSewageInput: 1007, + sewageOccur: 10.57, + underWaterInput: 80.6, }, ] /**==================================== @@ -186,8 +186,8 @@ export interface FlowDataItem { inflAmnt: number | string; infoRnDay: number; msrDt: string; - rainEffectDay? : number; - sumFlow? : number | string | ''; + rainEffectDay?: number; + sumFlow?: number | string | ''; } export interface ApiResponse { @@ -217,9 +217,9 @@ const fetchUnderWaterList = async (pageNo: number, pageSize: number, searchYear: // } // 시설들 유량 정보 조회 -export const fetchDetailListFlow = async (searchYear: string|undefined, fcltCdList: string[]): Promise => { +export const fetchDetailListFlow = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { try { - const res = await postFetch('fo', '/fclt/flow/'+searchYear, fcltCdList); + const res = await postFetch('fo', '/fclt/flow/' + searchYear, fcltCdList); return res; } catch (error) { console.error('시설정보 오수발생량 상세 데이터를 가져오는데 실패했습니다:', error); @@ -227,9 +227,9 @@ export const fetchDetailListFlow = async (searchYear: string|undefined, fcltCdLi } }; // 시설들 월별 물사용량 정보 조회 -export const fetchWtrUsgYmList = async (searchYear: string|undefined, fcltCdList: string[]): Promise => { +export const fetchWtrUsgYmList = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { try { - const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/'+searchYear, fcltCdList); + const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/' + searchYear, fcltCdList); return res; } catch (error) { console.error('시설들 월별 물사용량 데이터를 가져오는데 실패했습니다:', error); @@ -242,16 +242,16 @@ export const fetchWtrUsgYmList = async (searchYear: string|undefined, fcltCdList ====================================*/ export type UnderWaterActions = { searchUnderWaterList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void; - underWaterModal:(bscFctCd:string, searchYear:string, startYm:string, endYm:string)=>void + underWaterModal: (bscFctCd: string, searchYear: string, startYm: string, endYm: string) => void } export type UnderWaterType = { UnderWaterSearch: { isInit: boolean; - labelArray:string[]; + labelArray: string[]; }, - UnderWater : { + UnderWater: { isInit: boolean; upHeadList1: TableUpperProps[]; upHeadList2: TableUpperProps[]; @@ -262,7 +262,7 @@ export type UnderWaterType = { isLoading: boolean; }, - UnderWaterDetail : { + UnderWaterDetail: { isInit: boolean; upHeadListUnderWaterDetail: TableUpperProps[]; gridListUnderWaterDetail: UnderWaterInputModalProps[]; @@ -275,30 +275,30 @@ export const underWaterInitState: UnderWaterType = { labelArray: LabelArray, }, - UnderWater : { - isInit : false, - upHeadList1 : upHeadList1, - upHeadList2 : upHeadList2, - upHeadList3 : upHeadList3, - underWaterList : underWaterList, - underWaterCount : 4, - excelList : [], - isLoading : true, + UnderWater: { + isInit: false, + upHeadList1: upHeadList1, + upHeadList2: upHeadList2, + upHeadList3: upHeadList3, + underWaterList: underWaterList, + underWaterCount: 4, + excelList: [], + isLoading: true, }, - UnderWaterDetail : { + UnderWaterDetail: { isInit: false, upHeadListUnderWaterDetail: upHeadListUnderWaterDetail, gridListUnderWaterDetail: underWaterDetailList, } } -const dataFormSetting=(item : UnderWaterProps)=> { +const dataFormSetting = (item: UnderWaterProps) => { DataForm({ type: 'float0', column: 'fctCpc', item: item as unknown as Record }); DataForm({ type: 'float0', column: 'inflAmnt', item: item as unknown as Record }); - DataForm({ type: 'float0', column: 'underWaterInputYear', item: item as unknown as Record}); - DataForm({ type: 'float0', column: 'underWaterInputSummer', item: item as unknown as Record}); - DataForm({ type: 'float0', column: 'underWaterInputWinter', item: item as unknown as Record}); + DataForm({ type: 'float0', column: 'underWaterInputYear', item: item as unknown as Record }); + DataForm({ type: 'float0', column: 'underWaterInputSummer', item: item as unknown as Record }); + DataForm({ type: 'float0', column: 'underWaterInputWinter', item: item as unknown as Record }); } // 병렬 처리 제한용 헬퍼 @@ -314,23 +314,23 @@ const dataFormSetting=(item : UnderWaterProps)=> { export type UnderWaterStore = UnderWaterType & UnderWaterActions; -export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterType) => void)=>UnderWaterActions=(set: (fn: (state: UnderWaterType) => UnderWaterType) => void) => { +export const underWaterReducer: (set: (fn: (state: UnderWaterType) => UnderWaterType) => void) => UnderWaterActions = (set: (fn: (state: UnderWaterType) => UnderWaterType) => void) => { return { searchUnderWaterList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { const facilityInitData = await fetchFacilityListInit(pageNo, pageSize, part, nameCd, fcltCpct, operationValue, fcltyNm); - - if(pageSize < 5000){ + + if (pageSize < 5000) { set((state: UnderWaterType) => ({ ...state, UnderWater: { ...state.UnderWater, - underWaterList : facilityInitData.data, - underWaterCount : facilityInitData.count, - isInit : true, + underWaterList: facilityInitData.data, + underWaterCount: facilityInitData.count, + isInit: true, isLoading: true, }, })); - }else{ + } else { set((state: UnderWaterType) => ({ ...state, UnderWater: { @@ -339,43 +339,43 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy }, })); } - + const fcltylist = facilityInitData.data; - const fcltCdList : string[] = []; // 시설코드목록 - const underWaterPropsList : UnderWaterProps[] = []; // 오수발생량시설목록 + const fcltCdList: string[] = []; // 시설코드목록 + const underWaterPropsList: UnderWaterProps[] = []; // 오수발생량시설목록 fcltylist.forEach(item => { fcltCdList.push(item.bscFctCd); underWaterPropsList.push({ - bscFctCd : item.bscFctCd, - sidoNm : item.sido, - sggNm : item.gugun, - lclgvrnmntNm : '', - bscFctNm : item.bscFctNm, - daddr : item.daddr, - fctCpc : parseFloat(item.fctCpc.toString().replace(/,/g, '')), - inflAmnt : 0, - waterUsage : 0, - underWaterInputYear : 0, - underWaterInputSummer : 0, - underWaterInputWinter : 0, - properYn : '', - infoRnDay : 0, - rgnNm : item.rgnNm, - rvbsn : item.rvbsn, - lgbsn : item.lgbsn, - mdmbsn : item.mdmbsn, - msrDt : '', + bscFctCd: item.bscFctCd, + sidoNm: item.sido, + sggNm: item.gugun, + lclgvrnmntNm: '', + bscFctNm: item.bscFctNm, + daddr: item.daddr, + fctCpc: parseFloat(item.fctCpc.toString().replace(/,/g, '')), + inflAmnt: 0, + waterUsage: 0, + underWaterInputYear: 0, + underWaterInputSummer: 0, + underWaterInputWinter: 0, + properYn: '', + infoRnDay: 0, + rgnNm: item.rgnNm, + rvbsn: item.rvbsn, + lgbsn: item.lgbsn, + mdmbsn: item.mdmbsn, + msrDt: '', }); }); - - const soccurDetailRes : any = await fetchDetailListFlow(searchYear, fcltCdList); - const wtrUsgYmRes : any = await fetchWtrUsgYmList(searchYear, fcltCdList); - + + const soccurDetailRes: any = await fetchDetailListFlow(searchYear, fcltCdList); + const wtrUsgYmRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList); + for (const item of underWaterPropsList) { - + const detailList = soccurDetailRes?.data[item.bscFctCd]; const wtrUsgYmList = wtrUsgYmRes?.data[item.bscFctCd]; - + let chungcunSumFlow = 0; // 청천유입량 let sumChungcunDay = 0; // 청천일수 let sumSummerChungcunDay = 0; // 하절기 청천일수 @@ -387,39 +387,39 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy let totWinterUsage = 0; // 동절기 하수유입량 let totSummerDays = 0; // 하절기 일수 let totWinterDays = 0; // 동절기 일수 - + const summerMonth = ['06', '07', '08']; const winterMonth = ['01', '02']; - + let rainEffectDay = 0; detailList?.forEach(item2 => { if (item2.infoRnDay == null || item2.infoRnDay.trim() == 'x') item2.infoRnDay = 0; - if(Number(item2.infoRnDay) >= 3) { + if (Number(item2.infoRnDay) >= 3) { rainEffectDay = 2; - }else{ + } else { rainEffectDay--; } - if(rainEffectDay<0){ //청천시 + if (rainEffectDay < 0) { //청천시 chungcunSumFlow += Number(item2.inflAmnt); sumChungcunDay += 1; - if(item2.msrDt.substring(4,6) ==='06' || item2.msrDt.substring(4,6) ==='07' || item2.msrDt.substring(4,6) ==='08'){ + if (item2.msrDt.substring(4, 6) === '06' || item2.msrDt.substring(4, 6) === '07' || item2.msrDt.substring(4, 6) === '08') { // 하절기 6,7,8월 sumSummerChungcunDay += 1; sumSummerChungcunFlow += Number(item2.inflAmnt); //item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0; - }else if(item2.msrDt.substring(4,6) ==='01' || item2.msrDt.substring(4,6) ==='02'){ + } else if (item2.msrDt.substring(4, 6) === '01' || item2.msrDt.substring(4, 6) === '02') { // 동절기 1,2월 sumWinterChungcunDay += 1; sumWinterChungcunFlow += Number(item2.inflAmnt); //item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0; } } totWaterUsage += Number(item2.inflAmnt); - if(item2.msrDt.substring(4,6) ==='06' || item2.msrDt.substring(4,6) ==='07' || item2.msrDt.substring(4,6) ==='08'){ + if (item2.msrDt.substring(4, 6) === '06' || item2.msrDt.substring(4, 6) === '07' || item2.msrDt.substring(4, 6) === '08') { // 하절기 6,7,8월 totSummerDays += 1; totSummerUsage += Number(item2.inflAmnt); //item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0; - }else if(item2.msrDt.substring(4,6) ==='01' || item2.msrDt.substring(4,6) ==='02'){ + } else if (item2.msrDt.substring(4, 6) === '01' || item2.msrDt.substring(4, 6) === '02') { // 동절기 1,2월 totWinterDays += 1; totWinterUsage += Number(item2.inflAmnt); //item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0; @@ -427,8 +427,8 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy }); const count = detailList ? detailList.length : 0; - const avg = count == 0 ? 0 : totWaterUsage / count; // 일평균 유입량 - + const avg = count == 0 ? 0 : totWaterUsage / count; // 연간 일평균 유입량 + let wtrUsgYearTotal = 0; // 연간 물사용량 let summerWtrUsgTot = 0; // 하절기 물사용량 let winterWtrUsgTot = 0; // 동절기 물사용량 @@ -439,52 +439,52 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy const days = getDaysInMonth(item3.levyYm); wtrUsgYearTotal += Number(item3.wtrUsg); wtrUsgYearDays += days; - if(summerMonth.includes(item3.levyYm.slice(-2))){ + if (summerMonth.includes(item3.levyYm.slice(-2))) { summerWtrUsgTot += Number(item3.wtrUsg); summerWtrUsgDays += days; - }else if(winterMonth.includes(item3.levyYm.slice(-2))){ + } else if (winterMonth.includes(item3.levyYm.slice(-2))) { winterWtrUsgTot += Number(item3.wtrUsg); winterWtrUsgDays += days; } }); - + if (wtrUsgYearTotal > 0) { // 물사용량이 있는 경우 - const usage = chungcunSumFlow&&chungcunSumFlow>0?chungcunSumFlow / sumChungcunDay:0; // 청천시 일평균 유입량 - const summerUsage = sumSummerChungcunFlow?sumSummerChungcunFlow / sumSummerChungcunDay:0; // 하절기 청천시 일평균 유입량 - const winterUsage = sumWinterChungcunFlow?sumWinterChungcunFlow / sumWinterChungcunDay:0; // 동절기 청천시 일평균 유입량 - const wtrUsg = wtrUsgYearDays>0? wtrUsgYearTotal / wtrUsgYearDays: 0; // 일평균 물사용량 - const summerWtrUsg = summerWtrUsgTot?summerWtrUsgTot / summerWtrUsgDays:0; // 하절기 일평균 물사용량 - const winterWtrUsg = winterWtrUsgTot?winterWtrUsgTot / winterWtrUsgDays:0; // 동절기 일평균 물사용량 - + const usage = chungcunSumFlow && chungcunSumFlow > 0 ? chungcunSumFlow / sumChungcunDay : 0; // 청천시 일평균 유입량 + const summerUsage = sumSummerChungcunFlow ? sumSummerChungcunFlow / sumSummerChungcunDay : 0; // 하절기 청천시 일평균 유입량 + const winterUsage = sumWinterChungcunFlow ? sumWinterChungcunFlow / sumWinterChungcunDay : 0; // 동절기 청천시 일평균 유입량 + const wtrUsg = wtrUsgYearDays > 0 ? wtrUsgYearTotal / wtrUsgYearDays : 0; // 일평균 물사용량 + const summerWtrUsg = summerWtrUsgTot ? summerWtrUsgTot / summerWtrUsgDays : 0; // 하절기 일평균 물사용량 + const winterWtrUsg = winterWtrUsgTot ? winterWtrUsgTot / winterWtrUsgDays : 0; // 동절기 일평균 물사용량 + item.inflAmnt = roundNumber(avg, 0); - item.underWaterInputYear = Math.round((usage-(wtrUsg*OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율) - item.underWaterInputSummer = Math.round((summerUsage-(summerWtrUsg*OSU_PERCENT)) * 1) / 1; // 하절기지하수유입량(m³/일) - item.underWaterInputWinter = Math.round((winterUsage-(winterWtrUsg*OSU_PERCENT)) * 1) / 1; // 동절기지하수유입량(m³/일) - item.properYn = Math.round( (Number(usage-(wtrUsg*OSU_PERCENT)) / Number(item.inflAmnt)) * 100 * 1 ) / 1 > 20?'초과유입':'적정'; // 적정여부 + item.underWaterInputYear = Math.round((usage - (wtrUsg * OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율) + item.underWaterInputSummer = Math.round((summerUsage - (summerWtrUsg * OSU_PERCENT)) * 1) / 1; // 하절기지하수유입량(m³/일) + item.underWaterInputWinter = Math.round((winterUsage - (winterWtrUsg * OSU_PERCENT)) * 1) / 1; // 동절기지하수유입량(m³/일) + item.properYn = Math.round((Number(usage - (wtrUsg * OSU_PERCENT)) / Number(item.inflAmnt)) * 100 * 1) / 1 > 20 ? '초과유입' : '적정'; // 적정여부 } else { // 물사용량이 없는 경우, 일평균 유입량으로 물사용량 추정(물사용량 = 유입량*0.65) - const usage = chungcunSumFlow&&chungcunSumFlow>0?chungcunSumFlow / sumChungcunDay:0; // 청천시 일평균 유입량 - const summerUsage = sumSummerChungcunFlow?sumSummerChungcunFlow / sumSummerChungcunDay:0; // 하절기 청천시 일평균 유입량 - const winterUsage = sumWinterChungcunFlow?sumWinterChungcunFlow / sumWinterChungcunDay:0; // 동절기 청천시 일평균 유입량 + const usage = chungcunSumFlow && chungcunSumFlow > 0 ? chungcunSumFlow / sumChungcunDay : 0; // 청천시 일평균 유입량 + const summerUsage = sumSummerChungcunFlow ? sumSummerChungcunFlow / sumSummerChungcunDay : 0; // 하절기 청천시 일평균 유입량 + const winterUsage = sumWinterChungcunFlow ? sumWinterChungcunFlow / sumWinterChungcunDay : 0; // 동절기 청천시 일평균 유입량 const wtrUsg = avg * 0.65; // 일평균 물사용량 - const summerWtrUsg = totSummerDays>0? (totSummerUsage / totSummerDays)*0.65:0; // 하절기 일평균 물사용량 - const winterWtrUsg = totWinterDays>0? (totWinterUsage / totWinterDays)*0.65:0; // 동절기 일평균 물사용량 - + const summerWtrUsg = totSummerDays > 0 ? (totSummerUsage / totSummerDays) * 0.65 : 0; // 하절기 일평균 물사용량 + const winterWtrUsg = totWinterDays > 0 ? (totWinterUsage / totWinterDays) * 0.65 : 0; // 동절기 일평균 물사용량 + item.inflAmnt = roundNumber(avg, 0); //item.underWaterInputYear = Math.round((usage-(usage*0.65*OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일) - item.underWaterInputYear = Math.round((usage-(wtrUsg*OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율) - item.underWaterInputSummer = Math.round((summerUsage-(summerWtrUsg*OSU_PERCENT)) * 1) / 1; // 하절기지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율) - item.underWaterInputWinter = Math.round((winterUsage-(winterWtrUsg*OSU_PERCENT)) * 1) / 1; // 동절기지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율) - item.properYn = Math.round( (Number(usage-(wtrUsg*OSU_PERCENT)) / Number(item.inflAmnt)) * 100 * 1 ) / 1 > 20?'초과유입':'적정'; // 적정여부 - // 반올림 처리 - // ["fctCpc", "inflAmnt", "underWaterInputYear", "underWaterInputSummer", "underWaterInputWinter"].forEach( - // (key) => (item[key] = roundNumber(item[key], 0)) - // ); + item.underWaterInputYear = Math.round((usage - (wtrUsg * OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율) + item.underWaterInputSummer = Math.round((summerUsage - (summerWtrUsg * OSU_PERCENT)) * 1) / 1; // 하절기지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율) + item.underWaterInputWinter = Math.round((winterUsage - (winterWtrUsg * OSU_PERCENT)) * 1) / 1; // 동절기지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율) + item.properYn = Math.round((Number(usage - (wtrUsg * OSU_PERCENT)) / Number(item.inflAmnt)) * 100 * 1) / 1 > 20 ? '초과유입' : '적정'; // 적정여부 + // 반올림 처리 + // ["fctCpc", "inflAmnt", "underWaterInputYear", "underWaterInputSummer", "underWaterInputWinter"].forEach( + // (key) => (item[key] = roundNumber(item[key], 0)) + // ); } } - if(pageSize>= 5000){ + if (pageSize >= 5000) { const excelDownList: ExcelType[] = []; - underWaterPropsList.forEach((item : any) => { + underWaterPropsList.forEach((item: any) => { dataFormSetting(item) item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, '')); excelDownList.push({ @@ -510,10 +510,10 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy UnderWater: { ...state.UnderWater, excelList: excelDownList, - isLoading : false, + isLoading: false, }, })); - }else{ + } else { set((state: UnderWaterType) => ({ ...state, UnderWater: { @@ -521,21 +521,21 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy underWaterList: underWaterPropsList, underWaterCount: facilityInitData.count, excelList: [], - isLoading : false, + isLoading: false, }, })); } }, - - underWaterModal:async (bscFctCd, searchYear, startYm, endYm)=>{ + + underWaterModal: async (bscFctCd, searchYear, startYm, endYm) => { const fcltCdList = [bscFctCd]; - const wtrUsgRes : any = await fetchWtrUsgYmList(searchYear, fcltCdList); + const wtrUsgRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList); const res = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear); const monthData: SewageOccurDetailProps[] = []; let tot = 0, cnt = 0; let sunnyTot = 0, sunnyCnt = 0; - - if(startYm) { + + if (startYm) { res.data = res.data.filter((item: FlowDataItem) => { const month = item.msrDt?.substring(0, 6); return month >= startYm; @@ -547,7 +547,7 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy }); } } - if(endYm) { + if (endYm) { res.data = res.data.filter((item: FlowDataItem) => { const month = item.msrDt?.substring(0, 6); return month <= endYm; @@ -562,36 +562,40 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy let rainEffectDay = 0; res.data?.forEach(item2 => { if (item2.infoRnDay == null || item2.infoRnDay.trim() == 'x') item2.infoRnDay = 0; - if(Number(item2.infoRnDay) >= 3) { + if (Number(item2.infoRnDay) >= 3) { rainEffectDay = 2; - }else{ + } else { rainEffectDay--; } - + const month = item2.msrDt?.substring(4, 6); const monthIdx = month ? Number(month) - 1 : -1; - if (monthIdx >= 0 && (monthIdx>=Number(startYm.substring(4,6))-1 && monthIdx <= Number(endYm.substring(4, 6))-1)) { + if (monthIdx >= 0 && (monthIdx >= Number(startYm.substring(4, 6)) - 1 && monthIdx <= Number(endYm.substring(4, 6)) - 1)) { if (typeof monthData[monthIdx] === 'object') { monthData[monthIdx].sum += Number(item2.inflAmnt); // 유입량 합 monthData[monthIdx].cnt++; } else { - monthData[monthIdx] = {cnt:1, sum:Number(item2.inflAmnt), yr:item2.msrDt.substring(0,4) - , usage:0, sunnyCnt:0, sunnyInflAmnt:0, sunnyAvgInflAmnt: 0, cntWtrUsg:0, sumWtrUsg:0, avgWtrUsg:0}; + monthData[monthIdx] = { + cnt: 1, sum: Number(item2.inflAmnt), yr: item2.msrDt.substring(0, 4) + , usage: 0, sunnyCnt: 0, sunnyInflAmnt: 0, sunnyAvgInflAmnt: 0, cntWtrUsg: 0, sumWtrUsg: 0, avgWtrUsg: 0 + }; } - } - if(month >= startYm.substring(4, 6) && month <= endYm.substring(4, 6)){ + } + if (month >= startYm.substring(4, 6) && month <= endYm.substring(4, 6)) { cnt++; tot += item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0; } - if(rainEffectDay<0) { // 청천시 + if (rainEffectDay < 0) { // 청천시 if (typeof monthData[monthIdx] === 'object') { monthData[monthIdx].sunnyInflAmnt += Number(item2.inflAmnt); // 청천 유입량 합 monthData[monthIdx].sunnyCnt++; - }else { - monthData[monthIdx] = {cnt:1, sum:Number(item2.inflAmnt), yr:item2.msrDt.substring(0,4) - , usage:0, sunnyCnt:0, sunnyInflAmnt:0, sunnyAvgInflAmnt: 0, cntWtrUsg:0, sumWtrUsg:0, avgWtrUsg:0}; + } else { + monthData[monthIdx] = { + cnt: 1, sum: Number(item2.inflAmnt), yr: item2.msrDt.substring(0, 4) + , usage: 0, sunnyCnt: 0, sunnyInflAmnt: 0, sunnyAvgInflAmnt: 0, cntWtrUsg: 0, sumWtrUsg: 0, avgWtrUsg: 0 + }; } - if (month >= startYm.substring(4, 6) && month <= endYm.substring(4, 6)){ + if (month >= startYm.substring(4, 6) && month <= endYm.substring(4, 6)) { sunnyCnt++; sunnyTot += item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0; } @@ -610,32 +614,32 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy if (typeof monthData[monthIdx] === 'object') { monthData[monthIdx].sumWtrUsg += Number(item.wtrUsg); monthData[monthIdx].cntWtrUsg += days; - } + } } totWtrUsg += Number(item.wtrUsg); cntWtrUsg += days; }); } - - const tableData:UnderWaterInputModalProps[] = [] - - let maxWaterUsage = 0, minWaterUsage = 9999999999, avgWaterUsage = 0; // 물사용량 + + const tableData: UnderWaterInputModalProps[] = [] + + let maxWaterUsage = 0, minWaterUsage = 9999999999, avgWaterUsage = 0; // 물사용량 let maxSunnyInflAmnt = 0, minSunnyInflAmnt = 9999999999, avgSunnyInflAmnt = 0; // 청천 유입량 let maxUnderWaterInput = 0, minUnderWaterInput = 9999999999; // 지하수 유입량 monthData.forEach((item, index) => { - item.usage = item.sum/item.cnt; // 일평균 유입량 - item.avgWtrUsg = item.sum/item.cnt * 0.65; // 일평균 물사용량 : 수용가 물사용량이 없는 경우 + item.usage = item.sum / item.cnt; // 일평균 유입량 + item.avgWtrUsg = item.sum / item.cnt * 0.65; // 일평균 물사용량 : 수용가 물사용량이 없는 경우 // 일평균 물사용량 : 수용가 물사용량이 있는 경우 - if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg; + if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg; item.sunnyAvgInflAmnt = item.sunnyInflAmnt / item.sunnyCnt; // 청천 일평균 유입량 - const underWtrInput = Math.round((item.sunnyAvgInflAmnt-(item.avgWtrUsg*OSU_PERCENT)) * 1) / 1; // 지하수 유입량 평균 + const underWtrInput = Math.round((item.sunnyAvgInflAmnt - (item.avgWtrUsg * OSU_PERCENT)) * 1) / 1; // 지하수 유입량 평균 tableData.push({ - msrDt: item.yr+'-'+(index+1>=10?String(index+1):'0'+(index+1)), - realSewageInput:Math.round(item.sunnyAvgInflAmnt*1) /1, // 청천 실제 하수유입량 - sewageOccur:Math.round(item.avgWtrUsg*OSU_PERCENT * 1) / 1,// 오수발생량 + msrDt: item.yr + '-' + (index + 1 >= 10 ? String(index + 1) : '0' + (index + 1)), + realSewageInput: Math.round(item.sunnyAvgInflAmnt * 1) / 1, // 청천 실제 하수유입량 + sewageOccur: Math.round(item.avgWtrUsg * OSU_PERCENT * 1) / 1,// 오수발생량 underWaterInput: underWtrInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) }) - if (item.avgWtrUsg > maxWaterUsage) maxWaterUsage = item.avgWtrUsg; + if (item.avgWtrUsg > maxWaterUsage) maxWaterUsage = item.avgWtrUsg; if (item.sunnyAvgInflAmnt > maxSunnyInflAmnt) maxSunnyInflAmnt = item.sunnyAvgInflAmnt; if (item.avgWtrUsg < minWaterUsage) minWaterUsage = item.avgWtrUsg; if (item.sunnyAvgInflAmnt < minSunnyInflAmnt) minSunnyInflAmnt = item.sunnyAvgInflAmnt; @@ -643,43 +647,43 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy if (underWtrInput < minUnderWaterInput) minUnderWaterInput = underWtrInput; }); - if(monthData.length == 0){ - maxWaterUsage = 0; minWaterUsage = 0; avgWaterUsage = 0; + if (monthData.length == 0) { + maxWaterUsage = 0; minWaterUsage = 0; avgWaterUsage = 0; maxSunnyInflAmnt = 0; minSunnyInflAmnt = 0; avgSunnyInflAmnt = 0; } - - avgWaterUsage = cnt>0? tot/cnt * 0.65:0; // 일평균 물사용량 - if (totWtrUsg > 0 && cntWtrUsg > 0) avgWaterUsage = totWtrUsg / cntWtrUsg; // 일평균 물사용량 - avgSunnyInflAmnt = (sunnyCnt>0)?sunnyTot/sunnyCnt:0; // 청천 일평균 유입량 - const newData= [ - { - msrDt: '평균', - realSewageInput:Math.round(avgSunnyInflAmnt*1) /1, // 청천시 실제 하수유입량 - sewageOccur:Math.round(avgWaterUsage*OSU_PERCENT * 1) / 1, // 오수발생량 - underWaterInput: Math.round((avgSunnyInflAmnt-(avgWaterUsage*OSU_PERCENT)) * 1) / 1 // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) - //underWaterInput:Math.round((avgWaterUsage-(avgWaterUsage*0.65*0.8)) * 100) / 100, - }, - { - msrDt: '최대', - realSewageInput: Math.round(maxSunnyInflAmnt*1) /1, // 청천시 실제 하수유입량 - sewageOccur: Math.round(maxWaterUsage*OSU_PERCENT * 1) / 1, // 오수발생량 - underWaterInput: maxUnderWaterInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) - }, - { - msrDt: '최소', - realSewageInput: Math.round(minSunnyInflAmnt*1) /1, // 청천시 실제 하수유입량 - sewageOccur: Math.round(minWaterUsage*OSU_PERCENT * 1) / 1, // 오수발생량 - underWaterInput: minUnderWaterInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) - }, - ...tableData + avgWaterUsage = cnt > 0 ? tot / cnt * 0.65 : 0; // 일평균 물사용량 + if (totWtrUsg > 0 && cntWtrUsg > 0) avgWaterUsage = totWtrUsg / cntWtrUsg; // 일평균 물사용량 + avgSunnyInflAmnt = (sunnyCnt > 0) ? sunnyTot / sunnyCnt : 0; // 청천 일평균 유입량 + + const newData = [ + { + msrDt: '평균', + realSewageInput: Math.round(avgSunnyInflAmnt * 1) / 1, // 청천시 실제 하수유입량 + sewageOccur: Math.round(avgWaterUsage * OSU_PERCENT * 1) / 1, // 오수발생량 + underWaterInput: Math.round((avgSunnyInflAmnt - (avgWaterUsage * OSU_PERCENT)) * 1) / 1 // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) + //underWaterInput:Math.round((avgWaterUsage-(avgWaterUsage*0.65*0.8)) * 100) / 100, + }, + { + msrDt: '최대', + realSewageInput: Math.round(maxSunnyInflAmnt * 1) / 1, // 청천시 실제 하수유입량 + sewageOccur: Math.round(maxWaterUsage * OSU_PERCENT * 1) / 1, // 오수발생량 + underWaterInput: maxUnderWaterInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) + }, + { + msrDt: '최소', + realSewageInput: Math.round(minSunnyInflAmnt * 1) / 1, // 청천시 실제 하수유입량 + sewageOccur: Math.round(minWaterUsage * OSU_PERCENT * 1) / 1, // 오수발생량 + underWaterInput: minUnderWaterInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) + }, + ...tableData ] set((state: UnderWaterType) => ({ ...state, UnderWaterDetail: { ...state.UnderWaterDetail, - gridListUnderWaterDetail:newData + gridListUnderWaterDetail: newData } })) } From e5a750e8b9efdd32f2250eab06474f62316dbeb9 Mon Sep 17 00:00:00 2001 From: ljpark Date: Fri, 9 Jan 2026 13:06:41 +0900 Subject: [PATCH 13/34] =?UTF-8?q?fo:=20eslint=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/store/dashboard/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index fcddcc77b..f797fb428 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -5,7 +5,7 @@ import { getFetch, postFetch } from "@/app/components/api"; import CalcRainEffect from "@/app/components/common/CalcRainEffect"; import DataForm, { roundNumber } from "@/app/components/common/DataForm"; -import { getDaysInMonth } from "@/app/components/common/DataForm"; +// import { getDaysInMonth } from "@/app/components/common/DataForm"; import { fetchPlanInfo, OSU_PERCENT, qltyDataSetting, roundUp } from "../common"; import { type FacilityWaterQltyProps } from "../facilityWaterQlty"; import { fetchFlowRateModalList } from "../flowRate"; @@ -1467,7 +1467,7 @@ export const dashBoardReducer = ( })); const fcltCdList = [fcltyCd]; - const wtrUsgRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList); // 수용가의 실제 물사용량 + //const wtrUsgRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList); // 수용가의 실제 물사용량 const operList = { inFlow: { From b960a0336158c738fce5c56046c7d39d8f419124 Mon Sep 17 00:00:00 2001 From: ljpark Date: Fri, 9 Jan 2026 13:19:34 +0900 Subject: [PATCH 14/34] =?UTF-8?q?fo:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B3=80=EC=88=98=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/store/dashboard/index.tsx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index f797fb428..5129cbe2f 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -729,15 +729,15 @@ const fetchFacilityPlan = async (targetYear: string | undefined, fcltyCd: string }; // 시설들 월별 물사용량 정보 조회 -const fetchWtrUsgYmList = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { - try { - const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/' + searchYear, fcltCdList); - return res; - } catch (error) { - console.error('시설들 월별 물사용량 데이터를 가져오는데 실패했습니다:', error); - return null; - } -}; +// const fetchWtrUsgYmList = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { +// try { +// const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/' + searchYear, fcltCdList); +// return res; +// } catch (error) { +// console.error('시설들 월별 물사용량 데이터를 가져오는데 실패했습니다:', error); +// return null; +// } +// }; // 주요그래프 데이터 const fetchMainGraph = async (searchYear: string | undefined, fcltyCd: string | undefined) => { @@ -1466,7 +1466,7 @@ export const dashBoardReducer = ( }, })); - const fcltCdList = [fcltyCd]; + // const fcltCdList = [fcltyCd]; //const wtrUsgRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList); // 수용가의 실제 물사용량 const operList = { From 39de22045b149e44a9359210bf9aafecae46983a Mon Sep 17 00:00:00 2001 From: ljpark Date: Fri, 9 Jan 2026 13:21:38 +0900 Subject: [PATCH 15/34] fo: build --- apps/fo/app/store/dashboard/index.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index 5129cbe2f..44dabe9d3 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -2,7 +2,7 @@ * Store - 타입 */ -import { getFetch, postFetch } from "@/app/components/api"; +import { getFetch } from "@/app/components/api"; import CalcRainEffect from "@/app/components/common/CalcRainEffect"; import DataForm, { roundNumber } from "@/app/components/common/DataForm"; // import { getDaysInMonth } from "@/app/components/common/DataForm"; @@ -217,11 +217,11 @@ export interface DrainageEquipmentExcelType { stepFourSep: number | '', } -type WtrUsgYmProps = { - bscFctCd: string, // 처리구역시설코드 - levyYm: string, // 부과년월 - wtrUsg: number, // 월별 물사용량(m³/월) -} +// type WtrUsgYmProps = { +// bscFctCd: string, // 처리구역시설코드 +// levyYm: string, // 부과년월 +// wtrUsg: number, // 월별 물사용량(m³/월) +// } /** * Store - data */ From f279f498655ce52e105d7dcfb30640cdd7c4b486 Mon Sep 17 00:00:00 2001 From: ljpark Date: Fri, 9 Jan 2026 13:38:39 +0900 Subject: [PATCH 16/34] =?UTF-8?q?fo:=20build=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/(with-layout)/underWaterInput/modal/page.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/fo/app/pages/(with-layout)/underWaterInput/modal/page.tsx b/apps/fo/app/pages/(with-layout)/underWaterInput/modal/page.tsx index 2e0f5f27e..02b1891ad 100644 --- a/apps/fo/app/pages/(with-layout)/underWaterInput/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/underWaterInput/modal/page.tsx @@ -29,7 +29,7 @@ const tabList1 = [ export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYear=new Date().getFullYear().toString()} : ModalProps) { // 그리드 관련 - const {Common, UnderWaterDetail, unserWaterModal} = useFoStore((state) => state); + const {Common, UnderWaterDetail, underWaterModal} = useFoStore((state) => state); const { btnClass } = Common; const [startYmDate, setStartYmDate] = useState(searchYear+'01'); const [endYmDate, setEndYmDate] = useState(searchYear+'12'); @@ -74,8 +74,8 @@ export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYea }, [searchYear, tabTerm]); useEffect(()=>{ - unserWaterModal(fcltyCd, searchYear, searchYear+'01', searchYear+'12'); - }, [fcltyCd, searchYear, unserWaterModal]); + underWaterModal(fcltyCd, searchYear, searchYear+'01', searchYear+'12'); + }, [fcltyCd, searchYear, underWaterModal]); useEffect(() => { if(endYmDate < startYmDate) { @@ -93,8 +93,8 @@ export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYea }, [startYmDate, endYmDate, gridListUnderWaterDetail, prevStartYmDate, prevEndYmDate]); useEffect(() => { - unserWaterModal(fcltyCd, searchYear, prevStartYmDate, prevEndYmDate); - } , [fcltyCd, searchYear, unserWaterModal, prevStartYmDate, prevEndYmDate]); + underWaterModal(fcltyCd, searchYear, prevStartYmDate, prevEndYmDate); + } , [fcltyCd, searchYear, underWaterModal, prevStartYmDate, prevEndYmDate]); const excelDownload = () => { const excelDownList: any[] = []; From a6514cab644a081cc0f0aca1eb8c3c49bc91253f Mon Sep 17 00:00:00 2001 From: ljpark Date: Fri, 9 Jan 2026 16:26:10 +0900 Subject: [PATCH 17/34] =?UTF-8?q?fo:=20dashboard=20=EA=B0=95=EC=9A=B0?= =?UTF-8?q?=EC=9D=BC=20=EC=9A=B4=EC=98=81=ED=98=84=ED=99=A9=20tab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/components/common/CalcRainEffect.tsx | 103 ++++++++++++------ .../common/FacilityTermModalHeader.tsx | 7 +- .../app/pages/(with-layout)/flowRate/page.tsx | 2 +- apps/fo/app/store/dashboard/index.tsx | 9 +- 4 files changed, 79 insertions(+), 42 deletions(-) diff --git a/apps/fo/app/components/common/CalcRainEffect.tsx b/apps/fo/app/components/common/CalcRainEffect.tsx index beca33f78..0388c5951 100644 --- a/apps/fo/app/components/common/CalcRainEffect.tsx +++ b/apps/fo/app/components/common/CalcRainEffect.tsx @@ -10,41 +10,65 @@ */ export default function CalcRainEffect(data : any, weather='ALL') { - /* console.log("%c Calculate RainEffect !" , "background:blue;color:white"); - console.log("%c Data Length :"+data.length+" Weather : "+weather , "background:yellow;color:blue");*/ - // 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일) - for(let idx = 0; idx < data.length; idx++) { - const item = data[idx]; - if(item){ - if(item.infoRnDay && Number(item.infoRnDay) >= 3) { // 강우량이 3 이상인 경우 - item.rainEffectDay = 1; - } else { - item.rainEffectDay = 0; - } - - if(item.infoRnDay == 'x'){ - item.infoRnDay = '0.0'; - item.toBeInfoRnDay = '0.0'; - }else{ - item.infoRnDay = Number(item.infoRnDay).toFixed(1); - item.toBeInfoRnDay = Number(item.infoRnDay).toFixed(1); - } + let rtnDataAll : any = []; + let rtnDataSunny : any = []; + let rtnDataRain : any = []; + let rtnData : any = []; + let rainEffectStd = 0; + data.forEach(item => { + if (item.infoRnDay == null || item.infoRnDay == 'x' || item.infoRnDay == '') item.infoRnDay = 0; + if(Number(item.infoRnDay) >= 3) { // 강우일 + rainEffectStd = 2; + item.toBeInfoRnDay = item.infoRnDay; + } else { + rainEffectStd--; } - } - // 이틀 전, 하루 전이 강우영향일(3 이상)인 경우 해당 날도 강우영향일로 설정 - for(let idx = 0; idx < data.length; idx++) { - if(data[idx]) { - // 하루 전이 강우영향일(3 이상)인 경우 - if(idx > 0 && data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay) >= 3) { - data[idx]!.rainEffectDay = 1; - } - // 이틀 전이 강우영향일(3 이상)인 경우 - if(idx > 1 && data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay) >= 3) { - data[idx]!.rainEffectDay = 1; - } + if (rainEffectStd < 0) { // 청천일 + item.rainEffectDay = 0; + rtnDataSunny.push(item); + } else if (rainEffectStd >= 0) { // 강우일 + 강우영향일 + item.rainEffectDay = 1; + rtnDataRain.push(item); } - } + + rtnDataAll.push(item); + }); + + + // // 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일) + // for(let idx = 0; idx < data.length; idx++) { + // const item = data[idx]; + // if(item){ + // if(item.infoRnDay && Number(item.infoRnDay) >= 3) { // 강우량이 3 이상인 경우 + // item.rainEffectDay = 1; + // } else { + // item.rainEffectDay = 0; + // } + + // if(item.infoRnDay == 'x'){ + // item.infoRnDay = '0.0'; + // item.toBeInfoRnDay = '0.0'; + // }else{ + // item.infoRnDay = Number(item.infoRnDay).toFixed(1); + // item.toBeInfoRnDay = Number(item.infoRnDay).toFixed(1); + // } + // } + // } + + // // 이틀 전, 하루 전이 강우영향일(3 이상)인 경우 해당 날도 강우영향일로 설정 + // for(let idx = 0; idx < data.length; idx++) { + // if(data[idx]) { + // // 하루 전이 강우영향일(3 이상)인 경우 + // if(idx > 0 && data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay) >= 3) { + // data[idx]!.rainEffectDay = 1; + // } + // // 이틀 전이 강우영향일(3 이상)인 경우 + // if(idx > 1 && data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay) >= 3) { + // data[idx]!.rainEffectDay = 1; + // } + // } + // } for(let idx = 0; idx < data.length; idx++) { if(data[idx] && data[idx]?.rainEffectDay === 1) { @@ -63,13 +87,20 @@ export default function CalcRainEffect(data : any, weather='ALL') { } } - let rtnData : any = []; + // if (weather === 'ALL') { + // rtnData = data; + // } else if (weather === 'SUNNY') { + // rtnData = data.filter((item: any) => item.rainEffectDay === 0); + // } else { + // rtnData = data.filter((item: any) => item.rainEffectDay === 1); + // } + if (weather === 'ALL') { - rtnData = data; + rtnData = rtnDataAll; } else if (weather === 'SUNNY') { - rtnData = data.filter((item: any) => item.rainEffectDay === 0); + rtnData = rtnDataSunny; } else { - rtnData = data.filter((item: any) => item.rainEffectDay === 1); + rtnData = rtnDataRain; } return rtnData; } \ No newline at end of file diff --git a/apps/fo/app/components/common/FacilityTermModalHeader.tsx b/apps/fo/app/components/common/FacilityTermModalHeader.tsx index 52cee2ea3..84d6353b6 100644 --- a/apps/fo/app/components/common/FacilityTermModalHeader.tsx +++ b/apps/fo/app/components/common/FacilityTermModalHeader.tsx @@ -41,6 +41,7 @@ export default function FacilityTermModalHeader({ const isDateInRanges = (date: Date) => { const standYear = parseInt(searchYear); + const isLeapYear = (standYear % 4 === 0 && standYear % 100 !== 0) || (standYear % 400 === 0); const dateRanges:{start:Date, end:Date}[] = []; if (tabName.includes("_summer")) { @@ -51,7 +52,7 @@ export default function FacilityTermModalHeader({ } else if (tabName.includes("_winter")) { dateRanges.push({ start: new Date(standYear, 0, 1), - end: new Date(standYear, 1, 28) + end: new Date(standYear, 1, isLeapYear ? 29 : 28) }); } else { dateRanges.push({ @@ -70,6 +71,8 @@ export default function FacilityTermModalHeader({ useEffect(() => { let startDate = new Date(Number(searchYear), 0, 1); let endDate = new Date(Number(searchYear), 11, 31); + const standYear = Number(searchYear); + const isLeapYear = (standYear % 4 === 0 && standYear % 100 !== 0) || (standYear % 400 === 0); if(tabName.includes("_summer")) { startDate = new Date(Number(searchYear), 5, 1); @@ -78,7 +81,7 @@ export default function FacilityTermModalHeader({ setEndDate(endDate); } else if (tabName.includes("_winter")) { startDate = new Date(Number(searchYear), 0, 1); - endDate = new Date(Number(searchYear), 1, 28); + endDate = new Date(Number(searchYear), 1, isLeapYear ? 29 : 28); setStartDate(startDate); setEndDate(endDate); } else { diff --git a/apps/fo/app/pages/(with-layout)/flowRate/page.tsx b/apps/fo/app/pages/(with-layout)/flowRate/page.tsx index 77d96fff6..a1a5e22d1 100644 --- a/apps/fo/app/pages/(with-layout)/flowRate/page.tsx +++ b/apps/fo/app/pages/(with-layout)/flowRate/page.tsx @@ -216,7 +216,7 @@ export default function ProcessFacilitySearch() { {selectedRow !== null && ( } - bodyClass="sm:max-w-[90vw] w-[1250px] h-[780px]" + bodyClass="sm:max-w-[90vw] w-[1250px] h-[100dvh] max-h-[780px]" open={selectedRow !== null} onOpenChange={(open: boolean) => !open && closeModal()} /> diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index 44dabe9d3..8216dcd26 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -1992,7 +1992,7 @@ export const dashBoardReducer = ( const rainRate = ['0', '0', '0', '0', '0', '0', '0', '0']; const rainDate = [0, 0, 0, 0, 0, 0, 0, 0]; const inflAmtCnt = [0, 0, 0, 0, 0, 0, 0, 0]; - const inflAmnt = [0, 0, 0, 0, 0, 0, 0, 0]; + const inflAmnt: number[] = [0, 0, 0, 0, 0, 0, 0, 0]; const fcltyCpct = [0, 0, 0, 0, 0, 0, 0, 0]; const dsInflWqltBod: number[] = [0, 0, 0, 0, 0, 0, 0, 0]; const dsInflWqltCod: number[] = [0, 0, 0, 0, 0, 0, 0, 0]; @@ -2036,6 +2036,7 @@ export const dashBoardReducer = ( let totEfflWqltSs = 0; let totEfflWqltTn = 0; let totEfflWqltTp = 0; + let totInflAmnt = 0; rainEffectList.forEach((item: RainManageListProps) => { totInflAssctBfrWqltBod += item.inflAssctBfrWqltBod ? Number(item.inflAssctBfrWqltBod.toString().trim()) : 0; @@ -2048,6 +2049,7 @@ export const dashBoardReducer = ( totEfflWqltSs += item.efflWqltSs ? Number(item.efflWqltSs.toString().trim()) : 0; totEfflWqltTn += item.efflWqltTn ? Number(item.efflWqltTn.toString().trim()) : 0; totEfflWqltTp += item.efflWqltTp ? Number(item.efflWqltTp.toString().trim()) : 0; + totInflAmnt += item.inflAmnt ? Number(item.inflAmnt.toString().trim()) : 0; const toBeRain = item.toBeInfoRnDay ? Number(item.toBeInfoRnDay) : 0; @@ -2295,7 +2297,7 @@ export const dashBoardReducer = ( } } - for (let idx = 0; idx < inflAmnt.length; idx++) { + for (let idx = 1; idx < inflAmnt.length; idx++) { inflAmnt[idx] = calculateAverage(Number(inflAmnt[idx]), Number(inflAmtCnt[idx])); inflAssctBfrWqltBod[idx] = calculateAverage(Number(inflAssctBfrWqltBod[idx]), Number(inflAssctBfrWqltBodCnt[idx])); inflAssctBfrWqltToc[idx] = calculateAverage(Number(inflAssctBfrWqltToc[idx]), Number(inflAssctBfrWqltTocCnt[idx])); @@ -2314,7 +2316,8 @@ export const dashBoardReducer = ( return Number((arr.slice(1).reduce((sum, val) => sum + Number(val), 0))); }; - inflAmnt[0] = calculateAverage(calculateTotal(inflAmnt), dataIsCount); + // console.log(totInflAmnt); + inflAmnt[0] = calculateAverage(totInflAmnt, totItemCnt); fcltyCpct[0] = calculateTotal(fcltyCpct); inflAssctBfrWqltBod[0] = Number((Math.round((totInflAssctBfrWqltBod / totItemCnt) * 10) / 10).toFixed(1)); inflAssctBfrWqltToc[0] = Number((Math.round((totInflAssctBfrWqltToc / totItemCnt) * 10) / 10).toFixed(1)); From 58c8f118d3897c27f911d63e6052a29c37d4801e Mon Sep 17 00:00:00 2001 From: ljpark Date: Fri, 9 Jan 2026 16:34:52 +0900 Subject: [PATCH 18/34] =?UTF-8?q?fo:=20dashboard=20=EA=B0=95=EC=9A=B0?= =?UTF-8?q?=EC=9D=BC=EC=9A=B4=EC=98=81=ED=98=84=ED=99=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/components/common/CalcRainEffect.tsx | 6 +++--- apps/fo/app/store/dashboard/index.tsx | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/fo/app/components/common/CalcRainEffect.tsx b/apps/fo/app/components/common/CalcRainEffect.tsx index 0388c5951..a85f35443 100644 --- a/apps/fo/app/components/common/CalcRainEffect.tsx +++ b/apps/fo/app/components/common/CalcRainEffect.tsx @@ -10,9 +10,9 @@ */ export default function CalcRainEffect(data : any, weather='ALL') { - let rtnDataAll : any = []; - let rtnDataSunny : any = []; - let rtnDataRain : any = []; + const rtnDataAll : any = []; + const rtnDataSunny : any = []; + const rtnDataRain : any = []; let rtnData : any = []; let rainEffectStd = 0; data.forEach(item => { diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index 8216dcd26..572912a53 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -2289,13 +2289,13 @@ export const dashBoardReducer = ( return count > 0 ? Number((value / count)) : 0; }; - // 데이터 있는 항목만 계산 - let dataIsCount = 0; - for (let idx = 0; idx < inflAmnt.length; idx++) { - if (Number(inflAmnt[idx]) > 0) { - dataIsCount++; - } - } + // // 데이터 있는 항목만 계산 + // let dataIsCount = 0; + // for (let idx = 0; idx < inflAmnt.length; idx++) { + // if (Number(inflAmnt[idx]) > 0) { + // dataIsCount++; + // } + // } for (let idx = 1; idx < inflAmnt.length; idx++) { inflAmnt[idx] = calculateAverage(Number(inflAmnt[idx]), Number(inflAmtCnt[idx])); From 54c958e8fa832e1935ccb1c63908689196a0926d Mon Sep 17 00:00:00 2001 From: ljpark Date: Fri, 9 Jan 2026 18:10:19 +0900 Subject: [PATCH 19/34] =?UTF-8?q?fo:=20excel=20=EC=BB=AC=EB=9F=BC=20?= =?UTF-8?q?=EC=88=9C=EC=84=9C=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../facilityPrecipitation/modal/page.tsx | 3 ++- .../(with-layout)/sewageOccur/modal/page.tsx | 23 +++++++++++-------- .../src/ui/excel/index.tsx | 4 ++-- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx index 061d1738d..811f1c0ff 100644 --- a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx @@ -174,7 +174,8 @@ export default function PrecipitationModal(props: PrecipitationModalProps) { } if (excelDownList && excelDownList.length > 0) { - downloadExcelHeaders({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 강수현황', sheetNameArray: ['지하수유입량'], headerRange: 'A1:D1' }); + downloadExcelHeaders({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 강수현황' + , sheetNameArray: ['지하수유입량'], headerRange: 'A1:D1', headers }); } else if (totData.length == 0) { alert('다운받을 데이터가 없습니다.'); } diff --git a/apps/fo/app/pages/(with-layout)/sewageOccur/modal/page.tsx b/apps/fo/app/pages/(with-layout)/sewageOccur/modal/page.tsx index bc7fec4e8..223dc055a 100644 --- a/apps/fo/app/pages/(with-layout)/sewageOccur/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/sewageOccur/modal/page.tsx @@ -8,7 +8,7 @@ import { roundNumber } from "@/app/components/common/DataForm"; import { useFoStore } from "@/app/store"; import type { modalTableType } from "@/app/store/sewageOccur"; -import { DateMonthPicker, downloadExcel, UiTable } from "@common/business_components/ui"; +import { DateMonthPicker, downloadExcelHeaders, UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; import { Button, Table, TableCell, TableHead, TableRow } from "@common/components/ui"; import { useEffect, useState } from "react"; @@ -69,20 +69,25 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd } }, [endYearMonth, startYearMonth]); - const excelDownload = () => { + const excelDownload = () => { + // 헤더 순서를 명시적으로 정의 + const headers = ["날짜", "물사용량(m³/일)", "오수전환율(%)", "오수발생량 추정(m³/일)"] as const; + const excelDownList: any[] = []; if(detailList.length > 0){ detailList.forEach((item) => { - excelDownList.push({ - "날짜": item.msrDt, - "물사용량(m³/일)": roundNumber(item.waterUsage, 0), - "오수전환율(%)": roundNumber(item.swageChangePercent, 0), - "오수발생량 추정(m³/일)": roundNumber(item.estimationSewage, 0), - }); + // 순서를 보장하기 위해 헤더 순서대로 객체 생성 + const row: Record = {}; + row[headers[0]] = item.msrDt; + row[headers[1]] = roundNumber(item.waterUsage, 0); + row[headers[2]] = roundNumber(item.swageChangePercent, 0); + row[headers[3]] = roundNumber(item.estimationSewage, 0); + excelDownList.push(row); }); } if (excelDownList && excelDownList.length > 0) { - downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 오수발생량 추정', sheetNameArray: [props.fcltyName + ' 오수발생량 추정'], headerRange: 'A1:D1' }); + downloadExcelHeaders({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 오수발생량 추정' + , sheetNameArray: [props.fcltyName + ' 오수발생량 추정'], headerRange: 'A1:D1', headers }); } else if (detailList.length == 0) { alert('다운받을 데이터가 없습니다.'); } diff --git a/packages/common/business_components/src/ui/excel/index.tsx b/packages/common/business_components/src/ui/excel/index.tsx index 0b2659b69..048a0cc42 100644 --- a/packages/common/business_components/src/ui/excel/index.tsx +++ b/packages/common/business_components/src/ui/excel/index.tsx @@ -6,7 +6,7 @@ type ExcelDownloadProps = { fileName: string; sheetNameArray: string[]; headerRange?: string; - headers?: string[]|undefined; + headers?: readonly string[]|undefined; decimalArray0? : number[]; decimalArray1? : number[]; decimalArray2? : number[]; @@ -23,7 +23,7 @@ export const downloadExcel = ({ data, fileName = new Date().getTime().toString() export const downloadExcelHeaders = ({ data, fileName = new Date().getTime().toString() + '.xlsx', sheetNameArray = ["Sheet1"], headerRange='A1:V3', headers}: ExcelDownloadProps) => { const dataArray = Array.isArray(data) ? data : [data]; // headers가 제공되면 열 순서를 강제함 - const worksheet = XLSX.utils.json_to_sheet(dataArray, headers ? { header: headers } : undefined); + const worksheet = XLSX.utils.json_to_sheet(dataArray, headers ? { header: [...headers] } : undefined); const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, sheetNameArray[0]); excelStyle(XLSX.write(workbook, { bookType: "xlsx", type: "buffer" }), headerRange, fileName); From ac8c58d2a9d6626ca5c0d4529c3aba34533c9f7b Mon Sep 17 00:00:00 2001 From: dongsilove Date: Sat, 10 Jan 2026 15:33:36 +0900 Subject: [PATCH 20/34] =?UTF-8?q?fo:=20dashboard=20=EA=B0=95=EC=9A=B0?= =?UTF-8?q?=EC=9D=BC=EC=9A=B4=EC=98=81=ED=98=84=ED=99=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/components/common/CalcRainEffect.tsx | 71 +++-- .../pages/(with-layout)/dashboard/page.tsx | 9 +- .../dashboard/rainManage/page.tsx | 30 +- .../(with-layout)/flowRate/modal/page.tsx | 127 ++++---- apps/fo/app/store/dashboard/index.tsx | 130 +++++--- apps/fo/app/store/flowRate/index.tsx | 281 +++++++++--------- 6 files changed, 354 insertions(+), 294 deletions(-) diff --git a/apps/fo/app/components/common/CalcRainEffect.tsx b/apps/fo/app/components/common/CalcRainEffect.tsx index a85f35443..3ea198016 100644 --- a/apps/fo/app/components/common/CalcRainEffect.tsx +++ b/apps/fo/app/components/common/CalcRainEffect.tsx @@ -9,15 +9,16 @@ * @author jsyang */ -export default function CalcRainEffect(data : any, weather='ALL') { - const rtnDataAll : any = []; - const rtnDataSunny : any = []; - const rtnDataRain : any = []; - let rtnData : any = []; - let rainEffectStd = 0; - data.forEach(item => { +export default function CalcRainEffect(data: any, weather = 'ALL') { + const rtnDataAll: any = []; + const rtnDataSunny: any = []; + const rtnDataRain: any = []; + let rtnData: any = []; + let rainEffectStd = 0; + for (let idx = 0; idx < data.length; idx++) { + const item = data[idx]; if (item.infoRnDay == null || item.infoRnDay == 'x' || item.infoRnDay == '') item.infoRnDay = 0; - if(Number(item.infoRnDay) >= 3) { // 강우일 + if (Number(item.infoRnDay) >= 3) { // 강우일 rainEffectStd = 2; item.toBeInfoRnDay = item.infoRnDay; } else { @@ -29,14 +30,26 @@ export default function CalcRainEffect(data : any, weather='ALL') { rtnDataSunny.push(item); } else if (rainEffectStd >= 0) { // 강우일 + 강우영향일 item.rainEffectDay = 1; + if (idx > 1) { + // 전날 비가 왔고 오늘 강우량 3미만인 경우 전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전날 강우량으로 설정 + if (data[idx - 1]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx - 1]?.infoRnDay.toString().trim()) >= 3) { + data[idx]!.toBeInfoRnDay = data[idx - 1]!.infoRnDay; + } + } + if (idx > 2) { + // 전전날 비가 왔고 오늘 강우량 3미만인 경우 전전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전전날 강우량으로 설정 + if (data[idx - 2]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx - 2]?.infoRnDay.toString().trim()) >= 3) { + data[idx]!.toBeInfoRnDay = data[idx - 2]!.infoRnDay; + } + } rtnDataRain.push(item); } - - rtnDataAll.push(item); - }); - - // // 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일) + rtnDataAll.push(item); + } + + + // // 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일) // for(let idx = 0; idx < data.length; idx++) { // const item = data[idx]; // if(item){ @@ -70,22 +83,22 @@ export default function CalcRainEffect(data : any, weather='ALL') { // } // } - for(let idx = 0; idx < data.length; idx++) { - if(data[idx] && data[idx]?.rainEffectDay === 1) { - if(idx > 1){ - // 전날 비가 왔고 오늘 강우량 3미만인 경우 전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전날 강우량으로 설정 - if(data[idx-1]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx-1]?.infoRnDay.toString().trim()) >= 3) { - data[idx]!.toBeInfoRnDay = data[idx-1]!.infoRnDay; - } - } - if(idx > 2){ - // 전전날 비가 왔고 오늘 강우량 3미만인 경우 전전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전전날 강우량으로 설정 - if(data[idx-2]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx-2]?.infoRnDay.toString().trim()) >= 3) { - data[idx]!.toBeInfoRnDay = data[idx-2]!.infoRnDay; - } - } - } - } + // for(let idx = 0; idx < data.length; idx++) { + // if(data[idx] && data[idx]?.rainEffectDay === 1) { + // if(idx > 1){ + // // 전날 비가 왔고 오늘 강우량 3미만인 경우 전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전날 강우량으로 설정 + // if(data[idx-1]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx-1]?.infoRnDay.toString().trim()) >= 3) { + // data[idx]!.toBeInfoRnDay = data[idx-1]!.infoRnDay; + // } + // } + // if(idx > 2){ + // // 전전날 비가 왔고 오늘 강우량 3미만인 경우 전전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전전날 강우량으로 설정 + // if(data[idx-2]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx-2]?.infoRnDay.toString().trim()) >= 3) { + // data[idx]!.toBeInfoRnDay = data[idx-2]!.infoRnDay; + // } + // } + // } + // } // if (weather === 'ALL') { // rtnData = data; diff --git a/apps/fo/app/pages/(with-layout)/dashboard/page.tsx b/apps/fo/app/pages/(with-layout)/dashboard/page.tsx index b94fc21c1..6ab18b825 100644 --- a/apps/fo/app/pages/(with-layout)/dashboard/page.tsx +++ b/apps/fo/app/pages/(with-layout)/dashboard/page.tsx @@ -6,7 +6,10 @@ "use client" import { useFoStore } from "@/app/store"; -import { ContentsDiv, downloadExcel, downloadMultipleExcel, filePickedBlobArray, MainDiv, SelectBox, UITab, type SelectDataType } from "@common/business_components"; +import { + ContentsDiv, downloadExcel, downloadMultipleExcel, filePickedBlobArray, MainDiv + , SelectBox, UITab, type SelectDataType +} from "@common/business_components"; import { Button, TabsContent } from "@common/components/ui"; import { useEffect, useState } from "react"; import DashBoardFclty from "../dashboardMain/page"; @@ -50,9 +53,9 @@ type FacilityType = { export default function DashBoard() { // 입력값 상태 관리 - const { Common, initializeCommonData, searchMainGraph, searchRainManage, searchOperationStatus, OperationStatus, RainManage, MainGraph, PlanFclty } = useFoStore((state) => state); + const { Common, initializeCommonData, searchMainGraph, searchRainManage, searchOperationStatus + , OperationStatus, RainManage, MainGraph, PlanFclty } = useFoStore((state) => state); const [activeTab, setActiveTab] = useState('facilityInfo'); - const [filteredSigunData, setFilteredSigunData] = useState([{ text: "전체", val: '0' }]); const [sidoValue, setSidoValue] = useState('0'); const [sigunValue, setSigunValue] = useState('0'); diff --git a/apps/fo/app/pages/(with-layout)/dashboard/rainManage/page.tsx b/apps/fo/app/pages/(with-layout)/dashboard/rainManage/page.tsx index e084bf04d..55e6275c8 100644 --- a/apps/fo/app/pages/(with-layout)/dashboard/rainManage/page.tsx +++ b/apps/fo/app/pages/(with-layout)/dashboard/rainManage/page.tsx @@ -15,27 +15,13 @@ export type facilityInfoProps = { fcltyList?: { bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string, efflWqltStndrdNm: string }[]; }; -export default function RainManageTab({searchYear = '', fcltyList = []}: facilityInfoProps) { - - const { - Common, - searchRainManage, - RainManage - } = useFoStore((state) => state); +export default function RainManageTab({ searchYear = '', fcltyList = [] }: facilityInfoProps) { + const { Common, searchRainManage, RainManage } = useFoStore((state) => state); const [hasSearched, setHasSearched] = useState(false); - // 이전 시설코드 저장 - const [prevFacilityCode, setPrevFacilityCode] = useState(''); - - const { - isInit, - } = Common; - - const { - upHeadListRainManage, - rainManageList, - } = RainManage; - + const [prevFacilityCode, setPrevFacilityCode] = useState(''); // 이전 시설코드 저장 + const { isInit, } = Common; + const { upHeadListRainManage, rainManageList, } = RainManage; const tableData = fcltyList; useEffect(() => { @@ -50,17 +36,17 @@ export default function RainManageTab({searchYear = '', fcltyList = []}: facilit useEffect(() => { setHasSearched(false); }, [searchYear]); - + return (
- {}} + onPageChange={() => { }} widthFixed={true} > diff --git a/apps/fo/app/pages/(with-layout)/flowRate/modal/page.tsx b/apps/fo/app/pages/(with-layout)/flowRate/modal/page.tsx index 42512f802..822b52979 100644 --- a/apps/fo/app/pages/(with-layout)/flowRate/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/flowRate/modal/page.tsx @@ -34,11 +34,8 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st const [copyYearList, setCopyYearList] = useState([]); const [isLoading, setIsLoading] = useState(true); const prevExcelListRef = useRef(null); - const { - modalFlowRateListYear, - upHeadListFlowRateModalYear, - } = FlowRateModal; - + const { modalFlowRateListYear, upHeadListFlowRateModalYear, } = FlowRateModal; + const ref = useRef>({ startDate: new Date(), endDate: new Date(), @@ -52,11 +49,11 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st const filteredData = setFilterAfterData(returnType.filteredList as FlowRateModalInterface[]); setCopyYearList(filteredData); }, []); - + // 필터링 된 후 최대, 최소, 평균 값 계산 const setFilterAfterData = (filteredData: FlowRateModalInterface[]) => { if (!filteredData || filteredData.length === 0) return []; - + // 쉼표가 포함된 문자열을 숫자로 변환하는 함수 const parseNumber = (value: string | number | null | undefined): number => { if (value === null || value === undefined || value === '') return 0; @@ -89,7 +86,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st let avginfoRnDay = 0; let avgNoProcessInflAmnt = 0; let noProcessInflAmntCnt = 0; - + filteredData.forEach((item: FlowRateModalInterface) => { const totInflAmnt = parseNumber(item.totInflAmnt); const inflAmnt = parseNumber(item.inflAmnt); @@ -119,24 +116,24 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st avgefflAmnt += efflAmnt; avginfoRnDay += infoRnDay; - if(item.noProcessInflAmnt && item.noProcessInflAmnt.toString().trim() != '' && item.noProcessInflAmnt != undefined){ - const noProcessInflAmnt = Number(item.noProcessInflAmnt.toString().replaceAll(',','')); + if (item.noProcessInflAmnt && item.noProcessInflAmnt.toString().trim() != '' && item.noProcessInflAmnt != undefined) { + const noProcessInflAmnt = Number(item.noProcessInflAmnt.toString().replaceAll(',', '')); avgNoProcessInflAmnt += noProcessInflAmnt; maxNoProcessInflAmnt = Math.max(maxNoProcessInflAmnt, noProcessInflAmnt); minNoProcessInflAmnt = Math.min(minNoProcessInflAmnt, noProcessInflAmnt); - noProcessInflAmntCnt +=1; + noProcessInflAmntCnt += 1; } }); const newFilteredData = [ { msrDt: '평균', - totInflAmnt: avgtotInflAmnt && avgtotInflAmnt!=0 ? roundUp((avgtotInflAmnt / filteredData.length), 0) : 0, - inflAmnt: avginflAmnt && avginflAmnt!=0 ? roundUp((avginflAmnt / filteredData.length), 0) : 0, - sumFlow: avgsumFlow && avgsumFlow!=0 ? roundUp((avgsumFlow / filteredData.length), 0) : 0, - returnAmnt: avgreturnAmnt && avgreturnAmnt!=0 ? roundUp((avgreturnAmnt / filteredData.length), 0) : 0, - efflAmnt: avgefflAmnt && avgefflAmnt!=0 ? roundUp((avgefflAmnt / filteredData.length), 0) : 0, - noProcessInflAmnt : roundNumber(avgNoProcessInflAmnt / noProcessInflAmntCnt, 0), + totInflAmnt: avgtotInflAmnt && avgtotInflAmnt != 0 ? roundUp((avgtotInflAmnt / filteredData.length), 0) : 0, + inflAmnt: avginflAmnt && avginflAmnt != 0 ? roundUp((avginflAmnt / filteredData.length), 0) : 0, + sumFlow: avgsumFlow && avgsumFlow != 0 ? roundUp((avgsumFlow / filteredData.length), 0) : 0, + returnAmnt: avgreturnAmnt && avgreturnAmnt != 0 ? roundUp((avgreturnAmnt / filteredData.length), 0) : 0, + efflAmnt: avgefflAmnt && avgefflAmnt != 0 ? roundUp((avgefflAmnt / filteredData.length), 0) : 0, + noProcessInflAmnt: roundNumber(avgNoProcessInflAmnt / noProcessInflAmntCnt, 0), infoRnDay: avginfoRnDay > 0 ? roundUp((avginfoRnDay / filteredData.length), 1) : '0.0', rainEffectDay: 0, }, @@ -147,7 +144,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st sumFlow: roundUp(maxsumFlow, 0), returnAmnt: roundUp(maxreturnAmnt, 0), efflAmnt: roundUp(maxefflAmnt, 0), - noProcessInflAmnt : roundNumber(maxNoProcessInflAmnt, 0), + noProcessInflAmnt: roundNumber(maxNoProcessInflAmnt, 0), infoRnDay: maxinfoRnDay > 0 ? roundUp(maxinfoRnDay, 1) : '0.0', rainEffectDay: 0, }, @@ -158,7 +155,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st sumFlow: roundUp(minsumFlow, 0), returnAmnt: roundUp(minreturnAmnt, 0), efflAmnt: roundUp(minefflAmnt, 0), - noProcessInflAmnt : roundNumber(minNoProcessInflAmnt, 0), + noProcessInflAmnt: roundNumber(minNoProcessInflAmnt, 0), infoRnDay: mininfoRnDay > 0 ? roundUp(mininfoRnDay, 1) : '0.0', rainEffectDay: 0, }, @@ -185,7 +182,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st const excelDownload = () => { const excelDownList: modalExcelType[] = []; - if(copyYearList.length > 0){ + if (copyYearList.length > 0) { copyYearList.forEach((item) => { excelDownList.push({ "날짜": item.msrDt, @@ -200,7 +197,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st }); } if (excelDownList && excelDownList.length > 0) { - downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 유량현황', sheetNameArray: [props.fcltyName + ' 유량현황'], headerRange: 'A1:H1' }); + downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear + '년 ' + props.fcltyName + ' 유량현황', sheetNameArray: [props.fcltyName + ' 유량현황'], headerRange: 'A1:H1' }); } else if (prevExcelListRef.current && prevExcelListRef.current.length > 0) { alert('다운받을 데이터가 없습니다.'); } @@ -210,7 +207,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st return ( <> - @@ -224,16 +221,16 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st queryClick={filterData} />
- {}} - className="h-[370px]" - boldArray={[0,1,2]} + { }} + className="h-[370px]" + boldArray={[0, 1, 2]} />
@@ -251,16 +248,16 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st queryClick={filterData} />
- {}} - className="h-[370px]" - boldArray={[0,1,2]} + { }} + className="h-[370px]" + boldArray={[0, 1, 2]} />
@@ -278,23 +275,23 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st queryClick={filterData} />
- {}} - className="h-[370px]" - boldArray={[0,1,2]} + { }} + className="h-[370px]" + boldArray={[0, 1, 2]} />
- + searchList={modalFlowRateListYear} fcltyCd={props.facilityCd} @@ -305,16 +302,16 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st queryClick={filterData} />
- {}} - className="h-[370px]" - boldArray={[0,1,2]} + { }} + className="h-[370px]" + boldArray={[0, 1, 2]} />
@@ -332,10 +329,10 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st queryClick={filterData} />
- {}} className="h-[370px]" boldArray={[0,1,2]}/> + { }} className="h-[370px]" boldArray={[0, 1, 2]} />
- +
diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index 572912a53..8f3b4dd8a 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -1142,6 +1142,9 @@ export type DashBoardType = { mainGraphData: any; mainGraphYear: string; mainGraphFcltyCd: string; + flowRateData: any; + flowRateYear: string; + flowRateFcltyCd: string; }, DrainageEquipment: { @@ -1208,6 +1211,9 @@ export const dashBoardInitState: DashBoardType = { mainGraphData: null, mainGraphYear: '', mainGraphFcltyCd: '', + flowRateData: null, + flowRateYear: '', + flowRateFcltyCd: '', }, DrainageEquipment: { @@ -1515,7 +1521,24 @@ export const dashBoardReducer = ( // 연계처리수,지하수유입량 const bscFctCd = fcltyCd; - const res2 = await fetchFlowRateModalList(bscFctCd, searchYear); // /fclt/flow/ - 일별 유량 조회 + let res2: any = { data: [] }; + + // 이미 조회된 데이터가 있는지 확인 (연도와 시설코드가 같을 때만) + if (state.RainManage.flowRateYear === searchYear && state.RainManage.flowRateFcltyCd === fcltyCd && state.RainManage.flowRateData) { + res2 = state.RainManage.flowRateData; + } else { + res2 = await fetchFlowRateModalList(bscFctCd, searchYear); // /fclt/flow/ - 일별 유량 조회 + // 조회된 데이터 저장 + set((state: DashBoardType) => ({ + ...state, + RainManage: { + ...state.RainManage, + flowRateData: res2, + flowRateYear: searchYear, + flowRateFcltyCd: fcltyCd, + } + })); + } //const calData = CalcRainEffect(clone(res2.data), 'SUNNY'); //const calRainData = CalcRainEffect(clone(res2.data), 'RAIN'); @@ -1967,6 +1990,24 @@ export const dashBoardReducer = ( })); } + let res2: any = { data: [] }; + // 이미 조회된 데이터가 있는지 확인 (연도와 시설코드가 같을 때만) + if (state.RainManage.flowRateYear === searchYear && state.RainManage.flowRateFcltyCd === fcltyCd && state.RainManage.flowRateData) { + res2 = state.RainManage.flowRateData; + } else { + res2 = await fetchFlowRateModalList(fcltyCd, searchYear); // /fclt/flow/ - 일별 유량 조회 + // 조회된 데이터 저장 + set((state: DashBoardType) => ({ + ...state, + RainManage: { + ...state.RainManage, + flowRateData: res2, + flowRateYear: searchYear, + flowRateFcltyCd: fcltyCd, + } + })); + } + set((state: DashBoardType) => ({ ...state, RainManage: { @@ -1990,10 +2031,9 @@ export const dashBoardReducer = ( const itemList = ['계', '3~10mm 미만', '10~20mm 미만', '20~30mm 미만', '30~40mm 미만', '40~50mm 미만', '50~60mm 미만', '60mm 이상']; const rainRate = ['0', '0', '0', '0', '0', '0', '0', '0']; - const rainDate = [0, 0, 0, 0, 0, 0, 0, 0]; - const inflAmtCnt = [0, 0, 0, 0, 0, 0, 0, 0]; + const rainDate: number[] = [0, 0, 0, 0, 0, 0, 0, 0]; const inflAmnt: number[] = [0, 0, 0, 0, 0, 0, 0, 0]; - const fcltyCpct = [0, 0, 0, 0, 0, 0, 0, 0]; + const fcltyCpct: number[] = [0, 0, 0, 0, 0, 0, 0, 0]; const dsInflWqltBod: number[] = [0, 0, 0, 0, 0, 0, 0, 0]; const dsInflWqltCod: number[] = [0, 0, 0, 0, 0, 0, 0, 0]; const dsInflWqltSs: number[] = [0, 0, 0, 0, 0, 0, 0, 0]; @@ -2054,9 +2094,8 @@ export const dashBoardReducer = ( const toBeRain = item.toBeInfoRnDay ? Number(item.toBeInfoRnDay) : 0; if (toBeRain >= 3 && toBeRain < 10) { - rainDate[1] = Number(rainDate[1] || 0) + 1; - inflAmtCnt[1] = Number(inflAmtCnt[1] || 0) + 1; - inflAmnt[1] = Number(inflAmnt[1] || 0) + Number(item.inflAmnt || 0); + rainDate[1] = (rainDate[1] || 0) + 1; + inflAmnt[1] = (inflAmnt[1] || 0) + Number(item.inflAmnt || 0); fcltyCpct[1] = 0; inflAssctBfrWqltBodCnt[1] = Number(inflAssctBfrWqltBodCnt[1] || 0) + 1; inflAssctBfrWqltBod[1] = Number(inflAssctBfrWqltBod[1] || 0) + Number(item.inflAssctBfrWqltBod || 0); @@ -2079,9 +2118,8 @@ export const dashBoardReducer = ( efflWqltTpCnt[1] = Number(efflWqltTpCnt[1] || 0) + 1; efflWqltTp[1] = Number(efflWqltTp[1] || 0) + Number(item.efflWqltTp || 0); } else if (toBeRain >= 10 && toBeRain < 20) { - rainDate[2] = Number(rainDate[2] || 0) + 1; - inflAmtCnt[2] = Number(inflAmtCnt[2] || 0) + 1; - inflAmnt[2] = Number(inflAmnt[2] || 0) + Number(item.inflAmnt || 0); + rainDate[2] = (rainDate[2] || 0) + 1; + inflAmnt[2] = (inflAmnt[2] || 0) + Number(item.inflAmnt || 0); fcltyCpct[2] = 0; inflAssctBfrWqltBodCnt[2] = Number(inflAssctBfrWqltBodCnt[2] || 0) + 1; inflAssctBfrWqltBod[2] = Number(inflAssctBfrWqltBod[2] || 0) + Number(item.inflAssctBfrWqltBod || 0); @@ -2104,9 +2142,8 @@ export const dashBoardReducer = ( efflWqltTpCnt[2] = Number(efflWqltTpCnt[2] || 0) + 1; efflWqltTp[2] = Number(efflWqltTp[2] || 0) + Number(item.efflWqltTp || 0); } else if (toBeRain >= 20 && toBeRain < 30) { - rainDate[3] = Number(rainDate[3] || 0) + 1; - inflAmtCnt[3] = Number(inflAmtCnt[3] || 0) + 1; - inflAmnt[3] = Number(inflAmnt[3] || 0) + Number(item.inflAmnt || 0); + rainDate[3] = (rainDate[3] || 0) + 1; + inflAmnt[3] = (inflAmnt[3] || 0) + Number(item.inflAmnt || 0); fcltyCpct[3] = 0; inflAssctBfrWqltBodCnt[3] = Number(inflAssctBfrWqltBodCnt[3] || 0) + 1; inflAssctBfrWqltBod[3] = Number(inflAssctBfrWqltBod[3] || 0) + Number(item.inflAssctBfrWqltBod || 0); @@ -2129,9 +2166,8 @@ export const dashBoardReducer = ( efflWqltTpCnt[3] = Number(efflWqltTpCnt[3] || 0) + 1; efflWqltTp[3] = Number(efflWqltTp[3] || 0) + Number(item.efflWqltTp || 0); } else if (toBeRain >= 30 && toBeRain < 40) { - rainDate[4] = Number(rainDate[4] || 0) + 1; - inflAmtCnt[4] = Number(inflAmtCnt[4] || 0) + 1; - inflAmnt[4] = Number(inflAmnt[4] || 0) + Number(item.inflAmnt || 0); + rainDate[4] = (rainDate[4] || 0) + 1; + inflAmnt[4] = (inflAmnt[4] || 0) + Number(item.inflAmnt || 0); fcltyCpct[4] = item.inflAmnt && Number(item.inflAmnt) !== 0 ? Number(Math.round(Number(item.inflAmnt) / Number(item.fctCpc) * 10) / 10) : 0; inflAssctBfrWqltBodCnt[4] = Number(inflAssctBfrWqltBodCnt[4] || 0) + 1; inflAssctBfrWqltBod[4] = Number(inflAssctBfrWqltBod[4] || 0) + Number(item.inflAssctBfrWqltBod || 0); @@ -2154,9 +2190,8 @@ export const dashBoardReducer = ( efflWqltTpCnt[4] = Number(efflWqltTpCnt[4] || 0) + 1; efflWqltTp[4] = Number(efflWqltTp[4] || 0) + Number(item.efflWqltTp || 0); } else if (toBeRain >= 40 && toBeRain < 50) { - rainDate[5] = Number(rainDate[5] || 0) + 1; - inflAmtCnt[5] = Number(inflAmtCnt[5] || 0) + 1; - inflAmnt[5] = Number(inflAmnt[5] || 0) + Number(item.inflAmnt || 0); + rainDate[5] = (rainDate[5] || 0) + 1; + inflAmnt[5] = (inflAmnt[5] || 0) + Number(item.inflAmnt || 0); fcltyCpct[5] = 0; inflAssctBfrWqltBodCnt[5] = Number(inflAssctBfrWqltBodCnt[5] || 0) + 1; inflAssctBfrWqltBod[5] = Number(inflAssctBfrWqltBod[5] || 0) + Number(item.inflAssctBfrWqltBod || 0); @@ -2179,9 +2214,8 @@ export const dashBoardReducer = ( efflWqltTpCnt[5] = Number(efflWqltTpCnt[5] || 0) + 1; efflWqltTp[5] = Number(efflWqltTp[5] || 0) + Number(item.efflWqltTp || 0); } else if (toBeRain >= 50 && toBeRain < 60) { - rainDate[6] = Number(rainDate[6] || 0) + 1; - inflAmtCnt[6] = Number(inflAmtCnt[6] || 0) + 1; - inflAmnt[6] = Number(inflAmnt[6] || 0) + Number(item.inflAmnt || 0); + rainDate[6] = (rainDate[6] || 0) + 1; + inflAmnt[6] = (inflAmnt[6] || 0) + Number(item.inflAmnt || 0); fcltyCpct[6] = 0; inflAssctBfrWqltBodCnt[6] = Number(inflAssctBfrWqltBodCnt[6] || 0) + 1; inflAssctBfrWqltBod[6] = Number(inflAssctBfrWqltBod[6] || 0) + Number(item.inflAssctBfrWqltBod || 0); @@ -2204,9 +2238,8 @@ export const dashBoardReducer = ( efflWqltTpCnt[6] = Number(efflWqltTpCnt[6] || 0) + 1; efflWqltTp[6] = Number(efflWqltTp[6] || 0) + Number(item.efflWqltTp || 0); } else if (toBeRain >= 60) { - rainDate[7] = Number(rainDate[7] || 0) + 1; - inflAmtCnt[7] = Number(inflAmtCnt[7] || 0) + 1; - inflAmnt[7] = Number(inflAmnt[7] || 0) + Number(item.inflAmnt || 0); + rainDate[7] = (rainDate[7] || 0) + 1; + inflAmnt[7] = (inflAmnt[7] || 0) + Number(item.inflAmnt || 0); fcltyCpct[7] = 0; inflAssctBfrWqltBodCnt[7] = Number(inflAssctBfrWqltBodCnt[7] || 0) + 1; inflAssctBfrWqltBod[7] = Number(inflAssctBfrWqltBod[7] || 0) + Number(item.inflAssctBfrWqltBod || 0); @@ -2231,6 +2264,40 @@ export const dashBoardReducer = ( } }); + // 유량 = 순수하수 + 연계처리수 + 총인설비반류수 + const rainEffFlowList: any[] = CalcRainEffect(res2.data, 'RAIN_DAY'); + totInflAmnt = 0; inflAmnt.fill(0); rainDate.fill(0); + rainEffFlowList.forEach((item: any) => { // --일별 유량 start + const toBeRain = item.toBeInfoRnDay ? Number(item.toBeInfoRnDay) : 0; + const inflAmntOne = item.inflAmnt && item.inflAmnt !== 'x' ? Number(item.inflAmnt.toString().trim()) : 0; + const sumFlowOne = item.sumFlow && item.sumFlow !== 'x' ? Number(item.sumFlow.toString().trim()) : 0; + const returnAmntOne = item.returnAmnt && item.returnAmnt !== 'x' ? Number(item.returnAmnt.toString().trim()) : 0; + const inflowOne = inflAmntOne + sumFlowOne + returnAmntOne; + totInflAmnt = totInflAmnt + inflowOne; // 유량합계 + if (toBeRain >= 3 && toBeRain < 10) { + inflAmnt[1] = (inflAmnt[1] || 0) + inflowOne; + rainDate[1] = (rainDate[1] || 0) + 1; + } else if (toBeRain >= 10 && toBeRain < 20) { + inflAmnt[2] = (inflAmnt[2] || 0) + inflowOne; + rainDate[2] = (rainDate[2] || 0) + 1; + } else if (toBeRain >= 20 && toBeRain < 30) { + inflAmnt[3] = (inflAmnt[3] || 0) + inflowOne; + rainDate[3] = (rainDate[3] || 0) + 1; + } else if (toBeRain >= 30 && toBeRain < 40) { + inflAmnt[4] = (inflAmnt[4] || 0) + inflowOne; + rainDate[4] = (rainDate[4] || 0) + 1; + } else if (toBeRain >= 40 && toBeRain < 50) { + inflAmnt[5] = (inflAmnt[5] || 0) + inflowOne; + rainDate[5] = (rainDate[5] || 0) + 1; + } else if (toBeRain >= 50 && toBeRain < 60) { + inflAmnt[6] = (inflAmnt[6] || 0) + inflowOne; + rainDate[6] = (rainDate[6] || 0) + 1; + } else if (toBeRain >= 60) { + inflAmnt[7] = (inflAmnt[7] || 0) + inflowOne; + rainDate[7] = (rainDate[7] || 0) + 1; + } + }); // --일별 유량 end + // Process the data and create rain management list if (res.data && res.data.dsWqltObjs && res.data.dsWqltObjs.length > 0) { // 설계 유입수질 데이터 가져오기 - 0값이 있으면 이전 차수에서 가져오기 @@ -2289,16 +2356,8 @@ export const dashBoardReducer = ( return count > 0 ? Number((value / count)) : 0; }; - // // 데이터 있는 항목만 계산 - // let dataIsCount = 0; - // for (let idx = 0; idx < inflAmnt.length; idx++) { - // if (Number(inflAmnt[idx]) > 0) { - // dataIsCount++; - // } - // } - for (let idx = 1; idx < inflAmnt.length; idx++) { - inflAmnt[idx] = calculateAverage(Number(inflAmnt[idx]), Number(inflAmtCnt[idx])); + inflAmnt[idx] = rainDate[idx] ? Math.round((inflAmnt[idx] || 0) / (rainDate[idx] || 0)) : 0; inflAssctBfrWqltBod[idx] = calculateAverage(Number(inflAssctBfrWqltBod[idx]), Number(inflAssctBfrWqltBodCnt[idx])); inflAssctBfrWqltToc[idx] = calculateAverage(Number(inflAssctBfrWqltToc[idx]), Number(inflAssctBfrWqltTocCnt[idx])); inflAssctBfrWqltSs[idx] = calculateAverage(Number(inflAssctBfrWqltSs[idx]), Number(inflAssctBfrWqltSsCnt[idx])); @@ -2316,8 +2375,9 @@ export const dashBoardReducer = ( return Number((arr.slice(1).reduce((sum, val) => sum + Number(val), 0))); }; + // console.log(totInflAmnt); - inflAmnt[0] = calculateAverage(totInflAmnt, totItemCnt); + inflAmnt[0] = Math.round((totInflAmnt / totItemCnt)); // calculateAverage(totInflAmnt, totItemCnt); fcltyCpct[0] = calculateTotal(fcltyCpct); inflAssctBfrWqltBod[0] = Number((Math.round((totInflAssctBfrWqltBod / totItemCnt) * 10) / 10).toFixed(1)); inflAssctBfrWqltToc[0] = Number((Math.round((totInflAssctBfrWqltToc / totItemCnt) * 10) / 10).toFixed(1)); diff --git a/apps/fo/app/store/flowRate/index.tsx b/apps/fo/app/store/flowRate/index.tsx index 94d4b9326..432bc5ba5 100644 --- a/apps/fo/app/store/flowRate/index.tsx +++ b/apps/fo/app/store/flowRate/index.tsx @@ -1,6 +1,6 @@ import { getFetch } from "@/app/components/api"; import type { TableUpperProps } from "../dashboard"; -import DataForm, { roundNumber } from "@/app/components/common/DataForm"; +import DataForm from "@/app/components/common/DataForm"; import CalcRainEffect from "@/app/components/common/CalcRainEffect"; import { fetchFacilityWaterQltyListHist } from "../facilityWaterQlty"; import CommaToNumber from "@/app/components/common/CommaToNumber"; @@ -12,34 +12,34 @@ import CommaToNumber from "@/app/components/common/CommaToNumber"; /** * (1) 메인페이지 */ -const FlowRateSearchLabelArray:string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별']; +const FlowRateSearchLabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별']; export type flowRateListProps = { - bscFctCd : string, - sido : string, - gugun : string, - bscFctNm : string, - daddr : string, - fctCpc : number, - lclgvrnmntNm : string, - totInflAmnt : number | '', - inflAmnt : number | '', - sumFlow : number | '', - returnAmnt : number | '', - efflAmnt : number | '', - rgnNm : string, - rvbsn : string, - lgbsn : string, - mdmbsn : string, - infoRnDay : number | '', + bscFctCd: string, + sido: string, + gugun: string, + bscFctNm: string, + daddr: string, + fctCpc: number, + lclgvrnmntNm: string, + totInflAmnt: number | '', + inflAmnt: number | '', + sumFlow: number | '', + returnAmnt: number | '', + efflAmnt: number | '', + rgnNm: string, + rvbsn: string, + lgbsn: string, + mdmbsn: string, + infoRnDay: number | '', } export interface ExcelType { 시설코드: string, - 권역:string|'', - 단위유역:string|'', - 중권역:string|'', - 환경청:string|'', + 권역: string | '', + 단위유역: string | '', + 중권역: string | '', + 환경청: string | '', 시도: string, 시군구: string, 시설이름: string, @@ -66,105 +66,105 @@ export type modalExcelType = { * (2) 모달 */ export interface FlowRateModalInterface { - msrDt : string, - totInflAmnt : number | '', - inflAmnt : number | '', - sumFlow : number | '', - returnAmnt : number | '', - efflAmnt : number | '', - infoRnDay : number | string | '', - rainEffectDay : number | string | '' , - noProcessInflAmnt : number | string | '' + msrDt: string, + totInflAmnt: number | '', + inflAmnt: number | '', + sumFlow: number | '', + returnAmnt: number | '', + efflAmnt: number | '', + infoRnDay: number | string | '', + rainEffectDay: number | string | '', + noProcessInflAmnt: number | string | '' } export type FlowRateModalProps = { - msrDt : string, - totInflAmnt : number, - inflAmnt : number, - sumFlow : number, - returnAmnt : number, - efflAmnt : number, - infoRnDay : number | string | '', - rainEffectDay : number | string | '', - noProcessInflAmnt : number | string | '' + msrDt: string, + totInflAmnt: number, + inflAmnt: number, + sumFlow: number, + returnAmnt: number, + efflAmnt: number, + infoRnDay: number | string | '', + rainEffectDay: number | string | '', + noProcessInflAmnt: number | string | '' } /**==================================== * Store - data ====================================*/ - /** - * (1) 메인페이지 - */ +/** +* (1) 메인페이지 +*/ // 리스트 (행정별) -const upHeadList1:TableUpperProps[] = [ +const upHeadList1: TableUpperProps[] = [ { id: "A", title: "행정명", row: 0, colSpan: 2, widthPercent: 16 }, - { id: "sido", title: "시도", upName:"upChangeRe", row:1, widthPercent: 8 }, - { id: "gugun", title: "시군구", upName:"upChangeRe", row:1, widthPercent: 8 }, - { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10}, + { id: "sido", title: "시도", upName: "upChangeRe", row: 1, widthPercent: 8 }, + { id: "gugun", title: "시군구", upName: "upChangeRe", row: 1, widthPercent: 8 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 }, { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, - { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "totInflAmnt", title: "총 유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "inflAmnt", title: "하수유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "sumFlow", title: '연계처리량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "efflAmnt", title: '방류량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 } + { id: "fctCpc", title: "시설용량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "totInflAmnt", title: "총 유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "inflAmnt", title: "하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "sumFlow", title: '연계처리량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "efflAmnt", title: '방류량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 } ]; // 리스트 (권역별) -const upHeadList2:TableUpperProps[] = [ +const upHeadList2: TableUpperProps[] = [ { id: "A", title: "유역", row: 0, colSpan: 3, widthPercent: 24 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe", row:1, widthPercent: 8 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe", row:1, widthPercent: 8 }, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe", row:1, widthPercent: 8 }, + { id: "rvbsn", title: "권역", upName: "upChangeRe", row: 1, widthPercent: 8 }, + { id: "lgbsn", title: "단위유역", upName: "upChangeRe", row: 1, widthPercent: 8 }, + { id: "mdmbsn", title: "중권역", upName: "upChangeRe", row: 1, widthPercent: 8 }, { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 }, { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, - { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 10 }, - { id: "totInflAmnt", title: "총 유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "inflAmnt", title: "하수유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "sumFlow", title: '연계처리량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "efflAmnt", title: '방류량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 } + { id: "fctCpc", title: "시설용량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "totInflAmnt", title: "총 유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "inflAmnt", title: "하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "sumFlow", title: '연계처리량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "efflAmnt", title: '방류량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 } ]; // 리스트 (환경청별별) -const upHeadList3:TableUpperProps[] = [ +const upHeadList3: TableUpperProps[] = [ { id: "A", title: "유역", row: 0, colSpan: 3, widthPercent: 15 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe1", row:1, widthPercent: 5 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", row:1, widthPercent: 5 }, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", row:1, widthPercent: 5 }, - { id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 7 }, - { id: "B", title: "행정명", row: 0 ,colSpan: 2, widthPercent: 10 }, - { id: "sido", title: "시도", upName:"upChangeRe2", row:1, widthPercent: 5 }, - { id: "gugun", title: "시군구", upName:"upChangeRe2", row:1, widthPercent: 5 }, + { id: "rvbsn", title: "권역", upName: "upChangeRe1", row: 1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", upName: "upChangeRe1", row: 1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", upName: "upChangeRe1", row: 1, widthPercent: 5 }, + { id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "B", title: "행정명", row: 0, colSpan: 2, widthPercent: 10 }, + { id: "sido", title: "시도", upName: "upChangeRe2", row: 1, widthPercent: 5 }, + { id: "gugun", title: "시군구", upName: "upChangeRe2", row: 1, widthPercent: 5 }, { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 7 }, { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, - { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "totInflAmnt", title: "총 유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "inflAmnt", title: "하수유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "sumFlow", title: '연계처리량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, - { id: "efflAmnt", title: '방류량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 } + { id: "fctCpc", title: "시설용량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "totInflAmnt", title: "총 유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "inflAmnt", title: "하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "sumFlow", title: '연계처리량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "efflAmnt", title: '방류량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 } ]; -const flowRateList:flowRateListProps[] = [ +const flowRateList: flowRateListProps[] = [ ] /** * (2) 모달 */ -const upHeadListFlowRateModal:TableUpperProps[] = [ - { id: "msrDt", title: "날짜"}, - { id: "totInflAmnt", title: "총 유입량(m³/일)", align:"right"}, - { id: "inflAmnt", title: "하수유입량(m³/일)", align:"right"}, - { id: "sumFlow", title: "연계처리량(m³/일)", align:"right"}, - { id: "returnAmnt", title: "총인 반류수량(m³/일)", align:"right"}, - { id: "efflAmnt", title: "방류량(m³/일)", align:"right"}, - { id: "noProcessInflAmnt", title: "미처리하수 추정량(m³/일)", align:"right"}, - { id: "infoRnDay", title: "강우량(mm/일)", align:"right"} +const upHeadListFlowRateModal: TableUpperProps[] = [ + { id: "msrDt", title: "날짜" }, + { id: "totInflAmnt", title: "총 유입량(m³/일)", align: "right" }, + { id: "inflAmnt", title: "하수유입량(m³/일)", align: "right" }, + { id: "sumFlow", title: "연계처리량(m³/일)", align: "right" }, + { id: "returnAmnt", title: "총인 반류수량(m³/일)", align: "right" }, + { id: "efflAmnt", title: "방류량(m³/일)", align: "right" }, + { id: "noProcessInflAmnt", title: "미처리하수 추정량(m³/일)", align: "right" }, + { id: "infoRnDay", title: "강우량(mm/일)", align: "right" } ] -const modalFlowRateListYear:FlowRateModalProps[] = [ +const modalFlowRateListYear: FlowRateModalProps[] = [ ] /**==================================== @@ -172,12 +172,13 @@ const modalFlowRateListYear:FlowRateModalProps[] = [ ====================================*/ const fetchFlowRateList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { try { - const tailStr = partCd ? '/'+ partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : ''; + const tailStr = partCd ? '/' + partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : ''; const url = '/fclt/flow/' + pageNo + '/' + pageSize + '/' + searchYear + tailStr; const res = await getFetch('fo', url); return { data: res.data, count: res.count } } catch (error) { console.error('시설정보 유량현황 데이터를 가져오는데 실패했습니다:', error); + console.log(error); return { data: [], count: 0 }; } } @@ -186,12 +187,12 @@ export const fetchFlowRateModalList = async (bscFctCd: string, searchYear: strin try { const url = '/fclt/flow/' + bscFctCd + '/' + searchYear; const res = await getFetch('fo', url); - + // msrDt 오름차순으로 정렬 const sortedData = res.data.sort((a: FlowRateModalInterface, b: FlowRateModalInterface) => { return new Date(a.msrDt).getTime() - new Date(b.msrDt).getTime(); }); - + return { data: sortedData } } catch (error) { console.error('시설정보 유량현황 모달 데이터를 가져오는데 실패했습니다:', error); @@ -206,69 +207,69 @@ export const fetchFlowRateModalList = async (bscFctCd: string, searchYear: strin export type FlowRateSearchActions = { searchFlowRateList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void; - - searchFlowRateModalList : (bscFctCd: string, searchYear: string) => void; + + searchFlowRateModalList: (bscFctCd: string, searchYear: string) => void; } export type FlowRateSearchType = { FlowRateSearch: { isInit: boolean; - flowRateSearchLabelArray:string[]; + flowRateSearchLabelArray: string[]; }, - FlowRateList : { - isInit : boolean; + FlowRateList: { + isInit: boolean; upHeadList1: TableUpperProps[]; upHeadList2: TableUpperProps[]; upHeadList3: TableUpperProps[]; - flowRateList:flowRateListProps[]; + flowRateList: flowRateListProps[]; flowRateCount: number; excelList: ExcelType[]; isLoading: boolean; }, - FlowRateModal : { - isInit : boolean; - modalFlowRateListYear : FlowRateModalProps[]; - upHeadListFlowRateModalYear : TableUpperProps[]; + FlowRateModal: { + isInit: boolean; + modalFlowRateListYear: FlowRateModalProps[]; + upHeadListFlowRateModalYear: TableUpperProps[]; } } export type FlowRateSearchStore = FlowRateSearchType & FlowRateSearchActions; -const dataFormSetting=(item : flowRateListProps | FlowRateModalProps)=> { +const dataFormSetting = (item: flowRateListProps | FlowRateModalProps) => { DataForm({ type: 'date', column: 'msrDt', item: item as unknown as Record }); - DataForm({ type: 'float0', column: 'totInflAmnt', item: item as unknown as Record}); - DataForm({ type: 'float0', column: 'inflAmnt', item: item as unknown as Record}); - DataForm({ type: 'float0', column: 'sumFlow', item: item as unknown as Record}); - DataForm({ type: 'float0', column: 'efflWqltBod', item: item as unknown as Record}); - DataForm({ type: 'float0', column: 'returnAmnt', item: item as unknown as Record}); - DataForm({ type: 'float0', column: 'efflAmnt', item: item as unknown as Record}); + DataForm({ type: 'float0', column: 'totInflAmnt', item: item as unknown as Record }); + DataForm({ type: 'float0', column: 'inflAmnt', item: item as unknown as Record }); + DataForm({ type: 'float0', column: 'sumFlow', item: item as unknown as Record }); + DataForm({ type: 'float0', column: 'efflWqltBod', item: item as unknown as Record }); + DataForm({ type: 'float0', column: 'returnAmnt', item: item as unknown as Record }); + DataForm({ type: 'float0', column: 'efflAmnt', item: item as unknown as Record }); } -export const flowRateSearchInitState:FlowRateSearchType = { +export const flowRateSearchInitState: FlowRateSearchType = { FlowRateSearch: { isInit: false, flowRateSearchLabelArray: FlowRateSearchLabelArray, }, - FlowRateList : { - isInit : false, - upHeadList1 : upHeadList1, - upHeadList2 : upHeadList2, - upHeadList3 : upHeadList3, - flowRateList : flowRateList, - flowRateCount : 0, + FlowRateList: { + isInit: false, + upHeadList1: upHeadList1, + upHeadList2: upHeadList2, + upHeadList3: upHeadList3, + flowRateList: flowRateList, + flowRateCount: 0, excelList: [], isLoading: true, }, - FlowRateModal : { - isInit : false, - upHeadListFlowRateModalYear : upHeadListFlowRateModal, - modalFlowRateListYear : modalFlowRateListYear, + FlowRateModal: { + isInit: false, + upHeadListFlowRateModalYear: upHeadListFlowRateModal, + modalFlowRateListYear: modalFlowRateListYear, } } -export const flowRateSearchReducer:(set:(fn: (state: FlowRateSearchType) => FlowRateSearchType) => void)=>FlowRateSearchActions=(set: (fn: (state: FlowRateSearchType) => FlowRateSearchType) => void) => { +export const flowRateSearchReducer: (set: (fn: (state: FlowRateSearchType) => FlowRateSearchType) => void) => FlowRateSearchActions = (set: (fn: (state: FlowRateSearchType) => FlowRateSearchType) => void) => { return { searchFlowRateList: async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { set((state: FlowRateSearchType) => ({ @@ -288,7 +289,7 @@ export const flowRateSearchReducer:(set:(fn: (state: FlowRateSearchType) => Flow return item; }); - if(pageSize>5000){ + if (pageSize > 5000) { rtnData.forEach((item: flowRateListProps) => { excelDownList.push({ 시설코드: item.bscFctCd, @@ -312,15 +313,15 @@ export const flowRateSearchReducer:(set:(fn: (state: FlowRateSearchType) => Flow set((state: FlowRateSearchType) => ({ ...state, - FlowRateList: pageSize<5000?{ + FlowRateList: pageSize < 5000 ? { ...state.FlowRateList, flowRateList: rtnData, flowRateCount: res.count, - isLoading : false, - }:{ + isLoading: false, + } : { ...state.FlowRateList, excelList: excelDownList, - isLoading : false, + isLoading: false, }, })) }, @@ -336,37 +337,37 @@ export const flowRateSearchReducer:(set:(fn: (state: FlowRateSearchType) => Flow /강우시 일별유입BOD) */ //let rainInflAmnt = 0; - let sunnyInflAmnt = 0; - let sunnyBod = 0; + let sunnyInflAmnt = 0; // 청천시 일별유입유량 + let sunnyBod = 0; // 청천시 일별유입BOD //let rainDay = 0; let sunnyDay = 0; inflData.forEach(item => { - if(item.rainEffectDay == 1){ + if (item.rainEffectDay == 1) { //rainDay += 1; //rainInflAmnt += Number(item.inflAmnt); } else { - const msrDt = item.msrDt.replaceAll('-',''); + const msrDt = item.msrDt.replaceAll('-', ''); sunnyDay += 1; sunnyInflAmnt += Number(item.inflAmnt); - sunnyBod += Number(wqltData.filter((wqitem)=>wqitem.msrDt === msrDt)[0].inflAssctBfrWqltBod); + sunnyBod += Number(wqltData.filter((wqitem) => wqitem.msrDt === msrDt)[0].inflAssctBfrWqltBod); } }); //const yearRainAmnt = rainInflAmnt===0?0:rainInflAmnt / rainDay; - const yearSunnyAmnt = sunnyInflAmnt===0?0:sunnyInflAmnt / sunnyDay; - const yearSunnyBod = sunnyBod===0?0:sunnyBod / sunnyDay; - + const yearSunnyAmnt = sunnyInflAmnt === 0 ? 0 : sunnyInflAmnt / sunnyDay; // 청천시 연평균유입유량 + const yearSunnyBod = sunnyBod === 0 ? 0 : sunnyBod / sunnyDay; // 청천시 연평균유입BOD + const rtnData = inflData.map((item: FlowRateModalProps) => { - const dayBod = Number(wqltData.filter(wqitem=>wqitem.msrDt === item.msrDt.replaceAll('-',''))[0].inflAssctBfrWqltBod); - const noProcessInflAmnt = roundNumber(((Number(item.inflAmnt) * dayBod) - (yearSunnyAmnt * yearSunnyBod)) / dayBod, 0) - + const dayBod = Number(wqltData.filter(wqitem => wqitem.msrDt === item.msrDt.replaceAll('-', ''))[0].inflAssctBfrWqltBod); + const noProcessInflAmnt = Math.round(((Number(item.inflAmnt) * dayBod) - (yearSunnyAmnt * yearSunnyBod)) / dayBod) + item.totInflAmnt = Number(item.inflAmnt || 0) + Number(item.sumFlow || 0) + Number(item.returnAmnt || 0); - item.noProcessInflAmnt = noProcessInflAmnt && Number(noProcessInflAmnt.replaceAll(',','')) > 0 ? noProcessInflAmnt : ''; + item.noProcessInflAmnt = noProcessInflAmnt && noProcessInflAmnt > 0 ? noProcessInflAmnt : ''; dataFormSetting(item); return item; }); - + set((state: FlowRateSearchType) => ({ ...state, FlowRateModal: { From 94fa8eb7211e4c726944fdd3f11f649eaba0e27c Mon Sep 17 00:00:00 2001 From: dongsilove Date: Sat, 10 Jan 2026 20:43:46 +0900 Subject: [PATCH 21/34] =?UTF-8?q?fo:=20=EC=9C=A0=EB=9F=89=ED=98=84?= =?UTF-8?q?=ED=99=A9=20=20=EA=B0=95=EC=9A=B0=EC=8B=9C=20=ED=8F=89=EA=B7=A0?= =?UTF-8?q?=20=EB=8B=A8=EC=88=98=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/components/common/DataForm.tsx | 42 +++++----- .../common/FacilityTermModalHeader.tsx | 82 +++++++++---------- .../(with-layout)/flowRate/modal/page.tsx | 24 ++++-- apps/fo/app/store/flowRate/index.tsx | 54 ++++++------ 4 files changed, 107 insertions(+), 95 deletions(-) diff --git a/apps/fo/app/components/common/DataForm.tsx b/apps/fo/app/components/common/DataForm.tsx index b58322458..2c99129b2 100644 --- a/apps/fo/app/components/common/DataForm.tsx +++ b/apps/fo/app/components/common/DataForm.tsx @@ -26,7 +26,7 @@ export const getDaysInMonth = (yyyymm: string) => { return new Date(year, month, 0).getDate(); } -export const roundNumber = (value : any, decimals: number) => { +export const roundNumber = (value: any, decimals: number) => { if (typeof value === 'number') { return addCommas((Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals)).toFixed(decimals)); } else if (typeof value === 'string') { @@ -45,48 +45,48 @@ export const addCommas = (value: string | number): any => { index === 0 ? part : part.replace(/(\d{3})/g, '$1,') ).join('.'); } else if (typeof value === 'string') { - return value.includes('.')?value.split('.').map((part, index) => + return value.includes('.') ? value.split('.').map((part, index) => index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part - ).join('.'):String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ","); + ).join('.') : String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ","); } } export default function DataForm({ type, column, item }: DataFormProps) { - if(item) { + if (item) { const value = item[column]; - switch(type){ + switch (type) { case 'date': - if(value && typeof value === 'string' && value.length >= 8) + if (value && typeof value === 'string' && value.length >= 8 && !value.includes('-')) item[column] = value.substring(0, 4) + "-" + value.substring(4, 6) + "-" + value.substring(6, 8); - break; + break; case 'number': - if(value && value != '') { + if (value && value != '') { item[column] = value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); } - break; + break; case 'float0': - if(value) { - item[column] = item[column] = String(value).includes('.')?String(Math.round(parseFloat(value.toString().replace(/,/g, '')) * 1) / 1).split('.').map((part, index) => - index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part - ).join('.') - : String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ","); + if (value) { + item[column] = item[column] = String(value).includes('.') ? String(Math.round(parseFloat(value.toString().replace(/,/g, '')) * 1) / 1).split('.').map((part, index) => + index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part + ).join('.') + : String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ","); } - break; + break; case 'float1': - if(value) { + if (value) { item[column] = roundNumber(value, 1); } - break; + break; case 'float2': - if(value) { + if (value) { item[column] = roundNumber(value, 2); } - break; + break; case 'float3': - if(value) { + if (value) { item[column] = roundNumber(value, 3); } - break; + break; } } } \ No newline at end of file diff --git a/apps/fo/app/components/common/FacilityTermModalHeader.tsx b/apps/fo/app/components/common/FacilityTermModalHeader.tsx index 84d6353b6..4389e2f5a 100644 --- a/apps/fo/app/components/common/FacilityTermModalHeader.tsx +++ b/apps/fo/app/components/common/FacilityTermModalHeader.tsx @@ -4,14 +4,14 @@ import ListDiv from '@common/business_components/ui/list_div'; import { Table, TableCell, TableHead, TableRow } from '@common/components/ui'; import { useCallback, useEffect, useRef, useState } from 'react'; -type FacilityTermModalHeaderProps = { - fcltyCd : string; +type FacilityTermModalHeaderProps = { // T는 반드시 msrDt: string 필드를 가져야 한다 + fcltyCd: string; fcltyName: string; tabName: string; searchYear: string; searchList: T[]; ref: React.RefObject>; - queryClick:(returnType:ReturnType) => void; + queryClick: (returnType: ReturnType) => void; } export type ReturnType = { @@ -21,28 +21,28 @@ export type ReturnType = { filteredList: T[]; } -export default function FacilityTermModalHeader({ +export default function FacilityTermModalHeader({ searchList, - fcltyName, - tabName, + fcltyName, + tabName, searchYear, queryClick, ref }: FacilityTermModalHeaderProps) { - const {Common} = useFoStore((state) => state); + const { Common } = useFoStore((state) => state); const { selectFlowPanel } = Common; const [startDate, setStartDate] = useState(new Date(Number(searchYear), 0, 1)); const [endDate, setEndDate] = useState(new Date(Number(searchYear), 11, 31)); const startPickerRef = useRef(null); const endPickerRef = useRef(null); - const [flowPanel, setFlowPanel] = useState(selectFlowPanel[0]?.val ?? '00'); + const [flowPanel, setFlowPanel] = useState(selectFlowPanel[0]?.val ?? '0'); // 초기값 "전체" const [copySearchList, setCopySearchList] = useState(searchList); const [standSearchList, setStandSearchList] = useState(searchList); const isDateInRanges = (date: Date) => { const standYear = parseInt(searchYear); const isLeapYear = (standYear % 4 === 0 && standYear % 100 !== 0) || (standYear % 400 === 0); - const dateRanges:{start:Date, end:Date}[] = []; + const dateRanges: { start: Date, end: Date }[] = []; if (tabName.includes("_summer")) { dateRanges.push({ @@ -74,66 +74,66 @@ export default function FacilityTermModalHeader({ const standYear = Number(searchYear); const isLeapYear = (standYear % 4 === 0 && standYear % 100 !== 0) || (standYear % 400 === 0); - if(tabName.includes("_summer")) { - startDate = new Date(Number(searchYear), 5, 1); - endDate = new Date(Number(searchYear), 7, 31); + if (tabName.includes("_summer")) { // 하절기 + startDate = new Date(Number(searchYear), 5, 1); // 6월 ~ + endDate = new Date(Number(searchYear), 7, 31); // 8월 setStartDate(startDate); setEndDate(endDate); - } else if (tabName.includes("_winter")) { - startDate = new Date(Number(searchYear), 0, 1); - endDate = new Date(Number(searchYear), 1, isLeapYear ? 29 : 28); + } else if (tabName.includes("_winter")) { // 동절기 + startDate = new Date(Number(searchYear), 0, 1); // 1월 ~ + endDate = new Date(Number(searchYear), 1, isLeapYear ? 29 : 28); // 2월 setStartDate(startDate); setEndDate(endDate); - } else { + } else { // 연간 startDate = new Date(Number(searchYear), 0, 1); endDate = new Date(Number(searchYear), 11, 31); setStartDate(startDate); setEndDate(endDate); } - + let filteredData: T[] = []; - if(tabName.includes("_rain")) { + if (tabName.includes("_rain")) { // 강우시 filteredData = searchList.filter((item) => { const itemDate = new Date((item as T & { msrDt: string }).msrDt); const itemDateOnly = new Date(itemDate.getFullYear(), itemDate.getMonth(), itemDate.getDate()); const startDateOnly = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate()); const endDateOnly = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate()); const rainEffectDay = (item as T & { rainEffectDay: number }).rainEffectDay; - - if(flowPanel === '2'){ + + if (flowPanel === '2') { //3~10mm미만 const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay; return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 3 && infoRnDay < 10; - } else if(flowPanel === '3'){ + } else if (flowPanel === '3') { //10~20mm미만 const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay; return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 10 && infoRnDay < 20; - } else if(flowPanel === '4'){ + } else if (flowPanel === '4') { //20~30mm미만 const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay; return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 20 && infoRnDay < 30; - } else if(flowPanel === '5'){ + } else if (flowPanel === '5') { //30~40mm미만 const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay; return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 30 && infoRnDay < 40; - } else if(flowPanel === '6'){ + } else if (flowPanel === '6') { //40~50mm미만 const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay; return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 40 && infoRnDay < 50; - } else if(flowPanel === '7'){ + } else if (flowPanel === '7') { //50~60mm미만 const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay; return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 50 && infoRnDay < 60; - } else if(flowPanel === '8'){ + } else if (flowPanel === '8') { const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay; return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 60; } else { - return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && (rainEffectDay ===1); + return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && (rainEffectDay === 1); } }); - } else if(tabName.includes("_chuncheon")) { + } else if (tabName.includes("_chuncheon")) { // 청천시 filteredData = searchList.filter((item) => { const itemDate = new Date((item as T & { msrDt: string }).msrDt); const itemDateOnly = new Date(itemDate.getFullYear(), itemDate.getMonth(), itemDate.getDate()); const startDateOnly = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate()); const endDateOnly = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate()); const rainEffectDay = (item as T & { rainEffectDay: number }).rainEffectDay; - return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && rainEffectDay==0; + return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && rainEffectDay == 0; }); } else { filteredData = searchList.filter((item) => { @@ -149,7 +149,7 @@ export default function FacilityTermModalHeader({ }, [searchList, searchYear, tabName, flowPanel]); const handleStartDateSelect = (day: Date | undefined) => { - if(day && day > endDate) { + if (day && day > endDate) { alert('종료일은 시작일 이전일 수 없습니다.'); return; } @@ -172,7 +172,7 @@ export default function FacilityTermModalHeader({ }; const handleEndDateSelect = (day: Date | undefined) => { - if(day && day < startDate) { + if (day && day < startDate) { alert('종료일은 시작일 이후일 수 없습니다.'); return; } @@ -193,7 +193,7 @@ export default function FacilityTermModalHeader({ }); setCopySearchList(filteredData); }; - + const fncSetFilteredList = useCallback(() => { queryClick({ startDate: startDate, @@ -206,9 +206,9 @@ export default function FacilityTermModalHeader({ useEffect(() => { fncSetFilteredList(); }, [fncSetFilteredList]); - + useEffect(() => { - if(ref && ref.current) { + if (ref && ref.current) { const customRef = ref.current; customRef.startDate = startDate; customRef.endDate = endDate; @@ -225,18 +225,18 @@ export default function FacilityTermModalHeader({ {'시설명'} {tabName === "tab_term_rain" ? {fcltyName} : - {fcltyName}} + {fcltyName}} {tabName === "tab_term_rain" && ( <> {'강수구분'}
- setFlowPanel(val.toString())} - className="mx-3 w-[150px]" - label="" + className="mx-3 w-[150px]" + label="" selectClass="w-full p-1 border rounded bg-white" />
@@ -247,7 +247,7 @@ export default function FacilityTermModalHeader({
- handleStartDateSelect(date as Date)} @@ -261,7 +261,7 @@ export default function FacilityTermModalHeader({ handleEndDateSelect(date as Date)} + onSelect={(date) => handleEndDateSelect(date as Date)} className="w-full p-1 border rounded bg-white" disabled={(date) => !isDateInRanges(date)} defaultMonth={endDate} diff --git a/apps/fo/app/pages/(with-layout)/flowRate/modal/page.tsx b/apps/fo/app/pages/(with-layout)/flowRate/modal/page.tsx index 822b52979..4e0fffeb5 100644 --- a/apps/fo/app/pages/(with-layout)/flowRate/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/flowRate/modal/page.tsx @@ -8,6 +8,7 @@ import FacilityTermModalHeader from "@/app/components/common/FacilityTermModalHeader"; import { useFoStore } from "@/app/store"; import type { FlowRateModalInterface, modalExcelType } from "@/app/store/flowRate"; +import { dataFormSetting } from "@/app/store/flowRate"; import { downloadExcel, UITab, UiTable } from "@common/business_components/ui"; import { Button, TabsContent } from "@common/components/ui"; import { useCallback, useEffect, useRef, useState } from "react"; @@ -76,7 +77,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st let minreturnAmnt = parseNumber(filteredData[0]?.returnAmnt); let minefflAmnt = parseNumber(filteredData[0]?.efflAmnt); let mininfoRnDay = parseNumber(filteredData[0]?.infoRnDay && filteredData[0]?.infoRnDay.toString().trim() !== 'x' ? filteredData[0]?.infoRnDay.toString().trim() : 0); - let minNoProcessInflAmnt = 99999999; + let minNoProcessInflAmnt = 99999999; // 미처리하수 추정량 let avgtotInflAmnt = 0; let avginflAmnt = 0; @@ -125,6 +126,12 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st } }); + const formattedData = filteredData.map((item: FlowRateModalInterface) => { + const newItem = { ...item }; + dataFormSetting(newItem); + return newItem; + }); + const newFilteredData = [ { msrDt: '평균', @@ -159,7 +166,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st infoRnDay: mininfoRnDay > 0 ? roundUp(mininfoRnDay, 1) : '0.0', rainEffectDay: 0, }, - ...filteredData + ...formattedData ]; return newFilteredData; } @@ -210,7 +217,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st - + {/* 연간 */} searchList={modalFlowRateListYear} fcltyCd={props.facilityCd} @@ -237,7 +244,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
- + {/* 하절기 */} searchList={modalFlowRateListYear} fcltyCd={props.facilityCd} @@ -264,7 +271,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
- + {/* 동절기 */} searchList={modalFlowRateListYear} fcltyCd={props.facilityCd} @@ -291,7 +298,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
- + {/* 청천시 */} searchList={modalFlowRateListYear} fcltyCd={props.facilityCd} @@ -318,7 +325,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
- + {/* 강우시 */} searchList={modalFlowRateListYear} fcltyCd={props.facilityCd} @@ -329,7 +336,8 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st queryClick={filterData} />
- { }} className="h-[370px]" boldArray={[0, 1, 2]} /> + { }} className="h-[370px]" boldArray={[0, 1, 2]} />
diff --git a/apps/fo/app/store/flowRate/index.tsx b/apps/fo/app/store/flowRate/index.tsx index 432bc5ba5..7bec0be97 100644 --- a/apps/fo/app/store/flowRate/index.tsx +++ b/apps/fo/app/store/flowRate/index.tsx @@ -237,7 +237,7 @@ export type FlowRateSearchType = { export type FlowRateSearchStore = FlowRateSearchType & FlowRateSearchActions; -const dataFormSetting = (item: flowRateListProps | FlowRateModalProps) => { +export const dataFormSetting = (item: flowRateListProps | FlowRateModalProps | FlowRateModalInterface) => { DataForm({ type: 'date', column: 'msrDt', item: item as unknown as Record }); DataForm({ type: 'float0', column: 'totInflAmnt', item: item as unknown as Record }); DataForm({ type: 'float0', column: 'inflAmnt', item: item as unknown as Record }); @@ -330,44 +330,48 @@ export const flowRateSearchReducer: (set: (fn: (state: FlowRateSearchType) => Fl const inflData = CalcRainEffect(res.data); const res2 = await fetchFacilityWaterQltyListHist(searchYear, bscFctCd); - const wqltData = CalcRainEffect(res2?.data.wqltObjs); - + const wqltData = res2?.data.wqltObjs; + //const wqltData = CalcRainEffect(res2?.data.wqltObjs); /** - * [(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​ - /강우시 일별유입BOD) + * [(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)] / 강우시 일별유입BOD */ - //let rainInflAmnt = 0; let sunnyInflAmnt = 0; // 청천시 일별유입유량 - let sunnyBod = 0; // 청천시 일별유입BOD - //let rainDay = 0; + let sunnyBod = 0; // 청천시 일별유입BOD let sunnyDay = 0; - - inflData.forEach(item => { - if (item.rainEffectDay == 1) { - //rainDay += 1; - //rainInflAmnt += Number(item.inflAmnt); + let rainEffectDay = 0; + wqltData?.forEach(item => { + if (item.infoRnDay == null) item.infoRnDay = 0; + if (Number(item.infoRnDay) >= 3) { + rainEffectDay = 2; } else { - const msrDt = item.msrDt.replaceAll('-', ''); + rainEffectDay--; + } + if (rainEffectDay < 0) { //청천시 sunnyDay += 1; sunnyInflAmnt += Number(item.inflAmnt); - sunnyBod += Number(wqltData.filter((wqitem) => wqitem.msrDt === msrDt)[0].inflAssctBfrWqltBod); + sunnyBod += Number(item.inflAssctBfrWqltBod); } }); - //const yearRainAmnt = rainInflAmnt===0?0:rainInflAmnt / rainDay; - const yearSunnyAmnt = sunnyInflAmnt === 0 ? 0 : sunnyInflAmnt / sunnyDay; // 청천시 연평균유입유량 - const yearSunnyBod = sunnyBod === 0 ? 0 : sunnyBod / sunnyDay; // 청천시 연평균유입BOD - + const yearSunnyAmnt = sunnyDay > 0 ? sunnyInflAmnt / sunnyDay : 0; // 청천시 연평균유입유량 + const yearSunnyBod = sunnyDay > 0 ? sunnyBod / sunnyDay : 0; // 청천시 연평균유입BOD + console.log(inflData); const rtnData = inflData.map((item: FlowRateModalProps) => { - const dayBod = Number(wqltData.filter(wqitem => wqitem.msrDt === item.msrDt.replaceAll('-', ''))[0].inflAssctBfrWqltBod); + const targetWqItem = wqltData?.find(wqitem => wqitem.msrDt === item.msrDt.replaceAll('-', '')); + const dayBod = targetWqItem ? Number(targetWqItem.inflAssctBfrWqltBod) : 0; const noProcessInflAmnt = Math.round(((Number(item.inflAmnt) * dayBod) - (yearSunnyAmnt * yearSunnyBod)) / dayBod) + const totInflAmnt = Number(item.inflAmnt || 0) + Number(item.sumFlow || 0) + Number(item.returnAmnt || 0); - item.totInflAmnt = Number(item.inflAmnt || 0) + Number(item.sumFlow || 0) + Number(item.returnAmnt || 0); - item.noProcessInflAmnt = noProcessInflAmnt && noProcessInflAmnt > 0 ? noProcessInflAmnt : ''; - dataFormSetting(item); - return item; + return { + ...item, + totInflAmnt, + noProcessInflAmnt: noProcessInflAmnt && noProcessInflAmnt > 0 ? noProcessInflAmnt : '', + msrDt: (item.msrDt.length === 8 && !item.msrDt.includes('-')) ? + `${item.msrDt.slice(0, 4)}-${item.msrDt.slice(4, 6)}-${item.msrDt.slice(6, 8)}` + : item.msrDt, + }; }); - + console.log(rtnData); set((state: FlowRateSearchType) => ({ ...state, FlowRateModal: { From 36294fef80a0109abecaf4e67356fe413ec7d212 Mon Sep 17 00:00:00 2001 From: dongsilove Date: Mon, 12 Jan 2026 10:28:36 +0900 Subject: [PATCH 22/34] =?UTF-8?q?fo:=20=EC=B2=98=EB=A6=AC=EA=B5=AC?= =?UTF-8?q?=EC=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/(with-layout)/processArea/page.tsx | 3 +- apps/fo/app/store/processArea/index.tsx | 522 +++++++++--------- 2 files changed, 264 insertions(+), 261 deletions(-) diff --git a/apps/fo/app/pages/(with-layout)/processArea/page.tsx b/apps/fo/app/pages/(with-layout)/processArea/page.tsx index 009d72c9f..ba1e27767 100644 --- a/apps/fo/app/pages/(with-layout)/processArea/page.tsx +++ b/apps/fo/app/pages/(with-layout)/processArea/page.tsx @@ -167,7 +167,8 @@ export default function ProcessArea() {
- index !== undefined && cellClick(index)} headName={"처리구역정보"} tableData={mainList} headlist={upHeadList1} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} /> + index !== undefined && cellClick(index)} headName={"처리구역정보"} tableData={mainList} + headlist={upHeadList1} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} />
diff --git a/apps/fo/app/store/processArea/index.tsx b/apps/fo/app/store/processArea/index.tsx index 959b83794..31da21bfc 100644 --- a/apps/fo/app/store/processArea/index.tsx +++ b/apps/fo/app/store/processArea/index.tsx @@ -12,52 +12,52 @@ export type { TableUpperProps }; */ // 처리구역 리스트 export type ProcessAreaProps = { - swtrmtFcltCd : string, + swtrmtFcltCd: string, ctpvNm?: string, sggNm?: string, - swtrmtFcltNm : string, - location : string, - fctCpc : number | '', - fcltCpctSum : number | '', - ruse : boolean, - planYrDt4 : string, - planYr : string, - planYrDc1 : string, - planYrDc2 : string, - planYrDc3 : string, - planYrDc4 : string, + swtrmtFcltNm: string, + location: string, + fctCpc: number | '', + fcltCpctSum: number | '', + ruse: boolean, + planYrDt4: string, + planYr: string, + planYrDc1: string, + planYrDc2: string, + planYrDc3: string, + planYrDc4: string, /** * 증설계획 */ // 기승인(당초4단계), 현재, 변경1~4 - planSwageQntSumDt4 : number | '', - planSwageQntSum : number | '', - planSwageQntSumDc1 : number | '', - planSwageQntSumDc2 : number | '', - planSwageQntSumDc3 : number | '', - planSwageQntSumDc4 : number | '', + planSwageQntSumDt4: number | '', + planSwageQntSum: number | '', + planSwageQntSumDc1: number | '', + planSwageQntSumDc2: number | '', + planSwageQntSumDc3: number | '', + planSwageQntSumDc4: number | '', /** * 처리인구 */ // 기승인(당초4단계), 변경1~4 - swtrmtPpltnCntDt4 : number | '', - swtrmtPpltnCnt : number | '', - swtrmtPpltnCntDc1 : number | '', - swtrmtPpltnCntDc2 : number | '', - swtrmtPpltnCntDc3 : number | '', - swtrmtPpltnCntDc4 : number | '', + swtrmtPpltnCntDt4: number | '', + swtrmtPpltnCnt: number | '', + swtrmtPpltnCntDc1: number | '', + swtrmtPpltnCntDc2: number | '', + swtrmtPpltnCntDc3: number | '', + swtrmtPpltnCntDc4: number | '', /** * 처리구역면적 */ // 기승인(당초4단계), 변경1~4 - swtrmtZoneAreaDt4 : number | '', - swtrmtZoneArea : number | '', - swtrmtZoneAreaDc1 : number | '', - swtrmtZoneAreaDc2 : number | '', - swtrmtZoneAreaDc3 : number | '', - swtrmtZoneAreaDc4 : number | '', + swtrmtZoneAreaDt4: number | '', + swtrmtZoneArea: number | '', + swtrmtZoneAreaDc1: number | '', + swtrmtZoneAreaDc2: number | '', + swtrmtZoneAreaDc3: number | '', + swtrmtZoneAreaDc4: number | '', // 처리구역 - trtDstr : string | '', + trtDstr: string | '', } export interface ExcelType { @@ -89,32 +89,32 @@ export interface ExcelType { // (2) 처리구역 팝업 // 시설증설 계획 export type FcltyImproveInfoProps = { - planSwageQntSumDt4 : number | '', - planSwageQntSum : number | '', - planSwageQntSumDc1 : number | '', - planSwageQntSumDc2 : number | '', - planSwageQntSumDc3 : number | '', - planSwageQntSumDc4 : number | '', + planSwageQntSumDt4: number | '', + planSwageQntSum: number | '', + planSwageQntSumDc1: number | '', + planSwageQntSumDc2: number | '', + planSwageQntSumDc3: number | '', + planSwageQntSumDc4: number | '', } // 처리인구 계획 export type ProcessPopulationProps = { - swtrmtPpltnCntDt4 : number | '', - swtrmtPpltnCnt : number | '', - swtrmtPpltnCntDc1 : number | '', - swtrmtPpltnCntDc2 : number | '', - swtrmtPpltnCntDc3 : number | '', - swtrmtPpltnCntDc4 : number | '', + swtrmtPpltnCntDt4: number | '', + swtrmtPpltnCnt: number | '', + swtrmtPpltnCntDc1: number | '', + swtrmtPpltnCntDc2: number | '', + swtrmtPpltnCntDc3: number | '', + swtrmtPpltnCntDc4: number | '', } // 처리구역 계획 export type ProcessAreaPlanProps = { - swtrmtZoneAreaDt4 : number | '', - swtrmtZoneArea : number | '', - swtrmtZoneAreaDc1 : number | '', - swtrmtZoneAreaDc2 : number | '', - swtrmtZoneAreaDc3 : number | '', - swtrmtZoneAreaDc4 : number | '', - trtDstr : string, + swtrmtZoneAreaDt4: number | '', + swtrmtZoneArea: number | '', + swtrmtZoneAreaDc1: number | '', + swtrmtZoneAreaDc2: number | '', + swtrmtZoneAreaDc3: number | '', + swtrmtZoneAreaDc4: number | '', + trtDstr: string, } /**==================================== @@ -123,93 +123,93 @@ export type ProcessAreaPlanProps = { /** * (1) 메인페이지 - */ + */ // 검색단 -const ProcessFacilityLabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '시설상태', '연도별', '권역', '단위유역', '중권역', '환경청별']; +const ProcessFacilityLabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '시설상태', '연도별', '권역', '단위유역', '중권역', '환경청별']; // 리스트 헤더(행정별) -const upHeadList1:TableUpperProps[] = [ - { id: "A", title: "행정구역", colSpan:2, rowSpan:2, row:0 }, - { id: "ctpvNm", title: "시도", upName:"upChangeRe", row:2, widthPercent:4 }, - { id: "sggNm", title: "시군구", upName:"upChangeRe", row:2, widthPercent:4 }, - { id: "swtrmtFcltNm", title: "시설명", rowSpan:3, row:0, widthPercent: 6 }, - { id: "location", title: "주소", rowSpan:3, row:0, widthPercent: 12 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", rowSpan:3, row:0, widthPercent: 5 }, - { id: "B", title: "시설계획", colSpan:19, row: 0 }, - { id: "C", title: "증설계획(m³/일)", colSpan:6, row: 1 }, - { id: "planSwageQntSumDt4", title: "기승인\n4단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "planSwageQntSum", title: "현재", row:2, align:"right", widthPercent: 3.5 }, - { id: "planSwageQntSumDc1", title: "1단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "planSwageQntSumDc2", title: "2단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "planSwageQntSumDc3", title: "3단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "planSwageQntSumDc4", title: "4단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "D", title: "처리인구(인)", colSpan:6, row:1 }, - { id: "swtrmtPpltnCntDt4", title: "기승인\n4단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "swtrmtPpltnCnt", title: "현재", row:2, align:"right", widthPercent: 3.5 }, - { id: "swtrmtPpltnCntDc1", title: "1단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "swtrmtPpltnCntDc2", title: "2단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "swtrmtPpltnCntDc3", title: "3단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "swtrmtPpltnCntDc4", title: "4단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "E", title: "처리구역(km²)", colSpan:7, row:1 }, - { id: "swtrmtZoneAreaDt4", title: "기승인\n4단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "swtrmtZoneArea", title: "현재", row:2, align:"right", widthPercent: 3.5 }, - { id: "swtrmtZoneAreaDc1", title: "1단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "swtrmtZoneAreaDc2", title: "2단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "swtrmtZoneAreaDc3", title: "3단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "swtrmtZoneAreaDc4", title: "4단계", row:2, align:"right", widthPercent: 3.5 }, - { id: "trtDstr", title: "처리구역", row:2} +const upHeadList1: TableUpperProps[] = [ + { id: "A", title: "행정구역", colSpan: 2, rowSpan: 2, row: 0 }, + { id: "ctpvNm", title: "시도", upName: "upChangeRe", row: 2, widthPercent: 4 }, + { id: "sggNm", title: "시군구", upName: "upChangeRe", row: 2, widthPercent: 4 }, + { id: "swtrmtFcltNm", title: "시설명", rowSpan: 3, row: 0, widthPercent: 6 }, + { id: "location", title: "주소", rowSpan: 3, row: 0, widthPercent: 12 }, + { id: "fctCpc", title: "시설용량(m³/일)", align: "right", rowSpan: 3, row: 0, widthPercent: 5 }, + { id: "B", title: "시설계획", colSpan: 18, row: 0 }, + { id: "C", title: "증설계획(m³/일)", colSpan: 6, row: 1 }, + { id: "planSwageQntSumDt4", title: "기승인\n4단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "planSwageQntSum", title: "현재", row: 2, align: "right", widthPercent: 3.5 }, + { id: "planSwageQntSumDc1", title: "1단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "planSwageQntSumDc2", title: "2단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "planSwageQntSumDc3", title: "3단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "planSwageQntSumDc4", title: "4단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "D", title: "처리인구(인)", colSpan: 6, row: 1 }, + { id: "swtrmtPpltnCntDt4", title: "기승인\n4단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "swtrmtPpltnCnt", title: "현재", row: 2, align: "right", widthPercent: 3.5 }, + { id: "swtrmtPpltnCntDc1", title: "1단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "swtrmtPpltnCntDc2", title: "2단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "swtrmtPpltnCntDc3", title: "3단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "swtrmtPpltnCntDc4", title: "4단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "E", title: "처리구역(km²)", colSpan: 6, row: 1 }, + { id: "swtrmtZoneAreaDt4", title: "기승인\n4단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "swtrmtZoneArea", title: "현재", row: 2, align: "right", widthPercent: 3.5 }, + { id: "swtrmtZoneAreaDc1", title: "1단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "swtrmtZoneAreaDc2", title: "2단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "swtrmtZoneAreaDc3", title: "3단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "swtrmtZoneAreaDc4", title: "4단계", row: 2, align: "right", widthPercent: 3.5 }, + { id: "trtDstr", title: "처리구역", row: 0, rowSpan: 3 } // row - header에서 몇번째 행인지 ]; -const processAreaList:ProcessAreaProps[] = [ +const processAreaList: ProcessAreaProps[] = [ ] /** * 처리구역정보 상세팝업 - */ + */ // 시설증설 계획 (헤더) -const upHeadListFcltyImproveInfo:TableUpperProps[] = [ - { id: "planSwageQntSumDt4", title: "기승인\n4단계(m³/일)", rowSpan:2, row:0, align:"right"}, - { id: "A", title: "증설계획(m³/일)", colSpan:5, row:0}, - { id: "planSwageQntSum", title: "현재", row:1, align:"right"}, - { id: "planSwageQntSumDc1", title: "1단계", row:1, align:"right"}, - { id: "planSwageQntSumDc2", title: "2단계", row:1, align:"right"}, - { id: "planSwageQntSumDc3", title: "3단계", row:1, align:"right"}, - { id: "planSwageQntSumDc4", title: "4단계", row:1, align:"right"}, +const upHeadListFcltyImproveInfo: TableUpperProps[] = [ + { id: "planSwageQntSumDt4", title: "기승인\n4단계(m³/일)", rowSpan: 2, row: 0, align: "right" }, + { id: "A", title: "증설계획(m³/일)", colSpan: 5, row: 0 }, + { id: "planSwageQntSum", title: "현재", row: 1, align: "right" }, + { id: "planSwageQntSumDc1", title: "1단계", row: 1, align: "right" }, + { id: "planSwageQntSumDc2", title: "2단계", row: 1, align: "right" }, + { id: "planSwageQntSumDc3", title: "3단계", row: 1, align: "right" }, + { id: "planSwageQntSumDc4", title: "4단계", row: 1, align: "right" }, ]; // 시설증설 계획 (리스트) -const gridListFcltyImproveInfo:FcltyImproveInfoProps[] = [ +const gridListFcltyImproveInfo: FcltyImproveInfoProps[] = [ ]; // 처리인구 계획 (헤더) -const upHeadListProcessPopulation:TableUpperProps[] = [ - { id: "swtrmtPpltnCntDt4", title: "기승인\n4단계(인)", rowSpan:2, row:0, align:"right"}, - { id: "A", title: "처리인구(인)", colSpan:5, row:0}, - { id: "swtrmtPpltnCnt", title: "현재", row:1, align:"right"}, - { id: "swtrmtPpltnCntDc1", title: "1단계", row:1, align:"right"}, - { id: "swtrmtPpltnCntDc2", title: "2단계", row:1, align:"right"}, - { id: "swtrmtPpltnCntDc3", title: "3단계", row:1, align:"right"}, - { id: "swtrmtPpltnCntDc4", title: "4단계", row:1, align:"right"}, +const upHeadListProcessPopulation: TableUpperProps[] = [ + { id: "swtrmtPpltnCntDt4", title: "기승인\n4단계(인)", rowSpan: 2, row: 0, align: "right" }, + { id: "A", title: "처리인구(인)", colSpan: 5, row: 0 }, + { id: "swtrmtPpltnCnt", title: "현재", row: 1, align: "right" }, + { id: "swtrmtPpltnCntDc1", title: "1단계", row: 1, align: "right" }, + { id: "swtrmtPpltnCntDc2", title: "2단계", row: 1, align: "right" }, + { id: "swtrmtPpltnCntDc3", title: "3단계", row: 1, align: "right" }, + { id: "swtrmtPpltnCntDc4", title: "4단계", row: 1, align: "right" }, ]; // 처리인구 계획 (리스트) -const gridListProcessPopulation:ProcessPopulationProps[] = [ +const gridListProcessPopulation: ProcessPopulationProps[] = [ ]; // 처리구역 계획 (헤더) -const upHeadListProcessAreaPlan:TableUpperProps[] = [ - { id: "swtrmtZoneAreaDt4", title: "기승인\n4단계(km²)", rowSpan:2, row:0, align:"right"}, - { id: "A", title: "처리면적(km²)", colSpan:6, row:0, align:"right"}, - { id: "swtrmtZoneArea", title: "현재", row:1, align:"right"}, - { id: "swtrmtZoneAreaDc1", title: "1단계", row:1, align:"right"}, - { id: "swtrmtZoneAreaDc2", title: "2단계", row:1, align:"right"}, - { id: "swtrmtZoneAreaDc3", title: "3단계", row:1, align:"right"}, - { id: "swtrmtZoneAreaDc4", title: "4단계", row:1, align:"right"}, - { id: "trtDstr", title: "처리구역", row:1} +const upHeadListProcessAreaPlan: TableUpperProps[] = [ + { id: "swtrmtZoneAreaDt4", title: "기승인\n4단계(km²)", rowSpan: 2, row: 0, align: "right" }, + { id: "A", title: "처리면적(km²)", colSpan: 5, row: 0, align: "right" }, + { id: "swtrmtZoneArea", title: "현재", row: 1, align: "right" }, + { id: "swtrmtZoneAreaDc1", title: "1단계", row: 1, align: "right" }, + { id: "swtrmtZoneAreaDc2", title: "2단계", row: 1, align: "right" }, + { id: "swtrmtZoneAreaDc3", title: "3단계", row: 1, align: "right" }, + { id: "swtrmtZoneAreaDc4", title: "4단계", row: 1, align: "right" }, + // { id: "trtDstr", title: "처리구역", row: 1 } ]; // 시설증설 계획 (리스트) -const gridListProcessAreaPlan:ProcessAreaPlanProps[] = [ +const gridListProcessAreaPlan: ProcessAreaPlanProps[] = [ ]; /**==================================== @@ -227,113 +227,115 @@ const gridListProcessAreaPlan:ProcessAreaPlanProps[] = [ } }; */ -const fetchFacilityDetailInfo = async (pageNo:number, pageSize:number, swtrmtFcltCd: string[]) : Promise<{data:any[], count:number}> => { - try { - const res = await postFetch('fo', '/prcsFclt/ruseInfo/'+pageNo+'/'+pageSize, swtrmtFcltCd); - return {data: res.data, count:res.count}; - } catch (error) { - console.error('시설정보 데이터를 가져오는데 실패했습니다:', error); - return {data:[], count:0}; - } +const fetchFacilityDetailInfo = async (pageNo: number, pageSize: number, swtrmtFcltCd: string[]): Promise<{ data: any[], count: number }> => { + try { + const res = await postFetch('fo', '/prcsFclt/ruseInfo/' + pageNo + '/' + pageSize, swtrmtFcltCd); + return { data: res.data, count: res.count }; + } catch (error) { + console.error('시설정보 데이터를 가져오는데 실패했습니다:', error); + return { data: [], count: 0 }; + } }; // 시설정보 리스트 데이터 호출(구분 선택 후 시설명 있을 경우) -const fetchProcessAreaList = async (pageNo : number, pageSize : number, ctpvNm : string | undefined, sggNm : string | undefined, targetYear : string | undefined, set : (fn: (state: ProcessAreaType) => ProcessAreaType) => void): Promise<{data:any[], count:number}> => { - try { - const res = await fetchPlanInfo(targetYear, ctpvNm, sggNm, undefined); - if(res && res.length > 0){ - const enrichedData = await Promise.all( - res.map(async (item: ProcessAreaProps) => { - upHeadList1.forEach((head:TableUpperProps) => { - /* if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') { - head.title = '현재\n(' + item.planYr + '년)'; - } else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') { - head.title = '1단계\n(' + item.planYrDc1 + '년)'; - } else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') { - head.title = '2단계\n(' + item.planYrDc2 + '년)'; - } else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') { - head.title = '3단계\n(' + item.planYrDc3 + '년)'; - } else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') { - head.title = '4단계\n(' + item.planYrDc4 + '년)'; - } else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') { - head.title = '기승인\n4단계(' + item.planYrDt4 + '년)'; - } */ - if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') { - head.title = '현재'; - } else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') { - head.title = '1단계'; - } else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') { - head.title = '2단계'; - } else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') { - head.title = '3단계'; - } else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') { - head.title = '4단계'; - } else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') { - head.title = '기승인\n4단계'; - } - }); - return item; +const fetchProcessAreaList = async (pageNo: number, pageSize: number, ctpvNm: string | undefined, sggNm: string | undefined + , targetYear: string | undefined, set: (fn: (state: ProcessAreaType) => ProcessAreaType) => void): Promise<{ data: any[], count: number }> => { + try { + const res = await fetchPlanInfo(targetYear, ctpvNm, sggNm, undefined); + if (res && res.length > 0) { + const enrichedData = await Promise.all( + res.map(async (item: ProcessAreaProps) => { + upHeadList1.forEach((head: TableUpperProps) => { + /* if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') { + head.title = '현재\n(' + item.planYr + '년)'; + } else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') { + head.title = '1단계\n(' + item.planYrDc1 + '년)'; + } else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') { + head.title = '2단계\n(' + item.planYrDc2 + '년)'; + } else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') { + head.title = '3단계\n(' + item.planYrDc3 + '년)'; + } else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') { + head.title = '4단계\n(' + item.planYrDc4 + '년)'; + } else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') { + head.title = '기승인\n4단계(' + item.planYrDt4 + '년)'; + } */ + if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') { + head.title = '현재'; + } else if (head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') { + head.title = '1단계'; + } else if (head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') { + head.title = '2단계'; + } else if (head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') { + head.title = '3단계'; + } else if (head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') { + head.title = '4단계'; + } else if (head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') { + head.title = '기승인\n4단계'; + } + }); + return item; + }) + ); + + const startIndex = (pageNo - 1) * pageSize; + const endIndex = startIndex + pageSize; + const paginatedData = enrichedData.slice(startIndex, endIndex); + + const fcltyCdList: string[] = []; + paginatedData.forEach(item => { + fcltyCdList.push(item.swtrmtFcltCd); }) - ); - const startIndex = (pageNo - 1) * pageSize; - const endIndex = startIndex + pageSize; - const paginatedData = enrichedData.slice(startIndex, endIndex); - - const fcltyCdList : string[]= []; - paginatedData.forEach(item => { - fcltyCdList.push(item.swtrmtFcltCd); - }) - - const detailFcltylist = await fetchFacilityDetailInfo(1, pageSize, fcltyCdList); - paginatedData.forEach(item => { - const filterdData = detailFcltylist.data.filter(fItem=>fItem.bscFctCd === item.swtrmtFcltCd)[0] || null; - item.fcltCpctSum = filterdData ? filterdData.fctCpc : ''; - item.location = filterdData ? filterdData.addr : ''; - item.ctpvNm = filterdData ? filterdData.sido : ''; - item.sggNm = filterdData ? filterdData.gugun : ''; - }); - return {data: paginatedData, count: enrichedData.length}; - }else{ - return {data: [], count: 0}; - } - } catch (error) { - console.error('시설계획정보를 가져오는데 실패했습니다:', error); - set((state) => ({ - ...state, - ProcessArea : { - ...state.ProcessArea, - isLoading : false + const detailFcltylist = await fetchFacilityDetailInfo(1, pageSize, fcltyCdList); + paginatedData.forEach(item => { + const filterdData = detailFcltylist.data.filter(fItem => fItem.bscFctCd === item.swtrmtFcltCd)[0] || null; + item.fcltCpctSum = filterdData ? filterdData.fctCpc : ''; + item.location = filterdData ? filterdData.addr : ''; + item.ctpvNm = filterdData ? filterdData.sido : ''; + item.sggNm = filterdData ? filterdData.gugun : ''; + item.trtDstr = filterdData ? filterdData.trtDstr : ''; + }); + return { data: paginatedData, count: enrichedData.length }; + } else { + return { data: [], count: 0 }; } - })); - return {data: [], count: 0}; - } + } catch (error) { + console.error('시설계획정보를 가져오는데 실패했습니다:', error); + set((state) => ({ + ...state, + ProcessArea: { + ...state.ProcessArea, + isLoading: false + } + })); + return { data: [], count: 0 }; + } }; /**==================================== * Store - expaort =====================================*/ export type ProcessAreaActions = { - searchProcessAreaList : (pageNo: number, pageSize: number, ctpvNm?:string, sggNm?:string, targetYear?:string) => void; - initModalData : (swtrmtFcltCd:string) => void; + searchProcessAreaList: (pageNo: number, pageSize: number, ctpvNm?: string, sggNm?: string, targetYear?: string) => void; + initModalData: (swtrmtFcltCd: string) => void; } export type ProcessAreaType = { ProcessAreaSearch: { isInit: boolean; - processFacilityLabelArray:string[]; + processFacilityLabelArray: string[]; }, - ProcessArea : { + ProcessArea: { isInit: boolean; upHeadList1: TableUpperProps[]; processAreaList: ProcessAreaProps[]; processAreaCount: number; excelList: ExcelType[]; isLoading: boolean; - }, + }, - ProcessAreaDetail : { + ProcessAreaDetail: { isInit: boolean; upHeadListFcltyImproveInfo: TableUpperProps[]; gridListFcltyImproveInfo: FcltyImproveInfoProps[]; // Changed from facilityAreaProps to ProcessAreaProps @@ -350,23 +352,23 @@ export const processAreaInitState: ProcessAreaType = { processFacilityLabelArray: ProcessFacilityLabelArray, }, - ProcessArea : { - isInit : false, - upHeadList1 : upHeadList1, - processAreaList : processAreaList, - processAreaCount : 0, - excelList : [], - isLoading : true, + ProcessArea: { + isInit: false, + upHeadList1: upHeadList1, + processAreaList: processAreaList, + processAreaCount: 0, + excelList: [], + isLoading: true, }, - ProcessAreaDetail : { - isInit : false, - upHeadListFcltyImproveInfo : upHeadListFcltyImproveInfo, - gridListFcltyImproveInfo : gridListFcltyImproveInfo, - upHeadListProcessPopulation : upHeadListProcessPopulation, - gridListProcessPopulation : gridListProcessPopulation, - upHeadListProcessAreaPlan : upHeadListProcessAreaPlan, - gridListProcessAreaPlan : gridListProcessAreaPlan, + ProcessAreaDetail: { + isInit: false, + upHeadListFcltyImproveInfo: upHeadListFcltyImproveInfo, + gridListFcltyImproveInfo: gridListFcltyImproveInfo, + upHeadListProcessPopulation: upHeadListProcessPopulation, + gridListProcessPopulation: gridListProcessPopulation, + upHeadListProcessAreaPlan: upHeadListProcessAreaPlan, + gridListProcessAreaPlan: gridListProcessAreaPlan, }, } @@ -375,14 +377,14 @@ type SetStateFunction = (state: ProcessAreaType | ((state: ProcessAreaType) => P export type ProcessAreaStore = ProcessAreaType & ProcessAreaActions; -export const processAreaReducer:(set:SetStateFunction)=>ProcessAreaActions=(set: SetStateFunction) => { +export const processAreaReducer: (set: SetStateFunction) => ProcessAreaActions = (set: SetStateFunction) => { return { /** * 시설정보 리스트 데이터 호출 * @param pageNo : 페이지 번호 * @param pageSize : 페이지 크기 */ - searchProcessAreaList: async ( pageNo:number, pageSize:number, ctpvNm?:string, sggNm?:string, targetYear?:string) => { + searchProcessAreaList: async (pageNo: number, pageSize: number, ctpvNm?: string, sggNm?: string, targetYear?: string) => { set((state: ProcessAreaType) => ({ ...state, ProcessArea: { @@ -391,12 +393,12 @@ export const processAreaReducer:(set:SetStateFunction)=>ProcessAreaActions=(set: }, })); const res = await fetchProcessAreaList(pageNo, pageSize, ctpvNm, sggNm, targetYear, set); - res.data.forEach((item:ProcessAreaProps) => { + res.data.forEach((item: ProcessAreaProps) => { item.fctCpc = item.fcltCpctSum; - DataForm({ type: 'float1', column: 'fctCpc', item:item as unknown as Record}); + DataForm({ type: 'float1', column: 'fctCpc', item: item as unknown as Record }); }) const excelDownList: ExcelType[] = []; - if(pageSize>5000){ + if (pageSize > 5000) { res.data.forEach(item => { item.fctCpc = item.fctCpc ? parseFloat(item.fctCpc.toString().replace(/,/g, '')) : ''; excelDownList.push({ @@ -425,78 +427,78 @@ export const processAreaReducer:(set:SetStateFunction)=>ProcessAreaActions=(set: 처리구역: item.trtDstr }); }); - }else{ + } else { res.data.forEach(item => { item.fctCpc = item.fctCpc ? parseFloat(item.fctCpc.toString().replace(/,/g, '')) : ''; }) } - set((state:ProcessAreaType) => ({ + set((state: ProcessAreaType) => ({ ...state, - ProcessArea: pageSize<5000?{ + ProcessArea: pageSize < 5000 ? { ...state.ProcessArea, processAreaList: res.data, processAreaCount: res.count, - isLoading : false, - }:{ + isLoading: false, + } : { ...state.ProcessArea, excelList: excelDownList, - isLoading : false, + isLoading: false, }, })) }, - initModalData: async (swtrmtFcltCd:string) => { + initModalData: async (swtrmtFcltCd: string) => { set((state: ProcessAreaType) => { const rtnData = state.ProcessArea.processAreaList.find((item: ProcessAreaProps) => item.swtrmtFcltCd === swtrmtFcltCd); if (rtnData) { - upHeadListFcltyImproveInfo.forEach((head:TableUpperProps) => { - if(head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') { - head.title = rtnData.planYr? '현재\n(' + rtnData.planYr + '년)':head.title = '현재'; - } else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') { - head.title = rtnData.planYrDc1? '1단계\n(' + rtnData.planYrDc1 + '년)':head.title = '1단계'; - } else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') { - head.title = rtnData.planYrDc2? '2단계\n(' + rtnData.planYrDc2 + '년)':head.title = '2단계'; - } else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') { - head.title = rtnData.planYrDc3? '3단계\n(' + rtnData.planYrDc3 + '년)':head.title = '3단계'; - } else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') { - head.title = rtnData.planYrDc4? '4단계\n(' + rtnData.planYrDc4 + '년)':head.title = '4단계'; - } else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') { - head.title = rtnData.planYrDt4? '기승인\n4단계(' + rtnData.planYrDt4 + '년)':head.title = '기승인\n4단계'; + upHeadListFcltyImproveInfo.forEach((head: TableUpperProps) => { + if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') { + head.title = rtnData.planYr ? '현재\n(' + rtnData.planYr + '년)' : head.title = '현재'; + } else if (head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') { + head.title = rtnData.planYrDc1 ? '1단계\n(' + rtnData.planYrDc1 + '년)' : head.title = '1단계'; + } else if (head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') { + head.title = rtnData.planYrDc2 ? '2단계\n(' + rtnData.planYrDc2 + '년)' : head.title = '2단계'; + } else if (head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') { + head.title = rtnData.planYrDc3 ? '3단계\n(' + rtnData.planYrDc3 + '년)' : head.title = '3단계'; + } else if (head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') { + head.title = rtnData.planYrDc4 ? '4단계\n(' + rtnData.planYrDc4 + '년)' : head.title = '4단계'; + } else if (head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') { + head.title = rtnData.planYrDt4 ? '기승인\n4단계(' + rtnData.planYrDt4 + '년)' : head.title = '기승인\n4단계'; } }); - upHeadListProcessAreaPlan.forEach((head:TableUpperProps) => { - if(head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') { - head.title = rtnData.planYr? '현재\n(' + rtnData.planYr + '년)':head.title = '현재'; - } else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') { - head.title = rtnData.planYrDc1?'1단계\n(' + rtnData.planYrDc1 + '년)':head.title = '1단계'; - } else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') { - head.title = rtnData.planYrDc2?'2단계\n(' + rtnData.planYrDc2 + '년)':head.title = '2단계'; - } else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') { - head.title = rtnData.planYrDc3? '3단계\n(' + rtnData.planYrDc3 + '년)':head.title = '3단계'; - } else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') { - head.title = rtnData.planYrDc4?'4단계\n(' + rtnData.planYrDc4 + '년)':head.title = '4단계'; - } else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') { - head.title = rtnData.planYrDt4?'기승인\n4단계(' + rtnData.planYrDt4 + '년)':head.title = '기승인\n4단계'; + upHeadListProcessAreaPlan.forEach((head: TableUpperProps) => { + if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') { + head.title = rtnData.planYr ? '현재\n(' + rtnData.planYr + '년)' : head.title = '현재'; + } else if (head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') { + head.title = rtnData.planYrDc1 ? '1단계\n(' + rtnData.planYrDc1 + '년)' : head.title = '1단계'; + } else if (head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') { + head.title = rtnData.planYrDc2 ? '2단계\n(' + rtnData.planYrDc2 + '년)' : head.title = '2단계'; + } else if (head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') { + head.title = rtnData.planYrDc3 ? '3단계\n(' + rtnData.planYrDc3 + '년)' : head.title = '3단계'; + } else if (head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') { + head.title = rtnData.planYrDc4 ? '4단계\n(' + rtnData.planYrDc4 + '년)' : head.title = '4단계'; + } else if (head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') { + head.title = rtnData.planYrDt4 ? '기승인\n4단계(' + rtnData.planYrDt4 + '년)' : head.title = '기승인\n4단계'; } }); - upHeadListProcessPopulation.forEach((head:TableUpperProps) => { - if(head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') { - head.title = rtnData.planYr?'현재\n(' + rtnData.planYr + '년)':head.title = '현재'; - } else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') { - head.title = rtnData.planYrDc1?'1단계\n(' + rtnData.planYrDc1 + '년)':head.title = '1단계'; - } else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') { - head.title = rtnData.planYrDc2?'2단계\n(' + rtnData.planYrDc2 + '년)':head.title = '2단계'; - } else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') { - head.title = rtnData.planYrDc3?'3단계\n(' + rtnData.planYrDc3 + '년)':head.title = '3단계'; - } else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') { - head.title = rtnData.planYrDc4?'4단계\n(' + rtnData.planYrDc4 + '년)':head.title = '4단계'; - } else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') { - head.title = rtnData.planYrDt4?'기승인\n4단계(' + rtnData.planYrDt4 + '년)':head.title = '기승인\n4단계'; + upHeadListProcessPopulation.forEach((head: TableUpperProps) => { + if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') { + head.title = rtnData.planYr ? '현재\n(' + rtnData.planYr + '년)' : head.title = '현재'; + } else if (head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') { + head.title = rtnData.planYrDc1 ? '1단계\n(' + rtnData.planYrDc1 + '년)' : head.title = '1단계'; + } else if (head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') { + head.title = rtnData.planYrDc2 ? '2단계\n(' + rtnData.planYrDc2 + '년)' : head.title = '2단계'; + } else if (head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') { + head.title = rtnData.planYrDc3 ? '3단계\n(' + rtnData.planYrDc3 + '년)' : head.title = '3단계'; + } else if (head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') { + head.title = rtnData.planYrDc4 ? '4단계\n(' + rtnData.planYrDc4 + '년)' : head.title = '4단계'; + } else if (head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') { + head.title = rtnData.planYrDt4 ? '기승인\n4단계(' + rtnData.planYrDt4 + '년)' : head.title = '기승인\n4단계'; } }); - + // 시설증설 계획 데이터 생성 const fcltyImproveInfo: FcltyImproveInfoProps = { planSwageQntSumDt4: rtnData.planSwageQntSumDt4, From fe216499ec097caf6335a850b84bc09412e61c7d Mon Sep 17 00:00:00 2001 From: dongsilove Date: Mon, 12 Jan 2026 13:43:26 +0900 Subject: [PATCH 23/34] =?UTF-8?q?fo:=20=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../facilityWaterQlty/modal/page.tsx | 393 ++++++++---------- .../(with-layout)/facilityWaterQlty/page.tsx | 46 +- apps/fo/app/store/facilityWaterQlty/index.tsx | 317 +++++++------- 3 files changed, 346 insertions(+), 410 deletions(-) diff --git a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx index c10fd50cf..76c65ca3b 100644 --- a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx @@ -25,10 +25,10 @@ const commentArrayRain = [ "강우량 3mm 이상만 날과 강우영향일(강우일+2일)의 날" ]; -type ModalProps ={ +type ModalProps = { fcltyName: string; - facilityCd : string; - searchYear : string; + facilityCd: string; + searchYear: string; } const tabList1 = [ @@ -50,15 +50,15 @@ const tabList3 = [ { value: 'tab_term_winter_chongin', label: '동절기' } ]; -export default function WaterQualityModal({fcltyName='', facilityCd='', searchYear=new Date().getFullYear().toString()} : ModalProps) { +export default function WaterQualityModal({ fcltyName = '', facilityCd = '', searchYear = new Date().getFullYear().toString() }: ModalProps) { const [tabName, setTabName] = useState('tab_num1'); // 그리드 관련 - const {FacilityWaterQltyModal, + const { FacilityWaterQltyModal, searchFacilityWaterQltyListHist, Common } = useFoStore((state) => state); - const {btnClass, COD_YEAR} = Common; + const { btnClass, COD_YEAR } = Common; const { upHeadListModalYear, upHeadListModalYearCod, @@ -71,7 +71,7 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe const prevExcelListRef = useRef(null); const prevChoinginExcelListRef = useRef(null); - + // 필터링 된 후 최대, 최소, 평균 값 계산 const setFilterAfterData = (filteredData: FacilityWaterQltyProps[]) => { // 쉼표가 포함된 문자열을 숫자로 변환하는 함수 @@ -100,7 +100,7 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe let maxNoProcessInflAmnt = 0; let maxInfoRnDay = 0; - + // 초기값 설정 let minEfflWqltBod = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltBod) : 0; let minEfflWqltTn = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltTn) : 0; @@ -108,14 +108,14 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe let minefflWqltToc = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltToc) : 0; let minefflWqltCod = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltCod) : 0; let minEfflWqltSs = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltSs) : 0; - + let mininflAssctBfrWqltBod = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltBod) : 0; let mininflAssctBfrWqltTn = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltTn) : 0; let minInflAssctBfrWqltTp = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltTp) : 0; let mininflAssctBfrWqltToc = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltToc) : 0; let mininflAssctBfrWqltCod = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltCod) : 0; let mininflAssctBfrWqltSs = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltSs) : 0; - + let minTpInflWqltBod = 99999999; let minTpInflWqltTp = 99999999; let minNoProcessInflAmnt = 99999999; @@ -143,27 +143,27 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe let noProcessInflAmntCnt = 0; let avgInfoRnDay = 0; - + filteredData.forEach((item: FacilityWaterQltyProps) => { const efflWqltBod = parseNumber(item.efflWqltBod); const efflWqltTn = parseNumber(item.efflWqltTn); const efflWqltTp = parseNumber(item.efflWqltTp); const efflWqltToc = parseNumber(item.efflWqltToc); - const efflWqltCod = parseNumber(item.efflWqltCod?item.efflWqltCod.replaceAll("(","").replaceAll(")",""):0); + const efflWqltCod = parseNumber(item.efflWqltCod ? item.efflWqltCod.replaceAll("(", "").replaceAll(")", "") : 0); const efflWqltSs = parseNumber(item.efflWqltSs); const inflAssctBfrWqltBod = parseNumber(item.inflAssctBfrWqltBod); const inflAssctBfrWqltTn = parseNumber(item.inflAssctBfrWqltTn); const inflAssctBfrWqltTp = parseNumber(item.inflAssctBfrWqltTp); const inflAssctBfrWqltToc = parseNumber(item.inflAssctBfrWqltToc); - const inflAssctBfrWqltCod = parseNumber(item.inflAssctBfrWqltCod?item.inflAssctBfrWqltCod.replaceAll("(","").replaceAll(")",""):0); + const inflAssctBfrWqltCod = parseNumber(item.inflAssctBfrWqltCod ? item.inflAssctBfrWqltCod.replaceAll("(", "").replaceAll(")", "") : 0); const inflAssctBfrWqltSs = parseNumber(item.inflAssctBfrWqltSs); const tpInflWqltBod = parseNumber(item.tpInflWqltBod); const tpInflWqltTp = parseNumber(item.tpInflWqltTp); - if(item.tpInflWqltBod != null && item.tpInflWqltBod.trim() != '' && item.tpInflWqltBod != undefined ){ + if (item.tpInflWqltBod != null && item.tpInflWqltBod.trim() != '' && item.tpInflWqltBod != undefined) { tpInflWqltBodCnt += 1; } - if(item.tpInflWqltTp != null && item.tpInflWqltTp.trim() != '' && item.tpInflWqltTp != undefined ){ + if (item.tpInflWqltTp != null && item.tpInflWqltTp.trim() != '' && item.tpInflWqltTp != undefined) { tpInflWqltTpCnt += 1; } @@ -175,7 +175,7 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe maxefflWqltToc = Math.max(maxefflWqltToc, efflWqltToc); maxefflWqltCod = Math.max(maxefflWqltCod, efflWqltCod); maxEfflWqltSs = Math.max(maxEfflWqltSs, efflWqltSs); - + maxinflAssctBfrWqltBod = Math.max(maxinflAssctBfrWqltBod, inflAssctBfrWqltBod); maxinflAssctBfrWqltTn = Math.max(maxinflAssctBfrWqltTn, inflAssctBfrWqltTn); maxInflAssctBfrWqltTp = Math.max(maxInflAssctBfrWqltTp, inflAssctBfrWqltTp); @@ -202,11 +202,11 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe mininflAssctBfrWqltCod = Math.min(mininflAssctBfrWqltToc, inflAssctBfrWqltCod); mininflAssctBfrWqltSs = Math.min(mininflAssctBfrWqltSs, inflAssctBfrWqltSs); - if(item.tpInflWqltBod != null && item.tpInflWqltBod.trim() != '' && item.tpInflWqltBod != undefined ){ + if (item.tpInflWqltBod != null && item.tpInflWqltBod.trim() != '' && item.tpInflWqltBod != undefined) { minTpInflWqltBod = Math.min(minTpInflWqltBod, tpInflWqltBod); avgTpInflWqltBod += tpInflWqltBod; } - if(item.tpInflWqltTp != null && item.tpInflWqltTp.trim() != '' && item.tpInflWqltTp != undefined ){ + if (item.tpInflWqltTp != null && item.tpInflWqltTp.trim() != '' && item.tpInflWqltTp != undefined) { minTpInflWqltTp = Math.min(minTpInflWqltTp, tpInflWqltTp); avgTpInflWqltTp += tpInflWqltTp; } @@ -227,12 +227,12 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe avginflAssctBfrWqltCod += inflAssctBfrWqltCod; avginflAssctBfrWqltSs += inflAssctBfrWqltSs; - if(item.noProcessInflAmnt && item.noProcessInflAmnt.toString().trim() != '' && item.noProcessInflAmnt != undefined){ - const noProcessInflAmnt = Number(item.noProcessInflAmnt.toString().replaceAll(',','')); + if (item.noProcessInflAmnt && item.noProcessInflAmnt.toString().trim() != '' && item.noProcessInflAmnt != undefined) { + const noProcessInflAmnt = Number(item.noProcessInflAmnt.toString().replaceAll(',', '')); avgNoProcessInflAmnt += noProcessInflAmnt; maxNoProcessInflAmnt = Math.max(maxNoProcessInflAmnt, noProcessInflAmnt); minNoProcessInflAmnt = Math.min(minNoProcessInflAmnt, noProcessInflAmnt); - noProcessInflAmntCnt +=1; + noProcessInflAmntCnt += 1; } avgInfoRnDay += infoRnDay; @@ -241,18 +241,18 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe const newFilteredData = [ { msrDt: '평균', - efflWqltBod: filteredData.length==0 || avgEfflWqltBod===0?'0.0':roundNumber((avgEfflWqltBod / filteredData.length), 1), - efflWqltToc: filteredData.length==0 || avgefflWqltToc===0?'0.0':roundNumber((avgefflWqltToc / filteredData.length), 1), - efflWqltCod: filteredData.length==0 || avgefflWqltCod===0?"(0.0)":"("+roundNumber((avgefflWqltCod / filteredData.length), 1)+")", - efflWqltSs: filteredData.length==0 || avgEfflWqltSs===0?'0.0':roundNumber((avgEfflWqltSs / filteredData.length), 1), - efflWqltTn: filteredData.length==0 || avgEfflWqltTn ===0?'0.000':roundNumber((avgEfflWqltTn / filteredData.length), 3), - efflWqltTp: filteredData.length==0 || avgEfflWqltTp ===0?'0.000':roundNumber((avgEfflWqltTp / filteredData.length), 3), - inflAssctBfrWqltBod: filteredData.length==0 || avginflAssctBfrWqltBod===0?'0.0':roundNumber((avginflAssctBfrWqltBod / filteredData.length), 1), - inflAssctBfrWqltTn: filteredData.length==0 || avginflAssctBfrWqltTn===0?'0.000':roundNumber((avginflAssctBfrWqltTn / filteredData.length), 3), - inflAssctBfrWqltTp: filteredData.length==0 || avgInflAssctBfrWqltTp===0?'0.000':roundNumber((avgInflAssctBfrWqltTp / filteredData.length), 3), - inflAssctBfrWqltToc: filteredData.length==0 || avginflAssctBfrWqltToc===0?'0.0':roundNumber((avginflAssctBfrWqltToc / filteredData.length), 1), - inflAssctBfrWqltCod: filteredData.length==0 || avginflAssctBfrWqltCod===0?'(0.0)':"("+roundNumber((avginflAssctBfrWqltCod / filteredData.length), 1)+")", - inflAssctBfrWqltSs: filteredData.length==0 || avginflAssctBfrWqltSs===0?'0.0':roundNumber((avginflAssctBfrWqltSs / filteredData.length), 1), + efflWqltBod: filteredData.length == 0 || avgEfflWqltBod === 0 ? '0.0' : roundNumber((avgEfflWqltBod / filteredData.length), 1), + efflWqltToc: filteredData.length == 0 || avgefflWqltToc === 0 ? '0.0' : roundNumber((avgefflWqltToc / filteredData.length), 1), + efflWqltCod: filteredData.length == 0 || avgefflWqltCod === 0 ? "(0.0)" : "(" + roundNumber((avgefflWqltCod / filteredData.length), 1) + ")", + efflWqltSs: filteredData.length == 0 || avgEfflWqltSs === 0 ? '0.0' : roundNumber((avgEfflWqltSs / filteredData.length), 1), + efflWqltTn: filteredData.length == 0 || avgEfflWqltTn === 0 ? '0.000' : roundNumber((avgEfflWqltTn / filteredData.length), 3), + efflWqltTp: filteredData.length == 0 || avgEfflWqltTp === 0 ? '0.000' : roundNumber((avgEfflWqltTp / filteredData.length), 3), + inflAssctBfrWqltBod: filteredData.length == 0 || avginflAssctBfrWqltBod === 0 ? '0.0' : roundNumber((avginflAssctBfrWqltBod / filteredData.length), 1), + inflAssctBfrWqltTn: filteredData.length == 0 || avginflAssctBfrWqltTn === 0 ? '0.000' : roundNumber((avginflAssctBfrWqltTn / filteredData.length), 3), + inflAssctBfrWqltTp: filteredData.length == 0 || avgInflAssctBfrWqltTp === 0 ? '0.000' : roundNumber((avgInflAssctBfrWqltTp / filteredData.length), 3), + inflAssctBfrWqltToc: filteredData.length == 0 || avginflAssctBfrWqltToc === 0 ? '0.0' : roundNumber((avginflAssctBfrWqltToc / filteredData.length), 1), + inflAssctBfrWqltCod: filteredData.length == 0 || avginflAssctBfrWqltCod === 0 ? '(0.0)' : "(" + roundNumber((avginflAssctBfrWqltCod / filteredData.length), 1) + ")", + inflAssctBfrWqltSs: filteredData.length == 0 || avginflAssctBfrWqltSs === 0 ? '0.0' : roundNumber((avginflAssctBfrWqltSs / filteredData.length), 1), bscFctCd: "", bscFctNm: "", lclgvrnmntNm: "", @@ -260,25 +260,25 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe sggNm: "", addr: "", fctCpc: 0, - noProcessInflAmnt : roundNumber(avgNoProcessInflAmnt / noProcessInflAmntCnt, 0), - infoRnDay: filteredData.length==0 || avgInfoRnDay===0?'0.0':roundNumber(avgInfoRnDay / filteredData.length, 1), - tpInflWqltBod: filteredData.length==0 || avgTpInflWqltBod ===0 ?'0.0':roundNumber(avgTpInflWqltBod / tpInflWqltBodCnt, 1), - tpInflWqltTp: filteredData.length==0 || avgTpInflWqltTp === 0?'0.000':roundNumber(avgTpInflWqltTp / tpInflWqltTpCnt, 3) + noProcessInflAmnt: roundNumber(avgNoProcessInflAmnt / noProcessInflAmntCnt, 0), + infoRnDay: filteredData.length == 0 || avgInfoRnDay === 0 ? '0.0' : roundNumber(avgInfoRnDay / filteredData.length, 1), + tpInflWqltBod: filteredData.length == 0 || avgTpInflWqltBod === 0 ? '0.0' : roundNumber(avgTpInflWqltBod / tpInflWqltBodCnt, 1), + tpInflWqltTp: filteredData.length == 0 || avgTpInflWqltTp === 0 ? '0.000' : roundNumber(avgTpInflWqltTp / tpInflWqltTpCnt, 3) }, { - msrDt : '최대', - efflWqltBod : Math.round(maxEfflWqltBod * 10) / 10?roundNumber(maxEfflWqltBod, 1):'0.0', - efflWqltToc : Math.round(maxefflWqltToc * 10) / 10?roundNumber(maxefflWqltToc, 1):'0.0', - efflWqltCod : Math.round(maxefflWqltCod * 10) / 10?"("+roundNumber(maxefflWqltCod, 1)+")":'(0.0)', - efflWqltSs : Math.round(maxEfflWqltSs * 10) / 10?roundNumber(maxEfflWqltSs, 1):'0.0', - efflWqltTn : Math.round(maxEfflWqltTn * 1000) / 1000?roundNumber(maxEfflWqltTn, 3):'0.000', - efflWqltTp : Math.round(maxEfflWqltTp * 1000) / 1000?roundNumber(maxEfflWqltTp, 3):'0.000', - inflAssctBfrWqltBod : Math.round(maxinflAssctBfrWqltBod * 10) / 10?roundNumber(maxinflAssctBfrWqltBod, 1):'0.0', - inflAssctBfrWqltTn : Math.round(maxinflAssctBfrWqltTn * 1000) / 1000?roundNumber(maxinflAssctBfrWqltTn, 3):'0.000', - inflAssctBfrWqltTp : Math.round(maxInflAssctBfrWqltTp * 1000) / 1000?roundNumber(maxInflAssctBfrWqltTp, 3):'0.000', - inflAssctBfrWqltToc : Math.round(maxinflAssctBfrWqltToc * 10) / 10?roundNumber(maxinflAssctBfrWqltToc, 1):'0.0', - inflAssctBfrWqltCod : Math.round(maxinflAssctBfrWqltCod * 10) / 10?"("+roundNumber(maxinflAssctBfrWqltCod, 1)+")":'(0.0)', - inflAssctBfrWqltSs : Math.round(maxinflAssctBfrWqltSs * 10) / 10?roundNumber(maxinflAssctBfrWqltSs, 1):'0.0', + msrDt: '최대', + efflWqltBod: Math.round(maxEfflWqltBod * 10) / 10 ? roundNumber(maxEfflWqltBod, 1) : '0.0', + efflWqltToc: Math.round(maxefflWqltToc * 10) / 10 ? roundNumber(maxefflWqltToc, 1) : '0.0', + efflWqltCod: Math.round(maxefflWqltCod * 10) / 10 ? "(" + roundNumber(maxefflWqltCod, 1) + ")" : '(0.0)', + efflWqltSs: Math.round(maxEfflWqltSs * 10) / 10 ? roundNumber(maxEfflWqltSs, 1) : '0.0', + efflWqltTn: Math.round(maxEfflWqltTn * 1000) / 1000 ? roundNumber(maxEfflWqltTn, 3) : '0.000', + efflWqltTp: Math.round(maxEfflWqltTp * 1000) / 1000 ? roundNumber(maxEfflWqltTp, 3) : '0.000', + inflAssctBfrWqltBod: Math.round(maxinflAssctBfrWqltBod * 10) / 10 ? roundNumber(maxinflAssctBfrWqltBod, 1) : '0.0', + inflAssctBfrWqltTn: Math.round(maxinflAssctBfrWqltTn * 1000) / 1000 ? roundNumber(maxinflAssctBfrWqltTn, 3) : '0.000', + inflAssctBfrWqltTp: Math.round(maxInflAssctBfrWqltTp * 1000) / 1000 ? roundNumber(maxInflAssctBfrWqltTp, 3) : '0.000', + inflAssctBfrWqltToc: Math.round(maxinflAssctBfrWqltToc * 10) / 10 ? roundNumber(maxinflAssctBfrWqltToc, 1) : '0.0', + inflAssctBfrWqltCod: Math.round(maxinflAssctBfrWqltCod * 10) / 10 ? "(" + roundNumber(maxinflAssctBfrWqltCod, 1) + ")" : '(0.0)', + inflAssctBfrWqltSs: Math.round(maxinflAssctBfrWqltSs * 10) / 10 ? roundNumber(maxinflAssctBfrWqltSs, 1) : '0.0', bscFctCd: "", bscFctNm: "", lclgvrnmntNm: "", @@ -286,25 +286,25 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe sggNm: "", addr: "", fctCpc: 0, - noProcessInflAmnt : roundNumber(maxNoProcessInflAmnt, 0), - infoRnDay: Math.round(maxInfoRnDay * 10) / 10?roundNumber(maxInfoRnDay, 1):'0.0', - tpInflWqltBod: Math.round(maxTpInflWqltBod * 10) / 10?roundNumber(maxTpInflWqltBod, 1):'0.0', - tpInflWqltTp: Math.round(maxTpInflWqltTp * 1000) / 1000?roundNumber(maxTpInflWqltTp, 3):'0.000' + noProcessInflAmnt: roundNumber(maxNoProcessInflAmnt, 0), + infoRnDay: Math.round(maxInfoRnDay * 10) / 10 ? roundNumber(maxInfoRnDay, 1) : '0.0', + tpInflWqltBod: Math.round(maxTpInflWqltBod * 10) / 10 ? roundNumber(maxTpInflWqltBod, 1) : '0.0', + tpInflWqltTp: Math.round(maxTpInflWqltTp * 1000) / 1000 ? roundNumber(maxTpInflWqltTp, 3) : '0.000' }, { - msrDt : '최소', - efflWqltBod : Math.round(minEfflWqltBod * 10) / 10?roundNumber(minEfflWqltBod, 1) : '0.0', - efflWqltToc : Math.round(minefflWqltToc * 10) / 10?roundNumber(minefflWqltToc, 1) : '0.0', - efflWqltCod : Math.round(minefflWqltCod * 10) / 10?"("+roundNumber(minefflWqltCod, 1)+")" : '(0.0)', - efflWqltSs : Math.round(minEfflWqltSs * 10) / 10?roundNumber(minEfflWqltSs, 1) : '0.0', - efflWqltTn : Math.round(minEfflWqltTn * 1000) / 1000?roundNumber(minEfflWqltTn, 3) : '0.000', - efflWqltTp : Math.round(minEfflWqltTp * 1000) / 1000?roundNumber(minEfflWqltTp, 3) : '0.000', - inflAssctBfrWqltBod : Math.round(mininflAssctBfrWqltBod * 10) / 10?roundNumber(mininflAssctBfrWqltBod, 1) : '0.0', - inflAssctBfrWqltTn : Math.round(mininflAssctBfrWqltTn * 1000) / 1000?roundNumber(mininflAssctBfrWqltTn, 3) : '0.000', - inflAssctBfrWqltTp : Math.round(minInflAssctBfrWqltTp * 1000) / 1000?roundNumber(minInflAssctBfrWqltTp, 3) : '0.000', - inflAssctBfrWqltToc : Math.round(mininflAssctBfrWqltToc * 10) / 10?roundNumber(mininflAssctBfrWqltToc, 1) : '0.0', - inflAssctBfrWqltCod : Math.round(mininflAssctBfrWqltCod * 10) / 10?"("+roundNumber(mininflAssctBfrWqltCod, 1)+")" : '(0.0)', - inflAssctBfrWqltSs : Math.round(mininflAssctBfrWqltSs * 10) / 10?roundNumber(mininflAssctBfrWqltSs, 1) : '0.0', + msrDt: '최소', + efflWqltBod: Math.round(minEfflWqltBod * 10) / 10 ? roundNumber(minEfflWqltBod, 1) : '0.0', + efflWqltToc: Math.round(minefflWqltToc * 10) / 10 ? roundNumber(minefflWqltToc, 1) : '0.0', + efflWqltCod: Math.round(minefflWqltCod * 10) / 10 ? "(" + roundNumber(minefflWqltCod, 1) + ")" : '(0.0)', + efflWqltSs: Math.round(minEfflWqltSs * 10) / 10 ? roundNumber(minEfflWqltSs, 1) : '0.0', + efflWqltTn: Math.round(minEfflWqltTn * 1000) / 1000 ? roundNumber(minEfflWqltTn, 3) : '0.000', + efflWqltTp: Math.round(minEfflWqltTp * 1000) / 1000 ? roundNumber(minEfflWqltTp, 3) : '0.000', + inflAssctBfrWqltBod: Math.round(mininflAssctBfrWqltBod * 10) / 10 ? roundNumber(mininflAssctBfrWqltBod, 1) : '0.0', + inflAssctBfrWqltTn: Math.round(mininflAssctBfrWqltTn * 1000) / 1000 ? roundNumber(mininflAssctBfrWqltTn, 3) : '0.000', + inflAssctBfrWqltTp: Math.round(minInflAssctBfrWqltTp * 1000) / 1000 ? roundNumber(minInflAssctBfrWqltTp, 3) : '0.000', + inflAssctBfrWqltToc: Math.round(mininflAssctBfrWqltToc * 10) / 10 ? roundNumber(mininflAssctBfrWqltToc, 1) : '0.0', + inflAssctBfrWqltCod: Math.round(mininflAssctBfrWqltCod * 10) / 10 ? "(" + roundNumber(mininflAssctBfrWqltCod, 1) + ")" : '(0.0)', + inflAssctBfrWqltSs: Math.round(mininflAssctBfrWqltSs * 10) / 10 ? roundNumber(mininflAssctBfrWqltSs, 1) : '0.0', bscFctCd: "", bscFctNm: "", lclgvrnmntNm: "", @@ -312,10 +312,10 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe sggNm: "", addr: "", fctCpc: 0, - noProcessInflAmnt : roundNumber(minNoProcessInflAmnt, 0), - infoRnDay: Math.round(minInfoRnDay * 10) / 10?'0.0':roundNumber(minInfoRnDay, 1), - tpInflWqltBod: Math.round(minTpInflWqltBod * 10) / 10 && minTpInflWqltBod != 99999999?roundNumber(minTpInflWqltBod, 1):'0.0', - tpInflWqltTp: Math.round(minTpInflWqltTp * 1000) / 1000 && minTpInflWqltTp != 99999999?roundNumber(minTpInflWqltTp, 3):'0.000' + noProcessInflAmnt: roundNumber(minNoProcessInflAmnt, 0), + infoRnDay: Math.round(minInfoRnDay * 10) / 10 ? '0.0' : roundNumber(minInfoRnDay, 1), + tpInflWqltBod: Math.round(minTpInflWqltBod * 10) / 10 && minTpInflWqltBod != 99999999 ? roundNumber(minTpInflWqltBod, 1) : '0.0', + tpInflWqltTp: Math.round(minTpInflWqltTp * 1000) / 1000 && minTpInflWqltTp != 99999999 ? roundNumber(minTpInflWqltTp, 3) : '0.000' }, ...filteredData ]; @@ -326,7 +326,7 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe // 날짜 필터링 관련 상태 const [copyYearList, setCopyYearList] = useState([]); const [chongInWaterQltyYearList, setChongInWaterQltyYearList] = useState([]); - + useEffect(() => { searchFacilityWaterQltyListHist(searchYear, facilityCd); }, [searchYear, facilityCd, searchFacilityWaterQltyListHist]); @@ -354,10 +354,10 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe }, []); const excelDownload = () => { - - if(tabName === 'tab_num1'){ + + if (tabName === 'tab_num1') { //처리시설 수질현황 const excelDownList: modalExcelType[] = []; - if(copyYearList.length > 0){ + if (copyYearList.length > 0) { copyYearList.forEach((item) => { excelDownList.push({ 날짜: item.msrDt, @@ -371,26 +371,27 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe "유출SS(mg/L)": CommaToNumber(item.efflWqltSs), "유출TN(mg/L)": CommaToNumber(item.efflWqltTn), "유출TP(mg/L)": CommaToNumber(item.efflWqltTp), - "강우량(mm/일)": CommaToNumber(item.infoRnDay?item.infoRnDay.toString():"0.0"), + "강우량(mm/일)": CommaToNumber(item.infoRnDay ? item.infoRnDay.toString() : "0.0"), }); }); } if (excelDownList && excelDownList.length > 0) { downloadExcelFormat( - { data: JSON.parse(JSON.stringify(excelDownList)) - , fileName: searchYear+'년 '+fcltyName + ' 수질현황' + { + data: JSON.parse(JSON.stringify(excelDownList)) + , fileName: searchYear + '년 ' + fcltyName + ' 수질현황' , sheetNameArray: [fcltyName + ' 수질현황'] , headerRange: 'A1:L1' - , decimalArray1: [1,2,3,6,7,8,11] - , decimalArray3: [4,5,9,10] + , decimalArray1: [1, 2, 3, 6, 7, 8, 11] + , decimalArray3: [4, 5, 9, 10] }); } else if (prevExcelListRef.current && prevExcelListRef.current.length > 0) { alert('다운받을 데이터가 없습니다.'); } prevExcelListRef.current = excelDownList; - }else{ + } else { // 총인설비 수질현황 const excelDownList: modalChoinginExcelType[] = []; - if(chongInWaterQltyYearList.length > 0){ + if (chongInWaterQltyYearList.length > 0) { chongInWaterQltyYearList.forEach((item) => { excelDownList.push({ 날짜: item.msrDt, @@ -403,12 +404,13 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe } if (excelDownList && excelDownList.length > 0) { downloadExcelFormat( - { data: JSON.parse(JSON.stringify(excelDownList)) - , fileName: searchYear+'년 '+fcltyName + ' 총인설비수질현황' + { + data: JSON.parse(JSON.stringify(excelDownList)) + , fileName: searchYear + '년 ' + fcltyName + ' 총인설비수질현황' , sheetNameArray: [fcltyName + ' 총인설비수질현황'] , headerRange: 'A1:E1' - , decimalArray1: [1,3] - , decimalArray3: [2,4] + , decimalArray1: [1, 3] + , decimalArray3: [2, 4] }); } else if (prevChoinginExcelListRef.current && prevChoinginExcelListRef.current.length > 0) { alert('다운받을 데이터가 없습니다.'); @@ -424,7 +426,7 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe return ( <> setTabName(value)}> - {/* 처리시설 수질현황 */} @@ -433,24 +435,16 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe searchList={facilityWaterQltyYearList} - fcltyCd={facilityCd} - fcltyName={fcltyName} - tabName={"tab_term_year"} - searchYear={searchYear} - ref={ref} - queryClick={filterData} + fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_year" + searchYear={searchYear} ref={ref} queryClick={filterData} />
- {}} - className="h-[310px]" - boldArray={[0,1,2]} + { }} className="h-[310px]" boldArray={[0, 1, 2]} > @@ -460,132 +454,97 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe {/*

({msrmtDate?msrmtDate.substring(0,4)+'-'+msrmtDate.substring(4,6)+'-'+msrmtDate.substring(6,8):yesterDayStr})

*/}
- {}} - boldArray={[0,1,2]} + { }} boldArray={[0, 1, 2]} > - {msrmtDate != yesterDayStr?.replaceAll('-','') ? ( - + {msrmtDate != yesterDayStr?.replaceAll('-', '') ? ( + ) : null}
- + {/* 하절기 */} searchList={facilityWaterQltyYearList} - fcltyCd={facilityCd} - fcltyName={fcltyName} - tabName="tab_term_summer" - searchYear={searchYear} - ref={ref} - queryClick={filterData} + fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_summer" + searchYear={searchYear} ref={ref} queryClick={filterData} />
- { } } - className="h-[500px]" - boldArray={[0,1,2]} + headlist={Number(searchYear) < COD_YEAR ? upHeadListModalYearCod : upHeadListModalYear} + pageSize={0} total={0} cellClick={undefined} + onPageChange={() => { }} className="h-[500px]" boldArray={[0, 1, 2]} >
- + {/* 동절기 */} searchList={facilityWaterQltyYearList} - fcltyCd={facilityCd} - fcltyName={fcltyName} - tabName="tab_term_winter" - searchYear={searchYear} - ref={ref} - queryClick={filterData} + fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_winter" + searchYear={searchYear} ref={ref} queryClick={filterData} />
- {}} - className="h-[500px]" - boldArray={[0,1,2]} + { }} className="h-[500px]" boldArray={[0, 1, 2]} >
- + {/* 청천 */} searchList={facilityWaterQltyYearList} - fcltyCd={facilityCd} - fcltyName={fcltyName} - tabName="tab_term_chuncheon" - searchYear={searchYear} - ref={ref} - queryClick={filterData} + fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_chuncheon" + searchYear={searchYear} ref={ref} queryClick={filterData} />
- {}} - className="h-[500px]" - boldArray={[0,1,2]} + { }} className="h-[500px]" boldArray={[0, 1, 2]} >
- +
- + {/* 강우시 */} searchList={facilityWaterQltyYearList} - fcltyCd={facilityCd} - fcltyName={fcltyName} - tabName="tab_term_rain" - searchYear={searchYear} - ref={ref} - queryClick={filterData} + fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_rain" + searchYear={searchYear} ref={ref} queryClick={filterData} />
- {}} - className="h-[500px]" - boldArray={[0,1,2]} + { }} className="h-[500px]" boldArray={[0, 1, 2]} >
- +
@@ -596,24 +555,16 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe searchList={chongInWaterQltyYearList} - fcltyCd={facilityCd} - fcltyName={fcltyName} - tabName="tab_term_year" - searchYear={searchYear} - ref={ref} - queryClick={filterData} + fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_year" + searchYear={searchYear} ref={ref} queryClick={filterData} />
- {}} - className="h-[500px]" - boldArray={[0,1,2]} + { }} className="h-[500px]" boldArray={[0, 1, 2]} > @@ -623,24 +574,16 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe searchList={chongInWaterQltyYearList} - fcltyCd={facilityCd} - fcltyName={fcltyName} - tabName="tab_term_summer" - searchYear={searchYear} - ref={ref} - queryClick={filterData} + fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_summer" + searchYear={searchYear} ref={ref} queryClick={filterData} />
- {}} - className="h-[500px]" - boldArray={[0,1,2]} + { }} className="h-[500px]" boldArray={[0, 1, 2]} > @@ -650,24 +593,16 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe searchList={chongInWaterQltyYearList} - fcltyCd={facilityCd} - fcltyName={fcltyName} - tabName="tab_term_winter" - searchYear={searchYear} - ref={ref} - queryClick={filterData} + fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_winter" + searchYear={searchYear} ref={ref} queryClick={filterData} />
- {}} - className="h-[500px]" - boldArray={[0,1,2]} + pageSize={0} total={0} cellClick={undefined} + onPageChange={() => { }} className="h-[500px]" boldArray={[0, 1, 2]} > diff --git a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/page.tsx b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/page.tsx index 885ee2728..86a434d6b 100644 --- a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/page.tsx @@ -23,7 +23,7 @@ export default function ProcessFacilitySearch() { } = useFoStore((state) => state) || { FacilityWaterQltyList: { facilityWaterQltyList: [], facilityWaterQltyCount: 0 } }; const { - isInit, + isInit, selectUpdownData, selectOperationData, selectSidoData, @@ -66,26 +66,26 @@ export default function ProcessFacilitySearch() { const [fcltyCd, setFcltyCd] = useState(""); const [modalYear, setModalYear] = useState(""); - const searchFcltyQltyList = useCallback(({ partValue, regionValue, unitWaterShedValue, middleRegionValue, envPartValue, sidoValue, sigunValue }: ReturnType, pageNo: number, pageCnt:number=20) => { + const searchFcltyQltyList = useCallback(({ partValue, regionValue, unitWaterShedValue, middleRegionValue, envPartValue, sidoValue, sigunValue }: ReturnType, pageNo: number, pageCnt: number = 20) => { let nameCd, partStr; switch (partValue) { case 'R': if (regionValue !== '0') { - if(unitWaterShedValue==='0') nameCd = regionValue; - else if (middleRegionValue==='0') nameCd = unitWaterShedValue; + if (unitWaterShedValue === '0') nameCd = regionValue; + else if (middleRegionValue === '0') nameCd = unitWaterShedValue; else nameCd = middleRegionValue; } partStr = partValue break; default: - if(sidoValue !== '0') nameCd = ref.current.sidoValue!="0"?ref.current.sidoValue:sidoValue; - if(sigunValue !== '0') nameCd = sigunValue; - partStr = envPartValue !== '0' ? envPartValue:partValue; - break; + if (sidoValue !== '0') nameCd = ref.current.sidoValue != "0" ? ref.current.sidoValue : sidoValue; + if (sigunValue !== '0') nameCd = sigunValue; + partStr = envPartValue !== '0' ? envPartValue : partValue; + break; } - if(partStr ==='G'){ + if (partStr === 'G') { searchFacilityWaterQltyList(pageNo, pageCnt, searchYearValue); - }else{ + } else { searchFacilityWaterQltyList(pageNo, pageCnt, searchYearValue, partStr, nameCd || '0', fcltCpct, operationValue, fcltyName.trim() !== "" || fcltyName.trim() !== null ? fcltyName : undefined); } }, [operationValue, fcltyName, searchFacilityWaterQltyList, searchYearValue, fcltCpct]); @@ -138,34 +138,34 @@ export default function ProcessFacilitySearch() { useEffect(() => { if (!isInit) { - if(!initTrigger){ + if (!initTrigger) { initializeCommonData(); searchFcltyQltyList(ref.current, 1, 10); - setInitTrigger(true); + setInitTrigger(true); } } }, [isInit, initializeCommonData, searchFacilityWaterQltyList, searchFcltyQltyList, initTrigger]); useEffect(() => { - if(!excelTrigger) return; + if (!excelTrigger) return; if (excelList && excelList.length > 0) { downloadExcelFormat( { - data: excelList as unknown as JSON[], - fileName: '시설별 수질현황', - sheetNameArray: ['시설별 수질현황'], + data: excelList as unknown as JSON[], + fileName: '시설별 수질현황', + sheetNameArray: ['시설별 수질현황'], headerRange: 'A1:T1', - decimalArray1:[10,11,12,15,16,17], - decimalArray3:[13,14,18,19] + decimalArray1: [10, 11, 12, 15, 16, 17], + decimalArray3: [13, 14, 18, 19] } ); } }, [excelList, excelTrigger]); - const chkVal = useCallback((returntype:ReturnType) => { + const chkVal = useCallback((returntype: ReturnType) => { // setWidthSize(returntype.partValue=='A' ?"w-[120%]":"w-[130%]") - setUpheadList(returntype.partValue == 'R' ? upHeadList2 : returntype.partValue == 'G'?upHeadList3:upHeadList1); + setUpheadList(returntype.partValue == 'R' ? upHeadList2 : returntype.partValue == 'G' ? upHeadList3 : upHeadList1); setResetPage(true); }, [upHeadList1, upHeadList2, upHeadList3]); @@ -173,7 +173,7 @@ export default function ProcessFacilitySearch() { setExcelTrigger(true); searchFcltyQltyList(ref.current, 1, 10000); }, [searchFcltyQltyList]); - + const handlePageChange = useCallback((page: number) => { setResetPage(false); searchFcltyQltyList(ref.current, page, 10); @@ -202,7 +202,7 @@ export default function ProcessFacilitySearch() { queryClick={chkVal} excelClick={excelDownload} initClick={resetVal} - ref={ref} isAdmin={false} initSidoValue={"11"}/> + ref={ref} isAdmin={false} initSidoValue={"11"} />
@@ -215,7 +215,7 @@ export default function ProcessFacilitySearch() { {selectedRow !== null && ( } - bodyClass="sm:max-w-[90vw] w-[1300px] h-[920px]" + bodyClass="sm:max-w-[90vw] w-[1300px] h-[100dvh] max-h-[930px] overflow-y-auto" open={selectedRow !== null} onOpenChange={(open) => !open && closeModal()} noHeaderYn="Y" diff --git a/apps/fo/app/store/facilityWaterQlty/index.tsx b/apps/fo/app/store/facilityWaterQlty/index.tsx index 0eafcfcd0..5d2e886f4 100644 --- a/apps/fo/app/store/facilityWaterQlty/index.tsx +++ b/apps/fo/app/store/facilityWaterQlty/index.tsx @@ -37,8 +37,8 @@ export interface FacilityWaterQltyProps { inflAssctAftWqltBod: string | '', inflAssctBfrWqltToc: string | '', inflAssctAftWqltToc: string | '', - inflAssctBfrWqltCod : string | '', - inflAssctAftWqltCod : string | '', + inflAssctBfrWqltCod: string | '', + inflAssctAftWqltCod: string | '', inflAssctBfrWqltSs: string | '', inflAssctAftWqltSs: string | '', inflAssctBfrWqltTn: string | '', @@ -47,14 +47,14 @@ export interface FacilityWaterQltyProps { inflAssctAftWqltTp: string | '', efflWqltBod: string | '', efflWqltToc: string | '', - efflWqltCod : string | '', + efflWqltCod: string | '', efflWqltSs: string | '', efflWqltTn: string | '', efflWqltTp: string | '', - rgnNm:string|'', - rvbsn:string|'', - lgbsn:string|'', - mdmbsn:string|'', + rgnNm: string | '', + rvbsn: string | '', + lgbsn: string | '', + mdmbsn: string | '', inflAmnt: number | '', lclgvrnmntNm: string, infoRnDay: number | string | '', @@ -68,14 +68,14 @@ export interface FacilityWaterQltyProps { tpInflWqltTp: string | '', tpInflWqltEclgyTox: string | '', tpInflWqltClfgrpcnt: string | '', - noProcessInflAmnt : string | number | '', + noProcessInflAmnt: string | number | '', } export interface ExcelType { 시설코드: string, - 권역:string|'', - 단위유역:string|'', - 중권역:string|'', - 환경청:string|'', + 권역: string | '', + 단위유역: string | '', + 중권역: string | '', + 환경청: string | '', 시도: string, 시군구: string, 시설이름: string, @@ -146,74 +146,74 @@ const mainLabelArray: string[] = ['구분', '시도', '시군구', '용량별', // 시설수질리스트 헤더(행정별) const upHeadList1: TableUpperProps[] = [ - { id: "C", title: "행정명", colSpan: 2, row:0, widthPercent:10 }, - { id: "sidoNm", title: "시도", row: 1, widthPercent:5}, - { id: "sggNm", title: "시군구", row: 1, widthPercent:5 }, + { id: "C", title: "행정명", colSpan: 2, row: 0, widthPercent: 10 }, + { id: "sidoNm", title: "시도", row: 1, widthPercent: 5 }, + { id: "sggNm", title: "시군구", row: 1, widthPercent: 5 }, { id: "bscFctNm", title: "시설명", rowSpan: 2, row: 0, widthPercent: 10 }, { id: "addr", title: "주소", rowSpan: 2, row: 0 }, - { id: "fctCpc", title: "시설용량(m³/일)", align: "right", rowSpan: 2, row: 0, widthPercent:10 }, - { id: "A", title: "유입", colSpan: 5, row: 0, widthPercent:25 }, - { id: "B", title: "방류", colSpan: 5, row: 0, widthPercent:25 }, - { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row: 1, widthPercent:5 }, - { id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent:5 }, - { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent:5 }, - { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 4, align: "right", row: 1, widthPercent:5 }, - { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent:5 }, - { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row: 1, widthPercent:5 }, - { id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent:5 }, - { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent:5 }, - { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 4, align: "right", row: 1, widthPercent:5 }, - { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent:5 }, + { id: "fctCpc", title: "시설용량(m³/일)", align: "right", rowSpan: 2, row: 0, widthPercent: 10 }, + { id: "A", title: "유입", colSpan: 5, row: 0, widthPercent: 25 }, + { id: "B", title: "방류", colSpan: 5, row: 0, widthPercent: 25 }, + { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row: 1, widthPercent: 5 }, + { id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent: 5 }, + { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent: 5 }, + { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 4, align: "right", row: 1, widthPercent: 5 }, + { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent: 5 }, + { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row: 1, widthPercent: 5 }, + { id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent: 5 }, + { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent: 5 }, + { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 4, align: "right", row: 1, widthPercent: 5 }, + { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent: 5 }, ]; // 시설수질리스트 헤더(권역별) const upHeadList2: TableUpperProps[] = [ - { id: "C", title: "유역", colSpan: 3, row: 0, widthPercent:15 }, - { id: "rvbsn", title: "권역", upName: "upChangeRe1", upSequnce: 1, row:1, widthPercent:5 }, - { id: "lgbsn", title: "단위유역", upName: "upChangeRe1", upSequnce: 2, row:1, widthPercent:5 }, - { id: "mdmbsn", title: "중권역", upName: "upChangeRe1", upSequnce: 3, row:1, widthPercent:5 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent:10 }, - { id: "addr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/L)", align: "right", row:0, rowSpan:2, widthPercent:8 }, - { id: "A", title: "유입", colSpan: 5, row: 0, widthPercent:25 }, - { id: "B", title: "방류", colSpan: 5, row: 0, widthPercent:25 }, - { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row:1, widthPercent:5 }, - { id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1, widthPercent:5 }, - { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1, widthPercent:5 }, - { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1, widthPercent:5 }, - { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1, widthPercent:5 }, - { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row:1, widthPercent:5 }, - { id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1, widthPercent:5 }, - { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1, widthPercent:5 }, - { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1, widthPercent:5 }, - { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1, widthPercent:5 }, + { id: "C", title: "유역", colSpan: 3, row: 0, widthPercent: 15 }, + { id: "rvbsn", title: "권역", upName: "upChangeRe1", upSequnce: 1, row: 1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", upName: "upChangeRe1", upSequnce: 2, row: 1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", upName: "upChangeRe1", upSequnce: 3, row: 1, widthPercent: 5 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "addr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량(m³/L)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "A", title: "유입", colSpan: 5, row: 0, widthPercent: 25 }, + { id: "B", title: "방류", colSpan: 5, row: 0, widthPercent: 25 }, + { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row: 1, widthPercent: 5 }, + { id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent: 5 }, + { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent: 5 }, + { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent: 5 }, + { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent: 5 }, + { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row: 1, widthPercent: 5 }, + { id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent: 5 }, + { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent: 5 }, + { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent: 5 }, + { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent: 5 }, ]; // 시설수질리스트 헤더(환경청별) const upHeadList3: TableUpperProps[] = [ { id: "C", title: "유역", colSpan: 3, row: 0, widthPercent: 15 }, - { id: "rvbsn", title: "권역", row:1, widthPercent: 5 }, - { id: "lgbsn", title: "단위유역", row:1, widthPercent: 5 }, - { id: "mdmbsn", title: "중권역", row:1, widthPercent: 5 }, - { id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 7 }, + { id: "rvbsn", title: "권역", row: 1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", row: 1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", row: 1, widthPercent: 5 }, + { id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 7 }, { id: "D", title: "행정명", colSpan: 2, row: 0, widthPercent: 10 }, - { id: "sidoNm", title: "시도", upName: "upChangeRe2", row:1, widthPercent: 5 }, - { id: "sggNm", title: "시군구", upName: "upChangeRe2", row:1, widthPercent: 5 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, - { id: "addr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/L)", align: "right", row:0, rowSpan:2, widthPercent: 5 }, + { id: "sidoNm", title: "시도", upName: "upChangeRe2", row: 1, widthPercent: 5 }, + { id: "sggNm", title: "시군구", upName: "upChangeRe2", row: 1, widthPercent: 5 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "addr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량(m³/L)", align: "right", row: 0, rowSpan: 2, widthPercent: 5 }, { id: "A", title: "유입", colSpan: 5, row: 0, widthPercent: 20 }, { id: "B", title: "방류", colSpan: 5, row: 0, widthPercent: 20 }, - { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row:1, widthPercent: 4 }, - { id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1, widthPercent: 4 }, - { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1, widthPercent: 4 }, - { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1, widthPercent: 4 }, - { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1, widthPercent: 4 }, - { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row:1, widthPercent: 4 }, - { id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1, widthPercent: 4 }, - { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1, widthPercent: 4 }, - { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1, widthPercent: 4 }, - { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1, widthPercent: 4 }, + { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row: 1, widthPercent: 4 }, + { id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent: 4 }, + { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent: 4 }, + { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent: 4 }, + { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent: 4 }, + { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row: 1, widthPercent: 4 }, + { id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent: 4 }, + { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent: 4 }, + { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent: 4 }, + { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent: 4 }, ]; /** @@ -282,9 +282,9 @@ const upHeadListModalChongIn: TableUpperProps[] = [ ====================================*/ // 메인페이지 // 시설정보 수질 리스트 데이터 호출 -const fetchFacilityWaterQltyList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string|undefined, nameCd?: string|undefined, fcltCpct?: string|undefined, operationValue?: string|undefined, fcltyNm?: string | undefined): Promise<{ data: FacilityWaterQltyProps[], count: number }> => { +const fetchFacilityWaterQltyList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string | undefined, nameCd?: string | undefined, fcltCpct?: string | undefined, operationValue?: string | undefined, fcltyNm?: string | undefined): Promise<{ data: FacilityWaterQltyProps[], count: number }> => { try { - const tailStr = partCd ? '/'+ partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : ''; + const tailStr = partCd ? '/' + partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : ''; const url = '/fclt/qlty/' + pageNo + '/' + pageSize + '/' + searchYear + tailStr; const res = await getFetch('fo', url); return { data: res.data, count: res.count } @@ -295,7 +295,7 @@ const fetchFacilityWaterQltyList = async (pageNo: number, pageSize: number, sear } // 시설정보 수질 리스트 데이터 호출(모달-수질TMS) -const fetchFacilityWaterQltyTmsList = async (facilityCd: string|undefined) => { +const fetchFacilityWaterQltyTmsList = async (facilityCd: string | undefined) => { try { const res = await getFetch('wr', '/il/getTms/' + facilityCd); return { data: res.data, count: res.count }; @@ -306,7 +306,7 @@ const fetchFacilityWaterQltyTmsList = async (facilityCd: string|undefined) => { }; // 시설정보 수질 리스트 데이터 호출(모달-이력) -export const fetchFacilityWaterQltyListHist = async (searchYear: string|undefined, facilityCd: string|undefined): Promise => { +export const fetchFacilityWaterQltyListHist = async (searchYear: string | undefined, facilityCd: string | undefined): Promise => { try {// const res = await getFetch('fo', '/fclt/qlty/hist/' + searchYear + '/' + facilityCd); return res; @@ -316,9 +316,9 @@ export const fetchFacilityWaterQltyListHist = async (searchYear: string|undefine } }; // 시설정보 RDII 상세 [{BOD - inflAssctBfrWqltBod, 유입유량 inflAmnt, 강우량 infoRnDay, 측정일 msrDt}] -export const fetchFacilityRdiiDetailList = async (searchYear: string|undefined, swtrmtFcltCdList: string[]): Promise => { +export const fetchFacilityRdiiDetailList = async (searchYear: string | undefined, swtrmtFcltCdList: string[]): Promise => { try { - const res = await postFetch('fo', '/rdii/detail/'+searchYear, swtrmtFcltCdList); + const res = await postFetch('fo', '/rdii/detail/' + searchYear, swtrmtFcltCdList); return res; } catch (error) { console.error('시설정보 RDII 상세 데이터를 가져오는데 실패했습니다:', error); @@ -345,7 +345,7 @@ export type FacilityWaterQltyType = { FacilityWaterQltyModal: { // 처리시설 수질현황 upHeadListModalYear: TableUpperProps[]; - upHeadListModalYearCod : TableUpperProps[]; + upHeadListModalYearCod: TableUpperProps[]; facilityWaterQltyYearList: FacilityWaterQltyProps[]; upHeadListModalTms: TableUpperProps[]; facilityWaterQltyTmsList: FacilityWaterQltyTmsProps[]; @@ -431,8 +431,9 @@ const dataFormSetting = (item: FacilityWaterQltyProps) => { } export type FacilityWaterQltyStore = FacilityWaterQltyType & FacilityWaterQltyActions; - -export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType) => FacilityWaterQltyType) => void): FacilityWaterQltyActions => { +// 타입 정의를 분리하여 가독성 향상 +type SetFunc = (fn: (state: FacilityWaterQltyType) => FacilityWaterQltyType) => void; +export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions => { return { // 메인페이지 /** @@ -457,53 +458,53 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType const res = await fetchFacilityWaterQltyList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm); const rtnData = res.data.map(item => { dataFormSetting(item) - if(item.inflAssctBfrWqltTn) { - item.inflAssctBfrWqltTn = Number(Math.round(Number(item.inflAssctBfrWqltTn) * 1000)/1000).toFixed(3); + if (item.inflAssctBfrWqltTn) { + item.inflAssctBfrWqltTn = Number(Math.round(Number(item.inflAssctBfrWqltTn) * 1000) / 1000).toFixed(3); } - if(item.efflWqltTn){ - item.efflWqltTn = Number(Math.round(Number(item.efflWqltTn) * 1000)/1000).toFixed(3); + if (item.efflWqltTn) { + item.efflWqltTn = Number(Math.round(Number(item.efflWqltTn) * 1000) / 1000).toFixed(3); } - if(item.inflAssctBfrWqltTp){ - item.inflAssctBfrWqltTp = Number(Math.round(Number(item.inflAssctBfrWqltTp) * 1000)/1000).toFixed(3); + if (item.inflAssctBfrWqltTp) { + item.inflAssctBfrWqltTp = Number(Math.round(Number(item.inflAssctBfrWqltTp) * 1000) / 1000).toFixed(3); } - if(item.efflWqltTp){ - item.efflWqltTp = Number(Math.round(Number(item.efflWqltTp) * 1000)/1000).toFixed(3); + if (item.efflWqltTp) { + item.efflWqltTp = Number(Math.round(Number(item.efflWqltTp) * 1000) / 1000).toFixed(3); } - if(item.inflAssctBfrWqltToc){ - item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10)/10).toFixed(1); + if (item.inflAssctBfrWqltToc) { + item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10) / 10).toFixed(1); } - if(item.efflWqltToc){ - item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1); + if (item.efflWqltToc) { + item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10) / 10).toFixed(1); } - if(item.inflAssctBfrWqltBod){ - item.inflAssctBfrWqltBod = Number(Math.round(Number(item.inflAssctBfrWqltBod) * 10)/10).toFixed(1); + if (item.inflAssctBfrWqltBod) { + item.inflAssctBfrWqltBod = Number(Math.round(Number(item.inflAssctBfrWqltBod) * 10) / 10).toFixed(1); } - if(item.efflWqltBod){ - item.efflWqltBod = Number(Math.round(Number(item.efflWqltBod) * 10)/10).toFixed(1); + if (item.efflWqltBod) { + item.efflWqltBod = Number(Math.round(Number(item.efflWqltBod) * 10) / 10).toFixed(1); } - if(item.inflAssctBfrWqltSs){ - item.inflAssctBfrWqltSs = Number(Math.round(Number(item.inflAssctBfrWqltSs) * 10)/10).toFixed(1); + if (item.inflAssctBfrWqltSs) { + item.inflAssctBfrWqltSs = Number(Math.round(Number(item.inflAssctBfrWqltSs) * 10) / 10).toFixed(1); } - if(item.efflWqltSs){ - item.efflWqltSs = Number(Math.round(Number(item.efflWqltSs) * 10)/10).toFixed(1); + if (item.efflWqltSs) { + item.efflWqltSs = Number(Math.round(Number(item.efflWqltSs) * 10) / 10).toFixed(1); } - if(item.inflAssctBfrWqltToc){ - item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10)/10).toFixed(1); + if (item.inflAssctBfrWqltToc) { + item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10) / 10).toFixed(1); } - if(item.efflWqltToc){ - item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1); + if (item.efflWqltToc) { + item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10) / 10).toFixed(1); } return item; }); const excelDownList: ExcelType[] = []; - if(pageSize>5000){ + if (pageSize > 5000) { res.data.forEach(item => { dataFormSetting(item) item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, '')); item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || ''; item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || ''; - item.inflAssctBfrWqltToc = Number(searchYear) { dataFormSetting(item) item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, '')); item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || ''; item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || ''; - item.inflAssctBfrWqltToc = Number(searchYear) ({ ...state, - FacilityWaterQltyMain: pageSize<5000?{ + FacilityWaterQltyMain: pageSize < 5000 ? { ...state.FacilityWaterQltyMain, facilityWaterQltyList: rtnData, facilityWaterQltyCount: res.count, - isLoading : false, - }:{ + isLoading: false, + } : { ...state.FacilityWaterQltyMain, excelList: excelDownList, - isLoading : false, + isLoading: false, }, })) }, @@ -555,10 +556,10 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType searchFacilityWaterQltyListHist: async (searchYear: string, facilityCd: string) => { const res = await fetchFacilityWaterQltyListHist(searchYear, facilityCd); const res1 = await fetchFacilityWaterQltyTmsList(facilityCd); - + let rtnMsrmtDate = ''; const rtnTmsList: FacilityWaterQltyTmsProps[] = []; - if(res1.data){ + if (res1.data) { rtnTmsList.push({ part: '평균', toc: res1.data.tocAvgVl, @@ -584,7 +585,7 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType }); rtnMsrmtDate = res1.data.msrmtDate; - }else{ + } else { rtnTmsList.push({ part: '평균', toc: 0, @@ -606,20 +607,20 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType toc: 0, ss: 0, tn: 0, - tp: 0, + tp: 0, }); rtnMsrmtDate = ''; } - - if(Array.isArray(res) || !res || !('data' in res) || !res.data || !res.data.wqltObjs || res.data.wqltObjs.length === 0) { + + if (Array.isArray(res) || !res || !('data' in res) || !res.data || !res.data.wqltObjs || res.data.wqltObjs.length === 0) { set((state: FacilityWaterQltyType) => ({ ...state, FacilityWaterQltyModal: { ...state.FacilityWaterQltyModal, facilityWaterQltyYearList: [], - tmsList : rtnTmsList, - msrmtDate : rtnMsrmtDate + tmsList: rtnTmsList, + msrmtDate: rtnMsrmtDate } })) return; @@ -627,7 +628,7 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType // facilityPrecipitation의 rainEffectDay 계산 로직을 적용 const data = CalcRainEffect(res.data.wqltObjs); - + /** * [(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​ /강우시 일별유입BOD) @@ -639,7 +640,7 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType let sunnyDay = 0; data.forEach(item => { - if(item.rainEffectDay == 1){ + if (item.rainEffectDay == 1) { //rainDay += 1; //rainInflAmnt += Number(item.inflAmnt); } else { @@ -650,69 +651,69 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType }); //const yearRainAmnt = rainInflAmnt===0?0:rainInflAmnt / rainDay; - const yearSunnyAmnt = sunnyInflAmnt===0?0:sunnyInflAmnt / sunnyDay; - const yearSunnyBod = sunnyBod===0?0:sunnyBod / sunnyDay; + const yearSunnyAmnt = sunnyInflAmnt === 0 ? 0 : sunnyInflAmnt / sunnyDay; + const yearSunnyBod = sunnyBod === 0 ? 0 : sunnyBod / sunnyDay; // const rtnData = data.map((item: FacilityWaterQltyProps) => { dataFormSetting(item) - if(item.inflAssctBfrWqltTn) { - item.inflAssctBfrWqltTn = Number(Math.round(Number(item.inflAssctBfrWqltTn) * 1000)/1000).toFixed(3); + if (item.inflAssctBfrWqltTn) { + item.inflAssctBfrWqltTn = Number(Math.round(Number(item.inflAssctBfrWqltTn) * 1000) / 1000).toFixed(3); } - if(item.efflWqltTn){ - item.efflWqltTn = Number(Math.round(Number(item.efflWqltTn) * 1000)/1000).toFixed(3); + if (item.efflWqltTn) { + item.efflWqltTn = Number(Math.round(Number(item.efflWqltTn) * 1000) / 1000).toFixed(3); } - if(item.inflAssctBfrWqltTp){ - item.inflAssctBfrWqltTp = Number(Math.round(Number(item.inflAssctBfrWqltTp) * 1000)/1000).toFixed(3); + if (item.inflAssctBfrWqltTp) { + item.inflAssctBfrWqltTp = Number(Math.round(Number(item.inflAssctBfrWqltTp) * 1000) / 1000).toFixed(3); } - if(item.efflWqltTp){ - item.efflWqltTp = Number(Math.round(Number(item.efflWqltTp) * 1000)/1000).toFixed(3); + if (item.efflWqltTp) { + item.efflWqltTp = Number(Math.round(Number(item.efflWqltTp) * 1000) / 1000).toFixed(3); } - if(item.inflAssctBfrWqltToc){ - item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10)/10).toFixed(1); + if (item.inflAssctBfrWqltToc) { + item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10) / 10).toFixed(1); } - if(item.efflWqltToc){ - item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1); + if (item.efflWqltToc) { + item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10) / 10).toFixed(1); } - if(item.inflAssctBfrWqltCod){ - item.inflAssctBfrWqltCod = "("+Number(Math.round(Number(item.inflAssctBfrWqltCod) * 10)/10).toFixed(1)+")"; + if (item.inflAssctBfrWqltCod) { + item.inflAssctBfrWqltCod = "(" + Number(Math.round(Number(item.inflAssctBfrWqltCod) * 10) / 10).toFixed(1) + ")"; } - if(item.efflWqltCod){ - item.efflWqltCod = "("+Number(Math.round(Number(item.efflWqltCod) * 10)/10).toFixed(1)+")"; + if (item.efflWqltCod) { + item.efflWqltCod = "(" + Number(Math.round(Number(item.efflWqltCod) * 10) / 10).toFixed(1) + ")"; } - if(item.inflAssctBfrWqltBod){ - item.inflAssctBfrWqltBod = Number(Math.round(Number(item.inflAssctBfrWqltBod) * 10)/10).toFixed(1); + if (item.inflAssctBfrWqltBod) { + item.inflAssctBfrWqltBod = Number(Math.round(Number(item.inflAssctBfrWqltBod) * 10) / 10).toFixed(1); } - if(item.efflWqltBod){ - item.efflWqltBod = Number(Math.round(Number(item.efflWqltBod) * 10)/10).toFixed(1); + if (item.efflWqltBod) { + item.efflWqltBod = Number(Math.round(Number(item.efflWqltBod) * 10) / 10).toFixed(1); } - if(item.inflAssctBfrWqltSs){ - item.inflAssctBfrWqltSs = Number(Math.round(Number(item.inflAssctBfrWqltSs) * 10)/10).toFixed(1); + if (item.inflAssctBfrWqltSs) { + item.inflAssctBfrWqltSs = Number(Math.round(Number(item.inflAssctBfrWqltSs) * 10) / 10).toFixed(1); } - if(item.efflWqltSs){ - item.efflWqltSs = Number(Math.round(Number(item.efflWqltSs) * 10)/10).toFixed(1); + if (item.efflWqltSs) { + item.efflWqltSs = Number(Math.round(Number(item.efflWqltSs) * 10) / 10).toFixed(1); } - if(item.inflAssctBfrWqltToc){ - item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10)/10).toFixed(1); + if (item.inflAssctBfrWqltToc) { + item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10) / 10).toFixed(1); } - if(item.efflWqltToc){ - item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1); + if (item.efflWqltToc) { + item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10) / 10).toFixed(1); } - if(item.tpInflWqltBod){ - item.tpInflWqltBod = item.tpInflWqltBod?Number(Math.round(Number(item.tpInflWqltBod) * 10)/10).toFixed(1):Number(item.tpInflWqltBod)===0?'0.0':''; - }else{ + if (item.tpInflWqltBod) { + item.tpInflWqltBod = item.tpInflWqltBod ? Number(Math.round(Number(item.tpInflWqltBod) * 10) / 10).toFixed(1) : Number(item.tpInflWqltBod) === 0 ? '0.0' : ''; + } else { item.tpInflWqltBod = ''; } - if(item.tpInflWqltTp){ - item.tpInflWqltTp = item.tpInflWqltTp?Number(Math.round(Number(item.tpInflWqltTp) * 1000)/1000).toFixed(3): Number(item.tpInflWqltTp)===0?'0.000':''; - }else{ + if (item.tpInflWqltTp) { + item.tpInflWqltTp = item.tpInflWqltTp ? Number(Math.round(Number(item.tpInflWqltTp) * 1000) / 1000).toFixed(3) : Number(item.tpInflWqltTp) === 0 ? '0.000' : ''; + } else { item.tpInflWqltTp = ''; } const dayBod = Number(item.inflAssctBfrWqltBod); const noProcessInflAmnt = roundNumber(((Number(item.inflAmnt) * dayBod) - (yearSunnyAmnt * yearSunnyBod)) / dayBod, 0) - item.noProcessInflAmnt = noProcessInflAmnt && Number(noProcessInflAmnt.replaceAll(',','')) > 0 ? noProcessInflAmnt : ''; + item.noProcessInflAmnt = noProcessInflAmnt && Number(noProcessInflAmnt.replaceAll(',', '')) > 0 ? noProcessInflAmnt : ''; return item; }) @@ -721,8 +722,8 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType FacilityWaterQltyModal: { ...state.FacilityWaterQltyModal, facilityWaterQltyYearList: rtnData, - tmsList : rtnTmsList, - msrmtDate : rtnMsrmtDate + tmsList: rtnTmsList, + msrmtDate: rtnMsrmtDate } })) }, From 8f26c1482e5abcdc425ab63bd2bd32abc8cf5ab5 Mon Sep 17 00:00:00 2001 From: dongsilove Date: Mon, 12 Jan 2026 22:40:58 +0900 Subject: [PATCH 24/34] =?UTF-8?q?fo:=20=EC=B4=9D=EC=9D=B8=EC=84=A4?= =?UTF-8?q?=EB=B9=84=20=EC=88=98=EC=A7=88=ED=98=84=ED=99=A9=20=EA=B8=B0?= =?UTF-8?q?=EA=B0=84=EB=B3=84=20exceldownload?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/FacilityTermModalHeader.tsx | 2 +- .../facilityWaterQlty/modal/page.tsx | 55 +++++++++---------- apps/fo/app/store/facilityWaterQlty/index.tsx | 43 ++++----------- 3 files changed, 37 insertions(+), 63 deletions(-) diff --git a/apps/fo/app/components/common/FacilityTermModalHeader.tsx b/apps/fo/app/components/common/FacilityTermModalHeader.tsx index 4389e2f5a..a46b3652d 100644 --- a/apps/fo/app/components/common/FacilityTermModalHeader.tsx +++ b/apps/fo/app/components/common/FacilityTermModalHeader.tsx @@ -35,7 +35,7 @@ export default function FacilityTermModalHeader({ const [endDate, setEndDate] = useState(new Date(Number(searchYear), 11, 31)); const startPickerRef = useRef(null); const endPickerRef = useRef(null); - const [flowPanel, setFlowPanel] = useState(selectFlowPanel[0]?.val ?? '0'); // 초기값 "전체" + const [flowPanel, setFlowPanel] = useState(selectFlowPanel[0]?.val ?? '0'); // 강수구분 : 초기값 "전체" const [copySearchList, setCopySearchList] = useState(searchList); const [standSearchList, setStandSearchList] = useState(searchList); diff --git a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx index 76c65ca3b..7de556932 100644 --- a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx @@ -52,12 +52,10 @@ const tabList3 = [ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', searchYear = new Date().getFullYear().toString() }: ModalProps) { const [tabName, setTabName] = useState('tab_num1'); - - // 그리드 관련 - const { FacilityWaterQltyModal, - searchFacilityWaterQltyListHist, - Common - } = useFoStore((state) => state); + // 날짜 필터링 관련 상태 + const [copyYearList, setCopyYearList] = useState([]); + const [chongInWaterQltyYearList, setChongInWaterQltyYearList] = useState([]); + const { FacilityWaterQltyModal, searchFacilityWaterQltyListHist, Common } = useFoStore((state) => state); const { btnClass, COD_YEAR } = Common; const { upHeadListModalYear, @@ -72,6 +70,16 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea const prevExcelListRef = useRef(null); const prevChoinginExcelListRef = useRef(null); + useEffect(() => { + searchFacilityWaterQltyListHist(searchYear, facilityCd); + }, [searchYear, facilityCd, searchFacilityWaterQltyListHist]); + + useEffect(() => { + const filteredYearData = setFilterAfterData(facilityWaterQltyYearList); + setCopyYearList(filteredYearData as FacilityWaterQltyProps[]); + setChongInWaterQltyYearList(filteredYearData as FacilityWaterQltyProps[]); + }, [facilityWaterQltyYearList]); + // 필터링 된 후 최대, 최소, 평균 값 계산 const setFilterAfterData = (filteredData: FacilityWaterQltyProps[]) => { // 쉼표가 포함된 문자열을 숫자로 변환하는 함수 @@ -313,7 +321,7 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea addr: "", fctCpc: 0, noProcessInflAmnt: roundNumber(minNoProcessInflAmnt, 0), - infoRnDay: Math.round(minInfoRnDay * 10) / 10 ? '0.0' : roundNumber(minInfoRnDay, 1), + infoRnDay: Math.round(minInfoRnDay * 10) / 10 ? roundNumber(minInfoRnDay, 1) : '0.0', tpInflWqltBod: Math.round(minTpInflWqltBod * 10) / 10 && minTpInflWqltBod != 99999999 ? roundNumber(minTpInflWqltBod, 1) : '0.0', tpInflWqltTp: Math.round(minTpInflWqltTp * 1000) / 1000 && minTpInflWqltTp != 99999999 ? roundNumber(minTpInflWqltTp, 3) : '0.000' }, @@ -323,20 +331,6 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea return newFilteredData; } - // 날짜 필터링 관련 상태 - const [copyYearList, setCopyYearList] = useState([]); - const [chongInWaterQltyYearList, setChongInWaterQltyYearList] = useState([]); - - useEffect(() => { - searchFacilityWaterQltyListHist(searchYear, facilityCd); - }, [searchYear, facilityCd, searchFacilityWaterQltyListHist]); - - useEffect(() => { - const filteredYearData = setFilterAfterData(facilityWaterQltyYearList); - setCopyYearList(filteredYearData as FacilityWaterQltyProps[]); - setChongInWaterQltyYearList(filteredYearData as FacilityWaterQltyProps[]); - }, [facilityWaterQltyYearList]); - const yesterDay = new Date(); yesterDay.setDate(yesterDay.getDate() - 1); const yesterDayStr = yesterDay.toISOString().split('T')[0]; @@ -350,7 +344,8 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea const filterData = useCallback((returnType: ReturnType) => { const filteredData = setFilterAfterData(returnType.filteredList); - setCopyYearList(filteredData as FacilityWaterQltyProps[]); + setCopyYearList(filteredData as FacilityWaterQltyProps[]); // 처리시설 수질현황 + setChongInWaterQltyYearList(filteredData as FacilityWaterQltyProps[]); // 총인설비 수질현황 }, []); const excelDownload = () => { @@ -393,6 +388,8 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea const excelDownList: modalChoinginExcelType[] = []; if (chongInWaterQltyYearList.length > 0) { chongInWaterQltyYearList.forEach((item) => { + // if (copyYearList.length > 0) { + // copyYearList.forEach((item) => { excelDownList.push({ 날짜: item.msrDt, "유입BOD(mg/L)": CommaToNumber(item.tpInflWqltBod), @@ -432,7 +429,7 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea {/* 처리시설 수질현황 */} - + {/* 연간 */} searchList={facilityWaterQltyYearList} fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_year" @@ -449,9 +446,9 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea
-
+

수질 TMS

- {/*

({msrmtDate?msrmtDate.substring(0,4)+'-'+msrmtDate.substring(4,6)+'-'+msrmtDate.substring(6,8):yesterDayStr})

*/} +

({msrmtDate ? msrmtDate.substring(0, 4) + '-' + msrmtDate.substring(4, 6) + '-' + msrmtDate.substring(6, 8) : yesterDayStr})

- {/* 청천 */} + {/* 청천시 */} searchList={facilityWaterQltyYearList} fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_chuncheon" @@ -552,7 +549,7 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea {/* 총인설비 수질현황 */} - + {/* 연간 */} searchList={chongInWaterQltyYearList} fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_year" @@ -571,7 +568,7 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea
- + {/* 하절기 */} searchList={chongInWaterQltyYearList} fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_summer" @@ -590,7 +587,7 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea
- + {/* 동절기 */} searchList={chongInWaterQltyYearList} fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_winter" diff --git a/apps/fo/app/store/facilityWaterQlty/index.tsx b/apps/fo/app/store/facilityWaterQlty/index.tsx index 5d2e886f4..db60c5b2d 100644 --- a/apps/fo/app/store/facilityWaterQlty/index.tsx +++ b/apps/fo/app/store/facilityWaterQlty/index.tsx @@ -2,7 +2,7 @@ import DataForm, { roundNumber } from "@/app/components/common/DataForm"; import type { TableUpperProps } from "../dashboard"; import CalcRainEffect from "@/app/components/common/CalcRainEffect"; -import { COD_YEAR } from "../common"; +import { COD_YEAR } from "../common"; // 2021년 import CommaToNumber from "@/app/components/common/CommaToNumber"; export type { TableUpperProps }; @@ -431,7 +431,7 @@ const dataFormSetting = (item: FacilityWaterQltyProps) => { } export type FacilityWaterQltyStore = FacilityWaterQltyType & FacilityWaterQltyActions; -// 타입 정의를 분리하여 가독성 향상 + type SetFunc = (fn: (state: FacilityWaterQltyType) => FacilityWaterQltyType) => void; export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions => { return { @@ -447,7 +447,9 @@ export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions * @param operationValue : 운영상태코드 * @param fcltyNm : 시설명 */ - searchFacilityWaterQltyList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { + searchFacilityWaterQltyList: async (pageNo: number, pageSize: number, searchYear: string, part?: string + , nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { + set((state: FacilityWaterQltyType) => ({ ...state, FacilityWaterQltyMain: { @@ -567,7 +569,6 @@ export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions tn: res1.data.tnAvgVl, tp: res1.data.tpAvgVl, }); - rtnTmsList.push({ part: '최대', toc: res1.data.tocMaxVl, @@ -575,7 +576,6 @@ export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions tn: res1.data.tnMaxVl, tp: res1.data.tpMaxVl, }); - rtnTmsList.push({ part: '최소', toc: res1.data.tocMinVl, @@ -586,30 +586,9 @@ export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions rtnMsrmtDate = res1.data.msrmtDate; } else { - rtnTmsList.push({ - part: '평균', - toc: 0, - ss: 0, - tn: 0, - tp: 0, - }); - - rtnTmsList.push({ - part: '최대', - toc: 0, - ss: 0, - tn: 0, - tp: 0, - }); - - rtnTmsList.push({ - part: '최소', - toc: 0, - ss: 0, - tn: 0, - tp: 0, - }); - + rtnTmsList.push({ part: '평균', toc: 0, ss: 0, tn: 0, tp: 0, }); + rtnTmsList.push({ part: '최대', toc: 0, ss: 0, tn: 0, tp: 0, }); + rtnTmsList.push({ part: '최소', toc: 0, ss: 0, tn: 0, tp: 0, }); rtnMsrmtDate = ''; } @@ -633,10 +612,8 @@ export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions * [(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​ /강우시 일별유입BOD) */ - //let rainInflAmnt = 0; let sunnyInflAmnt = 0; let sunnyBod = 0; - //let rainDay = 0; let sunnyDay = 0; data.forEach(item => { @@ -700,12 +677,12 @@ export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10) / 10).toFixed(1); } - if (item.tpInflWqltBod) { + if (item.tpInflWqltBod) { // 총인 유입수질 BOD(mg/L) item.tpInflWqltBod = item.tpInflWqltBod ? Number(Math.round(Number(item.tpInflWqltBod) * 10) / 10).toFixed(1) : Number(item.tpInflWqltBod) === 0 ? '0.0' : ''; } else { item.tpInflWqltBod = ''; } - if (item.tpInflWqltTp) { + if (item.tpInflWqltTp) { // 총인 유입수질 TP(mg/L) item.tpInflWqltTp = item.tpInflWqltTp ? Number(Math.round(Number(item.tpInflWqltTp) * 1000) / 1000).toFixed(3) : Number(item.tpInflWqltTp) === 0 ? '0.000' : ''; } else { item.tpInflWqltTp = ''; From c57f05cc3ec8600f711cbbc3cd36b9853c5175de Mon Sep 17 00:00:00 2001 From: dongsilove Date: Tue, 13 Jan 2026 22:53:35 +0900 Subject: [PATCH 25/34] =?UTF-8?q?sn:=20showModal=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../map/searchModal/searchModal.tsx | 158 +++++++++--------- .../(without-layout)/stats/hasuStat/page.tsx | 14 +- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx b/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx index 34cdb674b..0906ce0ca 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx @@ -125,91 +125,91 @@ const SearchModal: React.FC = () => { {/* 📋 결과 리스트 */} {/* 기본정보 탭 */} {activeTab === 'basic' && ( -
-
- - { - const label = BASIC_TYPES.find((type) => type.val === basicType)?.text - return (<>{label} 조회 결과 ({tableCount.toLocaleString('ko-KR')})건); - })() - } - tableData={tableData} - headlist={dynamicHeadlist} - pageSize={10} - total={tableCount} - cellClick={handleBasicCellClick} - onPageChange={setCurPage} - resetPageNo={isResetPage} - resetSelection={isResetSelection} - curPage={curPage} - headButton={ -
- - -
- } - /> -
+
+ {/*
*/} + + { + const label = BASIC_TYPES.find((type) => type.val === basicType)?.text + return (<>{label} 조회 결과 ({tableCount.toLocaleString('ko-KR')})건); + })() + } + tableData={tableData} + headlist={dynamicHeadlist} + pageSize={10} + total={tableCount} + cellClick={handleBasicCellClick} + onPageChange={setCurPage} + resetPageNo={isResetPage} + resetSelection={isResetSelection} + curPage={curPage} + headButton={ +
+ + +
+ } + /> + {/*
*/}
)} {/* 유지관리 정보 탭 */} {activeTab === 'operation' && ( <> -
-
- - { - const label = WORK_TYPES.find((type) => type.val === workType)?.text - return (<>{label} 사업 현황 ({tableCount.toLocaleString('ko-KR')})건); - })() - } - tableData={tableData} - headlist={dynamicHeadlist} - pageSize={OPERATION_TABLE_SIZE} - total={tableCount} - cellClick={handleOperationCellClick} - onPageChange={setCurPage} - resetPageNo={isResetPage} - resetSelection={isResetSelection} - curPage={curPage} - headButton={ - - } - /> -
+
+ {/*
*/} + + { + const label = WORK_TYPES.find((type) => type.val === workType)?.text + return (<>{label} 사업 현황 ({tableCount.toLocaleString('ko-KR')})건); + })() + } + tableData={tableData} + headlist={dynamicHeadlist} + pageSize={OPERATION_TABLE_SIZE} + total={tableCount} + cellClick={handleOperationCellClick} + onPageChange={setCurPage} + resetPageNo={isResetPage} + resetSelection={isResetSelection} + curPage={curPage} + headButton={ + + } + /> + {/*
*/}
-
+
{/* 테이블2 영역 */} -
- - { - const label = WORK_TYPES.find((type) => type.val === workType)?.text - return (<>{label} 결과표 ({detailTableCount.toLocaleString('ko-KR')})건); - })() - } - tableData={detailTableData} - headlist={dynamicHeadlist2} - pageSize={OPERATION_TABLE_SIZE} - total={detailTableCount} - cellClick={handleOperationResultCellClick} - onPageChange={setDetailCurPage} - resetPageNo={isResetDetailPage} - resetSelection={isResetDetailSelection} - curPage={detailCurPage} - headButton={ -
- - -
- } - /> -
+ {/*
*/} + + { + const label = WORK_TYPES.find((type) => type.val === workType)?.text + return (<>{label} 결과표 ({detailTableCount.toLocaleString('ko-KR')})건); + })() + } + tableData={detailTableData} + headlist={dynamicHeadlist2} + pageSize={OPERATION_TABLE_SIZE} + total={detailTableCount} + cellClick={handleOperationResultCellClick} + onPageChange={setDetailCurPage} + resetPageNo={isResetDetailPage} + resetSelection={isResetDetailSelection} + curPage={detailCurPage} + headButton={ +
+ + +
+ } + /> + {/*
*/}
)} @@ -224,8 +224,8 @@ const SearchModal: React.FC = () => { bodyClass={` h-[100dvh] w-[90dvw] - max-w-[1200px] - max-h-[100dvh] + max-w-[1220px] + max-h-[970px] overflow-y-hidden z-[101] `} diff --git a/apps/wr/app/(without-layout)/stats/hasuStat/page.tsx b/apps/wr/app/(without-layout)/stats/hasuStat/page.tsx index 34ce031e1..d6e9ff601 100644 --- a/apps/wr/app/(without-layout)/stats/hasuStat/page.tsx +++ b/apps/wr/app/(without-layout)/stats/hasuStat/page.tsx @@ -20,20 +20,20 @@ export default function HasuStatPage() { const data = await res.json(); const ip: string = data?.ip || ""; if (didCancel) return; - //alert("Client IP:" + ip); + console.log("Client IP:" + ip); const is10 = /^10\./.test(ip); const is172 = /^172\./.test(ip); - setStatus(is10||is172 ? "redirect-internal" : "redirect-root"); + setStatus(is10 || is172 ? "redirect-internal" : "redirect-root"); // Use location.replace so user can't go back to this page - if (is10||is172) { + if (is10 || is172) { // redirect to internal IP // alert(process.env.NEXT_PUBLIC_HASUDOINFO_IN +'/cms/lay1/WS10000014/program.do'); - window.open(process.env.NEXT_PUBLIC_HASUDOINFO_IN +'/cms/lay1/WS10000014/program.do', '_blank'); + window.open(process.env.NEXT_PUBLIC_HASUDOINFO_IN + '/cms/lay1/WS10000014/program.do', '_blank'); } else { // alert(process.env.NEXT_PUBLIC_HASUDOINFO +'/cms/lay1/WS10000014/program.do'); - window.open(process.env.NEXT_PUBLIC_HASUDOINFO +'/cms/lay1/WS10000014/program.do', '_blank'); + window.open(process.env.NEXT_PUBLIC_HASUDOINFO + '/cms/lay1/WS10000014/program.do', '_blank'); } window.history.back(); } catch { @@ -53,13 +53,13 @@ export default function HasuStatPage() { }, []); return ( -
+
{status === "checking" &&
접속 IP 확인 중...
} {status === "redirect-internal" &&
내부망으로 이동합니다...
} {status === "redirect-root" &&
외부에서 접속하여 루트로 이동합니다...
} {status === "error-fallback" && (
- 문제가 발생하여 루트로 이동합니다. 이동하지 않으면 여기를 클릭하세요. + 문제가 발생하여 루트로 이동합니다. 이동하지 않으면 여기를 클릭하세요.
)}
From 7588ee4e6adfae2eb6821ef65b8e4e16fc995685 Mon Sep 17 00:00:00 2001 From: ljpark Date: Wed, 14 Jan 2026 17:05:26 +0900 Subject: [PATCH 26/34] =?UTF-8?q?dm:=20=EC=9C=A0=EC=82=AC=EC=82=AC?= =?UTF-8?q?=EB=A1=80=20=ED=8C=9D=EC=97=85=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/sdmMng/sdmInfoInsert/modalSimilar/page.tsx | 6 +++--- apps/dm/components/ui/sdmInfoInsertForm/component.tsx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/dm/app/(base-layout)/pages/sdmMng/sdmInfoInsert/modalSimilar/page.tsx b/apps/dm/app/(base-layout)/pages/sdmMng/sdmInfoInsert/modalSimilar/page.tsx index 22418c7b7..35836d07c 100644 --- a/apps/dm/app/(base-layout)/pages/sdmMng/sdmInfoInsert/modalSimilar/page.tsx +++ b/apps/dm/app/(base-layout)/pages/sdmMng/sdmInfoInsert/modalSimilar/page.tsx @@ -87,9 +87,9 @@ export default function ModalSimilarPage({ sply = 0, usageCd = '', money = 0 }: }, [getSimilarCaseList, money, searchUseType, sply, usageCd]); return ( -
+
- <div className="overflow-x-auto h-[450px] w-full mt-8" tabIndex={0} aria-label="유사사례 테이블 영역"> + <div className="overflow-x-auto h-[480px] w-full mt-8" tabIndex={0} aria-label="유사사례 테이블 영역"> <div className="w-[150%]"> <div className="card-header justify-self-start"> <h3 className="text-2xl font-medium text-label">유사사례</h3> @@ -148,7 +148,7 @@ export default function ModalSimilarPage({ sply = 0, usageCd = '', money = 0 }: </div> </div> </div> - <div className="overflow-x-auto h-[270px] w-full mt-8"> + <div className="overflow-x-auto h-[270px] w-full mt-8 overflow-y-hidden"> <div className="w-[130%]"> <UiTable headName={"사업비 상세정보"} diff --git a/apps/dm/components/ui/sdmInfoInsertForm/component.tsx b/apps/dm/components/ui/sdmInfoInsertForm/component.tsx index 17e4bfdc8..62b214f04 100644 --- a/apps/dm/components/ui/sdmInfoInsertForm/component.tsx +++ b/apps/dm/components/ui/sdmInfoInsertForm/component.tsx @@ -950,7 +950,7 @@ export function SdmInfoRegForm({ body={ <ModalSimilarPage sply={sply} usageCd={usageCd} money={money} /> } - bodyClass="sm:max-w-[100vw] w-[1400px] h-[900px]" + bodyClass="sm:max-w-[100vw] w-[1400px] h-[100dvh] max-h-[900px] overflow-y-auto overflow-x-hidden" open={isSimilarCase} onOpenChange={(open) => !open && setIsSimilarCase(false)} noHeaderYn="Y" From 21b043cbae0da414c37746dcae5e941928691897 Mon Sep 17 00:00:00 2001 From: ljpark <mind-one005@mind-one.co.kr> Date: Wed, 14 Jan 2026 17:51:48 +0900 Subject: [PATCH 27/34] =?UTF-8?q?dm:=20=EC=9C=A0=EC=82=AC=EC=82=AC?= =?UTF-8?q?=EB=A1=80=20=EC=82=AC=EC=97=85=EB=AA=85=20***=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dm/app/store/sdmMng/index.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/apps/dm/app/store/sdmMng/index.tsx b/apps/dm/app/store/sdmMng/index.tsx index b5b258839..ef7fb4cea 100644 --- a/apps/dm/app/store/sdmMng/index.tsx +++ b/apps/dm/app/store/sdmMng/index.tsx @@ -167,7 +167,7 @@ export type DemandMatchings = { // 유사사례 export type SimilarCaseType = { - ruseBizNm : string | ''; + ruseBizNm : string | ''; // 사업명 bizBgngDate : string | ''; bizEndDate : string | ''; splyFcltKnd : string | ''; @@ -751,11 +751,23 @@ export const SdmReducer = (set: any): SdmActions => { // 유사사례 조회 getSimilarCaseList: async (part: string, value: number|string) => { const res = await fetchGetSimilarCaseList(part, value); - if(res && res.length !== 0) { + const similarCaseList = res.map((el: SimilarCaseType) => { + const maskedBizNm = el.ruseBizNm + ? el.ruseBizNm.replace(/^(\s*)^\S+/, "***") // 첫 단어(공백 전까지) 치환 + : el.ruseBizNm; + + return { + ...el, + ruseBizNm: maskedBizNm, + }; + }); + console.log(similarCaseList); + + if(similarCaseList && similarCaseList.length !== 0) { set((state: SdmType) => ({ Sdm: { ...state.Sdm, - similarCaseList: res, + similarCaseList: similarCaseList, } })) return; From 4e27466f0099f314c64d1661498aca863c5eefe6 Mon Sep 17 00:00:00 2001 From: ljpark <mind-one005@mind-one.co.kr> Date: Thu, 15 Jan 2026 15:51:08 +0900 Subject: [PATCH 28/34] =?UTF-8?q?dm:=20GATEWAY=5FURL=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dm/.env.local | 2 +- apps/dm/.env.mindone | 1 + apps/dm/.env.production | 1 + apps/dm/app/store/wrStatus/index.tsx | 2 +- apps/dm/components/ui/api/index.ts | 25 +++++++++++++++++++------ apps/dm/middleware.ts | 23 ++++++++--------------- 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/apps/dm/.env.local b/apps/dm/.env.local index e73fe4485..88b6f8067 100644 --- a/apps/dm/.env.local +++ b/apps/dm/.env.local @@ -16,7 +16,7 @@ NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver NEXT_PUBLIC_CS_TUS_UPLOAD = /attach-service/api/v1/tus/upload NEXT_PUBLIC_NGII_URL = https://map.ngii.go.kr NEXT_PUBLIC_NGII_PARAM = 04trYP9_xwLAfALjwZ-B8g&service=WMTS&request=GetTile&version=1.0.0&format=image/png&layer=korean_map&style=korean&tilematrixset=korean&tilematrix={z}&tilecol={x}&tilerow={y} -NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service # 개발 서버 API +NEXT_PUBLIC_GATEWAY_URL=http://con.mind-one.co.kr:11083 # 개발 서버 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 # 박이정 NEXT_PUBLIC_CM_LOGIN_PAGE_URL = http://dev.onasys.co.kr:3000/auth/login diff --git a/apps/dm/.env.mindone b/apps/dm/.env.mindone index 1ca3ecfb6..da6f80177 100644 --- a/apps/dm/.env.mindone +++ b/apps/dm/.env.mindone @@ -14,6 +14,7 @@ NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11083/reuse-service/ap NEXT_PUBLIC_NGII_URL = https://map.ngii.go.kr NEXT_PUBLIC_NGII_PARAM = 04trYP9_xwLAfALjwZ-B8g&service=WMTS&request=GetTile&version=1.0.0&format=image/png&layer=korean_map&style=korean&tilematrixset=korean&tilematrix={z}&tilecol={x}&tilerow={y} NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service # 개발 서버 API +NEXT_PUBLIC_GATEWAY_URL=http://con.mind-one.co.kr:11083 # 개발 서버 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 # 박이정 NEXT_PUBLIC_CM_LOGIN_PAGE_URL = http://dev.onasys.co.kr:3000/auth/login diff --git a/apps/dm/.env.production b/apps/dm/.env.production index 2a08a80e0..5a401c89a 100644 --- a/apps/dm/.env.production +++ b/apps/dm/.env.production @@ -15,6 +15,7 @@ NEXT_PUBLIC_GEOSERVER_URL = http://172.29.143.87:8080/geoserver NEXT_PUBLIC_LX_GEOSERVER_URL = http://172.29.143.87:8080/geoserver_swl NEXT_PUBLIC_WR_SERVER_API_URL = http://apigateway.iipbs-was.svc.cluster.local:8000/reuse-service/api/v1 NEXT_PUBLIC_SEWERAGE_API_URL = http://apigateway.iipbs-was.svc.cluster.local:8000/sewerage-service +NEXT_PUBLIC_GATEWAY_URL = http://apigateway.iipbs-was.svc.cluster.local:8000 NEXT_PUBLIC_NGII_URL = http://172.29.143.87/poiact NEXT_PUBLIC_NGII_PARAM = BDE2BEF39DAFEC293AB6730150F222AC&service=WMTS&request=GetTile&version=1.0.0&format=image/png&layer=korean_map&style=korean&tilematrixset=korean&tilematrix={z}&tilecol={y}&tilerow={x} diff --git a/apps/dm/app/store/wrStatus/index.tsx b/apps/dm/app/store/wrStatus/index.tsx index bd43db731..b3c08e9e2 100644 --- a/apps/dm/app/store/wrStatus/index.tsx +++ b/apps/dm/app/store/wrStatus/index.tsx @@ -92,7 +92,7 @@ export const DmStatusReducer = (set: any): DmStatusActions => { const sewageCnt = item.sewageCnt; const rainwaterCnt = item.rainwaterCnt; const reclaimedCnt = item.reclaimedCnt; - console.log("regionText ", regionText); + if (!regionText) console.log("item.region ", item.region); if (regionText && regionText.text) { return { region: regionText ? regionText.text : item.region, diff --git a/apps/dm/components/ui/api/index.ts b/apps/dm/components/ui/api/index.ts index 7ba66c4ed..abb0c2c73 100644 --- a/apps/dm/components/ui/api/index.ts +++ b/apps/dm/components/ui/api/index.ts @@ -1,23 +1,33 @@ //8880 import { AUTH_USER_ID, CLAIM_NAME } from "@/src/shared/config"; -import { DEV_URL_FO, DEV_URL_WR } from "../config"; import { getCookie } from "@common/components/lib/cookie"; + const tokenId = getCookie(AUTH_USER_ID); const Authorization = getCookie(CLAIM_NAME); export const fetchType = { COMMON: "common", WR: "wr", - FO:'fo' + FO: "fo", + SN: "sn" }; +const API_VERSION = "/api/v1" +const servers = { + common: "", + local: "", + fo: "/operation-service" + API_VERSION, + wr: "/reuse-service" + API_VERSION, + sn: "/sewerage-service" + API_VERSION, +} + interface RequestParams { [key: string]: unknown; } export const getFetch = async (type: string, url: string) => { - const baseUrl = type === fetchType.FO ? DEV_URL_FO : DEV_URL_WR; + const baseUrl = servers[type]; const response = await fetch(baseUrl + url, { method: "GET", headers: { @@ -35,7 +45,8 @@ export const getFetch = async (type: string, url: string) => { }; export const postFetch = async (url: string, params: RequestParams) => { - const response = await fetch(DEV_URL_WR + url, { + const baseUrl = servers[fetchType.WR]; + const response = await fetch(baseUrl + url, { method: "POST", headers: { "Content-Type": "application/json", @@ -52,7 +63,8 @@ export const postFetch = async (url: string, params: RequestParams) => { }; export const putFetch = async (url: string, params: RequestParams) => { - const response = await fetch(DEV_URL_WR + url, { + const baseUrl = servers[fetchType.WR]; + const response = await fetch(baseUrl + url, { method: "PUT", headers: { "Content-Type": "application/json", @@ -69,7 +81,8 @@ export const putFetch = async (url: string, params: RequestParams) => { }; export const deleteFetch = async (url: string, params: RequestParams) => { - const response = await fetch(DEV_URL_WR + url, { + const baseUrl = servers[fetchType.WR]; + const response = await fetch(baseUrl + url, { method: "DELETE", headers: { "Content-Type": "application/json", diff --git a/apps/dm/middleware.ts b/apps/dm/middleware.ts index 0b2b21fbb..44d4cb390 100644 --- a/apps/dm/middleware.ts +++ b/apps/dm/middleware.ts @@ -1,13 +1,13 @@ import { NextRequest, NextResponse } from "next/server"; import { CLAIM_NAME, AUTH_USER_ID } from "./src/shared/config"; -import { SERVER_API_FO_URL, SERVER_API_WR_URL } from "./src/shared/config/env"; +// import { SERVER_API_FO_URL, SERVER_API_WR_URL } from "./src/shared/config/env"; // const CLAIM_NAME = "Authorization"; // const AUTH_USER_ID = "token-id"; 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 GATEWAY_URL = process.env.NEXT_PUBLIC_GATEWAY_URL || ""; const BUSINESS_JUSO_API_URL = process.env.NEXT_PUBLIC_FINDADRESS_URL || ""; const AdressKey = process.env.NEXT_PRIVATE_WR_ADDRESS_KEY || ""; @@ -112,7 +112,7 @@ export function middleware(req: NextRequest) { const url = req.nextUrl.clone(); url.searchParams.set("TYPENAME", typename.replace("hasudo:", "")); queryParams = url.searchParams.toString(); - newUrl = `${SEWERAGE_API_URL}/api/v1/map/geometry${queryParams ? `?${queryParams}` : ""}`; + newUrl = `${GATEWAY_URL}/api/v1/map/geometry${queryParams ? `?${queryParams}` : ""}`; } console.log(`[Middleware] Rewriting from '/geoserver' path to: ${newUrl}`); @@ -121,24 +121,17 @@ export function middleware(req: NextRequest) { if (pathname.startsWith("/reuse-service")) { const queryParams = searchParams.toString(); - const newUrl = `${SERVER_API_WR_URL}${pathname.replace("/reuse-service", "")}${queryParams ? `?${queryParams}` : "" - }`; + const newUrl = `${GATEWAY_URL}${pathname}${queryParams ? `?${queryParams}` : ""}`; console.log(`[Middleware] Rewriting from '/reuse-service' path to: ${newUrl}`); return NextResponse.rewrite(new URL(newUrl)); - } - - if (pathname.startsWith("/operation-service")) { + } else if (pathname.startsWith("/operation-service")) { const queryParams = searchParams.toString(); - const newUrl = `${SERVER_API_FO_URL}${pathname.replace("/operation-service", "")}${queryParams ? `?${queryParams}` : "" - }`; + const newUrl = `${GATEWAY_URL}${pathname}${queryParams ? `?${queryParams}` : ""}`; console.log(`[Middleware] Rewriting from '/operation-service' path to: ${newUrl}`); return NextResponse.rewrite(new URL(newUrl)); - } - - if (pathname.startsWith("/sewerage-service")) { + } else if (pathname.startsWith("/sewerage-service")) { const queryParams = searchParams.toString(); - const newUrl = `${SEWERAGE_API_URL}${pathname.replace("/sewerage-service", "")}${queryParams ? `?${queryParams}` : "" - }`; + const newUrl = `${GATEWAY_URL}${pathname}${queryParams ? `?${queryParams}` : ""}`; console.log(`[Middleware] Rewriting from '/sewerage-service' path to: ${newUrl}`); return NextResponse.rewrite(new URL(newUrl)); } From 3716e8c7b2e4b48d4bdc500f304e7ac3a139611d Mon Sep 17 00:00:00 2001 From: dongsilove <ljparkmindone@gmail.com> Date: Thu, 15 Jan 2026 21:14:49 +0900 Subject: [PATCH 29/34] =?UTF-8?q?dm:=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/sdmMng/sdmInfoInsert/page.tsx | 18 +- .../pages/sdmMng/sdmLogout/page.tsx | 22 + apps/dm/app/store/sdmMng/index.tsx | 617 +++++++++--------- 3 files changed, 348 insertions(+), 309 deletions(-) create mode 100644 apps/dm/app/(base-layout)/pages/sdmMng/sdmLogout/page.tsx diff --git a/apps/dm/app/(base-layout)/pages/sdmMng/sdmInfoInsert/page.tsx b/apps/dm/app/(base-layout)/pages/sdmMng/sdmInfoInsert/page.tsx index b6a395974..df418b20f 100644 --- a/apps/dm/app/(base-layout)/pages/sdmMng/sdmInfoInsert/page.tsx +++ b/apps/dm/app/(base-layout)/pages/sdmMng/sdmInfoInsert/page.tsx @@ -1,5 +1,11 @@ "use client"; +/** + * 수요정보등록 화면 + * + * 🔗 사용 API + * - 수요정보등록: POST /reuseFc/request/demandInfo + */ import { useDmStore } from "@/app/store"; import { sdmInfoFormSchema, type DemandCompBizType, type SdmInfoFormData } from "@/app/store/sdmMng"; import { SdmInfoRegForm } from "@/components/ui/sdmInfoInsertForm/component"; @@ -60,7 +66,7 @@ function SdmInfoInsertContent() { ...prev, sdmNm: searchParams.get("dmdCoNm") || "", })); - if(searchParams.get("dmdInfoId")){ + if (searchParams.get("dmdInfoId")) { // const data = { // dmdCoNm: searchParams.get("dmdCoNm") || '', // ctpvCd: searchParams.get("ctpvCd") || '', @@ -69,8 +75,8 @@ function SdmInfoInsertContent() { // daddr: searchParams.get("daddr") || '', // telno: searchParams.get("telno") || '', // } - - // sessionStorage.setItem("user", JSON.stringify(data || {})); + + // sessionStorage.setItem("user", JSON.stringify(data || {})); } //sessionStorage.setItem("user", JSON.parse(user||'') || ""); setIsLogin(user || searchParams.get("dmdInfoId") ? true : false); @@ -121,7 +127,7 @@ function SdmInfoInsertContent() { const userData = JSON.parse(user); if (userData.dmdCoNm) { setFacilityName(userData.dmdCoNm); - form.setValue("sdmNm", userData.dmdCoNm); + form.setValue("sdmNm", userData.dmdCoNm); // 수요처명(회사명) } } catch (error) { console.error("Error parsing user data:", error); @@ -203,10 +209,10 @@ function SdmInfoInsertContent() { tph: Number(data.tph) || null, trbt: Number(data.trbt) || null, ph: data.ph || "", - blgcOxygDmndQnt: Number(data.bod) ||null, + blgcOxygDmndQnt: Number(data.bod) || null, clIonQnt: Number(data.clIonQnt) || null, smll: data.smll || "", - cdtnv: Number(data.cdtnv) ||null, + cdtnv: Number(data.cdtnv) || null, crmty: Number(data.crmty) || null, rmrk: data.rmrk || "", bzmnNo: "", diff --git a/apps/dm/app/(base-layout)/pages/sdmMng/sdmLogout/page.tsx b/apps/dm/app/(base-layout)/pages/sdmMng/sdmLogout/page.tsx new file mode 100644 index 000000000..2c682bdbf --- /dev/null +++ b/apps/dm/app/(base-layout)/pages/sdmMng/sdmLogout/page.tsx @@ -0,0 +1,22 @@ +"use client"; +/** + * 수요처 로그아웃 화면 + * + * 🔗 사용 API + * + */ +import { useDmStore } from "@/app/store"; +import { useRouter } from "next/navigation"; +import { useEffect } from "react"; + +export default function SdmLogout() { + const router = useRouter(); + const { actionLogout } = useDmStore((state) => state); + + useEffect(() => { + actionLogout(); + router.push("/pages/sdmMng/sdmInfoInsert"); + }, [actionLogout, router]); + + return null; +} diff --git a/apps/dm/app/store/sdmMng/index.tsx b/apps/dm/app/store/sdmMng/index.tsx index ef7fb4cea..2e52ac13d 100644 --- a/apps/dm/app/store/sdmMng/index.tsx +++ b/apps/dm/app/store/sdmMng/index.tsx @@ -50,8 +50,8 @@ export const sdmInfoFormSchema = z.object({ // 모든 수질 관련 필드 // 총대장균군수는 null 값을 불검출로 표시하기때문에 해당 검사에서 제외함. const allFields: (keyof typeof data)[] = [ - "tn", "combResdch", "tph", - "trbt", "ph", "bod", "clIonQnt", + "tn", "combResdch", "tph", + "trbt", "ph", "bod", "clIonQnt", "smll", "cdtnv", "crmty", ]; @@ -104,38 +104,38 @@ export type SdmInfoFormData = z.infer<typeof sdmInfoFormSchema>; // 수요처 정보 export type DemandCompBizType = { - index : number | ''; - dmdInfoId : string | ''; - dmdInfoFk : string | ''; - bzmnNo : string | ''; - dmdCoNm : string | ''; - daddr : string | ''; - telno : string | ''; - rgtr : string | ''; - useUsgCd : string | ''; - ctpvCd : string | ''; - sggCd : string | ''; - dmdAplyPswd : string | ''; - wntUntprc : number | ''; - dmndTmng : Date | ''; - dmndQty : number | ''; - grssClfg : number | null //총대장균군수 - tn : number | null //총질소 - combResdch : number | null //결합잔류염소 - tph : number | null //총인 - trbt : number | null //탁도 - ph : string | ''; //수소이온농 - blgcOxygDmndQnt : number | null //생물학적산소요구량 - clIonQnt : number | null //염화물 - smll : string | ''; //냄새 - cdtnv : number | null; //전기전도도 - crmty : number | null //색도 - rmrk : string | ''; - reqDt : string | ''; - dmdInfoSn : number | ''; - status : string | ''; - splyCndtList:SupplyCandidate[]|[], - ruseUtztnFcltNm?:string|'' + index: number | ''; + dmdInfoId: string | ''; + dmdInfoFk: string | ''; + bzmnNo: string | ''; + dmdCoNm: string | ''; + daddr: string | ''; + telno: string | ''; + rgtr: string | ''; + useUsgCd: string | ''; + ctpvCd: string | ''; + sggCd: string | ''; + dmdAplyPswd: string | ''; + wntUntprc: number | ''; + dmndTmng: Date | ''; + dmndQty: number | ''; + grssClfg: number | null //총대장균군수 + tn: number | null //총질소 + combResdch: number | null //결합잔류염소 + tph: number | null //총인 + trbt: number | null //탁도 + ph: string | ''; //수소이온농 + blgcOxygDmndQnt: number | null //생물학적산소요구량 + clIonQnt: number | null //염화물 + smll: string | ''; //냄새 + cdtnv: number | null; //전기전도도 + crmty: number | null //색도 + rmrk: string | ''; + reqDt: string | ''; + dmdInfoSn: number | ''; + status: string | ''; + splyCndtList: SupplyCandidate[] | [], + ruseUtztnFcltNm?: string | '' } @@ -147,107 +147,107 @@ export type SupplyCandidate = { export type DemandMatchings = { - splyFcltFk : string | ''; - splyFcltFlg : string | ''; - pbnstRuseFcltBizFk : number | ''; - splyBgngDay : string | ''; - splyEndDay : string | ''; - splyCpct : number | ''; - splyFmYn : string | ''; - useUsgCd : string | ''; - dmdInfoSn : number | ''; - splyCndtList : string | ''; - mtchnCmptnYmd : string | ''; - rvwCmptnYmd : string | ''; - regDt : string | ''; - rgtr : string | ''; - mdfcnDt : string | ''; - mdfr : string | ''; + splyFcltFk: string | ''; + splyFcltFlg: string | ''; + pbnstRuseFcltBizFk: number | ''; + splyBgngDay: string | ''; + splyEndDay: string | ''; + splyCpct: number | ''; + splyFmYn: string | ''; + useUsgCd: string | ''; + dmdInfoSn: number | ''; + splyCndtList: string | ''; + mtchnCmptnYmd: string | ''; + rvwCmptnYmd: string | ''; + regDt: string | ''; + rgtr: string | ''; + mdfcnDt: string | ''; + mdfr: string | ''; } // 유사사례 export type SimilarCaseType = { - ruseBizNm : string | ''; // 사업명 - bizBgngDate : string | ''; - bizEndDate : string | ''; - splyFcltKnd : string | ''; - splyFcltNm : string | ''; - splyFcltCpct : string | ''; - dmdFcltNm : string | ''; - dmdFcltAddr : string | ''; - ruseFcltCpct : string | ''; - ruseFcltPplLen : string | ''; - ruseFcltUsg : string | ''; - ruseFcltSplyCpct : string | ''; - ruseFcltPrcsMsrc : string | ''; - grnteWqUsg : string | ''; - grnteWqGrssClfg : string | ''; - grnteWqCombResdch : string | ''; - grnteWqTrbt : string | ''; - grnteWqBod : string | ''; - grnteWqSmll : string | ''; - grnteWqCrmty : string | ''; - grnteWqTn : string | ''; - grnteWqTp : string | ''; - grnteWqPh : string | ''; - grnteWqClIonQnt : string | ''; - grnteWqCndctStat : string | ''; - grnteWqRmrk : string | ''; - reqBizReuseFcltCst : string | ''; - reqBizPplCst : string | ''; - reqBizArchCst : string | ''; - reqBizMchnCst : string | ''; - reqBizMtrngCst : string | ''; - reqBizGisCst : string | ''; - reqBizCctvCst : string | ''; - reqBizCmcnCst : string | ''; - reqBizWstCst : string | ''; - reqBizDesignCst : string | ''; - reqBizSpvsCst : string | ''; - reqBizSbsdCst : string | ''; - reqBizEtc : string | ''; - reqBizGrssCst : string | ''; - prcmPlanNlep : string | ''; - prcmPlanLcep : string | ''; - prcmPlanBrdnCst : string | ''; - prcmPlanEcqrRt : string | ''; - prcmPlanGrssCst : string | ''; - clclnNlep : string | ''; - clclnLcep : string | ''; - clclnBrdnCst : string | ''; - clclnEcqrRt : string | ''; - clclnGrssCst : string | ''; + ruseBizNm: string | ''; // 사업명 + bizBgngDate: string | ''; + bizEndDate: string | ''; + splyFcltKnd: string | ''; + splyFcltNm: string | ''; + splyFcltCpct: string | ''; + dmdFcltNm: string | ''; + dmdFcltAddr: string | ''; + ruseFcltCpct: string | ''; + ruseFcltPplLen: string | ''; + ruseFcltUsg: string | ''; + ruseFcltSplyCpct: string | ''; + ruseFcltPrcsMsrc: string | ''; + grnteWqUsg: string | ''; + grnteWqGrssClfg: string | ''; + grnteWqCombResdch: string | ''; + grnteWqTrbt: string | ''; + grnteWqBod: string | ''; + grnteWqSmll: string | ''; + grnteWqCrmty: string | ''; + grnteWqTn: string | ''; + grnteWqTp: string | ''; + grnteWqPh: string | ''; + grnteWqClIonQnt: string | ''; + grnteWqCndctStat: string | ''; + grnteWqRmrk: string | ''; + reqBizReuseFcltCst: string | ''; + reqBizPplCst: string | ''; + reqBizArchCst: string | ''; + reqBizMchnCst: string | ''; + reqBizMtrngCst: string | ''; + reqBizGisCst: string | ''; + reqBizCctvCst: string | ''; + reqBizCmcnCst: string | ''; + reqBizWstCst: string | ''; + reqBizDesignCst: string | ''; + reqBizSpvsCst: string | ''; + reqBizSbsdCst: string | ''; + reqBizEtc: string | ''; + reqBizGrssCst: string | ''; + prcmPlanNlep: string | ''; + prcmPlanLcep: string | ''; + prcmPlanBrdnCst: string | ''; + prcmPlanEcqrRt: string | ''; + prcmPlanGrssCst: string | ''; + clclnNlep: string | ''; + clclnLcep: string | ''; + clclnBrdnCst: string | ''; + clclnEcqrRt: string | ''; + clclnGrssCst: string | ''; } // 사업비 상세정보 export type MoneyDetailType = { - reqBizGrssCst : string | ''; - reqBizReuseFcltCst : string | ''; - reqBizPplCst : string | ''; - reqBizArchCst : string | ''; - reqBizMchnCst : string | ''; - reqBizMtrngCst : string | ''; - reqBizGisCst : string | ''; - reqBizCctvCst : string | ''; - reqBizCmcnCst : string | ''; - reqBizWstCst : string | ''; - reqBizDesignCst : string | ''; - reqBizSpvsCst : string | ''; - reqBizSbsdCst : string | ''; - reqBizEtc : string | ''; - + reqBizGrssCst: string | ''; + reqBizReuseFcltCst: string | ''; + reqBizPplCst: string | ''; + reqBizArchCst: string | ''; + reqBizMchnCst: string | ''; + reqBizMtrngCst: string | ''; + reqBizGisCst: string | ''; + reqBizCctvCst: string | ''; + reqBizCmcnCst: string | ''; + reqBizWstCst: string | ''; + reqBizDesignCst: string | ''; + reqBizSpvsCst: string | ''; + reqBizSbsdCst: string | ''; + reqBizEtc: string | ''; + /** 재원조달계획(백만원원) */ - prcmPlanGrssCst : string | ''; - prcmPlanNlep : string | ''; - prcmPlanLcep : string | ''; - prcmPlanBrdnCst : string | ''; - prcmPlanEcqrRt : string | ''; + prcmPlanGrssCst: string | ''; + prcmPlanNlep: string | ''; + prcmPlanLcep: string | ''; + prcmPlanBrdnCst: string | ''; + prcmPlanEcqrRt: string | ''; /** 사업비 정산(백만원) */ - clclnGrssCst : string | ''; - clclnNlep : string | ''; - clclnLcep : string | ''; - clclnBrdnCst : string | ''; - clclnEcqrRt : string | ''; + clclnGrssCst: string | ''; + clclnNlep: string | ''; + clclnLcep: string | ''; + clclnBrdnCst: string | ''; + clclnEcqrRt: string | ''; } // 규칙 타입 선언 export type DisableRulesType = Record<string, string[]>; @@ -255,144 +255,144 @@ export type DisableRulesType = Record<string, string[]>; * Store - 데이터 ====================================*/ // 수요처 정보 -const demandCompList : DemandCompType[] = [ +const demandCompList: DemandCompType[] = [ ] const disableRules: DisableRulesType = { - "청소": ["tn", 'tph',"clIonQnt" ,'cdtnv'], - "화장실용수": ["tn", 'tph',"clIonQnt" ,'cdtnv'], - "세척": ["combResdch", "crmty",'tph','tn',"clIonQnt",'cdtnv'], - "살수": ["combResdch", "crmty",'tph','tn',"clIonQnt",'cdtnv'], - "조경": ["combResdch", "crmty",'tph','cdtnv'], - "농업_간접용수": ["combResdch", "crmty",'tn','tph','clIonQnt'], - "농업_직접용수": ["combResdch", "crmty",'tn','tph','clIonQnt'], - "하천": ["combResdch", "trbt", "crmty" ,'clIonQnt','cdtnv'], - '공업':[] - }; + "청소": ["tn", 'tph', "clIonQnt", 'cdtnv'], + "화장실용수": ["tn", 'tph', "clIonQnt", 'cdtnv'], + "세척": ["combResdch", "crmty", 'tph', 'tn', "clIonQnt", 'cdtnv'], + "살수": ["combResdch", "crmty", 'tph', 'tn', "clIonQnt", 'cdtnv'], + "조경": ["combResdch", "crmty", 'tph', 'cdtnv'], + "농업_간접용수": ["combResdch", "crmty", 'tn', 'tph', 'clIonQnt'], + "농업_직접용수": ["combResdch", "crmty", 'tn', 'tph', 'clIonQnt'], + "하천": ["combResdch", "trbt", "crmty", 'clIonQnt', 'cdtnv'], + '공업': [] +}; - const defaultRules: Record<string, object> = { - "청소": { - grssClfg: null, - combResdch:0.2, - trbt: 2, - bod: 5, - crmty: 20, - ph: "5.8~8.5", - smll:'불쾌하지않을것', - tn:null, - tph: null, - clIonQnt: null, - cdtnv: null, +const defaultRules: Record<string, object> = { + "청소": { + grssClfg: null, + combResdch: 0.2, + trbt: 2, + bod: 5, + crmty: 20, + ph: "5.8~8.5", + smll: '불쾌하지않을것', + tn: null, + tph: null, + clIonQnt: null, + cdtnv: null, - }, - "화장실용수": { - grssClfg: null, - combResdch:0.2, - trbt: 2, - bod: 5, - crmty: 20, - smll:'불쾌하지않을것', - ph: "5.8~8.5", - tn:null, - tph: null, - clIonQnt: null, - cdtnv: null, - }, - "세척": { - grssClfg: null, - trbt: 2, - bod: 5, - ph: "5.8~8.5", - combResdch:null, - smll:'불쾌하지않을것', - crmty:null, - tn:null, - tph: null, - clIonQnt: null, - cdtnv: null, - }, - "살수": { - grssClfg: null, - trbt: 2, - bod: 5, - ph: "5.8~8.5", - smll:'불쾌하지않을것', - combResdch:null, - crmty:null, - tn:null, - tph: null, - clIonQnt: null, - cdtnv: null, - }, - "조경": { - grssClfg: null, - trbt: 2, - bod: 5, - ph: "5.8~8.5", - smll:'불쾌하지않을것', - clIonQnt:250, - combResdch:null, - crmty:null, - tn:null, - tph: null, - cdtnv: null, - }, - "농업_간접용수": { - grssClfg: null, - trbt: 5, - bod: 8, - ph: "5.8~8.5", - cdtnv:2000, - combResdch:null, - crmty:null, - tn:null, - tph: null, - clIonQnt: null, - }, - "농업_직접용수": { - grssClfg: null, - trbt: 2, - bod: 8, - smll:'불쾌하지않을것', - ph: "5.8~8.5", - cdtnv:700, - combResdch:null, - crmty:null, - tn:null, - tph: null, - clIonQnt: null, - }, - "하천": { - grssClfg: 1000, - bod: 5, - tn: 10, - tph: 0.5, - smll:'불쾌하지않을것', - ph: "5.8~8.5", - combResdch:null, - trbt:null, - crmty:null, - clIonQnt: null, - cdtnv:null - }, - '공업':{ - grssClfg: null, - bod: null, - tn: null, - tph: null, - ph: "~", - combResdch:null, - smll:'불쾌하지않을것', - trbt:null, - crmty:null, - clIonQnt: null, - cdtnv:null - } - }; + }, + "화장실용수": { + grssClfg: null, + combResdch: 0.2, + trbt: 2, + bod: 5, + crmty: 20, + smll: '불쾌하지않을것', + ph: "5.8~8.5", + tn: null, + tph: null, + clIonQnt: null, + cdtnv: null, + }, + "세척": { + grssClfg: null, + trbt: 2, + bod: 5, + ph: "5.8~8.5", + combResdch: null, + smll: '불쾌하지않을것', + crmty: null, + tn: null, + tph: null, + clIonQnt: null, + cdtnv: null, + }, + "살수": { + grssClfg: null, + trbt: 2, + bod: 5, + ph: "5.8~8.5", + smll: '불쾌하지않을것', + combResdch: null, + crmty: null, + tn: null, + tph: null, + clIonQnt: null, + cdtnv: null, + }, + "조경": { + grssClfg: null, + trbt: 2, + bod: 5, + ph: "5.8~8.5", + smll: '불쾌하지않을것', + clIonQnt: 250, + combResdch: null, + crmty: null, + tn: null, + tph: null, + cdtnv: null, + }, + "농업_간접용수": { + grssClfg: null, + trbt: 5, + bod: 8, + ph: "5.8~8.5", + cdtnv: 2000, + combResdch: null, + crmty: null, + tn: null, + tph: null, + clIonQnt: null, + }, + "농업_직접용수": { + grssClfg: null, + trbt: 2, + bod: 8, + smll: '불쾌하지않을것', + ph: "5.8~8.5", + cdtnv: 700, + combResdch: null, + crmty: null, + tn: null, + tph: null, + clIonQnt: null, + }, + "하천": { + grssClfg: 1000, + bod: 5, + tn: 10, + tph: 0.5, + smll: '불쾌하지않을것', + ph: "5.8~8.5", + combResdch: null, + trbt: null, + crmty: null, + clIonQnt: null, + cdtnv: null + }, + '공업': { + grssClfg: null, + bod: null, + tn: null, + tph: null, + ph: "~", + combResdch: null, + smll: '불쾌하지않을것', + trbt: null, + crmty: null, + clIonQnt: null, + cdtnv: null + } +}; // 사용용도 -const useTypesData : SelectDataType[] = [ +const useTypesData: SelectDataType[] = [ { text: '청소', val: "청소" }, { text: "화장실용수", val: "화장실용수" }, { text: "세척", val: "세척" }, @@ -440,8 +440,8 @@ export const similarCaseModalHeader: TableUpperProps[] = [ ] // 유사사례 데이터 -const similarCaseList : SimilarCaseType[] = [ - +const similarCaseList: SimilarCaseType[] = [ + ] // 사업비 상세정보 모달 헤더 @@ -477,12 +477,12 @@ export const moneyDetailModalHeader: TableUpperProps[] = [ ] // 사업비 상세정보 -const moneyDetailList : MoneyDetailType[] = [ +const moneyDetailList: MoneyDetailType[] = [ ] // 수요정보 신청현황 헤더 export const upHeadSdmInfoStatus: TableUpperProps[] = [ - { id: "index", title: "No."}, + { id: "index", title: "No." }, { id: "ctpvCd", title: "시도", row: 0, rowSpan: 2 }, { id: "sggCd", title: "시군구", row: 0, rowSpan: 2 }, { id: "dmdCoNm", title: "회사명", row: 0, rowSpan: 2 }, @@ -501,7 +501,7 @@ export const upHeadSdmInfoStatus: TableUpperProps[] = [ const postSdmData = async (data: DemandCompType) => { try { await postFetch("/reuseFc/request", data); - sessionStorage.setItem("user", JSON.stringify(data) ); + sessionStorage.setItem("user", JSON.stringify(data)); toast.success("수요처 등록에 성공하였습니다."); return true; } catch (error) { @@ -526,16 +526,16 @@ const postSdmLoginData = async (data: DemandCompType) => { try { const res = await postFetch("/reuseFc/request/login", data); const jsonData = await res.json(); - + const status = jsonData.status; const loginData = jsonData.data; let loginSuccess = false; - if(status === 200 && loginData != null) { + if (status === 200 && loginData != null) { alert("수요처 로그인에 성공하였습니다."); sessionStorage.setItem("user", JSON.stringify(loginData)); loginSuccess = true; - } else if(status === 401) { - alert("패스워드가 틀렸습니다."); + } else if (status === 401) { + alert("패스워드가 일치하지 않습니다."); loginSuccess = false; } else { alert("등록된 수요처가 없습니다."); @@ -553,35 +553,35 @@ const getDemandCompList = async (searchText: string, pageCnt: number) => { try { const url = '/reuseFc/request/' + (searchText ? searchText : '') + '/' + pageCnt; const res = await getFetch(fetchType.WR, url); - return { - data: res?.data || [], - count: res?.count || 0 + return { + data: res?.data || [], + count: res?.count || 0 } } catch (error) { - console.error(error+' 수요처 정보를 불러오지 못했습니다.'); + console.error(error + ' 수요처 정보를 불러오지 못했습니다.'); return { data: [], count: 0 }; } } -const getSdmInfoStatusList = async (dmdInfoId : string) => { +const getSdmInfoStatusList = async (dmdInfoId: string) => { try { const url = '/reuseFc/request/' + dmdInfoId; const res = await getFetch(fetchType.WR, url); return res?.data || []; } catch (error) { - console.error(error+' 수요정보 신청현황을 불러오지 못했습니다.'); + console.error(error + ' 수요정보 신청현황을 불러오지 못했습니다.'); return []; } } // 유사사례 조회 -const fetchGetSimilarCaseList = async (part: string, value: number|string) => { +const fetchGetSimilarCaseList = async (part: string, value: number | string) => { try { const url = '/reuseFc/pubFcRuseCase/dm/' + part + '/' + (value ? value : 0); const res = await getFetch(fetchType.WR, url); return res?.data || []; } catch (error) { - console.error(error+' 유사사례 조회에 실패하였습니다.'); + console.error(error + ' 유사사례 조회에 실패하였습니다.'); return []; } } @@ -590,23 +590,24 @@ const fetchGetSimilarCaseList = async (part: string, value: number|string) => { * Store - expaort ====================================*/ export type SdmActions = { - initializeSdmData: () => void; - insertSdmData: (data: DemandCompType) => Promise<void>; - insertSdmInfoData: (data: DemandCompBizType) => Promise<void>; - getDemandCompList: (searchText: string, pageCnt: number) => Promise<void>; - actionLogin: (data: DemandCompType) => Promise<void>; - getSdmInfoStatusList: (dmdInfoId: string) => Promise<void>; - getSimilarCaseList: (part: string, value: number|string) => Promise<void>; + initializeSdmData: () => void; + insertSdmData: (data: DemandCompType) => Promise<void>; + insertSdmInfoData: (data: DemandCompBizType) => Promise<void>; + getDemandCompList: (searchText: string, pageCnt: number) => Promise<void>; + actionLogin: (data: DemandCompType) => Promise<void>; + getSdmInfoStatusList: (dmdInfoId: string) => Promise<void>; + getSimilarCaseList: (part: string, value: number | string) => Promise<void>; + actionLogout: () => Promise<void>; } -export type SdmType ={ - Sdm :{ +export type SdmType = { + Sdm: { isInit: boolean; useTypesData: SelectDataType[]; demandCompList: DemandCompType[]; upHeadSimilarCaseList: TableUpperProps[]; similarCaseList: SimilarCaseType[]; - upHeadMoneyDetailList : TableUpperProps[]; + upHeadMoneyDetailList: TableUpperProps[]; moneyDetailList: MoneyDetailType[]; // 수요정보 신청현황 @@ -615,28 +616,28 @@ export type SdmType ={ defaultRules: Record<string, object> disableRules: DisableRulesType; // 로그인관련 - successNextPage : boolean; + successNextPage: boolean; successLogin: boolean; } } export const SdmState: SdmType = { - Sdm:{ - isInit:false, + Sdm: { + isInit: false, useTypesData: useTypesData, demandCompList: demandCompList, upHeadSimilarCaseList: similarCaseModalHeader, similarCaseList: similarCaseList, - upHeadMoneyDetailList : moneyDetailModalHeader, + upHeadMoneyDetailList: moneyDetailModalHeader, moneyDetailList: moneyDetailList, // 수요정보 신청현황 sdmInfoStatusList: [], - defaultRules:defaultRules, - disableRules:disableRules, + defaultRules: defaultRules, + disableRules: disableRules, upHeadSdmInfoStatus: upHeadSdmInfoStatus, // 로그인관련 - successNextPage : false, + successNextPage: false, successLogin: false, } } @@ -648,13 +649,13 @@ export const SdmReducer = (set: any): SdmActions => { insertSdmData: async (data: DemandCompType) => { const preRes = await getSdmInfoStatusList(data.dmdInfoId); - if(preRes?.dmdInfoId) { + if (preRes?.dmdInfoId) { toast.error('이미 등록된 수요처입니다.'); return; } const res = await postSdmData(data); - if(res) { + if (res) { set((state: SdmType) => ({ Sdm: { ...state.Sdm, @@ -671,7 +672,7 @@ export const SdmReducer = (set: any): SdmActions => { // 수요처 정보 getDemandCompList: async (searchText: string, pageCnt: number) => { const res = await getDemandCompList(searchText, pageCnt); - if(res.data.length === 0) { + if (res.data.length === 0) { set((state: SdmType) => ({ Sdm: { ...state.Sdm, @@ -693,7 +694,7 @@ export const SdmReducer = (set: any): SdmActions => { getSdmInfoStatusList: async (dmdInfoId: string) => { const res = await getSdmInfoStatusList(dmdInfoId); - if(res.length === 0) { + if (res.length === 0) { set((state: SdmType) => ({ Sdm: { ...state.Sdm, @@ -704,13 +705,13 @@ export const SdmReducer = (set: any): SdmActions => { } //const sdmInfoStatusList : DemandCompBizType[] = []; - const sdmInfoStatusList : DemandCompBizType[]= res.demandInfo.map((el: DemandCompBizType, index: number) => { + const sdmInfoStatusList: DemandCompBizType[] = res.demandInfo.map((el: DemandCompBizType, index: number) => { const matchingInfo = res.demandMatchings.find((matching: DemandMatchings) => matching.dmdInfoSn === el.dmdInfoSn); const status = matchingInfo?.splyFcltFlg?.trim() === 'Sub' ? '검토' : matchingInfo?.splyFcltFlg?.trim() === 'matched' ? '매칭완료' : '신청'; const ruseUtztnFcltNm = matchingInfo?.ruseUtztnFcltNm ? matchingInfo.ruseUtztnFcltNm : ''; - return( { + return ({ ...el, index: ++index, bzmnNo: res.bzmnNo, @@ -723,8 +724,8 @@ export const SdmReducer = (set: any): SdmActions => { sggCd: res.sggCd, useUsgCd: el.useUsgCd, dmndTmng: el.dmndTmng, - dmdInfoSn : el.dmdInfoSn, - status : status, + dmdInfoSn: el.dmdInfoSn, + status: status, splyCndtList: el.splyCndtList, ruseUtztnFcltNm: ruseUtztnFcltNm || '' }) @@ -749,7 +750,7 @@ export const SdmReducer = (set: any): SdmActions => { }, // 유사사례 조회 - getSimilarCaseList: async (part: string, value: number|string) => { + getSimilarCaseList: async (part: string, value: number | string) => { const res = await fetchGetSimilarCaseList(part, value); const similarCaseList = res.map((el: SimilarCaseType) => { const maskedBizNm = el.ruseBizNm @@ -762,24 +763,34 @@ export const SdmReducer = (set: any): SdmActions => { }; }); console.log(similarCaseList); - - if(similarCaseList && similarCaseList.length !== 0) { + + if (similarCaseList && similarCaseList.length !== 0) { set((state: SdmType) => ({ - Sdm: { + Sdm: { ...state.Sdm, similarCaseList: similarCaseList, } })) return; - }else{ + } else { set((state: SdmType) => ({ - Sdm: { + Sdm: { ...state.Sdm, similarCaseList: [], } })) return; } + }, + + actionLogout: async () => { + sessionStorage.removeItem("user"); + set((state: SdmType) => ({ + Sdm: { + ...state.Sdm, + successLogin: false, + } + })) } } } From 943d858c5aa36b5d51c71277ead4ce3f128279da Mon Sep 17 00:00:00 2001 From: ljpark <mind-one005@mind-one.co.kr> Date: Fri, 16 Jan 2026 17:37:49 +0900 Subject: [PATCH 30/34] =?UTF-8?q?cm:=20=EC=9A=B0=ED=8E=B8=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EB=96=BC=EC=96=B4=EB=82=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business_components/src/lib/utils.ts | 2 +- .../business_components/src/ui/index.ts | 3 +- .../src/ui/sdmInsertForm/form.tsx | 185 +-------------- .../ui/search_address/SearchAddressModal.tsx | 221 ++++++++++++++++++ .../src/ui/search_address/findAddress.ts | 118 ++++++++++ .../src/ui/search_address/index.ts | 3 + .../src/ui/search_address/zipService.ts | 66 ++++++ 7 files changed, 419 insertions(+), 179 deletions(-) create mode 100644 packages/common/business_components/src/ui/search_address/SearchAddressModal.tsx create mode 100644 packages/common/business_components/src/ui/search_address/findAddress.ts create mode 100644 packages/common/business_components/src/ui/search_address/index.ts create mode 100644 packages/common/business_components/src/ui/search_address/zipService.ts diff --git a/packages/common/business_components/src/lib/utils.ts b/packages/common/business_components/src/lib/utils.ts index a5ef19350..1a87df14d 100644 --- a/packages/common/business_components/src/lib/utils.ts +++ b/packages/common/business_components/src/lib/utils.ts @@ -2,5 +2,5 @@ import { clsx, type ClassValue } from "clsx"; import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); + return twMerge(clsx(inputs)); //clsx 결과 (단순 합치기):twMerge 결과 (Tailwind 충돌 제거) } diff --git a/packages/common/business_components/src/ui/index.ts b/packages/common/business_components/src/ui/index.ts index db1132b58..ae419bd83 100644 --- a/packages/common/business_components/src/ui/index.ts +++ b/packages/common/business_components/src/ui/index.ts @@ -15,6 +15,7 @@ export * from "./search_form_right"; export * from "./search_input"; export * from "./search_input_select"; // export * from "./search_input_address"; +export * from "./search_address"; export * from "./select"; export * from "./tab"; export * from "./table"; @@ -24,4 +25,4 @@ export * from "./sdmInsertForm"; export * from "./popover_ui"; export * from "./date_month_picker"; export * from "./date_picker_range" -export * from "./map/GisOverlay"; \ No newline at end of file +export * from "./map/GisOverlay"; diff --git a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx index 6f0cbff2b..b2499ab43 100644 --- a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx +++ b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx @@ -1,4 +1,4 @@ -import { Button, Input, Label } from "@common/components"; +import { Button, Input } from "@common/components"; import { AsYouType } from "libphonenumber-js"; import React, { useCallback, useEffect, useState } from "react"; import type { ControllerRenderProps, UseFormReturn } from "react-hook-form"; @@ -6,10 +6,7 @@ import { FormField } from "../form"; import { FormUi } from "../form_ui"; import { SelectBox } from "../select"; import { SdmSearchForm } from "./sdmNameBox"; -import { UiModal, UiTable } from '../../ui'; -import type { Zip, ZipSearchParams } from "../search_input_address/zipService"; -import { findAddress } from "../search_input_address/findAddress"; -import { cn } from "@common/components"; +import { SearchAddressModal } from "../search_address/SearchAddressModal"; // 수요처 정보 export type DemandCompType = { @@ -91,7 +88,6 @@ export function SdmRegForm({ readOnly, openNetwork, }: SdmRegFormProps) { - const PAGE_SIZE = 10; const [sidoValue, setSidoValue] = useState<string>(""); const [sigunValue, setSigunValue] = useState<string>(""); const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([ @@ -104,30 +100,6 @@ export function SdmRegForm({ const [zipId, setZipId] = useState<number | undefined>(undefined); const [address, setAddress] = useState<string | undefined>(""); const [detailedAddress, setDetailedAddress] = useState<string>(""); - const [curPage, setCurPage] = useState<number>(1); - // 우편번호 검색 관련 상태 - const [zipSearchResults, setZipSearchResults] = useState<Zip[]>([]); - const [zipTotalElements, setZipTotalElements] = useState<number>(-1); - const [searchQuery, setSearchQuery] = useState<ZipSearchParams>({ - roadNm: "", - bldgNoMno: null, - bldgNoSno: null, - page: curPage, - size: PAGE_SIZE - }); - const [isResetPage, setIsResetPage] = useState<boolean>(false); - const [isResetSelection, setIsResetSelection] = useState<boolean>(false); - const [selectedRowIndex, setSelectedRowIndex] = useState<number | undefined>(undefined); - const [selectedZip, setSelectedZip] = useState<Zip>(); - const [isSelectedZip, setIsSelectedZip] = useState<boolean>(false); - - const handleCellClick = (index: any, headId: any) => { - console.log('index', index); - console.log('headId', headId); - setSelectedZip(zipSearchResults[index]); - setIsSelectedZip(true); - console.log('selectedZip', zipSearchResults[index]); - }; const formatPhoneNumber = (value: string) => { const input = value; @@ -293,17 +265,6 @@ export function SdmRegForm({ [orgBznmNo, setIsDuplicate], ); - // 우편번호 선택 함수 - const handleSelectAddress = () => { - setZipId(selectedZip?.zipId); - setAddress(selectedZip?.zipAddr || ""); - setDetailedAddress(""); - setIsZipModalOpen(false); - setSelectedZip(undefined); - setIsSelectedZip(false); - setSelectedRowIndex(undefined); - }; - useEffect(() => { if (updateList?.dmdInfoId) { form.reset(updateList); @@ -325,16 +286,6 @@ export function SdmRegForm({ console.log("form.formState.errors ", form.formState.errors); }, [form.formState.errors]); - useEffect(() => { - console.log("curPage ", curPage); - searchQuery.page = curPage - 1; - const fetchAddress = async () => { - const result = await findAddress(searchQuery); - setZipSearchResults(result?.content); - }; - fetchAddress(); - }, [curPage]); - // 폼 제출 전에 주소 합치기 useEffect(() => { // address와 detailedAddress를 합쳐서 daddr에 설정 @@ -344,105 +295,6 @@ export function SdmRegForm({ } }, [address, detailedAddress, form]); - const renderBody = () => ( - <> - <form - onSubmit={async (e) => { - e.preventDefault(); - e.stopPropagation(); - const result = await findAddress(searchQuery); - setZipSearchResults(result?.content); - setZipTotalElements(result?.totalElements); - }} - className="mb-4 space-y-2" - > - {/* 검색 조건 부분 */} - <div className="card card-border !m-0 flex flex-col gap-4 p-4"> - <div className="grid grid-cols-3 gap-4"> - <div className="flex flex-col"> - <Label className="mb-1 font-bold text-base">도로명</Label> - <Input - value={searchQuery.roadNm || ""} - onChange={(e) => - setSearchQuery({ - ...searchQuery, - roadNm: e.target.value, - }) - } - placeholder="예: 테헤란로" - className="!text-[1.3rem]" - /> - </div> - - <div className="flex flex-col"> - <Label className="mb-1 text-base">건물본번</Label> - <Input - type="number" - value={searchQuery.bldgNoMno ?? ""} - onChange={(e) => { - const value = e.target.value - ? parseInt(e.target.value) - : null; - setSearchQuery({ - ...searchQuery, - bldgNoMno: value, - }); - }} - placeholder="예: 123" - className="!text-[1.3rem]" - /> - </div> - - <div className="flex flex-col"> - <Label className="mb-1 text-base">건물부번</Label> - <Input - type="number" - value={searchQuery.bldgNoSno ?? ""} - onChange={(e) => { - const value = e.target.value - ? parseInt(e.target.value) - : null; - setSearchQuery({ - ...searchQuery, - bldgNoSno: value, - }); - }} - placeholder="예: 45" - className="!text-[1.3rem]" - /> - </div> - </div> - - <div className="flex justify-end"> - <Button className="rounded-md" type="submit">검색</Button> - </div> - </div> - </form> - - {/* 검색 결과 부분 */} - {zipTotalElements > 0 && ( - <UiTable - headName='' - tableData={zipSearchResults} - headlist={[{ id: 'zoneNo', title: '우편번호' }, { id: 'zipAddr', title: '주소' }]} - pageSize={PAGE_SIZE} - total={zipTotalElements} - cellClick={handleCellClick} - onPageChange={setCurPage} - resetPageNo={isResetPage} - resetSelection={isResetSelection} - index={selectedRowIndex} - /> - )} - {zipTotalElements === 0 && ( - <div className={cn("flex h-96 flex-col items-center justify-center gap-4")}> - <i className="diveicon di-info-circle text-3xl" /> - 조회된 데이터가 없습니다. - </div> - )} - </> - ); - const formFields: Array<{ name: keyof FormSchema; @@ -725,35 +577,14 @@ export function SdmRegForm({ /> ); })} - <UiModal - headerTitle="주소 검색" - headerTitleClass="text-2xl font-bold text-gray-900" + <SearchAddressModal open={isZipModalOpen} onOpenChange={setIsZipModalOpen} - bodyClass={` - ${zipTotalElements > -1 ? 'h-[80vh]' : 'h-[30vh]'} - w-[30vw] - min-w-[500px] - max-w-[90vw] - max-h-[85vh] - overflow-y-auto - !fixed - !top-[50%] - !left-[50%] - !-translate-x-1/2 - !-translate-y-1/2 - z-[101] - flex - flex-col - `} - body={renderBody()} - footerContent={ - <div className="w-full flex justify-center items-center gap-4"> - <Button className="rounded-md" size="lg" onClick={handleSelectAddress} disabled={!isSelectedZip}>선택</Button> - <Button className="rounded-md" size="lg" onClick={() => setIsZipModalOpen(false)}>취소</Button> - </div> - } - useDirectRender={true} + onSelect={(zip) => { + setZipId(zip.zipId); + setAddress(zip.zipAddr || ""); + setDetailedAddress(""); + }} /> </> ); diff --git a/packages/common/business_components/src/ui/search_address/SearchAddressModal.tsx b/packages/common/business_components/src/ui/search_address/SearchAddressModal.tsx new file mode 100644 index 000000000..55529f89a --- /dev/null +++ b/packages/common/business_components/src/ui/search_address/SearchAddressModal.tsx @@ -0,0 +1,221 @@ +import { Button, Input, Label, cn } from "@common/components"; +import React, { useState, useEffect } from "react"; +import { UiModal } from "../dialog_ui"; +import { UiTable } from "../table"; +import type { Zip, ZipSearchParams } from "./zipService"; +import { findAddress } from "./findAddress"; + +interface SearchAddressModalProps { + open: boolean; + onOpenChange: (open: boolean) => void; + onSelect: (zip: Zip) => void; +} + +export function SearchAddressModal({ open, onOpenChange, onSelect }: SearchAddressModalProps) { + const PAGE_SIZE = 10; + const [curPage, setCurPage] = useState<number>(1); + const [zipSearchResults, setZipSearchResults] = useState<Zip[]>([]); + const [zipTotalElements, setZipTotalElements] = useState<number>(-1); + const [searchQuery, setSearchQuery] = useState<ZipSearchParams>({ + roadNm: "", + bldgNoMno: null, + bldgNoSno: null, + page: 1, + size: PAGE_SIZE + }); + const [isResetPage, setIsResetPage] = useState<boolean>(false); + const [isResetSelection, setIsResetSelection] = useState<boolean>(false); + const [selectedRowIndex, setSelectedRowIndex] = useState<number | undefined>(undefined); + const [selectedZip, setSelectedZip] = useState<Zip>(); + const [isSelectedZip, setIsSelectedZip] = useState<boolean>(false); + + // Initialize/Reset state when modal opens + useEffect(() => { + if (open) { + setCurPage(1); + setZipSearchResults([]); + setZipTotalElements(-1); + setSearchQuery({ + roadNm: "", + bldgNoMno: null, + bldgNoSno: null, + page: 0, + size: PAGE_SIZE + }); + setSelectedZip(undefined); + setIsSelectedZip(false); + setSelectedRowIndex(undefined); + setIsResetPage(true); + setTimeout(() => setIsResetPage(false), 100); + } + }, [open]); + + // Pagination Effect + useEffect(() => { + if (!open || zipTotalElements === -1) return; + + // Correctly update query for pagination without mutation + const nextPage = curPage - 1; + if (searchQuery.page !== nextPage) { + const newQuery = { ...searchQuery, page: nextPage }; + setSearchQuery(newQuery); + + const fetchAddress = async () => { + const result = await findAddress(newQuery); + setZipSearchResults(result?.content || []); + }; + fetchAddress(); + } + }, [curPage, open, zipTotalElements]); + + const handleCellClick = (index: any) => { + setSelectedZip(zipSearchResults[index]); + setIsSelectedZip(true); + setSelectedRowIndex(index); + }; + + const handleSearch = async (e: React.FormEvent) => { + e.preventDefault(); + e.stopPropagation(); + + const query = { ...searchQuery, page: 0 }; + setSearchQuery(query); + setCurPage(1); + setIsResetPage(true); + + const result = await findAddress(query); + setZipSearchResults(result?.content || []); + setZipTotalElements(result?.totalElements || 0); + + setTimeout(() => setIsResetPage(false), 100); + }; + + const handleConfirm = () => { + if (selectedZip) { + onSelect(selectedZip); + onOpenChange(false); + } + }; + + return ( + <UiModal + headerTitle="주소 검색" + headerTitleClass="text-2xl font-bold text-gray-900" + open={open} + onOpenChange={onOpenChange} + bodyClass={` + ${zipTotalElements > -1 ? 'h-[80vh]' : 'h-[30vh]'} + w-[30vw] + min-w-[500px] + max-w-[90vw] + min-h-[235px] + overflow-y-auto + !fixed + !top-[50%] + !left-[50%] + !-translate-x-1/2 + !-translate-y-1/2 + z-[101] + flex + flex-col + `} + body={ + <> + <form + onSubmit={handleSearch} + className="mb-4 space-y-2" + > + <div className="card card-border !m-0 flex flex-col gap-4 p-4"> + <div className="grid grid-cols-3 gap-4"> + <div className="flex flex-col"> + <Label className="mb-1 font-bold text-base">도로명</Label> + <Input + value={searchQuery.roadNm || ""} + onChange={(e) => + setSearchQuery({ + ...searchQuery, + roadNm: e.target.value, + }) + } + placeholder="예: 테헤란로" + className="!text-[1.3rem]" + /> + </div> + + <div className="flex flex-col"> + <Label className="mb-1 text-base">건물본번</Label> + <Input + type="number" + value={searchQuery.bldgNoMno ?? ""} + onChange={(e) => { + const value = e.target.value + ? parseInt(e.target.value) + : null; + setSearchQuery({ + ...searchQuery, + bldgNoMno: value, + }); + }} + placeholder="예: 123" + className="!text-[1.3rem]" + /> + </div> + + <div className="flex flex-col"> + <Label className="mb-1 text-base">건물부번</Label> + <Input + type="number" + value={searchQuery.bldgNoSno ?? ""} + onChange={(e) => { + const value = e.target.value + ? parseInt(e.target.value) + : null; + setSearchQuery({ + ...searchQuery, + bldgNoSno: value, + }); + }} + placeholder="예: 45" + className="!text-[1.3rem]" + /> + </div> + </div> + + <div className="flex justify-end"> + <Button className="rounded-md" type="submit">검색</Button> + </div> + </div> + </form> + + {zipTotalElements > 0 && ( + <UiTable + headName='' + tableData={zipSearchResults} + headlist={[{ id: 'zoneNo', title: '우편번호' }, { id: 'zipAddr', title: '주소' }]} + pageSize={PAGE_SIZE} + total={zipTotalElements} + cellClick={handleCellClick} + onPageChange={setCurPage} + resetPageNo={isResetPage} + resetSelection={isResetSelection} + index={selectedRowIndex} + /> + )} + {zipTotalElements === 0 && ( + <div className={cn("flex h-96 flex-col items-center justify-center gap-4")}> + <i className="diveicon di-info-circle text-3xl" /> + 조회된 데이터가 없습니다. + </div> + )} + </> + } + footerContent={ + <div className="w-full flex justify-center items-center gap-4"> + <Button className="rounded-md" size="lg" onClick={handleConfirm} disabled={!isSelectedZip}>선택</Button> + <Button className="rounded-md" size="lg" onClick={() => onOpenChange(false)}>취소</Button> + </div> + } + useDirectRender={true} + /> + ); +} diff --git a/packages/common/business_components/src/ui/search_address/findAddress.ts b/packages/common/business_components/src/ui/search_address/findAddress.ts new file mode 100644 index 000000000..5e5ba4360 --- /dev/null +++ b/packages/common/business_components/src/ui/search_address/findAddress.ts @@ -0,0 +1,118 @@ + +// const Key = 'U01TX0FVVEgyMDI1MDgyODE0MTAxNzExNjEyMjA' +// const addresssKey = 'devU01TX0FVVEgyMDI1MDgyNTEwMzkwNDExNjEwNTM='; //인증키 만료일은 2025-11-23 + +import type { Zip, ZipSearchParams } from "./zipService"; + +/** + * 주소 API 응답 타입 + * https://business.juso.go.kr/addrlink/main.do 해당 사이트 참조 + */ +export type AddressApiResponse = { + results: { + common: { + errorMessage: string; + countPerPage: string; + totalCount: string; + errorCode: string; + currentPage: string; + }; + juso: addressType[]; + }; +} + +export type addressType = { + detBdNmList: string; + engAddr: string; + rn: string; + emdNm: string; + zipNo: string; + roadAddrPart2: string; + emdNo: string; + sggNm: string; + jibunAddr: string; + siNm: string; + roadAddrPart1: string; + bdNm: string; + admCd: string; + udrtYn: string; + lnbrMnnm: string; + roadAddr: string; + lnbrSlno: string; + buldMnnm: string; + bdKdcd: string; + liNm: string; + rnMgtSn: string; + mtYn: string; + bdMgtSn: string; + buldSlno: string; +} + +/** + * 주소에 따른 검색 + * @param search : 검색어 + * @returns addressType[] 주소 배열 + */ +export const findAddress = async (searchQuery: ZipSearchParams): Promise<any> => { + if (!searchQuery) return []; + + // 쿼리 파라미터 생성 + const params = new URLSearchParams(); + if (searchQuery.roadNm) params.append('roadNm', searchQuery.roadNm); + if (searchQuery.bldgNoMno != null) params.append('bldgNoMno', searchQuery.bldgNoMno.toString()); + if (searchQuery.bldgNoSno != null) params.append('bldgNoSno', searchQuery.bldgNoSno.toString()); + if (searchQuery.page != null) params.append('page', searchQuery.page.toString()); + if (searchQuery.size != null) params.append('size', searchQuery.size.toString()); + + const url = `/cms-service/api/v1/zips?${params.toString()}`; + try { + const response = await fetch(url); + if (!response.ok) throw new Error('Network response was not ok'); + + const data = await response.json(); + if (data) return data + else return []; + } catch (error) { + console.error('Error fetching address data:', error); + return []; + } + +} + + + +export const searchFilter = (search: string) => { + + + if (search.length > 0) { + //특수문자 제거 + const expText = /[%=><]/; + if (expText.test(search) == true) { + alert("특수문자를 입력 할수 없습니다."); + search = search.split(expText).join(""); + return false; + } + + //특정문자열(sql예약어의 앞뒤공백포함) 제거 + const sqlArray = [ + //sql 예약어 + "OR", "SELECT", "INSERT", "DELETE", "UPDATE", "CREATE", "DROP", "EXEC", + "UNION", "FETCH", "DECLARE", "TRUNCATE" + ] + + let regex; + for (let i = 0; i < sqlArray.length; i++) { + regex = new RegExp(sqlArray[i] as string, "gi"); + + if (regex.test(search)) { + alert("\"" + sqlArray[i] + "\"와(과) 같은 특정문자로 검색할 수 없습니다."); + search = search.replace(regex, ""); + return false; + } + } + } + return true; + + + +} diff --git a/packages/common/business_components/src/ui/search_address/index.ts b/packages/common/business_components/src/ui/search_address/index.ts new file mode 100644 index 000000000..b790bb492 --- /dev/null +++ b/packages/common/business_components/src/ui/search_address/index.ts @@ -0,0 +1,3 @@ +export * from "./SearchAddressModal"; +export * from "./findAddress"; +export * from "./zipService"; diff --git a/packages/common/business_components/src/ui/search_address/zipService.ts b/packages/common/business_components/src/ui/search_address/zipService.ts new file mode 100644 index 000000000..03e4a8ccc --- /dev/null +++ b/packages/common/business_components/src/ui/search_address/zipService.ts @@ -0,0 +1,66 @@ +interface SortConfig { + empty: boolean; + sorted: boolean; + unsorted: boolean; +} + +interface PageableConfig { + sort: SortConfig; + offset: number; + pageNumber: number; + pageSize: number; + paged: boolean; + unpaged: boolean; +} + +export interface PageableList<T> { + content: T[]; + pageable: PageableConfig; + sort: SortConfig; + totalPages: number; + totalElements: number; + number: number; + numberOfElements: number; + size: number; + first: boolean; + last: boolean; + empty: boolean; +} + +export interface PageableParams { + page?: number; + size?: number; + sort?: string; +} + + +export interface ZipSearchParams extends PageableParams { + zoneNo?: string; // 구역번호 + ctpvNm?: string; // 시도명 + sggNm?: string; // 시군구명 + emdNm?: string; // 읍면동명 + roadNm?: string; // 도로명 + stdgNm?: string; // 법정동명 + dongNm?: string; // 행정동명 + bldgNoMno?: number | null; // 빌딩본번 + bldgNoSno?: number | null; // 빌딩딩부번 + lotnoMno?: number | null; // 지번본번 + lotnoSno?: number | null; // 지번부번 +} + +export interface Zip { + zipId: number; + zoneNo: string; + ctpvNm: string; + sggNm: string; + emdNm: string; + roadNm: string; + bldgNoMno: number; + bldgNoSno: number; + lotnoMno: number; + lotnoSno: number; + lotno: string; + zipAddr: string; +} + +export type ZipList = PageableList<Zip>; From 44580f515668811272493e3ac030a485a286e7e7 Mon Sep 17 00:00:00 2001 From: dongsilove <ljparkmindone@gmail.com> Date: Sun, 18 Jan 2026 21:21:19 +0900 Subject: [PATCH 31/34] =?UTF-8?q?fo:=EC=88=98=EC=A7=88=ED=98=84=ED=99=A9?= =?UTF-8?q?=20=EC=B4=9D=EC=9D=B8=EC=84=A4=EB=B9=84tab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../facilityWaterQlty/modal/page.tsx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx index 7de556932..470a44e4c 100644 --- a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx @@ -77,7 +77,7 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea useEffect(() => { const filteredYearData = setFilterAfterData(facilityWaterQltyYearList); setCopyYearList(filteredYearData as FacilityWaterQltyProps[]); - setChongInWaterQltyYearList(filteredYearData as FacilityWaterQltyProps[]); + setChongInWaterQltyYearList(facilityWaterQltyYearList); }, [facilityWaterQltyYearList]); // 필터링 된 후 최대, 최소, 평균 값 계산 @@ -344,8 +344,7 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea const filterData = useCallback((returnType: ReturnType<FacilityWaterQltyProps>) => { const filteredData = setFilterAfterData(returnType.filteredList); - setCopyYearList(filteredData as FacilityWaterQltyProps[]); // 처리시설 수질현황 - setChongInWaterQltyYearList(filteredData as FacilityWaterQltyProps[]); // 총인설비 수질현황 + setCopyYearList(filteredData as FacilityWaterQltyProps[]); // 처리시설/총인설비 수질현황 }, []); const excelDownload = () => { @@ -386,10 +385,10 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea prevExcelListRef.current = excelDownList; } else { // 총인설비 수질현황 const excelDownList: modalChoinginExcelType[] = []; - if (chongInWaterQltyYearList.length > 0) { - chongInWaterQltyYearList.forEach((item) => { - // if (copyYearList.length > 0) { - // copyYearList.forEach((item) => { + // if (chongInWaterQltyYearList.length > 0) { + // chongInWaterQltyYearList.forEach((item) => { + if (copyYearList.length > 0) { + copyYearList.forEach((item) => { excelDownList.push({ 날짜: item.msrDt, "유입BOD(mg/L)": CommaToNumber(item.tpInflWqltBod), @@ -610,4 +609,4 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea </UITab> </> ); -} \ No newline at end of file +} From e464d298ad4b89a47fe53636968de360150a1059 Mon Sep 17 00:00:00 2001 From: ljpark <mind-one005@mind-one.co.kr> Date: Mon, 19 Jan 2026 13:24:29 +0900 Subject: [PATCH 32/34] =?UTF-8?q?wr:=2036=20=EA=B3=84=ED=86=B5=EB=8F=84=20?= =?UTF-8?q?=ED=8F=89=EB=A9=B4=EB=8F=84=20=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/pages/(with-layout)/rdi/page.tsx | 3 +- .../matMng/coMat/ruseCaseMng/page.tsx | 156 ++++++++++-------- .../ruseFcltMng/fcltReg/pbnstReg/page.tsx | 4 + .../app/store/matDmd/ruseCaseMng/headList.tsx | 4 +- .../fcltReg/pbnstReg/mngReg/mngRegForm.tsx | 7 +- .../src/ui/file-upload/lib/file_upload.tsx | 1 + .../ui/search_address/SearchAddressModal.tsx | 2 +- .../src/ui/table/index.tsx | 7 +- 8 files changed, 108 insertions(+), 76 deletions(-) diff --git a/apps/fo/app/pages/(with-layout)/rdi/page.tsx b/apps/fo/app/pages/(with-layout)/rdi/page.tsx index 47142e0a1..98120523a 100644 --- a/apps/fo/app/pages/(with-layout)/rdi/page.tsx +++ b/apps/fo/app/pages/(with-layout)/rdi/page.tsx @@ -215,7 +215,8 @@ export default function Rdi() { <LoadingOverlay isLoading={isLoading} /> <div className="h-full w-full overflow-x-scroll min-[1200px]:overflow-x-hidden"> <div className="w-[120%] min-[1200px]:w-[100%]"> - <UiTable cellClick={ undefined } headName={"RDII추정"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} /> + <UiTable cellClick={ undefined } headName={"RDII추정"} tableData={mainList} headlist={upheadList} + pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} /> </div> <UnderComment divHeight={"0"} commentArray={commentArray} /> </div> diff --git a/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx b/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx index afea9d894..6001d8827 100644 --- a/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx +++ b/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx @@ -24,6 +24,7 @@ import { Button, Label } from "@common/components/ui"; import { useEffect, useState } from "react"; import toast, { Toaster } from "react-hot-toast"; import { useTranslation } from "react-i18next"; +import * as XLSX from "xlsx"; export default function RuseCaseMng() { const { code, ruseCaseMng, selectRuseCaseMng, ruseCaseMngInit } = useWrStore( @@ -76,7 +77,9 @@ export default function RuseCaseMng() { }; useEffect(() => { - if (excelList !== undefined && excelList.length === 0) { + if (!excelList) return; + + if (excelList.length === 0) { toast.error(t("excelDownErrMsg")); return; } @@ -86,74 +89,93 @@ export default function RuseCaseMng() { } // 받은 파일 바인너리 처리 const blobRet = await response.arrayBuffer(); - if (excelList) { - const excelData1 = excelList.map((item) => { - return [ - item.ruseBizNm, - item.bizBgngDate, - item.bizEndDate, - item.splyFcltKnd, - item.splyFcltNm, - item.splyFcltCpct, - item.dmdFcltNm, - item.dmdFcltAddr, - item.ruseFcltCpct, - item.ruseFcltPplLen, - item.ruseFcltUsg, - item.ruseFcltSplyCpct, - item.ruseFcltPrcsMsrc, - item.grnteWqUsg, - item.grnteWqGrssClfg, - item.grnteWqCombResdch, - item.grnteWqTrbt, - item.grnteWqBod, - item.grnteWqSmll, - item.grnteWqCrmty, - item.grnteWqTn, - item.grnteWqTp, - item.grnteWqPh, - item.grnteWqClIonQnt, - item.grnteWqCndctStat, - item.grnteWqRmrk, - item.reqBizGrssCst, - item.reqBizReuseFcltCst, - item.reqBizPplCst, - item.reqBizArchCst, - item.reqBizMchnCst, - item.reqBizMtrngCst, - item.reqBizGisCst, - item.reqBizCctvCst, - item.reqBizCmcnCst, - item.reqBizWstCst, - item.reqBizDesignCst, - item.reqBizSpvsCst, - item.reqBizSbsdCst, - item.reqBizEtc, - item.prcmPlanGrssCst, - item.prcmPlanNlep, - item.prcmPlanLcep, - item.prcmPlanBrdnCst, - item.prcmPlanEcqrRt, - item.clclnGrssCst, - item.clclnNlep, - item.clclnLcep, - item.clclnBrdnCst, - item.clclnEcqrRt, - ]; - }); - const sheetParameter: SheetParameter[] = [ - { - data: excelData1, - headerNum: 2, - headerRange: "A1:AX1", - sheetName: "물재이용사례", - startCol: "A", - }, + const replaceHeaderText = (text: string) => + text + .replaceAll("사업시작일", "사업시작년") + .replaceAll("사업종료일", "사업종료년"); + + const wb = XLSX.read(blobRet, { type: "array" }); + wb.SheetNames.forEach((sheetName) => { + const sheet = wb.Sheets[sheetName]; + if (!sheet) return; + + Object.keys(sheet).forEach((addr) => { + if (addr.startsWith("!")) return; + const cell = sheet[addr] as XLSX.CellObject | undefined; + if (!cell || typeof cell.v !== "string") return; + const next = replaceHeaderText(cell.v); + if (next !== cell.v) cell.v = next; + }); + }); + const updatedBlob = XLSX.write(wb, { bookType: "xlsx", type: "array" }); + + const excelData1 = excelList.map((item) => { + return [ + item.ruseBizNm, + item.bizBgngDate, + item.bizEndDate, + item.splyFcltKnd, + item.splyFcltNm, + item.splyFcltCpct, + item.dmdFcltNm, + item.dmdFcltAddr, + item.ruseFcltCpct, + item.ruseFcltPplLen, + item.ruseFcltUsg, + item.ruseFcltSplyCpct, + item.ruseFcltPrcsMsrc, + item.grnteWqUsg, + item.grnteWqGrssClfg, + item.grnteWqCombResdch, + item.grnteWqTrbt, + item.grnteWqBod, + item.grnteWqSmll, + item.grnteWqCrmty, + item.grnteWqTn, + item.grnteWqTp, + item.grnteWqPh, + item.grnteWqClIonQnt, + item.grnteWqCndctStat, + item.grnteWqRmrk, + item.reqBizGrssCst, + item.reqBizReuseFcltCst, + item.reqBizPplCst, + item.reqBizArchCst, + item.reqBizMchnCst, + item.reqBizMtrngCst, + item.reqBizGisCst, + item.reqBizCctvCst, + item.reqBizCmcnCst, + item.reqBizWstCst, + item.reqBizDesignCst, + item.reqBizSpvsCst, + item.reqBizSbsdCst, + item.reqBizEtc, + item.prcmPlanGrssCst, + item.prcmPlanNlep, + item.prcmPlanLcep, + item.prcmPlanBrdnCst, + item.prcmPlanEcqrRt, + item.clclnGrssCst, + item.clclnNlep, + item.clclnLcep, + item.clclnBrdnCst, + item.clclnEcqrRt, ]; - // 버퍼에 있는 엑셀데이터 전달 후 json으로 변환 - await filePickedBlobArray(blobRet, "물재이용사례현황", sheetParameter); - } + }); + + const sheetParameter: SheetParameter[] = [ + { + data: excelData1, + headerNum: 2, + headerRange: "A1:AX1", + sheetName: "물재이용사례", + startCol: "A", + }, + ]; + // 버퍼에 있는 엑셀데이터 전달 후 json으로 변환 + await filePickedBlobArray(updatedBlob, "물재이용사례현황", sheetParameter); }); }, [excelList]); diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx index d5d0e9b33..e460aa31e 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -45,6 +45,10 @@ import { useTranslation } from "react-i18next"; * indexMng: 시설정보 * indexBiz: 차수별 정보 * 로 하수재이용 시설에 등록된 시설 및 차수별 정보를 관리한다. + * 🔗 사용 API + * 하수재이용시설을 등록 /reuseFc/pubFc + * 첨부파일 삭제 /attach-service/api/v1/atfl/attachments/atflCd// + * 첨부파일 다운로드 /attach-service/api/v1/atflcd/download/ * */ export default function PublicReuseFaciltyInsert() { diff --git a/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx b/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx index 8ed65ee7d..c201f5d28 100644 --- a/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx +++ b/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx @@ -11,14 +11,14 @@ export const ruseCaseHeadListExport: TableUpperProps[] = [ }, { id: "bizBgngDate", - title: "사업시작일", + title: "사업시작년", visible: true, row: 0, rowSpan: 2, }, { id: "bizEndDate", - title: "사업종료일", + title: "사업종료년", visible: true, row: 0, rowSpan: 2, diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx index 6fd110297..d4e7fe940 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx @@ -35,10 +35,11 @@ export type FilesType = { file: File; }; +const diagramFileTypes = ".pdf,.jpg,.jpeg,.png,.bmp"; /** * 재이용시설 등록 - 하수재이용 시설등록 - * 재이용시설 등록 - 하수재이용 시설현황 + * 재이용시설 등록 - 하수재이용 시설현황 * - layout.tsx에 의해 공통 레이아웃이 적용됨 * - with-layout 적용 * - 하수처리시설에 하수재이용 시설 시설 정보를 등록한다. @@ -459,7 +460,7 @@ export function PbnstMngForm({ setFiles={(files: File[] | null) => { if (files) fileHandler(files, "relation"); }} - fileTypes=".pdf" + fileTypes={diagramFileTypes} onFileClick={(index) => { fileDownLoad( relationfiles?.find( @@ -497,7 +498,7 @@ export function PbnstMngForm({ setFiles={(files: File[] | null) => { if (files) fileHandler(files, "plan"); }} - fileTypes=".pdf" + fileTypes={diagramFileTypes} onFileClick={(index) => { fileDownLoad( planFiles?.find( diff --git a/packages/common/business_components/src/ui/file-upload/lib/file_upload.tsx b/packages/common/business_components/src/ui/file-upload/lib/file_upload.tsx index 42662ab1d..030ddda95 100644 --- a/packages/common/business_components/src/ui/file-upload/lib/file_upload.tsx +++ b/packages/common/business_components/src/ui/file-upload/lib/file_upload.tsx @@ -93,6 +93,7 @@ export const FileUploader = forwardRef< ".jpeg": "image/jpeg", ".png": "image/png", ".gif": "image/gif", + ".bmp": "image/bmp", ".doc": "application/msword", ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", ".xls": "application/vnd.ms-excel", diff --git a/packages/common/business_components/src/ui/search_address/SearchAddressModal.tsx b/packages/common/business_components/src/ui/search_address/SearchAddressModal.tsx index 55529f89a..699d3cc50 100644 --- a/packages/common/business_components/src/ui/search_address/SearchAddressModal.tsx +++ b/packages/common/business_components/src/ui/search_address/SearchAddressModal.tsx @@ -24,7 +24,7 @@ export function SearchAddressModal({ open, onOpenChange, onSelect }: SearchAddre size: PAGE_SIZE }); const [isResetPage, setIsResetPage] = useState<boolean>(false); - const [isResetSelection, setIsResetSelection] = useState<boolean>(false); + const [isResetSelection] = useState<boolean>(false); const [selectedRowIndex, setSelectedRowIndex] = useState<number | undefined>(undefined); const [selectedZip, setSelectedZip] = useState<Zip>(); const [isSelectedZip, setIsSelectedZip] = useState<boolean>(false); diff --git a/packages/common/business_components/src/ui/table/index.tsx b/packages/common/business_components/src/ui/table/index.tsx index a0b421db8..1a0fc57c0 100644 --- a/packages/common/business_components/src/ui/table/index.tsx +++ b/packages/common/business_components/src/ui/table/index.tsx @@ -119,7 +119,6 @@ export function UiTable({ }; const leafCols = getLeafCols(headlist); - return ( <> {headName ? ( @@ -263,7 +262,11 @@ export function UiTable({ <TableCell colSpan={ headlist.filter((item) => item.visible != false).length - - headlist.filter((item) => item.visible != false && item.colSpan).length + headlist.filter( + (item) => + item.visible != false && + (item.colSpan || ["A", "B", "C"].includes(item.id)), + ).length } className="h-24 text-center text-gray-500" > From 122e10f85175af6239a6ca05c395325c01e9c8f6 Mon Sep 17 00:00:00 2001 From: ljpark <mind-one005@mind-one.co.kr> Date: Mon, 19 Jan 2026 16:38:26 +0900 Subject: [PATCH 33/34] =?UTF-8?q?wr:=20=EC=9E=AC=EC=9B=90=ED=98=91?= =?UTF-8?q?=EC=9D=98=20=EB=AC=B8=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matMng/coMat/ruseCaseMng/page.tsx | 4 +++ .../ruseFcltMng/fcltReg/pbnstReg/page.tsx | 34 +++++++++---------- .../ruseFcltMng/fcltSttn/htdflSttn/page.tsx | 11 +++--- .../ruseFcltMng/fcltSttn/pbnstSttn/page.tsx | 19 ++++++----- .../ruseFcltMng/fcltSttn/rainSttn/page.tsx | 3 ++ .../ruseFcltMng/fcltSttn/rswtSttn/page.tsx | 3 ++ apps/wr/app/store/common/auth/index.tsx | 3 +- .../ruseFcltMng/fcltReg/pbnstReg/index.tsx | 4 +-- 8 files changed, 47 insertions(+), 34 deletions(-) diff --git a/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx b/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx index 6001d8827..a64c57364 100644 --- a/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx +++ b/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx @@ -321,8 +321,12 @@ export default function RuseCaseMng() { }} resetPageNo={resetPage} /> + <span className="text-2xl font-bold text-gray-500"> + ☞ 본 사례의 사업비는 재원협의 단계의 정보이므로, 최종확정된 비용이 아닙니다. + </span> </div> </ListDiv> + </div> </div> </ContentsDiv> diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx index e460aa31e..f6d83e29c 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -1,3 +1,19 @@ +/** + * 재이용시설 등록 - 하수재이용 시설등록 + * + * - layout.tsx에 의해 공통 레이아웃이 적용됨 + * - with-layout 적용 + * - 하수처리시설에 하수재이용 시설을 등록 한다. + * - form으로 시설정보 및 차수별 정보의 컴포넌트 데이터를 관리한다 + * indexMng: 시설정보 + * indexBiz: 차수별 정보 + * 로 하수재이용 시설에 등록된 시설 및 차수별 정보를 관리한다. + * 🔗 사용 API + * 하수재이용시설을 등록 /reuseFc/pubFc + * 첨부파일 삭제 /attach-service/api/v1/atfl/attachments/atflCd// + * 첨부파일 다운로드 /attach-service/api/v1/atflcd/download/ + * */ + "use client"; import { ContentsDiv, @@ -35,22 +51,6 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { createDefaultPbnstItem } from "./utilsZod"; import { useTranslation } from "react-i18next"; -/** - * 재이용시설 등록 - 하수재이용 시설등록 - * - * - layout.tsx에 의해 공통 레이아웃이 적용됨 - * - with-layout 적용 - * - 하수처리시설에 하수재이용 시설을 등록 한다. - * - form으로 시설정보 및 차수별 정보의 컴포넌트 데이터를 관리한다 - * indexMng: 시설정보 - * indexBiz: 차수별 정보 - * 로 하수재이용 시설에 등록된 시설 및 차수별 정보를 관리한다. - * 🔗 사용 API - * 하수재이용시설을 등록 /reuseFc/pubFc - * 첨부파일 삭제 /attach-service/api/v1/atfl/attachments/atflCd// - * 첨부파일 다운로드 /attach-service/api/v1/atflcd/download/ - * */ - export default function PublicReuseFaciltyInsert() { const { auth, @@ -108,7 +108,7 @@ export default function PublicReuseFaciltyInsert() { useEffect(() => { if (useInitRef.current == true && laeSeCd !== undefined) { - pubHasuInit("1", laeSeCd); + pubHasuInit("1", laeSeCd); //page: string, sggOrCity: string } }, [useInitRef.current, laeSeCd]); diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/htdflSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/htdflSttn/page.tsx index beaa71569..ea4b49924 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/htdflSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/htdflSttn/page.tsx @@ -1,5 +1,7 @@ +/** + * 온배수시설 현황 + */ "use client"; - import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; import type { @@ -34,11 +36,9 @@ import toast, { Toaster } from "react-hot-toast"; import { useTranslation } from "react-i18next"; export default function HtdflSttn() { - const { code, htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore( - (state) => state - ); + const { auth, code, htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state); + const { laeSeCd } = auth; // 지자체구분코드 const { htdflSttnRes, htdflSttnResCount } = htdflSttn; - const isDownloadTriggered = useRef(false); const { t } = useTranslation('base'); const [pageNation, setPageNation] = useState(1); @@ -57,6 +57,7 @@ export default function HtdflSttn() { // }>({ isOpen: false, chBuilding: [] }); const [fcltNm, setFcltNm] = useState<string>(""); + console.log("laeSeCd : ", laeSeCd); useEffect(() => { htdflSttnSearch(false, pageNation, htdflSttnSize, String(getConValue()), fcltNm, code.cityCd, code.sggCd); isResetPage(false) diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index ca0b04f31..2a2340253 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -1,3 +1,12 @@ +/** + * 하수재이용 시설 현황 + * 재이용시설 현황 - 하수재이용시설 현황 + * - layout.tsx에 의해 공통 레이아웃이 적용됨 + * - with-layout 적용 + * 하수처리시설. 하수재이용시설 , 하수재이용시설 실적에 대한 정보를 확인한다. + * 모달 : 테이블의 헤더를 원하는대로 조절해서 볼수 있다. + * 클릭시 해당 재이용ㅇ + * */ "use client"; import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; @@ -24,15 +33,7 @@ import { useCallback, useEffect, useRef, useState } from "react"; import toast, { Toaster } from "react-hot-toast"; import { useTranslation } from "react-i18next"; -/** - * 하수재이용 시설 현황 - * 재이용시설 현황 - 하수재이용시설 현황 - * - layout.tsx에 의해 공통 레이아웃이 적용됨 - * - with-layout 적용 - * 하수처리시설. 하수재이용시설 , 하수재이용시설 실적에 대한 정보를 확인한다. - * 모달 : 테이블의 헤더를 원하는대로 조절해서 볼수 있다. - * 클릭시 해당 재이용ㅇ - * */ + export default function PbnstSttn() { const { code, diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx index f5ec6e8c8..46f1fa0c4 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx @@ -1,3 +1,6 @@ +/** + * 빗물재이용시설 현황 + */ "use client"; import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx index 7cb81d209..268ef8a35 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx @@ -1,3 +1,6 @@ +/** + * 중수도시설 현황 + */ "use client"; import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; diff --git a/apps/wr/app/store/common/auth/index.tsx b/apps/wr/app/store/common/auth/index.tsx index 7b647d5e7..209b1fb8a 100644 --- a/apps/wr/app/store/common/auth/index.tsx +++ b/apps/wr/app/store/common/auth/index.tsx @@ -10,7 +10,7 @@ export type authState = { regAuthrtYn: string; mdfcnAuthrtYn: string; delAuthrtYn: string; - laeSeCd: string; + laeSeCd: string; // 지자체구분코드 myUUID?: string; }; }; @@ -72,6 +72,7 @@ export const authActionsExport: (set: any, get: any) => authActions = ( return; } const infoMe = await getUserInfo(); + console.log(infoMe); const isLaeSeCd = infoMe.laeSeCd.slice(0, 2) === "G3" ? infoMe.laeSeCd.slice(2) : "0"; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index b1e0daf82..d595a0624 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -118,7 +118,7 @@ const hasuListFetch = async ( if (searchTxt) { url = url + `/${searchTxt}`; } - const rainRes = await postFectch(url, data, fetchType.COMMON); + const rainRes = await postFectch(url, data, fetchType.COMMON); // fo const hasuList = rainRes.data.map((item: any) => { return { @@ -176,7 +176,7 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { // 하수처리시설을 조회한다(운영실태) pubHasuInit: async (page: string, sggOrCity: string) => { try { - const pbnstHasuRes = await hasuListFetch(page, sggOrCity); + const pbnstHasuRes = await hasuListFetch(page, sggOrCity); // /prcsFclt/ruseInfo return set((state: pubFacState) => ({ ...state, pbnst: { From 3eb8861d0619231f307f0d29af3f6b88445d70ce Mon Sep 17 00:00:00 2001 From: ljpark <mind-one005@mind-one.co.kr> Date: Mon, 19 Jan 2026 18:11:56 +0900 Subject: [PATCH 34/34] =?UTF-8?q?dm:=20=EB=AC=BC=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=ED=98=84=ED=99=A9=20=EC=8B=9C=EB=8F=84=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dm/app/store/wrStatus/index.tsx | 14 ++++----- apps/dm/app/store/wrStatus/type.ts | 10 ++++--- .../facilityPrecipitation/page.tsx | 30 +++++++++++-------- .../app/store/facilityPrecipitation/index.tsx | 4 ++- 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/apps/dm/app/store/wrStatus/index.tsx b/apps/dm/app/store/wrStatus/index.tsx index b3c08e9e2..d3cc61cc4 100644 --- a/apps/dm/app/store/wrStatus/index.tsx +++ b/apps/dm/app/store/wrStatus/index.tsx @@ -85,22 +85,20 @@ export const DmStatusReducer = (set: any): DmStatusActions => { const boardData: DmStatusBoardType[] = data.data.map( (item: DmStatusDataType) => { - const regionText = cityCd.find((city) => item.region === city.val); + const regionText = item.sidoNm; //cityCd.find((city) => item.region === city.val); const sewage = item.sewage; const rainwater = item.rainwater; const reclaimed = item.reclaimed; const sewageCnt = item.sewageCnt; const rainwaterCnt = item.rainwaterCnt; const reclaimedCnt = item.reclaimedCnt; - if (!regionText) console.log("item.region ", item.region); - if (regionText && regionText.text) { + return { - region: regionText ? regionText.text : item.region, - sewage: sewageCnt + "(" + sewage + ")", - rainwater: rainwaterCnt + "(" + rainwater + ")", - reclaimed: reclaimedCnt + "(" + reclaimed + ")", + region: regionText ? regionText : item.region, + sewage: sewageCnt + "(" + sewage.toLocaleString() + ")", + rainwater: rainwaterCnt + "(" + rainwater.toLocaleString() + ")", + reclaimed: reclaimedCnt + "(" + reclaimed.toLocaleString() + ")", }; - } } ).filter((item): item is DmStatusBoardType => item !== undefined); diff --git a/apps/dm/app/store/wrStatus/type.ts b/apps/dm/app/store/wrStatus/type.ts index 513a5fb01..2cf1b36f0 100644 --- a/apps/dm/app/store/wrStatus/type.ts +++ b/apps/dm/app/store/wrStatus/type.ts @@ -1,14 +1,16 @@ export type DmStatusDataType = { - region: string; + sidoNm: string; // 시도명 + region: string; // 시도코드 sewage: string; rainwater: string; reclaimed: string; - sewageCnt:string - rainwaterCnt:string - reclaimedCnt:string + sewageCnt:string; + rainwaterCnt:string; + reclaimedCnt:string; }; export type DmStatusBoardType = { + sidoNm: string; // 시도명 region: string; sewage: string; rainwater: string; diff --git a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/page.tsx b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/page.tsx index 0e46505e0..18a769871 100644 --- a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/page.tsx @@ -209,10 +209,13 @@ export default function FacilityPrecipitation() { <ContentsDiv> <SearchBaseForm leftChildren={<> - <SelectBox className="col-span-3" label={labelArray[3] as string} selectArray={selectUpdownData} onSelectValue={(val) => setFcltCpct(val.toString())} value={fcltCpct} selectClass={undefined} /> + <SelectBox className="col-span-3" label={labelArray[3] as string} selectArray={selectUpdownData} + onSelectValue={(val) => setFcltCpct(val.toString())} value={fcltCpct} selectClass={undefined} /> <SearchInput className={"col-span-3"} label={labelArray[4] as string} textValue={fcltyName} setText={setFcltyName} /> - <SelectBox className="col-span-3" label={labelArray[6] as string} selectArray={selectSearchYear} onSelectValue={(val) => setSearchYear(val.toString())} value={searchYear} selectClass={undefined} /> - <SelectBox className="col-span-3" label={labelArray[5] as string} selectArray={selectOperationData} onSelectValue={(val) => setOperationValue(val.toString())} value={operationValue} selectClass={undefined} /> + <SelectBox className="col-span-3" label={labelArray[6] as string} selectArray={selectSearchYear} + onSelectValue={(val) => setSearchYear(val.toString())} value={searchYear} selectClass={undefined} /> + <SelectBox className="col-span-3" label={labelArray[5] as string} selectArray={selectOperationData} + onSelectValue={(val) => setOperationValue(val.toString())} value={operationValue} selectClass={undefined} /> </>} rightChildren={undefined} selectSidoData={selectSidoData} @@ -226,16 +229,19 @@ export default function FacilityPrecipitation() { excelClick={excelDownload} initClick={resetVal} ref={ref} isAdmin={false}/> - <ListDiv> - <LoadingOverlay isLoading={isLoading} /> - <div className="h-full w-full overflow-x-scroll min-[1200px]:overflow-x-hidden"> - <div className="w-[120%] min-[1200px]:w-[100%]"> - <UiTable cellClick={(index: number | undefined) => index !== undefined && cellClick(index)} headName={"시설별 강수현황"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} /> + <ListDiv> + <LoadingOverlay isLoading={isLoading} /> + <div className="h-full w-full overflow-x-scroll min-[1200px]:overflow-x-hidden"> + <div className="w-[120%] min-[1200px]:w-[100%]"> + <UiTable cellClick={(index: number | undefined) => index !== undefined && cellClick(index)} + headName={"시설별 강수현황"} + tableData={mainList} headlist={upheadList} pageSize={10} total={total} + resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} /> + </div> + <UnderComment divHeight={"3"} commentArray={["강우일은 3mm 이상만 해당 / 강우영향일은 강우일 및 강우일 후 연속 2일간으로 정의"]} /> </div> - <UnderComment divHeight={"3"} commentArray={["강우일은 3mm 이상만 해당 / 강우영향일은 강우일 및 강우일 후 연속 2일간으로 정의"]} /> - </div> - </ListDiv> - </ContentsDiv> + </ListDiv> + </ContentsDiv> {selectedRow !== null && ( <UiModal body={<PrecipitationModal searchYear={searchYear} fcltyName={fcltyNm} facilityCd={fcltyCd} detailList={gridListPrecipitationDetail}></PrecipitationModal>} diff --git a/apps/fo/app/store/facilityPrecipitation/index.tsx b/apps/fo/app/store/facilityPrecipitation/index.tsx index 6272ef55b..b18471eca 100644 --- a/apps/fo/app/store/facilityPrecipitation/index.tsx +++ b/apps/fo/app/store/facilityPrecipitation/index.tsx @@ -153,7 +153,9 @@ export const fetchFacilityRainDetailList = async (searchYear: string|undefined, } }; -const fetchFacilityPrecipitationList = async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { +const fetchFacilityPrecipitationList = async (pageNo: number, pageSize: number, searchYear: string, part?: string + , nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { + const tailStr = '/'+pageNo + '/' + pageSize + '/' + searchYear + (part?'/' + part:'' ) + (nameCd?'/' + nameCd:'' ) + (fcltCpct?'/' + fcltCpct:'' ) + (operationValue?'/' + operationValue:'' ) + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') ; const url = '/fclt/rain' + tailStr; const res = await getFetch('fo', url);