rdii추가

This commit is contained in:
2025-06-30 21:19:25 +09:00
parent 8bb8825c5e
commit 5aebb3ba77
6 changed files with 688 additions and 90 deletions
+2 -2
View File
@@ -9,6 +9,6 @@ NEXT_PUBLIC_AUTH_USER_ID = token-id
NEXT_PUBLIC_ACCESS_TOKEN = access-token
NEXT_PUBLIC_REFRESH_TOKEN = refresh-token
#NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/api # 개발 서버 API
NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883/sewerage-service/api # 최용성 부장님 API
NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/api # 개발 서버 API
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883/sewerage-service/api # 최용성 부장님 API
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.66:8883/sewerage-service/api # 박이정 차장님 API
@@ -1,9 +1,11 @@
'use client'
import { VerticalTable } from '@/components/ui/verticalTable';
import React, { useState } from 'react'
import InputSection from '../InputSection';
import { handleInputChange } from '../common';
import { Button } from '@common/components/ui';
import InfilChart from './chart/infilChart';
import RdiiChart from './chart/rdiiChart';
// 하수관로
// TODO: RDII 버튼인가 그거 팝업 두개 구현 필요
const inputColumn = [
@@ -15,17 +17,24 @@ 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 [isModalInfil, setIsModalInfil] = React.useState(false);
const [isModalRdii, setIsModalRdii] = React.useState(false);
const [btnTxt, setBtnTxt] = useState<string>("");
const openModal = (e: React.MouseEvent<HTMLButtonElement>) => {
const openModalRdii = (e: React.MouseEvent<HTMLButtonElement>) => {
e.currentTarget.textContent && setBtnTxt(e.currentTarget.textContent)
setIsModalOpen(true);
setIsModalRdii(true);
}
const openModalInfil = (e: React.MouseEvent<HTMLButtonElement>) => {
e.currentTarget.textContent && setBtnTxt(e.currentTarget.textContent)
setIsModalInfil(true);
};
const closeModal = () => {
setIsModalOpen(false);
const closeModalInfil = () => {
setIsModalInfil(false);
};
const closeModalRdii = () => {
setIsModalRdii(false);};
const [repairData, setRepairData] = useState([
{ year: "2025", type: "개대체" },
{ year: "2025", type: "보수" },
@@ -68,20 +77,21 @@ const SwtrmtFclt = ({ featureData }: { featureData: any }) => {
<div className="absolute bottom-0 left-0 w-full flex justify-start space-x-2 p-4">
<Button
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
onClick={openModal}
onClick={openModalInfil}
>
Infil
</Button>
<Button
className="px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700"
onClick={openModal}
onClick={openModalRdii}
>
RDII
</Button>
</div>
<InfilChart btnTxt={btnTxt} isModalOpen={isModalOpen} setIsModalOpen={setIsModalOpen} closeModal={closeModal} />
<InfilChart btnTxt={btnTxt} isModalOpen={isModalInfil} setIsModalOpen={setIsModalInfil} closeModal={closeModalInfil} />
<RdiiChart btnTxt={btnTxt} isModalOpen={isModalRdii} setIsModalOpen={setIsModalRdii} closeModal={closeModalRdii} />
</div>
)
}
export default SwtrmtFclt
export default MsSwagePpl
@@ -0,0 +1,209 @@
import {useState, useEffect} from 'react';
import { getData } from '@/components/lib/api';
export type TInftwtAnls = {
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;
};
export type TInftwtAnlsRslt = {
inftwtAnlsSn: number;
pplMngNo: string;
anlsTm: string;
predcOilq:number;
}
export type TRdiiAnls = {
rainInfwtAnlsSn: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;
atflRainNm: string;
atflNm: string;
drtwSwtcRt:number;
anlsInfo: string;
scsYn: string;
srcNm: string; // 출처이름
};
export type TRdiiAnlsRslt = {
rainInfwtAnlsSn: number;
pplMngNo: string;
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);
const month = dateStr.slice(4, 6);
return {
text: `${year}-${month}`,
val: dateStr
};
});
yyyymms1.unshift({ val: '0', text: '선택' });
return yyyymms1;
};
const selectAplcnYms = async(gubun:string) => { // 상수사용월
try {
const queryString = '';
const result = await getData(`v1/${gubun}/aplcnYm${queryString ? `?${queryString}` : ''}`);
if (result && result.length > 0) {
console.log("selectAplcnYms", result);
return getOptionsAplcnYm(result);
}
} catch (error) {
console.error(error);
}
};
export const useAplcnYms = (gubun:string) => {
const [data, setData] = useState<{ text: string; val: string }[]>([]);
useEffect(() => {
const fetch = async (gubun:string) => {
const result = await selectAplcnYms(gubun);
if (result) setData(result);
};
fetch(gubun);
}, []);
return data;
};
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;
};
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);
}
};
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) {
console.error(error);
}
};
export const getOptionsRdiiAnlsInfo = (anlsArr: TRdiiAnls[]): { text: string; val: number }[] => {
const options = anlsArr.map(anls => ({
text: anls.anlsInfo,
val: anls.rainInfwtAnlsSn,
}));
options.unshift({ val: 0, text: '선택' });
return options;
};
export const selectRdiiAnls = async(aplcnYm:String) => { // 침입수분석
try {
const queryString = aplcnYm ? `aplcnYm=${aplcnYm}` : '';
const result = await getData(`v1/rdiiAnls${queryString ? `?${queryString}` : ''}`);
if (result && result.numberOfElements > 0) {
console.log("selectRdiiAnls", result.content);
return result.content;
}
} catch (error) {
console.error(error);
}
};
export const getChartDataRdiiAnlsRslt = (arr: TRdiiAnlsRslt[]): { label: string; val: number }[] => {
const options = arr.map(anlsRslt => ({
label: anlsRslt.anlsTm,
val: anlsRslt.predcOilq,
}));
return options;
};
export const selectRdiiAnlsRslt = async(rainInfwtAnlsSn:number, pplMngNo:string) => { // 침입수분석 결과
try {
if ((rainInfwtAnlsSn === undefined || rainInfwtAnlsSn === 0) || !pplMngNo) {
console.warn("RdiiAnlsSn or pplMngNo is not provided");
return [];
}
const result = await getData(`v1/rdiiAnlsRslt/ppl/${rainInfwtAnlsSn}/${pplMngNo}`);
if (result && result.numberOfElements > 0) {
console.log("selectRdiiAnlsRslt", result.content);
return result.content;
}
} catch (error) {
console.error(error);
}
};
@@ -1,17 +1,38 @@
import React, { useState } from 'react'
import { type ChartConfig, MainChart, CHART_FORM } from "@common/business_components";
import Modal from '@/components/ui/modal';
import { Button } from '@common/components/ui';
'use client'
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 React, { useEffect, useState } from 'react';
import type { TInftwtAnls } from './aplcnYms';
import { getChartDataInftwtAnlsRslt, getOptionsInftwtAnlsInfo, selectInftwtAnls, selectInftwtAnlsRslt, useAplcnYms } from './aplcnYms';
import { selectOilq, getChartDataOilq } 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<HTMLButtonElement>(null); // 버튼 참조
const [popupPosition, setPopupPosition] = useState<{ top: number; left: number }>({ top: 0, left: 0 }); // 팝업 위치
const [aplcnYm, setAplcnYm] = useState("");
const [inftwtAnlss, setInftwtAnlss] = useState<TInftwtAnls[]>([]);
const [inftwtAnlsInfos, setInftwtAnlsInfos] = useState<any[]>([]); // 침입수분석정보 options
const [inftwtAnls, setInftwtAnls] = useState<TInftwtAnls | null>(null); // 침입수분석정보
const [inftwtAnlsSn, setInftwtAnlsSn] = useState<number>(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 = useAplcnYms('inftwtAnlsRslt'); // 상수사용월 데이터 가져오기
const openPopup = () => {
if (buttonRef.current) {
const rect = buttonRef.current.getBoundingClientRect(); // 버튼 위치 계산
@@ -22,36 +43,90 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
}
setPopupOpen(true); // 팝업 열기
};
console.log("btnTxt", btnTxt);
const closePopup = () => { setPopupOpen(false); }; // 팝업 닫기
//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<string, { label: string; color: string }>) 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 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([]);
return;
}
selectInftwtAnls(aplcnYm)
.then((data) => {
setInftwtAnlss(data ?? []);
setInftwtAnlsInfos(getOptionsInftwtAnlsInfo(data));
setInftwtAnlsSn(0); // 초기화
})
.catch((error) => {
console.error("selectInftwtAnls 에러:", error);
setInftwtAnlss([]);
setInftwtAnlsInfos([]);
});
}, [aplcnYm]);
// 값 표시
useEffect(() => {
// 선택된 침입수분석 정보에 대한 처리 로직
if (inftwtAnlsSn === 0) return;
const selectedAnls = inftwtAnlss.find(anls => anls.inftwtAnlsSn === inftwtAnlsSn);
if (selectedAnls) {
setInftwtAnls(selectedAnls);
}
}, [inftwtAnlsSn]);
const closePopup = () => { // 팝업 닫기
selectInftwtAnlsRslt(inftwtAnlsSn, "L13101003").then((data) => {// 침입수분석 결과 조회
const rsltData = getChartDataInftwtAnlsRslt(data ?? []);
setChartData(prev => ({
...prev,
chartData1: rsltData // 침입수분석결과
}));
});
selectOilq(inftwtAnlsSn,"L13101003").then((data) => {// 유량 조회
const rsltData = getChartDataOilq(data ?? []);
setChartData(prev => ({
...prev,
chartData2: rsltData // 유량
}));
});
setPopupOpen(false);
};
return (
<Modal isModalOpen={isModalOpen} setIsModalOpen={setIsModalOpen} closeModal={closeModal}>
const renderBody = () => (
<>
{/* <Modal isModalOpen={isModalOpen} setIsModalOpen={setIsModalOpen} closeModal={closeModal} > */}
{/* 분석 입력현황 조회 */}
<div className='grid grid-cols-4 gap-4'>
<div className="grid grid-rows-4 gap-4 mb-4">
@@ -75,65 +150,111 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
</div>
{popupOpen && (
<div
className="absolute bg-gray-100 border border-gray-300 w-[320px] shadow-lg p-4 rounded"
className="absolute bg-gray-100 border border-gray-300 w-[420px] shadow-lg p-6 rounded text-2xl"
style={{
top: popupPosition.top,
left: popupPosition.left,
zIndex: 1000,
}}
>
<div className="text-lg font-bold mb-2">분석 입력현황</div>
<div className="grid grid-cols-2 gap-2">
<div>상수사용량 정보:</div>
<div>
<input type='month' defaultValue={getCurrentDate()} className="border border-gray-300 rounded px-2 py-1" />
<div className="font-bold mb-6 text-3xl">침입수분석 입력현황</div>
<div className='flex flex-col'>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">상수사용월:</Label>
<SelectBox
className="w-[200px] mr-8 z-[51] mb-2"
selectClass="rounded-lg bg-white"
label=''
selectArray={aplcnYms}
value={aplcnYm}
onSelectValue={(val) => {
setAplcnYm(String(val));
}}
/>
</div>
<div>오수 전환율:</div>
<div>
<select className="border border-gray-300 rounded px-2 py-1">
<option>0.85</option>
<option>0.90</option>
</select>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">분석정보:</Label>
<SelectBox
className="w-[200px] mr-8 z-[51] mb-2"
selectClass="rounded-lg bg-white"
label=''
selectArray={inftwtAnlsInfos}
value={inftwtAnlsSn}
onSelectValue={(val) => {
setInftwtAnlsSn(Number(val));
}}
/>
</div>
<div>수용가-맨홀 매칭:</div>
<div>
<select className="border border-gray-300 rounded px-2 py-1">
<option>매칭(양평).shp</option>
<option>매칭(서울).shp</option>
</select>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">오수전환율:</Label>
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center mb-2"
placeholder="입력"
value={inftwtAnls?.drtwSwtcRt ?? ""}
readOnly={true}
/>
</div>
<div>관망도 자료:</div>
<div>
<select className="border border-gray-300 rounded px-2 py-1">
<option>양평.inp</option>
<option>서울.inp</option>
</select>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">시간패턴 파일명:</Label>
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center mb-2"
placeholder="입력"
value={inftwtAnls?.atflHrPttnNm ?? ""}
readOnly={true}
/>
</div>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">수용가-맨홀 매칭:</Label>
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center mb-2"
placeholder="입력"
value={inftwtAnls?.atflMpngNm ?? ""}
readOnly={true}
/>
</div>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">관망도 파일명:</Label>
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center mb-2"
placeholder="입력"
value={inftwtAnls?.atflInpNm ?? ""}
readOnly={true}
/>
</div>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">유량 파일명:</Label>
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center mb-2"
placeholder="입력"
value={inftwtAnls?.atflOilqNm ?? "없음"}
readOnly={true}
/>
</div>
{btnTxt === 'RDII' ? <><div>강우 자료:</div>
<div>
<select className="border border-gray-300 rounded px-2 py-1">
<option>R20240815.xlsx</option>
</select>
</div>
<div>RTX 계수 출처:</div>
<div>
<select className="border border-gray-300 rounded px-2 py-1">
<option>2015년 하수도정비기본계획</option>
</select>
</div>
</> : null}
</div>
<div className="flex justify-end mt-4 space-x-2">
<button className="px-4 py-2 bg-gray-600 text-white rounded" onClick={closePopup}>
저장
</button>
<button className="px-4 py-2 bg-gray-600 text-white rounded" onClick={closePopup}>
종료
분석결과 도표
</button>
</div>
</div>
)}
</Modal>
</div>)}
{/* </Modal > */}
</>
)
return (
<UiModal
open={isModalOpen}
onOpenChange={setIsModalOpen}
bodyClass={`
h-[50vh]
w-[50vw]
max-w-none
max-h-none
overflow-visible
z-[50]
`}
body={renderBody()}
/>
)
}
@@ -0,0 +1,258 @@
'use client'
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 React, { useEffect, useState } from 'react';
import type { TRdiiAnls, TRdiiAnlsRslt, TOilqData } from './aplcnYms';
import { getChartDataRdiiAnlsRslt, selectRdiiAnlsRslt } from './aplcnYms';
import { getOptionsRdiiAnlsInfo, selectRdiiAnls, useAplcnYms } from './aplcnYms';
type ModalOpenProp = {
isModalOpen: boolean,
setIsModalOpen: (open: boolean) => void,
closeModal: () => void,
btnTxt?: string,
}
const RdiiChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOpenProp) => {
const [popupOpen, setPopupOpen] = React.useState(true);
const buttonRef = React.useRef<HTMLButtonElement>(null); // 버튼 참조
const [popupPosition, setPopupPosition] = useState<{ top: number; left: number }>({ top: 0, left: 0 }); // 팝업 위치
const [aplcnYm, setAplcnYm] = useState("");
const [rdiiAnlss, setRdiiAnlss] = useState<TRdiiAnls[]>([]);
const [rdiiAnlsInfos, setRdiiAnlsInfos] = useState<any[]>([]); // 강우유입수분석정보 options
const [rdiiAnls, setRdiiAnls] = useState<TRdiiAnls | null>(null); // 강우유입수분석정보
const [rainInfwtAnlsSn, setRainInfwtAnlsSn] = useState<number>(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 = useAplcnYms('rdiiAnlsRslt'); // 상수사용월 데이터 가져오기
const openPopup = () => {
if (buttonRef.current) {
const rect = buttonRef.current.getBoundingClientRect(); // 버튼 위치 계산
setPopupPosition({
top: rect.bottom + window.scrollY, // 버튼 아래쪽
left: rect.left + window.scrollX, // 버튼 왼쪽
});
}
setPopupOpen(true); // 팝업 열기
};
//console.log("btnTxt", btnTxt);
const chartForm = CHART_FORM.LINE;
const chartConfig = {
chartData1: { label: '강우유입수예측유량', color: "red", },
chartData2: { label: '실측유량', color: "orange", }
} as ChartConfig;
useEffect(() => {
if (isModalOpen === false) {
setPopupOpen(true); // 모달이 닫힐 때 팝업은
setAplcnYm(""); // 상수사용월 초기화
setRdiiAnlss([]); // 강우유입수분석 초기화
setRdiiAnlsInfos([]); // 강우유입수분석정보 초기화
setRdiiAnls(null); // 강우유입수분석정보 초기화
setRainInfwtAnlsSn(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 === "") {
setRainInfwtAnlsSn(0); // 초기화
setRdiiAnlsInfos([]);
return;
}
selectRdiiAnls(aplcnYm)
.then((data) => {
setRdiiAnlss(data ?? []);
setRdiiAnlsInfos(getOptionsRdiiAnlsInfo(data));
setRainInfwtAnlsSn(0); // 초기화
})
.catch((error) => {
console.error("selectrdiiAnls 에러:", error);
setRdiiAnlss([]);
setRdiiAnlsInfos([]);
});
}, [aplcnYm]);
// 값 표시
useEffect(() => {
// 선택된 강우유입수분석 정보에 대한 처리 로직
if (rainInfwtAnlsSn === 0) return;
const selectedAnls = rdiiAnlss.find(anls => anls.rainInfwtAnlsSn === rainInfwtAnlsSn);
if (selectedAnls) {
setRdiiAnls(selectedAnls);
}
}, [rainInfwtAnlsSn]);
const closePopup = () => { // 팝업 닫기
selectRdiiAnlsRslt(rainInfwtAnlsSn, "L13101003").then((data) => {// 강우유입수분석 결과 조회
const rsltData = getChartDataRdiiAnlsRslt(data ?? []);
setChartData(prev => ({
...prev,
chartData1: rsltData // 강우유입수분석결과
}));
});
// selectOilq(rdiiAnlsSn,"L13101003").then((data) => {// 유량 조회
// const rsltData = getChartDataOilq(data ?? []);
// setChartData(prev => ({
// ...prev,
// chartData2: rsltData // 유량
// }));
// });
setPopupOpen(false);
};
const renderBody = () => (
<>
{/* 분석 입력현황 조회 */}
<div className='grid grid-cols-4 gap-4'>
<div className="grid grid-rows-4 gap-4 mb-4">
<Button className="bg-white text-white w-[130px] font-bold px-4 mt-2 py-2" onClick={openPopup}>
분석 입력현황 조회
</Button>
{/* 강우유입수량 분석결과 */}
<div className="bg-white text-red-600 font-bold px-4 py-2 ">
강우유입수량 분석결과
<div className="flex items-center mt-2">
<span className="text-black text-xl font-bold">120</span>
<span className="ml-2 text-black">m³/d</span>
</div>
</div>
</div>
{/* 차트 */}
<div className="w-[500px] h-[300px] bg-white p-4">
<MainChart chartConfig={chartConfig} chartForm={chartForm} chartData={chartData} chartTitle={'관로유량'} />
</div>
</div>
{popupOpen && (
<div
className="absolute bg-gray-100 border border-gray-300 w-[420px] shadow-lg p-6 rounded text-2xl"
style={{
top: popupPosition.top,
left: popupPosition.left,
zIndex: 1000,
}}
>
<div className="font-bold mb-6 text-3xl">강우유입수분석 입력현황</div>
<div className='flex flex-col'>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">상수사용월:</Label>
<SelectBox
className="w-[200px] mr-8 z-[51]"
selectClass="rounded-lg bg-white"
label=''
selectArray={aplcnYms}
value={aplcnYm}
onSelectValue={(val) => {
setAplcnYm(String(val));
}}
/>
</div>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">분석정보:</Label>
<SelectBox
className="w-[200px] mr-8 z-[51]"
selectClass="rounded-lg bg-white"
label=''
selectArray={rdiiAnlsInfos}
value={rainInfwtAnlsSn}
onSelectValue={(val) => {
setRainInfwtAnlsSn(Number(val));
}}
/>
</div>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">오수전환율:</Label>
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center"
placeholder=""
value={rdiiAnls?.drtwSwtcRt ?? ""}
readOnly={true}
/>
</div>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">수용가-맨홀 매칭:</Label>
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center"
placeholder=""
value={rdiiAnls?.atflMpngNm ?? ""}
readOnly={true}
/>
</div>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">관망도 파일명:</Label>
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center"
placeholder=""
value={rdiiAnls?.atflInpNm ?? ""}
readOnly={true}
/>
</div>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">강우 파일명:</Label>
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center"
placeholder=""
value={rdiiAnls?.atflRainNm ?? ""}
readOnly={true}
/>
</div>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">RTK계수 출처:</Label>
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center"
placeholder=""
value={rdiiAnls?.srcNm ?? "없음"}
readOnly={true}
/>
</div>
</div>
<div className="flex justify-end mt-4 space-x-2">
<button className="px-4 py-2 bg-gray-600 text-white rounded" onClick={closePopup}>
분석결과 도표
</button>
</div>
</div>)}
{/* </Modal > */}
</>
)
return (
<UiModal
open={isModalOpen}
onOpenChange={setIsModalOpen}
bodyClass={`
h-[50vh]
w-[40vw]
max-w-none
max-h-none
overflow-visible
z-[50]
`}
body={renderBody()}
/>
)
}
export default RdiiChart
+1 -1
View File
@@ -9,7 +9,7 @@
"packages/*"
],
"scripts": {
"build": "turbo run build --filter=!wr",
"build": "turbo run build --filter=!wr --filter=!cs",
"build:common": "turbo run build --filter=@common/*",
"dev": "turbo run dev",
"dev:cs": "turbo run dev --filter=cs",