From 6487b3c11efa71474c43139d18bdfb9e6618059e Mon Sep 17 00:00:00 2001 From: mind-one005 Date: Fri, 27 Jun 2025 19:03:15 +0900 Subject: [PATCH 01/11] =?UTF-8?q?=EC=B5=9C=EC=B4=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../map/components/common/index.ts | 4 +- .../components/popupComponent/MsSwagePpl.tsx | 1 + .../popupComponent/chart/aplcnYms.ts | 46 +++++++++++ .../popupComponent/chart/infilChart.tsx | 79 +++++++++++++++++-- apps/sn/app/components/lib/utils/date.ts | 12 +++ 5 files changed, 133 insertions(+), 9 deletions(-) create mode 100644 apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts diff --git a/apps/sn/app/(map-layout)/map/components/common/index.ts b/apps/sn/app/(map-layout)/map/components/common/index.ts index a17d2a0a8..03edf7d7a 100644 --- a/apps/sn/app/(map-layout)/map/components/common/index.ts +++ b/apps/sn/app/(map-layout)/map/components/common/index.ts @@ -20,9 +20,9 @@ type LayerContentMap = { // 레이어 선택시 변경되는 팝업 컨텐츠 동적으로 변경하도록 작업 const layerContentMap: LayerContentMap = { // TODO: gis데이터 추가되면 추가 작업 필요 - "하수처리시설": { component: SwtrmtFclt, }, + // "하수처리시설": { component: SwtrmtFclt, }, // 하수관로 개발용 - // "하수처리시설": { component: MsSwagePpl, }, + "하수처리시설": { component: MsSwagePpl, }, "하수처리구역": {}, "우수토실": { component: Ssc, }, "중점우수토실": { component: Ssc, }, // 중점우수토실 여부 설정 diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx index 43f70de24..7d6e45d34 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx @@ -1,3 +1,4 @@ +'use client' import { VerticalTable } from '@/components/ui/verticalTable'; import React, { useState } from 'react' import InputSection from '../InputSection'; diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts new file mode 100644 index 000000000..695c13560 --- /dev/null +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts @@ -0,0 +1,46 @@ +import {useState, useEffect} from 'react'; + +const convertToTextValArray = (yyyymms: string[]): { text: string; val: string }[] => { + return yyyymms.map(dateStr => { + const year = dateStr.slice(0, 4); + const month = dateStr.slice(4, 6); + return { + text: `${year}-${month}`, + val: dateStr + }; + }); +}; +const selectAplcnYms = async() => { // 상수사용월 + try { + //const result = await getData('v1/inftwtAnlsRslt/aplcnYm'); + let result = null; + const res = await fetch('http://con.mind-one.co.kr:11083/sewerage-service/api/v1/inftwtAnlsRslt/aplcnYm', { + method: "GET", + body: null, + }); + if (res.ok) { + result = await res.json(); + } + + if (result && result.length > 0) { + //setAplcnYms(convertToTextValArray(result)); + console.log("selectAplcnYms", result); + return convertToTextValArray(result); + } + } catch (error) { + console.error(error); + } +}; +export const useAplcnYms = () => { + const [data, setData] = useState<{ text: string; val: string }[]>([]); + + useEffect(() => { + const fetch = async () => { + const result = await selectAplcnYms(); + if (result) setData(result); + }; + fetch(); + }, []); + + return data; +}; \ No newline at end of file diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx index f82184db8..7e6ba39b8 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx @@ -1,17 +1,25 @@ -import React, { useState } from 'react' +'use client' +import React, { useState, useMemo, useEffect } from 'react' +import { SelectBox } from '@common/business_components/ui' import { type ChartConfig, MainChart, CHART_FORM } from "@common/business_components"; import Modal from '@/components/ui/modal'; import { Button } from '@common/components/ui'; +import { getData } from "@/components/lib/api"; +import { useAplcnYms } from './aplcnYms'; type ModalOpenProp = { isModalOpen: boolean, setIsModalOpen: (open: boolean) => void, closeModal: () => void, btnTxt?: string, } + const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOpenProp) => { - const [popupOpen, setPopupOpen] = React.useState(false); + const [popupOpen, setPopupOpen] = React.useState(true); const buttonRef = React.useRef(null); // 버튼 참조 const [popupPosition, setPopupPosition] = useState<{ top: number; left: number }>({ top: 0, left: 0 }); // 팝업 위치 + const [aplcnYm, setAplcnYm] = useState(""); + const [aplcnYms, setAplcnYms] = useState<{ text: string; val: string }[]>([]); + //const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기 const openPopup = () => { if (buttonRef.current) { const rect = buttonRef.current.getBoundingClientRect(); // 버튼 위치 계산 @@ -22,7 +30,7 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp } setPopupOpen(true); // 팝업 열기 }; - console.log("btnTxt", btnTxt); + //console.log("btnTxt", btnTxt); const closePopup = () => { setPopupOpen(false); }; // 팝업 닫기 const chartForm = CHART_FORM.LINE; const chartData = { @@ -50,6 +58,47 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp const month = String(today.getMonth() + 1).padStart(2, "0"); // 월은 0부터 시작하므로 +1 return `${year}-${month}`; }; + + const convertToTextValArray = (yyyymms: string[]): { text: string; val: string }[] => { + return yyyymms.map(dateStr => { + const year = dateStr.slice(0, 4); + const month = dateStr.slice(4, 6); + return { + text: `${year}-${month}`, + val: dateStr + }; + }); + }; + const selectAplcnYms = async() => { // 상수사용월 + try { + //const result = await getData('v1/inftwtAnlsRslt/aplcnYm'); + let result = null; + const res = await fetch('http://con.mind-one.co.kr:11083/sewerage-service/api/v1/inftwtAnlsRslt/aplcnYm', { + method: "GET", + body: null, + }); + if (res.ok) { + result = await res.json(); + } + + if (result && result.length > 0) { + //setAplcnYms(convertToTextValArray(result)); + console.log("selectAplcnYms", result); + return convertToTextValArray(result); + } + } catch (error) { + console.error(error); + } + } + useEffect(() => { + const fetchAplcnYms = async () => { + const aplcnYmsData = await selectAplcnYms(); + setAplcnYms(aplcnYmsData||[]); + console.log("aplcnYms: ", aplcnYms); + //setAplcnYm(getCurrentDate()); + }; + fetchAplcnYms(); + }, [aplcnYms]); return ( {/* 분석 입력현황 조회 */} @@ -75,18 +124,34 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp {popupOpen && (
-
분석 입력현황
+
침입수분석 입력현황
-
상수사용량 정보:
+
- + setAplcnYm(String(value))} + /> +
+
+
+ setAplcnYm(String(value))} + />
오수 전환율:
diff --git a/apps/sn/app/components/lib/utils/date.ts b/apps/sn/app/components/lib/utils/date.ts index 9319d7013..fe717301f 100644 --- a/apps/sn/app/components/lib/utils/date.ts +++ b/apps/sn/app/components/lib/utils/date.ts @@ -11,3 +11,15 @@ export const yearOptions = Array.from({ length: 10 }, (_, i) => { const year = new Date().getFullYear() - i; return { text: `${year}년`, val: year.toString() }; }); + +// ["202506", "202505", "202502", "202405"] 을 SelectBox의 옵션으로 변환 +export const convertToTextValArray = (yyyymms: string[]): { text: string; val: string }[] => { + return yyyymms.map(dateStr => { + const year = dateStr.slice(0, 4); + const month = dateStr.slice(4, 6); + return { + text: `${year}-${month}`, + val: dateStr + }; + }); +}; \ No newline at end of file From f5d8f8fe233f6cace257ab04710449af11d6e478 Mon Sep 17 00:00:00 2001 From: mind-one005 Date: Sat, 28 Jun 2025 10:57:35 +0900 Subject: [PATCH 02/11] =?UTF-8?q?=EC=A4=91=EA=B0=84..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../popupComponent/chart/aplcnYms.ts | 46 ++++++++++++++- .../popupComponent/chart/infilChart.tsx | 57 +++---------------- .../popupComponent/chart/inftwtAnls.ts | 0 3 files changed, 52 insertions(+), 51 deletions(-) create mode 100644 apps/sn/app/(map-layout)/map/components/popupComponent/chart/inftwtAnls.ts diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts index 695c13560..174cd4d7c 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts @@ -1,7 +1,7 @@ import {useState, useEffect} from 'react'; const convertToTextValArray = (yyyymms: string[]): { text: string; val: string }[] => { - return yyyymms.map(dateStr => { + let yyyymms1 = yyyymms.map(dateStr => { const year = dateStr.slice(0, 4); const month = dateStr.slice(4, 6); return { @@ -9,6 +9,8 @@ const convertToTextValArray = (yyyymms: string[]): { text: string; val: string } val: dateStr }; }); + yyyymms1.unshift({ val: '0', text: '선택' }); + return yyyymms1; }; const selectAplcnYms = async() => { // 상수사용월 try { @@ -23,7 +25,6 @@ const selectAplcnYms = async() => { // 상수사용월 } if (result && result.length > 0) { - //setAplcnYms(convertToTextValArray(result)); console.log("selectAplcnYms", result); return convertToTextValArray(result); } @@ -31,6 +32,47 @@ const selectAplcnYms = async() => { // 상수사용월 console.error(error); } }; +type InftwtAnls = { + inftwtAnlsSn:number; + aplcnYm: string; + enoCd: string; + ctpvCd: string; + sggCd: string; + swageTmplntCd: string; + swageTmplntNm: string; + swtrmtZoneCd: string; + swtrmtZoneNm: string; + atflCd: string; + atflId: string; + atflInpNm: string; + atflHrPttnNm: string; + atflMpngNm: string; + atflOilqNm: string; + atflNm: string; + drtwSwtcRt:number; + anlsInfo: string; + scsYn: string; +}; +const selectInftwtAnls = async(aplcnYm:String) => { // 침입수분석 + try { + //const result = await getData('v1/inftwtAnlsRslt/aplcnYm'); + let result = null; + const res = await fetch('http://con.mind-one.co.kr:11083/sewerage-service/api/v1/inftwtAnls', { + method: "GET", + body: JSON.stringify({aplcnYm}), + }); + if (res.ok) { + result = await res.json(); + } + + if (result && result.numberOfElements > 0) { + console.log("selectInftwtAnls", result.content); + return result.content as InftwtAnls[]; + } + } catch (error) { + console.error(error); + } +}; export const useAplcnYms = () => { const [data, setData] = useState<{ text: string; val: string }[]>([]); diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx index 7e6ba39b8..5d1d5bb42 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx @@ -18,8 +18,8 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp const buttonRef = React.useRef(null); // 버튼 참조 const [popupPosition, setPopupPosition] = useState<{ top: number; left: number }>({ top: 0, left: 0 }); // 팝업 위치 const [aplcnYm, setAplcnYm] = useState(""); - const [aplcnYms, setAplcnYms] = useState<{ text: string; val: string }[]>([]); - //const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기 + //const [aplcnYms, setAplcnYms] = useState<{ text: string; val: string }[]>([]); + const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기 const openPopup = () => { if (buttonRef.current) { const rect = buttonRef.current.getBoundingClientRect(); // 버튼 위치 계산 @@ -59,46 +59,6 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp return `${year}-${month}`; }; - const convertToTextValArray = (yyyymms: string[]): { text: string; val: string }[] => { - return yyyymms.map(dateStr => { - const year = dateStr.slice(0, 4); - const month = dateStr.slice(4, 6); - return { - text: `${year}-${month}`, - val: dateStr - }; - }); - }; - const selectAplcnYms = async() => { // 상수사용월 - try { - //const result = await getData('v1/inftwtAnlsRslt/aplcnYm'); - let result = null; - const res = await fetch('http://con.mind-one.co.kr:11083/sewerage-service/api/v1/inftwtAnlsRslt/aplcnYm', { - method: "GET", - body: null, - }); - if (res.ok) { - result = await res.json(); - } - - if (result && result.length > 0) { - //setAplcnYms(convertToTextValArray(result)); - console.log("selectAplcnYms", result); - return convertToTextValArray(result); - } - } catch (error) { - console.error(error); - } - } - useEffect(() => { - const fetchAplcnYms = async () => { - const aplcnYmsData = await selectAplcnYms(); - setAplcnYms(aplcnYmsData||[]); - console.log("aplcnYms: ", aplcnYms); - //setAplcnYm(getCurrentDate()); - }; - fetchAplcnYms(); - }, [aplcnYms]); return ( {/* 분석 입력현황 조회 */} @@ -135,13 +95,12 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
- setAplcnYm(String(value))} - /> +
diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/inftwtAnls.ts b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/inftwtAnls.ts new file mode 100644 index 000000000..e69de29bb From 381bae8e2664b27d4c3d1a8edb841fc86a86e683 Mon Sep 17 00:00:00 2001 From: mind-one005 Date: Sat, 28 Jun 2025 22:01:56 +0900 Subject: [PATCH 03/11] =?UTF-8?q?=EC=B9=A8=EC=9E=85=EC=88=98=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=84=A0=ED=83=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../popupComponent/chart/aplcnYms.ts | 83 +++++++++---------- .../popupComponent/chart/infilChart.tsx | 58 ++++++++----- 2 files changed, 77 insertions(+), 64 deletions(-) diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts index 174cd4d7c..9b20398e3 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts @@ -1,38 +1,6 @@ import {useState, useEffect} from 'react'; - -const convertToTextValArray = (yyyymms: string[]): { text: string; val: string }[] => { - let yyyymms1 = yyyymms.map(dateStr => { - const year = dateStr.slice(0, 4); - const month = dateStr.slice(4, 6); - return { - text: `${year}-${month}`, - val: dateStr - }; - }); - yyyymms1.unshift({ val: '0', text: '선택' }); - return yyyymms1; -}; -const selectAplcnYms = async() => { // 상수사용월 - try { - //const result = await getData('v1/inftwtAnlsRslt/aplcnYm'); - let result = null; - const res = await fetch('http://con.mind-one.co.kr:11083/sewerage-service/api/v1/inftwtAnlsRslt/aplcnYm', { - method: "GET", - body: null, - }); - if (res.ok) { - result = await res.json(); - } - - if (result && result.length > 0) { - console.log("selectAplcnYms", result); - return convertToTextValArray(result); - } - } catch (error) { - console.error(error); - } -}; -type InftwtAnls = { +import { getData } from '@/components/lib/api'; +export type TInftwtAnls = { inftwtAnlsSn:number; aplcnYm: string; enoCd: string; @@ -53,21 +21,46 @@ type InftwtAnls = { anlsInfo: string; scsYn: string; }; -const selectInftwtAnls = async(aplcnYm:String) => { // 침입수분석 - try { - //const result = await getData('v1/inftwtAnlsRslt/aplcnYm'); - let result = null; - const res = await fetch('http://con.mind-one.co.kr:11083/sewerage-service/api/v1/inftwtAnls', { - method: "GET", - body: JSON.stringify({aplcnYm}), +const getOptionsAplcnYm = (yyyymms: string[]): { text: string; val: string }[] => { + let yyyymms1 = yyyymms.map(dateStr => { + const year = dateStr.slice(0, 4); + const month = dateStr.slice(4, 6); + return { + text: `${year}-${month}`, + val: dateStr + }; }); - if (res.ok) { - result = await res.json(); + yyyymms1.unshift({ val: '0', text: '선택' }); + return yyyymms1; +}; +export const getOptionsInftwtAnlsInfo = (anlsArr: TInftwtAnls[]): { text: string; val: number }[] => { + const options = anlsArr.map(anls => ({ + text: anls.anlsInfo, + val: anls.inftwtAnlsSn, + })); + options.unshift({ val: 0, text: '선택' }); + return options; +}; +const selectAplcnYms = async() => { // 상수사용월 + try { + const queryString = ''; + const result = await getData(`v1/inftwtAnlsRslt/aplcnYm${queryString ? `?${queryString}` : ''}`); + if (result && result.length > 0) { + console.log("selectAplcnYms", result); + return getOptionsAplcnYm(result); } + } catch (error) { + console.error(error); + } +}; +export const selectInftwtAnls = async(aplcnYm:String) => { // 침입수분석 + try { + const queryString = aplcnYm ? `aplcnYm=${aplcnYm}` : ''; + const result = await getData(`v1/inftwtAnls${queryString ? `?${queryString}` : ''}`); if (result && result.numberOfElements > 0) { console.log("selectInftwtAnls", result.content); - return result.content as InftwtAnls[]; + return result.content; } } catch (error) { console.error(error); @@ -85,4 +78,4 @@ export const useAplcnYms = () => { }, []); return data; -}; \ No newline at end of file +}; diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx index 5d1d5bb42..2fbaf845a 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx @@ -5,7 +5,9 @@ import { type ChartConfig, MainChart, CHART_FORM } from "@common/business_compon import Modal from '@/components/ui/modal'; import { Button } from '@common/components/ui'; import { getData } from "@/components/lib/api"; -import { useAplcnYms } from './aplcnYms'; +import type { TInftwtAnls } from './aplcnYms'; +import { useAplcnYms, selectInftwtAnls, getOptionsInftwtAnlsInfo} from './aplcnYms'; +import { set } from 'react-hook-form'; type ModalOpenProp = { isModalOpen: boolean, setIsModalOpen: (open: boolean) => void, @@ -18,6 +20,11 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp const buttonRef = React.useRef(null); // 버튼 참조 const [popupPosition, setPopupPosition] = useState<{ top: number; left: number }>({ top: 0, left: 0 }); // 팝업 위치 const [aplcnYm, setAplcnYm] = useState(""); + const [inftwtAnlss, setInftwtAnlss] = useState([]); + const [inftwtAnlsInfos, setInftwtAnlsInfos] = useState([]); // 침입수분석정보 options + const [inftwtAnls, setInftwtAnls] = useState(null); // 침입수분석정보 + const [inftwtAnlsSn, setInftwtAnlsSn] = useState(0); // 침입수분석 정보 선택시 사용 + //const [aplcnYms, setAplcnYms] = useState<{ text: string; val: string }[]>([]); const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기 const openPopup = () => { @@ -58,7 +65,24 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp const month = String(today.getMonth() + 1).padStart(2, "0"); // 월은 0부터 시작하므로 +1 return `${year}-${month}`; }; - + const onChangeAplcnYm = (e: React.ChangeEvent) => { + const selectedValue = e.target.value; + selectInftwtAnls(selectedValue).then((data) => { + setInftwtAnlss(data ?? []); + console.log("onChangeAplcnYm", selectedValue, inftwtAnlss); + setInftwtAnlsInfos(getOptionsInftwtAnlsInfo(data ?? [])); + }); + setAplcnYm(selectedValue); + }; + const onChangeInftwtAnlsInfo = (e: React.ChangeEvent) => { + const selectedInfo = e.target.value; + setInftwtAnlsSn(Number(selectedInfo)); // 선택값 상태로 저장 + // 선택된 침입수분석 정보에 대한 처리 로직 추가 + const selectedAnls = inftwtAnlss.find(anls => anls.inftwtAnlsSn === Number(selectedInfo)); + if (selectedAnls) { + setInftwtAnls(selectedAnls); + } + }; return ( {/* 분석 입력현황 조회 */} @@ -92,11 +116,11 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp }} >
침입수분석 입력현황
-
+
+ {inftwtAnlsInfos.map(opt => ( + + ))} +
오수 전환율:
- +
수용가-맨홀 매칭:
@@ -149,10 +172,7 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
-
From 713d4efd46a70acb2ea16c549a4c4cf8a9f7eb39 Mon Sep 17 00:00:00 2001 From: mind-one005 Date: Sun, 29 Jun 2025 20:58:27 +0900 Subject: [PATCH 04/11] =?UTF-8?q?=EC=B9=A8=EC=9E=85=EC=88=98=EB=B6=84?= =?UTF-8?q?=EC=84=9D=EA=B2=B0=EA=B3=BC=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/popupComponent/MsSwagePpl.tsx | 2 +- .../popupComponent/chart/aplcnYms.ts | 54 ++++++++++++++----- .../popupComponent/chart/infilChart.tsx | 22 ++++---- .../popupComponent/chart/inftwtAnls.ts | 0 4 files changed, 54 insertions(+), 24 deletions(-) delete mode 100644 apps/sn/app/(map-layout)/map/components/popupComponent/chart/inftwtAnls.ts diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx index 7d6e45d34..a3c634306 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx @@ -16,7 +16,7 @@ const inputColumn = [ { id: "flow", title: "흐름방식", type: "select", options: ["자연유하", "압송"] }, { id: "place", title: "매설위치", type: "select", options: ["도로", "하상"] }, ]; -const SwtrmtFclt = ({ featureData }: { featureData: any }) => { +const MsSwagePpl = ({ featureData }: { featureData: any }) => { // SwtrmtFclt console.log("featureData", featureData); const [isModalOpen, setIsModalOpen] = React.useState(false); const [btnTxt, setBtnTxt] = useState(""); diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts index 9b20398e3..ccce0095a 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts @@ -21,6 +21,12 @@ export type TInftwtAnls = { anlsInfo: string; scsYn: string; }; +export type TInftwtAnlsRslt = { + inftwtAnlsSn: number; + pplMngNo: string; + anlsTm: string; + predcOilq:number; +} const getOptionsAplcnYm = (yyyymms: string[]): { text: string; val: string }[] => { let yyyymms1 = yyyymms.map(dateStr => { const year = dateStr.slice(0, 4); @@ -53,19 +59,6 @@ const selectAplcnYms = async() => { // 상수사용월 console.error(error); } }; - -export const selectInftwtAnls = async(aplcnYm:String) => { // 침입수분석 - try { - const queryString = aplcnYm ? `aplcnYm=${aplcnYm}` : ''; - const result = await getData(`v1/inftwtAnls${queryString ? `?${queryString}` : ''}`); - if (result && result.numberOfElements > 0) { - console.log("selectInftwtAnls", result.content); - return result.content; - } - } catch (error) { - console.error(error); - } -}; export const useAplcnYms = () => { const [data, setData] = useState<{ text: string; val: string }[]>([]); @@ -79,3 +72,38 @@ export const useAplcnYms = () => { return data; }; + +export const selectInftwtAnls = async(aplcnYm:String) => { // 침입수분석 + try { + const queryString = aplcnYm ? `aplcnYm=${aplcnYm}` : ''; + const result = await getData(`v1/inftwtAnls${queryString ? `?${queryString}` : ''}`); + if (result && result.numberOfElements > 0) { + console.log("selectInftwtAnls", result.content); + return result.content; + } + } catch (error) { + console.error(error); + } +}; +export const getChartDataInftwtAnlsRslt = (arr: TInftwtAnlsRslt[]): { label: string; val: number }[] => { + const options = arr.map(anlsRslt => ({ + label: anlsRslt.anlsTm, + val: anlsRslt.predcOilq, + })); + return options; +}; +export const selectInftwtAnlsRslt = async(inftwtAnlsSn:number, pplMngNo:string) => { // 침입수분석 결과 + try { + if ((inftwtAnlsSn === undefined || inftwtAnlsSn === 0) || !pplMngNo) { + console.warn("inftwtAnlsSn or pplMngNo is not provided"); + return []; + } + const result = await getData(`v1/inftwtAnlsRslt/ppl/${inftwtAnlsSn}/${pplMngNo}`); + if (result && result.numberOfElements > 0) { + console.log("selectInftwtAnlsRslt", result.content); + return result.content; + } + } catch (error) { + console.error(error); + } +}; diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx index 2fbaf845a..40534a849 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx @@ -5,8 +5,9 @@ import { type ChartConfig, MainChart, CHART_FORM } from "@common/business_compon import Modal from '@/components/ui/modal'; import { Button } from '@common/components/ui'; import { getData } from "@/components/lib/api"; -import type { TInftwtAnls } from './aplcnYms'; +import type { TInftwtAnls, TInftwtAnlsRslt } from './aplcnYms'; import { useAplcnYms, selectInftwtAnls, getOptionsInftwtAnlsInfo} from './aplcnYms'; +import { selectInftwtAnlsRslt, getChartDataInftwtAnlsRslt} from './aplcnYms'; import { set } from 'react-hook-form'; type ModalOpenProp = { isModalOpen: boolean, @@ -15,7 +16,7 @@ type ModalOpenProp = { btnTxt?: string, } -const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOpenProp) => { +const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal}: ModalOpenProp) => { const [popupOpen, setPopupOpen] = React.useState(true); const buttonRef = React.useRef(null); // 버튼 참조 const [popupPosition, setPopupPosition] = useState<{ top: number; left: number }>({ top: 0, left: 0 }); // 팝업 위치 @@ -24,7 +25,7 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp const [inftwtAnlsInfos, setInftwtAnlsInfos] = useState([]); // 침입수분석정보 options const [inftwtAnls, setInftwtAnls] = useState(null); // 침입수분석정보 const [inftwtAnlsSn, setInftwtAnlsSn] = useState(0); // 침입수분석 정보 선택시 사용 - + //const [aplcnYms, setAplcnYms] = useState<{ text: string; val: string }[]>([]); const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기 const openPopup = () => { @@ -38,7 +39,7 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp setPopupOpen(true); // 팝업 열기 }; //console.log("btnTxt", btnTxt); - const closePopup = () => { setPopupOpen(false); }; // 팝업 닫기 + const chartForm = CHART_FORM.LINE; const chartData = { chartData1: [ @@ -59,11 +60,12 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp }; return config; }, {} as Record) satisfies ChartConfig; - const getCurrentDate = () => { - const today = new Date(); - const year = today.getFullYear(); - const month = String(today.getMonth() + 1).padStart(2, "0"); // 월은 0부터 시작하므로 +1 - return `${year}-${month}`; + + const closePopup = () => { // 팝업 닫기 + selectInftwtAnlsRslt(inftwtAnlsSn,"L13101003").then((data) => { + chartData.chartData1 = getChartDataInftwtAnlsRslt(data ?? []); + }); + setPopupOpen(false); }; const onChangeAplcnYm = (e: React.ChangeEvent) => { const selectedValue = e.target.value; @@ -84,7 +86,7 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp } }; return ( - + {/* 분석 입력현황 조회 */}
diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/inftwtAnls.ts b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/inftwtAnls.ts deleted file mode 100644 index e69de29bb..000000000 From a2d48745b34db67a46e7c331063743a42052401e Mon Sep 17 00:00:00 2001 From: mind-one005 Date: Sun, 29 Jun 2025 21:55:41 +0900 Subject: [PATCH 05/11] =?UTF-8?q?chartdata=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/popupComponent/MsSwagePpl.tsx | 2 +- .../popupComponent/chart/infilChart.tsx | 68 ++++++++++++------- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx index a3c634306..e1829085c 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx @@ -85,4 +85,4 @@ const MsSwagePpl = ({ featureData }: { featureData: any }) => { // SwtrmtFclt ) } -export default SwtrmtFclt \ No newline at end of file +export default MsSwagePpl \ No newline at end of file diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx index 40534a849..31c92d339 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx @@ -25,6 +25,14 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal}: ModalOpe const [inftwtAnlsInfos, setInftwtAnlsInfos] = useState([]); // 침입수분석정보 options const [inftwtAnls, setInftwtAnls] = useState(null); // 침입수분석정보 const [inftwtAnlsSn, setInftwtAnlsSn] = useState(0); // 침입수분석 정보 선택시 사용 + const [chartData, setChartData] = useState<{ chartData1: { label: string; val: number }[]; chartData2: { label: string; val: number }[] }>({ + chartData1: [{ label: "1", val: 20 }, + { label: "3", val: 40 }, + { label: "5", val: 60 },], + chartData2: [{ label: "1", val: 15 }, + { label: "3", val: 35 }, + { label: "5", val: 55 },], + }); //const [aplcnYms, setAplcnYms] = useState<{ text: string; val: string }[]>([]); const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기 @@ -41,18 +49,18 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal}: ModalOpe //console.log("btnTxt", btnTxt); const chartForm = CHART_FORM.LINE; - const chartData = { - chartData1: [ - { label: "1", val: 20 }, - { label: "3", val: 40 }, - { label: "5", val: 60 }, - ], - chartData2: [ - { label: "1", val: 15 }, - { label: "3", val: 35 }, - { label: "5", val: 55 }, - ], - } + // const chartData = { + // chartData1: [ + // { label: "1", val: 20 }, + // { label: "3", val: 40 }, + // { label: "5", val: 60 }, + // ], + // chartData2: [ + // { label: "1", val: 15 }, + // { label: "3", val: 35 }, + // { label: "5", val: 55 }, + // ], + // } const chartConfig = Object.values(chartData).flat().reduce((config, element) => { config[element.label] = { label: element.label, @@ -62,8 +70,12 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal}: ModalOpe }, {} as Record) satisfies ChartConfig; const closePopup = () => { // 팝업 닫기 - selectInftwtAnlsRslt(inftwtAnlsSn,"L13101003").then((data) => { - chartData.chartData1 = getChartDataInftwtAnlsRslt(data ?? []); + selectInftwtAnlsRslt(inftwtAnlsSn,"L13101003").then((data) => {// 침입수분석 결과 조회 + const rsltData = getChartDataInftwtAnlsRslt(data ?? []); + setChartData({ + chartData1: rsltData, + chartData2: rsltData, // 예시로 같은 데이터를 사용 + }); }); setPopupOpen(false); }; @@ -139,24 +151,28 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal}: ModalOpe
오수 전환율:
- +
+
시간패턴 파일명:
+
+
수용가-맨홀 매칭:
- +
-
관망도 자료:
+
관망도 파일명:
- + +
+
유량 파일명:
+
+
{btnTxt === 'RDII' ? <>
강우 자료:
From 515f75bd804f0645cc383ed3e742fad46dbb2f78 Mon Sep 17 00:00:00 2001 From: mind-one005 Date: Mon, 30 Jun 2025 15:45:01 +0900 Subject: [PATCH 06/11] =?UTF-8?q?=EA=B7=B8=EB=9E=98=ED=94=84=20x=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../popupComponent/chart/aplcnYms.ts | 32 ++++++++- .../popupComponent/chart/infilChart.tsx | 70 ++++++++++--------- 2 files changed, 68 insertions(+), 34 deletions(-) diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts index ccce0095a..53b4c7954 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts @@ -27,6 +27,12 @@ export type TInftwtAnlsRslt = { anlsTm: string; predcOilq:number; } +export type TOilqData = { + inftwtAnlsSn: number; // 침입수분석 일련번호 + pplMngNo: string; // 관로관리번호 + mtrngDt: string; // 계측일시 + oilq: number; // 유량 +} const getOptionsAplcnYm = (yyyymms: string[]): { text: string; val: string }[] => { let yyyymms1 = yyyymms.map(dateStr => { const year = dateStr.slice(0, 4); @@ -78,7 +84,7 @@ export const selectInftwtAnls = async(aplcnYm:String) => { // 침입수분석 const queryString = aplcnYm ? `aplcnYm=${aplcnYm}` : ''; const result = await getData(`v1/inftwtAnls${queryString ? `?${queryString}` : ''}`); if (result && result.numberOfElements > 0) { - console.log("selectInftwtAnls", result.content); + //console.log("selectInftwtAnls", result.content); return result.content; } } catch (error) { @@ -100,7 +106,29 @@ export const selectInftwtAnlsRslt = async(inftwtAnlsSn:number, pplMngNo:string) } const result = await getData(`v1/inftwtAnlsRslt/ppl/${inftwtAnlsSn}/${pplMngNo}`); if (result && result.numberOfElements > 0) { - console.log("selectInftwtAnlsRslt", result.content); + //console.log("selectInftwtAnlsRslt", result.content); + return result.content; + } + } catch (error) { + console.error(error); + } +}; +export const getChartDataOilq = (arr: TOilqData[]): { label: string; val: number }[] => { + const options = arr.map(anlsRslt => ({ + label: anlsRslt.mtrngDt, + val: anlsRslt.oilq, + })); + return options; +}; +export const selectOilq = async(inftwtAnlsSn:number, pplMngNo:string) => { // 유량 + try { + if ((inftwtAnlsSn === undefined || inftwtAnlsSn === 0) || !pplMngNo) { + console.warn("inftwtAnlsSn or pplMngNo is not provided"); + return []; + } + const result = await getData(`v1/inftwtAnlsRslt/oilqppl/${inftwtAnlsSn}/${pplMngNo}`); + if (result && result.numberOfElements > 0) { + console.log("selectOilq", result.content); return result.content; } } catch (error) { diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx index 31c92d339..fcdf5dbf8 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx @@ -5,9 +5,11 @@ import { type ChartConfig, MainChart, CHART_FORM } from "@common/business_compon import Modal from '@/components/ui/modal'; import { Button } from '@common/components/ui'; import { getData } from "@/components/lib/api"; + import type { TInftwtAnls, TInftwtAnlsRslt } from './aplcnYms'; import { useAplcnYms, selectInftwtAnls, getOptionsInftwtAnlsInfo} from './aplcnYms'; import { selectInftwtAnlsRslt, getChartDataInftwtAnlsRslt} from './aplcnYms'; +import { selectOilq, getChartDataOilq} from './aplcnYms'; import { set } from 'react-hook-form'; type ModalOpenProp = { isModalOpen: boolean, @@ -26,14 +28,25 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal}: ModalOpe const [inftwtAnls, setInftwtAnls] = useState(null); // 침입수분석정보 const [inftwtAnlsSn, setInftwtAnlsSn] = useState(0); // 침입수분석 정보 선택시 사용 const [chartData, setChartData] = useState<{ chartData1: { label: string; val: number }[]; chartData2: { label: string; val: number }[] }>({ - chartData1: [{ label: "1", val: 20 }, - { label: "3", val: 40 }, - { label: "5", val: 60 },], - chartData2: [{ label: "1", val: 15 }, - { label: "3", val: 35 }, - { label: "5", val: 55 },], - }); - + chartData1: [],chartData2: [],}); + useEffect(() => { + if(isModalOpen === false){ + setPopupOpen(true); // 모달이 닫힐 때 팝업은 + setAplcnYm(""); // 상수사용월 초기화 + setInftwtAnlss([]); // 침입수분석 초기화 + setInftwtAnlsInfos([]); // 침입수분석정보 초기화 + setInftwtAnls(null); // 침입수분석정보 초기화 + setInftwtAnlsSn(0); // 침입수분석 일련번호 초기화 + setChartData({ + chartData1: [{ label: "1", val: 20 }, + { label: "3", val: 40 }, + { label: "5", val: 60 },], + chartData2: [{ label: "1", val: 15 }, + { label: "3", val: 35 }, + { label: "5", val: 55 },], + }); // 차트 데이터 초기화 + } + }, [isModalOpen]); //const [aplcnYms, setAplcnYms] = useState<{ text: string; val: string }[]>([]); const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기 const openPopup = () => { @@ -49,34 +62,26 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal}: ModalOpe //console.log("btnTxt", btnTxt); const chartForm = CHART_FORM.LINE; - // const chartData = { - // chartData1: [ - // { label: "1", val: 20 }, - // { label: "3", val: 40 }, - // { label: "5", val: 60 }, - // ], - // chartData2: [ - // { label: "1", val: 15 }, - // { label: "3", val: 35 }, - // { label: "5", val: 55 }, - // ], - // } - const chartConfig = Object.values(chartData).flat().reduce((config, element) => { - config[element.label] = { - label: element.label, - color: "hsl(var(--chart-1))", - }; - return config; - }, {} as Record) satisfies ChartConfig; - + const chartConfig = { + chartData1: {label: '침입수예측유량',color: "red",}, + chartData2: {label: '실측유량',color: "orange",} + } as ChartConfig; + const closePopup = () => { // 팝업 닫기 selectInftwtAnlsRslt(inftwtAnlsSn,"L13101003").then((data) => {// 침입수분석 결과 조회 const rsltData = getChartDataInftwtAnlsRslt(data ?? []); - setChartData({ - chartData1: rsltData, - chartData2: rsltData, // 예시로 같은 데이터를 사용 - }); + setChartData(prev => ({ + ...prev, + chartData1: rsltData // 침입수분석결과 + })); }); + // selectOilq(inftwtAnlsSn,"L13101003").then((data) => {// 유량 조회 + // const rsltData = getChartDataOilq(data ?? []); + // setChartData(prev => ({ + // ...prev, + // chartData2: rsltData // 유량 + // })); + // }); setPopupOpen(false); }; const onChangeAplcnYm = (e: React.ChangeEvent) => { @@ -97,6 +102,7 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal}: ModalOpe setInftwtAnls(selectedAnls); } }; + return ( {/* 분석 입력현황 조회 */} From a0ee6f34f5dad2038ade287ae51d7b62be7392ec Mon Sep 17 00:00:00 2001 From: swcho Date: Mon, 30 Jun 2025 15:46:12 +0900 Subject: [PATCH 07/11] =?UTF-8?q?refactor=20:=20inflChart.tsx=20=EA=B3=B5?= =?UTF-8?q?=ED=86=B5=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../popupComponent/chart/infilChart.tsx | 310 +++++++++++++----- 1 file changed, 221 insertions(+), 89 deletions(-) diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx index 31c92d339..f96065a4e 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx @@ -1,13 +1,12 @@ 'use client' import React, { useState, useMemo, useEffect } from 'react' import { SelectBox } from '@common/business_components/ui' -import { type ChartConfig, MainChart, CHART_FORM } from "@common/business_components"; -import Modal from '@/components/ui/modal'; -import { Button } from '@common/components/ui'; +import { type ChartConfig, MainChart, CHART_FORM, UiModal } from "@common/business_components"; +import { Button, Input, Label } from '@common/components'; import { getData } from "@/components/lib/api"; import type { TInftwtAnls, TInftwtAnlsRslt } from './aplcnYms'; -import { useAplcnYms, selectInftwtAnls, getOptionsInftwtAnlsInfo} from './aplcnYms'; -import { selectInftwtAnlsRslt, getChartDataInftwtAnlsRslt} from './aplcnYms'; +import { useAplcnYms, selectInftwtAnls, getOptionsInftwtAnlsInfo } from './aplcnYms'; +import { selectInftwtAnlsRslt, getChartDataInftwtAnlsRslt } from './aplcnYms'; import { set } from 'react-hook-form'; type ModalOpenProp = { isModalOpen: boolean, @@ -16,26 +15,86 @@ type ModalOpenProp = { btnTxt?: string, } -const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal}: ModalOpenProp) => { +// 더미 데이터 리스트 +const rainDataList = [ + { val: "R20240815.xlsx", text: "R20240815.xlsx" }, + { val: "R20240701.xlsx", text: "R20240701.xlsx" }, + { val: "R20240615.xlsx", text: "R20240615.xlsx" }, + { val: "R20240531.xlsx", text: "R20240531.xlsx" }, + { val: "R20240420.xlsx", text: "R20240420.xlsx" }, +]; +const rtxSourceList = [ + { val: "2015년 하수도정비기본계획", text: "2015년 하수도정비기본계획" }, + { val: "2018년 하수도정비기본계획", text: "2018년 하수도정비기본계획" }, + { val: "2020년 하수도정비기본계획", text: "2020년 하수도정비기본계획" }, + { val: "2022년 하수도정비기본계획", text: "2022년 하수도정비기본계획" }, + { val: "2024년 하수도정비기본계획", text: "2024년 하수도정비기본계획" }, +]; +// 상수사용월 더미 데이터 +const dummyAplcnYms = [ + { val: '0', text: '선택' }, + { val: '202401', text: '2024-01' }, + { val: '202402', text: '2024-02' }, + { val: '202403', text: '2024-03' }, + { val: '202404', text: '2024-04' }, + { val: '202405', text: '2024-05' }, + { val: '202406', text: '2024-06' }, + { val: '202407', text: '2024-07' }, + { val: '202408', text: '2024-08' }, + { val: '202409', text: '2024-09' }, + { val: '202410', text: '2024-10' }, + { val: '202411', text: '2024-11' }, + { val: '202412', text: '2024-12' }, +]; +// 침입수분석정보 더미 데이터 +const dummyInftwtAnlsInfos = [ + { val: 0, text: '선택' }, + { val: 1001, text: '서울시 강남구 침입수분석 1차' }, + { val: 1002, text: '서울시 강남구 침입수분석 2차' }, + { val: 1003, text: '서울시 서초구 침입수분석 1차' }, + { val: 1004, text: '부산시 해운대구 침입수분석 1차' }, + { val: 1005, text: '대구시 수성구 침입수분석 1차' }, + { val: 1006, text: '인천시 연수구 침입수분석 1차' }, + { val: 1007, text: '광주시 북구 침입수분석 1차' }, + { val: 1008, text: '대전시 유성구 침입수분석 1차' }, + { val: 1009, text: '울산시 남구 침입수분석 1차' }, + { val: 1010, text: '경기도 성남시 침입수분석 1차' }, +]; + +const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOpenProp) => { const [popupOpen, setPopupOpen] = React.useState(true); const buttonRef = React.useRef(null); // 버튼 참조 const [popupPosition, setPopupPosition] = useState<{ top: number; left: number }>({ top: 0, left: 0 }); // 팝업 위치 const [aplcnYm, setAplcnYm] = useState(""); const [inftwtAnlss, setInftwtAnlss] = useState([]); - const [inftwtAnlsInfos, setInftwtAnlsInfos] = useState([]); // 침입수분석정보 options - const [inftwtAnls, setInftwtAnls] = useState(null); // 침입수분석정보 + // const [inftwtAnlsInfos, setInftwtAnlsInfos] = useState([]); // 침입수분석정보 options + const [inftwtAnls, setInftwtAnls] = useState(null); // 침입수분석정보 const [inftwtAnlsSn, setInftwtAnlsSn] = useState(0); // 침입수분석 정보 선택시 사용 + const [drtwSwtcRt, setDrtwSwtcRt] = useState(0); // 오수전환율 + const [atflHrPttnNm, setAtflHrPttnNm] = useState(0); // 시간패턴 파일명 + const [atflMpng, setAtflMpng] = useState(0); // 수용가-맨홀 매칭 + const [atflInpNm, setAtflInpNm] = useState(0); // 관망도 파일명 + const [tbSnOilqData, setTbSnOilqData] = useState(0); // 유량 파일명 const [chartData, setChartData] = useState<{ chartData1: { label: string; val: number }[]; chartData2: { label: string; val: number }[] }>({ chartData1: [{ label: "1", val: 20 }, - { label: "3", val: 40 }, - { label: "5", val: 60 },], + { label: "3", val: 40 }, + { label: "5", val: 60 },], chartData2: [{ label: "1", val: 15 }, - { label: "3", val: 35 }, - { label: "5", val: 55 },], + { label: "3", val: 35 }, + { label: "5", val: 55 },], }); + // 상수사용월, 분석정보 더미 데이터로 초기화 (API 호출 실패 시 대비) + const [selectedAplcnYms, setSelectedAplcnYms] = useState(dummyAplcnYms[0]?.val || "0"); + const [selectedInftwtAnlsInfos, setSelectedInftwtAnlsInfos] = useState(dummyInftwtAnlsInfos[0]?.val || 0); + // 선택된 값들을 위한 상태 추가 + const [selectedRainData, setSelectedRainData] = useState(rainDataList[0]?.val || "선택"); // 초기값으로 첫 번째 항목 선택 + const [selectedRtxSource, setSelectedRtxSource] = useState(rtxSourceList[0]?.val || "선택"); + // API에서 데이터를 가져오지 못할 경우 더미 데이터 사용 + // const aplcnYms = useAplcnYms().length > 0 ? useAplcnYms() : dummyAplcnYms; + //const [aplcnYms, setAplcnYms] = useState<{ text: string; val: string }[]>([]); - const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기 + // const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기 const openPopup = () => { if (buttonRef.current) { const rect = buttonRef.current.getBoundingClientRect(); // 버튼 위치 계산 @@ -47,7 +106,7 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal}: ModalOpe setPopupOpen(true); // 팝업 열기 }; //console.log("btnTxt", btnTxt); - + const chartForm = CHART_FORM.LINE; // const chartData = { // chartData1: [ @@ -70,35 +129,38 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal}: ModalOpe }, {} as Record) satisfies ChartConfig; const closePopup = () => { // 팝업 닫기 - selectInftwtAnlsRslt(inftwtAnlsSn,"L13101003").then((data) => {// 침입수분석 결과 조회 + selectInftwtAnlsRslt(inftwtAnlsSn, "L13101003").then((data) => {// 침입수분석 결과 조회 const rsltData = getChartDataInftwtAnlsRslt(data ?? []); setChartData({ chartData1: rsltData, chartData2: rsltData, // 예시로 같은 데이터를 사용 }); }); - setPopupOpen(false); + setPopupOpen(false); }; - const onChangeAplcnYm = (e: React.ChangeEvent) => { - const selectedValue = e.target.value; - selectInftwtAnls(selectedValue).then((data) => { - setInftwtAnlss(data ?? []); - console.log("onChangeAplcnYm", selectedValue, inftwtAnlss); - setInftwtAnlsInfos(getOptionsInftwtAnlsInfo(data ?? [])); - }); - setAplcnYm(selectedValue); - }; - const onChangeInftwtAnlsInfo = (e: React.ChangeEvent) => { - const selectedInfo = e.target.value; - setInftwtAnlsSn(Number(selectedInfo)); // 선택값 상태로 저장 - // 선택된 침입수분석 정보에 대한 처리 로직 추가 - const selectedAnls = inftwtAnlss.find(anls => anls.inftwtAnlsSn === Number(selectedInfo)); - if (selectedAnls) { - setInftwtAnls(selectedAnls); - } - }; - return ( - + // const onChangeAplcnYm = (e: React.ChangeEvent) => { + // const selectedValue = e.target.value; + // selectInftwtAnls(selectedValue).then((data) => { + // setInftwtAnlss(data ?? []); + // console.log("onChangeAplcnYm", selectedValue, inftwtAnlss); + // setInftwtAnlsInfos(getOptionsInftwtAnlsInfo(data ?? [])); + // }); + // setAplcnYm(selectedValue); + // }; + // const onChangeInftwtAnlsInfo = (e: React.ChangeEvent) => { + // const selectedInfo = e.target.value; + // setInftwtAnlsSn(Number(selectedInfo)); // 선택값 상태로 저장 + // // 선택된 침입수분석 정보에 대한 처리 로직 추가 + // const selectedAnls = inftwtAnlss.find(anls => anls.inftwtAnlsSn === Number(selectedInfo)); + // if (selectedAnls) { + // setInftwtAnls(selectedAnls); + // } + // }; + + + const renderBody = () => ( + <> + {/* */} {/* 분석 입력현황 조회 */}
@@ -130,72 +192,142 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal}: ModalOpe }} >
침입수분석 입력현황
-
-
-
- +
+
+ + { + setSelectedAplcnYms(String(val)); + }} + />
-
-
- +
+ + { + setSelectedInftwtAnlsInfos(Number(val)); + }} + />
-
오수 전환율:
-
- +
+ + { + setDrtwSwtcRt(Number(e.target.value)); + }} + />
-
시간패턴 파일명:
-
- +
+ + { + setAtflHrPttnNm(Number(e.target.value)); + }} + />
-
수용가-맨홀 매칭:
-
- +
+ + { + setAtflMpng(Number(e.target.value)); + }} + />
-
관망도 파일명:
-
- +
+ + { + setAtflInpNm(Number(e.target.value)); + }} + />
-
유량 파일명:
-
- +
+ + { + setTbSnOilqData(Number(e.target.value)); + }} + />
- {btnTxt === 'RDII' ? <>
강우 자료:
-
- -
-
RTX 계수 출처:
-
- -
- : null} + {btnTxt === 'RDII' ? + <> +
+ + { + setSelectedRainData(String(val)); + }} + /> +
+
+ + { + setSelectedRtxSource(String(val)); + }} + /> +
+ : null}
-
- )} - +
)} + {/* */} + + ) + + return ( + ) } From 2c3b2785bcef03905d0191e29bc009c7a2f60243 Mon Sep 17 00:00:00 2001 From: swcho Date: Mon, 30 Jun 2025 16:33:54 +0900 Subject: [PATCH 08/11] =?UTF-8?q?refactor:=20infilChart.tsx=20=EA=B3=B5?= =?UTF-8?q?=ED=86=B5=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../popupComponent/chart/infilChart.tsx | 242 ++++++------------ 1 file changed, 79 insertions(+), 163 deletions(-) diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx index c8816d114..7de4848e5 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx @@ -1,15 +1,11 @@ 'use client' -import React, { useState, useMemo, useEffect } from 'react' -import { SelectBox } from '@common/business_components/ui' -import { type ChartConfig, MainChart, CHART_FORM, UiModal } from "@common/business_components"; +import { CHART_FORM, type ChartConfig, MainChart, UiModal } from "@common/business_components"; +import { SelectBox } from '@common/business_components/ui'; import { Button, Input, Label } from '@common/components'; -import { getData } from "@/components/lib/api"; +import React, { useEffect, useState } from 'react'; -import type { TInftwtAnls, TInftwtAnlsRslt } from './aplcnYms'; -import { useAplcnYms, selectInftwtAnls, getOptionsInftwtAnlsInfo} from './aplcnYms'; -import { selectInftwtAnlsRslt, getChartDataInftwtAnlsRslt} from './aplcnYms'; -import { selectOilq, getChartDataOilq} from './aplcnYms'; -import { set } from 'react-hook-form'; +import type { TInftwtAnls } from './aplcnYms'; +import { getChartDataInftwtAnlsRslt, getOptionsInftwtAnlsInfo, selectInftwtAnls, selectInftwtAnlsRslt, useAplcnYms } from './aplcnYms'; type ModalOpenProp = { isModalOpen: boolean, setIsModalOpen: (open: boolean) => void, @@ -17,51 +13,7 @@ type ModalOpenProp = { btnTxt?: string, } -// 더미 데이터 리스트 -const rainDataList = [ - { val: "R20240815.xlsx", text: "R20240815.xlsx" }, - { val: "R20240701.xlsx", text: "R20240701.xlsx" }, - { val: "R20240615.xlsx", text: "R20240615.xlsx" }, - { val: "R20240531.xlsx", text: "R20240531.xlsx" }, - { val: "R20240420.xlsx", text: "R20240420.xlsx" }, -]; -const rtxSourceList = [ - { val: "2015년 하수도정비기본계획", text: "2015년 하수도정비기본계획" }, - { val: "2018년 하수도정비기본계획", text: "2018년 하수도정비기본계획" }, - { val: "2020년 하수도정비기본계획", text: "2020년 하수도정비기본계획" }, - { val: "2022년 하수도정비기본계획", text: "2022년 하수도정비기본계획" }, - { val: "2024년 하수도정비기본계획", text: "2024년 하수도정비기본계획" }, -]; -// 상수사용월 더미 데이터 -const dummyAplcnYms = [ - { val: '0', text: '선택' }, - { val: '202401', text: '2024-01' }, - { val: '202402', text: '2024-02' }, - { val: '202403', text: '2024-03' }, - { val: '202404', text: '2024-04' }, - { val: '202405', text: '2024-05' }, - { val: '202406', text: '2024-06' }, - { val: '202407', text: '2024-07' }, - { val: '202408', text: '2024-08' }, - { val: '202409', text: '2024-09' }, - { val: '202410', text: '2024-10' }, - { val: '202411', text: '2024-11' }, - { val: '202412', text: '2024-12' }, -]; -// 침입수분석정보 더미 데이터 -const dummyInftwtAnlsInfos = [ - { val: 0, text: '선택' }, - { val: 1001, text: '서울시 강남구 침입수분석 1차' }, - { val: 1002, text: '서울시 강남구 침입수분석 2차' }, - { val: 1003, text: '서울시 서초구 침입수분석 1차' }, - { val: 1004, text: '부산시 해운대구 침입수분석 1차' }, - { val: 1005, text: '대구시 수성구 침입수분석 1차' }, - { val: 1006, text: '인천시 연수구 침입수분석 1차' }, - { val: 1007, text: '광주시 북구 침입수분석 1차' }, - { val: 1008, text: '대전시 유성구 침입수분석 1차' }, - { val: 1009, text: '울산시 남구 침입수분석 1차' }, - { val: 1010, text: '경기도 성남시 침입수분석 1차' }, -]; + const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOpenProp) => { const [popupOpen, setPopupOpen] = React.useState(true); @@ -72,11 +24,6 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp const [inftwtAnlsInfos, setInftwtAnlsInfos] = useState([]); // 침입수분석정보 options const [inftwtAnls, setInftwtAnls] = useState(null); // 침입수분석정보 const [inftwtAnlsSn, setInftwtAnlsSn] = useState(0); // 침입수분석 정보 선택시 사용 - const [drtwSwtcRt, setDrtwSwtcRt] = useState(0); // 오수전환율 - const [atflHrPttnNm, setAtflHrPttnNm] = useState(0); // 시간패턴 파일명 - const [atflMpng, setAtflMpng] = useState(0); // 수용가-맨홀 매칭 - const [atflInpNm, setAtflInpNm] = useState(0); // 관망도 파일명 - const [tbSnOilqData, setTbSnOilqData] = useState(0); // 유량 파일명 const [chartData, setChartData] = useState<{ chartData1: { label: string; val: number }[]; chartData2: { label: string; val: number }[] }>({ chartData1: [{ label: "1", val: 20 }, { label: "3", val: 40 }, @@ -86,36 +33,12 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp { label: "5", val: 55 },], }); // chartData1: [],chartData2: [],}); - useEffect(() => { - if(isModalOpen === false){ - setPopupOpen(true); // 모달이 닫힐 때 팝업은 - setAplcnYm(""); // 상수사용월 초기화 - setInftwtAnlss([]); // 침입수분석 초기화 - setInftwtAnlsInfos([]); // 침입수분석정보 초기화 - setInftwtAnls(null); // 침입수분석정보 초기화 - setInftwtAnlsSn(0); // 침입수분석 일련번호 초기화 - setChartData({ - chartData1: [{ label: "1", val: 20 }, - { label: "3", val: 40 }, - { label: "5", val: 60 },], - chartData2: [{ label: "1", val: 15 }, - { label: "3", val: 35 }, - { label: "5", val: 55 },], - }); // 차트 데이터 초기화 - } - }, [isModalOpen]); - // 상수사용월, 분석정보 더미 데이터로 초기화 (API 호출 실패 시 대비) - const [selectedAplcnYms, setSelectedAplcnYms] = useState(dummyAplcnYms[0]?.val || "0"); - const [selectedInftwtAnlsInfos, setSelectedInftwtAnlsInfos] = useState(dummyInftwtAnlsInfos[0]?.val || 0); - // 선택된 값들을 위한 상태 추가 - const [selectedRainData, setSelectedRainData] = useState(rainDataList[0]?.val || "선택"); // 초기값으로 첫 번째 항목 선택 - const [selectedRtxSource, setSelectedRtxSource] = useState(rtxSourceList[0]?.val || "선택"); // API에서 데이터를 가져오지 못할 경우 더미 데이터 사용 // const aplcnYms = useAplcnYms().length > 0 ? useAplcnYms() : dummyAplcnYms; //const [aplcnYms, setAplcnYms] = useState<{ text: string; val: string }[]>([]); - // const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기 + const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기 const openPopup = () => { if (buttonRef.current) { const rect = buttonRef.current.getBoundingClientRect(); // 버튼 위치 계산 @@ -130,10 +53,60 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp const chartForm = CHART_FORM.LINE; const chartConfig = { - chartData1: {label: '침입수예측유량',color: "red",}, - chartData2: {label: '실측유량',color: "orange",} - } as ChartConfig; - + chartData1: { label: '침입수예측유량', color: "red", }, + chartData2: { label: '실측유량', color: "orange", } + } as ChartConfig; + + useEffect(() => { + if (isModalOpen === false) { + setPopupOpen(true); // 모달이 닫힐 때 팝업은 + setAplcnYm(""); // 상수사용월 초기화 + setInftwtAnlss([]); // 침입수분석 초기화 + setInftwtAnlsInfos([]); // 침입수분석정보 초기화 + setInftwtAnls(null); // 침입수분석정보 초기화 + setInftwtAnlsSn(0); // 침입수분석 일련번호 초기화 + setChartData({ + chartData1: [{ label: "1", val: 20 }, + { label: "3", val: 40 }, + { label: "5", val: 60 },], + chartData2: [{ label: "1", val: 15 }, + { label: "3", val: 35 }, + { label: "5", val: 55 },], + }); // 차트 데이터 초기화 + } + }, [isModalOpen]); + + // 상수사용월 변경시 분석 정보 리스트 가져오기 + useEffect(() => { + // aplcnYm이 비어있거나 "0"이면 API 호출하지 않음 + if (!aplcnYm || aplcnYm === "0" || aplcnYm === "") { + setInftwtAnlsSn(0); // 초기화 + setInftwtAnlsInfos([{ val: 0, text: '선택' }]); + return; + } + + selectInftwtAnls(aplcnYm) + .then((data) => { + setInftwtAnlss(data ?? []); + setInftwtAnlsInfos(getOptionsInftwtAnlsInfo(data)); + }) + .catch((error) => { + console.error("selectInftwtAnls 에러:", error); + setInftwtAnlss([]); + setInftwtAnlsInfos([{ val: 0, text: '선택' }]); + }); + setInftwtAnlsSn(0); // 초기화 + }, [aplcnYm]); + + // 값 표시 + useEffect(() => { + // 선택된 침입수분석 정보에 대한 처리 로직 + const selectedAnls = inftwtAnlss.find(anls => anls.inftwtAnlsSn === inftwtAnlsSn); + if (selectedAnls) { + setInftwtAnls(selectedAnls); + } + }, [inftwtAnlsSn, inftwtAnlss]); + const closePopup = () => { // 팝업 닫기 selectInftwtAnlsRslt(inftwtAnlsSn, "L13101003").then((data) => {// 침입수분석 결과 조회 const rsltData = getChartDataInftwtAnlsRslt(data ?? []); @@ -149,27 +122,9 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp // chartData2: rsltData // 유량 // })); // }); - setPopupOpen(false); + setPopupOpen(false); }; - const onChangeAplcnYm = (e: React.ChangeEvent) => { - const selectedValue = e.target.value; - selectInftwtAnls(selectedValue).then((data) => { - setInftwtAnlss(data ?? []); - console.log("onChangeAplcnYm", selectedValue, inftwtAnlss); - setInftwtAnlsInfos(getOptionsInftwtAnlsInfo(data ?? [])); - }); - setAplcnYm(selectedValue); - }; - const onChangeInftwtAnlsInfo = (e: React.ChangeEvent) => { - const selectedInfo = e.target.value; - setInftwtAnlsSn(Number(selectedInfo)); // 선택값 상태로 저장 - // 선택된 침입수분석 정보에 대한 처리 로직 추가 - const selectedAnls = inftwtAnlss.find(anls => anls.inftwtAnlsSn === Number(selectedInfo)); - if (selectedAnls) { - setInftwtAnls(selectedAnls); - } - }; - + const renderBody = () => ( @@ -213,10 +168,10 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp className="w-[200px] mr-8 z-[51]" selectClass="rounded-lg bg-white" label='' - selectArray={dummyAplcnYms} - value={selectedAplcnYms} + selectArray={aplcnYms} + value={aplcnYm} onSelectValue={(val) => { - setSelectedAplcnYms(String(val)); + setAplcnYm(String(val)); }} />
@@ -226,10 +181,10 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp className="w-[200px] mr-8 z-[51]" selectClass="rounded-lg bg-white" label='' - selectArray={dummyInftwtAnlsInfos} - value={selectedInftwtAnlsInfos} + selectArray={inftwtAnlsInfos} + value={inftwtAnlsSn} onSelectValue={(val) => { - setSelectedInftwtAnlsInfos(Number(val)); + setInftwtAnlsSn(Number(val)); }} />
@@ -238,10 +193,8 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp { - setDrtwSwtcRt(Number(e.target.value)); - }} + value={inftwtAnls?.drtwSwtcRt ?? ""} + readOnly={true} />
@@ -249,10 +202,8 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp { - setAtflHrPttnNm(Number(e.target.value)); - }} + value={inftwtAnls?.atflHrPttnNm ?? ""} + readOnly={true} />
@@ -260,10 +211,8 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp { - setAtflMpng(Number(e.target.value)); - }} + value={inftwtAnls?.atflMpngNm ?? ""} + readOnly={true} />
@@ -271,10 +220,8 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp { - setAtflInpNm(Number(e.target.value)); - }} + value={inftwtAnls?.atflInpNm ?? ""} + readOnly={true} />
@@ -282,41 +229,10 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp { - setTbSnOilqData(Number(e.target.value)); - }} + value={inftwtAnls?.atflOilqNm ?? "없음"} + readOnly={true} />
- {btnTxt === 'RDII' ? - <> -
- - { - setSelectedRainData(String(val)); - }} - /> -
-
- - { - setSelectedRtxSource(String(val)); - }} - /> -
- : null}