feat:
- 중점우수토실 상세페이지 작업 - 하수관로 침입수 분석, RDII 분석 버튼 위치 변경 - 시설 정보 API 호출 하지 않고 GIS 지도에서 가져오는 방식으로 변경
This commit is contained in:
@@ -30,75 +30,76 @@ export const MsSwagePplCol = [
|
||||
|
||||
// 하수처리시설
|
||||
export const SwtrmtFcltCol = [
|
||||
{ id: 'swtrmtFcltNm', title: '하수처리시설명' },
|
||||
{ id: 'fcltCpct', title: '시설용량' },
|
||||
{ id: 'rgnExpln', title: '지역설명' },
|
||||
{ id: 'cmcnYmd', title: '준공일자' },
|
||||
{ id: 'oprtngStrtYmd', title: '가동개시일자' },
|
||||
{ id: 'clsgYmd', title: '폐쇄일자' },
|
||||
// { id: 'prcsMsrcCd', title: '처리공법코드' },
|
||||
// { id: 'laeCd', title: '지자체코드' },
|
||||
{ id: 'laeNm', title: '지자체명' },
|
||||
{ id: 'ctpvNm', title: '시도명' },
|
||||
{ id: 'sggNm', title: '시군구명' },
|
||||
// { id: 'sareaCd', title: '권역코드' },
|
||||
{ id: 'sareaNm', title: '권역명' },
|
||||
{ id: 'lrgeSareaNm', title: '대권역명' },
|
||||
{ id: 'rvrNm', title: '하천명' },
|
||||
{ id: 'swtrmt_fclt_nm', title: '하수처리시설명' },
|
||||
{ id: 'fclt_cpct', title: '시설용량' },
|
||||
{ id: 'rgn_expln', title: '지역설명' },
|
||||
{ id: 'cmcn_ymd', title: '준공일자' },
|
||||
{ id: 'oprtng_strt_ymd', title: '가동개시일자' },
|
||||
{ id: 'clsg_ymd', title: '폐쇄일자' },
|
||||
// { id: 'prcs_msrc_cd', title: '처리공법코드' },
|
||||
// { id: 'lae_cd', title: '지자체코드' },
|
||||
{ id: 'lae_nm', title: '지자체명' },
|
||||
{ id: 'ctpv_nm', title: '시도명' },
|
||||
{ id: 'sgg_nm', title: '시군구명' },
|
||||
// { id: 'sarea_cd', title: '권역코드' },
|
||||
{ id: 'sarea_nm', title: '권역명' },
|
||||
{ id: 'lrge_sarea_nm', title: '대권역명' },
|
||||
{ id: 'rvr_nm', title: '하천명' },
|
||||
{ id: 'addr', title: '주소' },
|
||||
{ id: 'daddr', title: '상세주소' },
|
||||
{ id: 'rdnmAddr', title: '도로명주소' },
|
||||
{ id: 'dtlRdnmAddr', title: '상세도로명주소' },
|
||||
{ id: 'dschgWtstNm', title: '방류수계명' },
|
||||
{ id: 'pllnArea', title: '부지면적' },
|
||||
{ id: 'mngRprtvBzentyNm', title: '관리대행업제명' },
|
||||
{ id: 'swtrmtPpltnCnt', title: '하수처리인구수' },
|
||||
{ id: 'prcsZoneAreaSum', title: '처리구역면적합계' },
|
||||
{ id: 'dtl_addr', title: '상세주소' },
|
||||
{ id: 'rdnm_addr', title: '도로명주소' },
|
||||
{ id: 'dtl_rdnm_addr', title: '상세도로명주소' },
|
||||
{ id: 'dschg_wtst_nm', title: '방류수계명' },
|
||||
{ id: 'plln_area', title: '부지면적' },
|
||||
{ id: 'mng_rprtv_bzenty_nm', title: '관리대행업제명' },
|
||||
{ id: 'swtrmt_ppltn_cnt', title: '하수처리인구수' },
|
||||
{ id: 'prcs_zone_area_sum', title: '처리구역면적합계' },
|
||||
{ id: 'xcrd', title: 'X좌표' },
|
||||
{ id: 'ycrd', title: 'Y좌표' },
|
||||
// { id: 'oprtngSttsCd', title: '가동상태코드' },
|
||||
{ id: 'rprsMsrcCn', title: '대표공법내용' },
|
||||
{ id: 'sttyCrtrBod', title: '법정기준생물화학적산소요구량' },
|
||||
{ id: 'sttyCrtrToc', title: '법정기준TOC' },
|
||||
{ id: 'sttyCrtrSs', title: '법정기준SS' },
|
||||
{ id: 'sttyCrtrTn', title: '법정기준총질소' },
|
||||
{ id: 'sttyCrtrTph', title: '법정기준총인' },
|
||||
{ id: 'sttyCrtrClbclCnt', title: '법정기준대장균수' },
|
||||
{ id: 'bsnNm', title: '유역명' },
|
||||
{ id: 'rprs_msrc_cn', title: '대표공법내용' },
|
||||
{ id: 'stty_crtr_bod', title: '법정기준생물화학적산소요구량' },
|
||||
{ id: 'stty_crtr_toc', title: '법정기준TOC' },
|
||||
{ id: 'stty_crtr_ss', title: '법정기준SS' },
|
||||
{ id: 'stty_crtr_tn', title: '법정기준총질소' },
|
||||
{ id: 'stty_crtr_tph', title: '법정기준총인' },
|
||||
{ id: 'stty_crtr_clbcl_cnt', title: '법정기준대장균수' },
|
||||
{ id: 'bsn_nm', title: '유역명' },
|
||||
// { id: 'obsrvnSptCd', title: '관측지점코드' },
|
||||
];
|
||||
|
||||
// 하수처리구역
|
||||
export const SwtrmtPrcsZoneCol = [
|
||||
{ id: 'swtrmtZoneSn', title: '하수처리구역 일련번호' },
|
||||
{ id: 'swtrmtZoneNm', title: '하수처리구역명' },
|
||||
// { id: 'swtrmtFcltCd', title: '하수처리시설코드' },
|
||||
// { id: 'ctpvCd', title: '시도코드' },
|
||||
{ id: 'ctpvNm', title: '시도명' },
|
||||
// { id: 'sggCd', title: '시군구코드' },
|
||||
{ id: 'sggNm', title: '시군구명' },
|
||||
{ id: 'swtrmtFcltNm', title: '하수처리시설명' },
|
||||
// { id: 'swtrmtZoneSn', title: '하수처리구역 일련번호' },
|
||||
{ id: 'swtrmt_zone_nm', title: '하수처리구역명' },
|
||||
// { id: 'swtrmt_fclt_cd', title: '하수처리시설코드' },
|
||||
// { id: 'ctpv_cd', title: '시도코드' },
|
||||
{ id: 'ctpv_nm', title: '시도명' },
|
||||
// { id: 'sgg_cd', title: '시군구코드' },
|
||||
{ id: 'sgg_nm', title: '시군구명' },
|
||||
{ id: 'swtrmt_fclt_nm', title: '하수처리시설명' },
|
||||
];
|
||||
|
||||
// 하수맨홀
|
||||
export const MsSwageMhlCol = [
|
||||
// { id: 'fid', title: 'FID' },
|
||||
// { id: 'geom', title: 'geometry' },
|
||||
// { id: 'ftreSmbolCd', title: '지형지물부호코드' },
|
||||
{ id: 'fcltMngNo', title: '시설관리번호' },
|
||||
// { id: 'pbadmsEmdCd', title: '행정읍면동코드' },
|
||||
{ id: 'mapshtNo', title: '도엽번호' },
|
||||
// { id: 'mngInstCd', title: '관리기관코드' },
|
||||
{ id: 'instlYmd', title: '설치일자' },
|
||||
{ id: 'lastDrdgnYmd', title: '최종준설일자' },
|
||||
// { id: 'usgCd', title: '용도코드' },
|
||||
// { id: 'fcltyShpCd', title: '시설물형태코드' },
|
||||
// { id: 'mhlKndCd', title: '맨홀종류코드' },
|
||||
{ id: 'swageMhDiam', title: '하수맨홀구경' },
|
||||
{ id: 'wdthLen', title: '가로길이' },
|
||||
{ id: 'vrtcLen', title: '세로길이' },
|
||||
// { id: 'ftre_smbol_cd', title: '지형지물부호코드' },
|
||||
{ id: 'fclt_mng_no', title: '시설관리번호' },
|
||||
// { id: 'pbadms_emd_cd', title: '행정읍면동코드' },
|
||||
{ id: 'mapsht_no', title: '도엽번호' },
|
||||
// { id: 'mng_inst_cd', title: '관리기관코드' },
|
||||
{ id: 'instl_ymd', title: '설치일자' },
|
||||
{ id: 'last_drdgn_ymd', title: '최종준설일자' },
|
||||
// { id: 'usg_cd', title: '용도코드' },
|
||||
// { id: 'fclty_shp_cd', title: '시설물형태코드' },
|
||||
// { id: 'mhl_knd_cd', title: '맨홀종류코드' },
|
||||
{ id: 'swage_mh_diam', title: '하수맨홀구경' },
|
||||
{ id: 'wdth_len', title: '가로길이' },
|
||||
{ id: 'vrtc_len', title: '세로길이' },
|
||||
// { id: 'mqltCd', title: '재질코드' },
|
||||
{ id: 'altdVl', title: '표고' },
|
||||
// { id: 'ang_dir', title: '표고' },
|
||||
{ id: 'altd_vl', title: '표고' },
|
||||
{ id: 'dpthlVl', title: '심도' },
|
||||
// { id: 'instMngNo', title: '기관관리번호' }
|
||||
];
|
||||
|
||||
@@ -3,9 +3,8 @@ 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';
|
||||
|
||||
|
||||
// 하수관로
|
||||
const inputColumn = [
|
||||
{ id: "title", title: "설치주제", type: "select", options: ["BTL", "재정사업"] },
|
||||
@@ -16,80 +15,63 @@ const inputColumn = [
|
||||
{ id: "flow", title: "흐름방식", type: "select", options: ["자연유하", "압송"] },
|
||||
{ id: "place", title: "매설위치", type: "select", options: ["도로", "하상"] },
|
||||
];
|
||||
const MsSwagePpl = ({ featureData }: { featureData: any }) => { // SwtrmtFclt
|
||||
console.log("featureData", featureData);
|
||||
const [isModalInfil, setIsModalInfil] = React.useState(false);
|
||||
const [isModalRdii, setIsModalRdii] = React.useState(false);
|
||||
const [btnTxt, setBtnTxt] = useState<string>("");
|
||||
const pplMngNo= featureData?.pplMngNo || ""; // 관로관리번호
|
||||
const openModalRdii = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.currentTarget.textContent && setBtnTxt(e.currentTarget.textContent)
|
||||
setIsModalRdii(true);
|
||||
}
|
||||
const openModalInfil = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.currentTarget.textContent && setBtnTxt(e.currentTarget.textContent)
|
||||
setIsModalInfil(true);
|
||||
};
|
||||
const closeModalInfil = () => {
|
||||
setIsModalInfil(false);
|
||||
};
|
||||
const closeModalRdii = () => {
|
||||
setIsModalRdii(false);};
|
||||
|
||||
const MsSwagePpl = ({ featureData }: { featureData: any }) => {
|
||||
const [repairData, setRepairData] = useState([
|
||||
{ year: "2025", type: "개대체" },
|
||||
{ year: "2025", type: "보수" },
|
||||
]);
|
||||
|
||||
const [cleaningData, setCleaningData] = useState([
|
||||
{ year: "2025", type: "청소" },
|
||||
{ year: "2025", type: "준설" },
|
||||
]);
|
||||
|
||||
const [inspectionData, setInspectionData] = useState([
|
||||
{ year: "2025", type: "관로기술진단" },
|
||||
{ year: "2025", type: "관로기술진단" },
|
||||
]);
|
||||
|
||||
const dataMap = {
|
||||
repair: { data: repairData, setData: setRepairData },
|
||||
cleaning: { data: cleaningData, setData: setCleaningData },
|
||||
inspection: { data: inspectionData, setData: setInspectionData },
|
||||
};
|
||||
const keysToExtract = [
|
||||
"swtrmt_zone_cd",
|
||||
"mltv_dtdv_nm",
|
||||
"fid",
|
||||
"lyrTypeNm",
|
||||
"reg_dt",
|
||||
"mdfcn_dt",
|
||||
"rgtr",
|
||||
"mdfr",
|
||||
];
|
||||
// const filteredData = Object.entries(featureData)
|
||||
// .filter(([key]) => keysToExtract.includes(key)) // 필요한 키만 필터링
|
||||
// .map(([key, value]) => ({ key, value: value ?? "N/A" })); // 테이블 데이터 형식으로 변환
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<VerticalTable headName='자체 입력정보' tableData={[]} headlist={inputColumn} pageSize={20} total={0} children={undefined} cellClick={undefined} isEditable={true} onPageChange={function (page: number): void {
|
||||
throw new Error("Function not implemented.");
|
||||
}}></VerticalTable>
|
||||
<InputSection title="보수 및 갱신" data={repairData} sectionKey="repair" onInputChange={(section, index, field, value) => handleInputChange(section, index, field, value, dataMap)} />
|
||||
<InputSection title="청소 및 준설" data={cleaningData} sectionKey="cleaning" onInputChange={(section, index, field, value) => handleInputChange(section, index, field, value, dataMap)} />
|
||||
<InputSection title="점검 및 진단" data={inspectionData} sectionKey="inspection" onInputChange={(section, index, field, value) => handleInputChange(section, index, field, value, dataMap)} />
|
||||
<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={openModalInfil}
|
||||
>
|
||||
Infil
|
||||
</Button>
|
||||
<Button
|
||||
className="px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700"
|
||||
onClick={openModalRdii}
|
||||
>
|
||||
RDII
|
||||
</Button>
|
||||
</div>
|
||||
<InfilChart btnTxt={btnTxt} isModalOpen={isModalInfil} setIsModalOpen={setIsModalInfil} closeModal={closeModalInfil} pplMngNo={pplMngNo} />
|
||||
<RdiiChart btnTxt={btnTxt} isModalOpen={isModalRdii} setIsModalOpen={setIsModalRdii} closeModal={closeModalRdii} pplMngNo={pplMngNo}/>
|
||||
<VerticalTable
|
||||
headName='자체 입력정보'
|
||||
tableData={[]}
|
||||
headlist={inputColumn}
|
||||
pageSize={20}
|
||||
total={0}
|
||||
children={undefined}
|
||||
cellClick={undefined}
|
||||
isEditable={true}
|
||||
onPageChange={function (page: number): void {
|
||||
throw new Error("Function not implemented.");
|
||||
}}
|
||||
/>
|
||||
<InputSection
|
||||
title="보수 및 갱신"
|
||||
data={repairData}
|
||||
sectionKey="repair"
|
||||
onInputChange={(section, index, field, value) => handleInputChange(section, index, field, value, dataMap)}
|
||||
/>
|
||||
<InputSection
|
||||
title="청소 및 준설"
|
||||
data={cleaningData}
|
||||
sectionKey="cleaning"
|
||||
onInputChange={(section, index, field, value) => handleInputChange(section, index, field, value, dataMap)}
|
||||
/>
|
||||
<InputSection
|
||||
title="점검 및 진단"
|
||||
data={inspectionData}
|
||||
sectionKey="inspection"
|
||||
onInputChange={(section, index, field, value) => handleInputChange(section, index, field, value, dataMap)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,36 +1,41 @@
|
||||
// 우수토실
|
||||
import { UiModal, UiTable } from '@common/business_components/ui';
|
||||
import { Button, TableHead, TableRow } from '@common/components/ui';
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { untrtSwgRainCol3, untrtSwgRainCol4, untrtSwgRainCol5 } from '../common/table';
|
||||
import LoadingOverlay from '@/components/ui/LoadingBar';
|
||||
|
||||
const Ssc = ({ featureData, chkMainSsc, additionalData }: {
|
||||
featureData: any,
|
||||
chkMainSsc?: boolean,
|
||||
additionalData?: any
|
||||
}) => {
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [isDataLoaded, setIsDataLoaded] = useState(false);
|
||||
console.log('featureData data received:', featureData); // 추가 데이터 확인용
|
||||
console.log('Additional data received:', additionalData); // 추가 데이터 확인용
|
||||
|
||||
const [isModalOpen, setIsModalOpen] = React.useState(false);
|
||||
const openModal = () => {
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
const closeModal = () => {
|
||||
setIsModalOpen(false);
|
||||
if (!isDataLoaded) {
|
||||
setTimeout(() => setIsDataLoaded(true), 100);
|
||||
}
|
||||
};
|
||||
|
||||
// 데이터 전처리: 합쳐진 필드 추가
|
||||
const preprocessedData = featureData ? [{
|
||||
...featureData,
|
||||
flwmtr_combined: `${featureData.flwmtr_mesure_tp_etc || '-'} / ${featureData.flwmtr_knd || '-'}`
|
||||
}] : [];
|
||||
// const preprocessedData = featureData ? [{
|
||||
// ...featureData,
|
||||
// flwmtr_combined: `${featureData.flwmtr_mesure_tp_etc || '-'} / ${featureData.flwmtr_knd || '-'}`
|
||||
// }] : [];
|
||||
|
||||
const renderModalBody = () => (
|
||||
<div className='grid grid-cols-1 gap-4 p-4'>
|
||||
{/* 강우정보 테이블 */}
|
||||
<UiTable
|
||||
headName='강우정보'
|
||||
tableData={preprocessedData}
|
||||
tableData={featureData}
|
||||
headlist={untrtSwgRainCol3}
|
||||
pageSize={10}
|
||||
total={0}
|
||||
@@ -44,7 +49,7 @@ const Ssc = ({ featureData, chkMainSsc, additionalData }: {
|
||||
{/* 측정정보 테이블 */}
|
||||
<UiTable
|
||||
headName='측정정보'
|
||||
tableData={preprocessedData}
|
||||
tableData={featureData}
|
||||
headlist={untrtSwgRainCol4}
|
||||
pageSize={10}
|
||||
total={0}
|
||||
@@ -84,7 +89,7 @@ const Ssc = ({ featureData, chkMainSsc, additionalData }: {
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -102,7 +107,7 @@ const Ssc = ({ featureData, chkMainSsc, additionalData }: {
|
||||
}}
|
||||
/> */}
|
||||
|
||||
{!chkMainSsc ? null :
|
||||
{chkMainSsc && (
|
||||
<div>
|
||||
<div className="card-header">
|
||||
<h3 className="text-2xl mx-3 font-medium text-label">중점우수토실 운영정보</h3>
|
||||
@@ -131,7 +136,7 @@ const Ssc = ({ featureData, chkMainSsc, additionalData }: {
|
||||
// footerContent={renderFooterContent()}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,16 +4,15 @@ import Modal from "@/components/ui/modal";
|
||||
import { VerticalTable } from "@/components/ui/verticalTable";
|
||||
import { useGisContext } from "@common/business_components/ui/map/Gis";
|
||||
import { Button } from "@common/components/ui";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useEffect, useRef, useState, useCallback, useMemo } from "react";
|
||||
import { getLayerContentComponent } from "./components/common";
|
||||
import { SwtrmtFcltCol, SwtrmtPrcsZoneCol, untrtSwgRainCol1, untrtSwgRainCol2, MsSwagePplCol, SewagePump, MsSwageMhlCol } from "./components/common/table";
|
||||
import InfilChart from './components/popupComponent/chart/infilChart';
|
||||
import RdiiChart from './components/popupComponent/chart/rdiiChart';
|
||||
|
||||
// TODO:
|
||||
const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, featureData: any }) => {
|
||||
const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject<number[]>; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; };
|
||||
// const featureId = featureData.getId(); // 피처의 id 가져오기
|
||||
const featureId = typeof featureData.getId === 'function'
|
||||
? featureData.getId()
|
||||
: featureData.fid;
|
||||
const [layerNm, setLayerNm] = useState<string>(""); // 레이어 이름 상태
|
||||
const [tableData, setTableData] = useState<any>(null); // 피처 데이터
|
||||
const [mntrngsData, setMntrngsData] = useState(false); // 수량/수질 측정 정보
|
||||
@@ -24,6 +23,68 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
const contentRef = useRef<HTMLDivElement>(null);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false); // 모달 열기 상태
|
||||
const [chkMainSsc, setChkMainSsc] = useState(false); // 중점우수토실 여부
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
// 🎯 추가 데이터 로딩 상태 분리
|
||||
const [isAdditionalDataLoading, setIsAdditionalDataLoading] = useState(false);
|
||||
const [additionalDataError, setAdditionalDataError] = useState<string | null>(null);
|
||||
// 🎯 InfilChart 및 RdiiChart 관련 상태 추가
|
||||
const [isModalInfil, setIsModalInfil] = useState(false);
|
||||
const [isModalRdii, setIsModalRdii] = useState(false);
|
||||
const [btnTxt, setBtnTxt] = useState<string>("");
|
||||
|
||||
// 🎯 관로관리번호 추출
|
||||
const pplMngNo = featureData?.values_?.fclt_mng_no || "";
|
||||
// const featureId = featureData.getId(); // 피처의 id 가져오기
|
||||
|
||||
const featureId = typeof featureData.getId === 'function'
|
||||
? featureData.getId()
|
||||
: featureData.fid;
|
||||
console.log('featureId', featureId);
|
||||
|
||||
// 🎯 추가 데이터 API 호출 함수 (독립적으로 실행)
|
||||
const fetchAdditionalData = useCallback(async (adstDstrCd: string, manageNo: string) => {
|
||||
if (!adstDstrCd || !manageNo) {
|
||||
console.warn('추가 데이터 호출 실패: 필수 매개변수 누락', { adstDstrCd, manageNo });
|
||||
return [];
|
||||
}
|
||||
|
||||
setIsAdditionalDataLoading(true);
|
||||
setAdditionalDataError(null);
|
||||
|
||||
try {
|
||||
console.log(`추가 데이터 API 호출 시작: v1/onsemiro/swgRain/${adstDstrCd}/${manageNo}/mntrngs`);
|
||||
|
||||
// 🎯 타임아웃 설정 (10초)
|
||||
const timeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('API 타임아웃')), 10000)
|
||||
);
|
||||
|
||||
const apiPromise = getData(`v1/onsemiro/swgRain/${adstDstrCd}/${manageNo}/mntrngs`);
|
||||
|
||||
const response = await Promise.race([apiPromise, timeoutPromise]) as any;
|
||||
|
||||
console.log('추가 데이터 API 호출 성공:', response);
|
||||
return response?.content || [];
|
||||
} catch (error) {
|
||||
console.error('추가 데이터 로딩 실패:', error);
|
||||
setAdditionalDataError(error instanceof Error ? error.message : '알 수 없는 오류');
|
||||
return [];
|
||||
} finally {
|
||||
setIsAdditionalDataLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 🎯 데이터 전처리 메모이제이션
|
||||
const processedData = useMemo(() => {
|
||||
if (!featureData?.values_) return null;
|
||||
|
||||
const data = featureData.values_;
|
||||
return {
|
||||
...data,
|
||||
discharge_pipe_spec: `직경: ${data.pipe_diameter || '-'} / 높이: ${data.pipe_hg || '-'} / 길이: ${data.pipe_lt || '-'}`,
|
||||
flwmtr_combined: `${data.flwmtr_mesure_tp_etc || '-'} / ${data.flwmtr_knd || '-'}`
|
||||
};
|
||||
}, [featureData?.values_]);
|
||||
|
||||
// 피쳐데이터의 현재 레이어 이름 가져오는 함수
|
||||
const getSelectedLayers = () => {
|
||||
@@ -37,7 +98,7 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
featureLayer = layer; // 피처가 속한 레이어 찾기
|
||||
}
|
||||
});
|
||||
console.log("featureLayer.get('lyrTyNm');", featureLayer.get('lyrTyNm'));
|
||||
// console.log("featureLayer.get('lyrTyNm');", featureLayer.get('lyrTyNm'));
|
||||
// SearchModal 클릭 이벤트와 Gis 클릭 이벤트 구분하기
|
||||
if (featureLayer.get('lyrNm') === null) {
|
||||
if (featureData.lyrTypeNm === 'tb_il_swage_prcs_fclt') result = '하수처리시설';
|
||||
@@ -64,15 +125,17 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
if (featureId) {
|
||||
if (!featureId) return;
|
||||
|
||||
try {
|
||||
const selectedLayerName = getSelectedLayers(); // 레이어 이름 가져오기
|
||||
setLayerNm(selectedLayerName); // 상태 업데이트
|
||||
const layerId = featureId.split('.')[0]
|
||||
|
||||
console.log('gis data', featureData.values_);
|
||||
// let data = await getData(`v1/fclts/${featureId}?lyrTypeNm=${layerId}`);
|
||||
let data = featureData.values_;
|
||||
console.log('api data', data)
|
||||
setfetchData(data)
|
||||
setTableData(data);
|
||||
|
||||
switch (selectedLayerName) {
|
||||
case '하수처리시설':
|
||||
setHeadlist(SwtrmtFcltCol);
|
||||
@@ -88,16 +151,23 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
setButtonChk(false)
|
||||
setChkMainSsc(true)
|
||||
|
||||
// 데이터 전처리: 합쳐진 필드 추가
|
||||
data = data ? {
|
||||
...data,
|
||||
discharge_pipe_spec: `직경: ${data.pipe_diameter || '-'} / 높이: ${data.pipe_hg || '-'} / 길이: ${data.pipe_lt || '-'}`
|
||||
} : {};
|
||||
setfetchData([processedData])
|
||||
setTableData(processedData);
|
||||
setIsLoading(false); // 기본 렌더링 완료
|
||||
|
||||
// 수량/수질측정 정보 데이터 호출
|
||||
const additionalResponse = await getData(`v1/onsemiro/swgRain/${data.adst_dstr_cd}/${data.manage_no}/mntrngs`);
|
||||
setMntrngsData(additionalResponse.content);
|
||||
break;
|
||||
if (data?.adst_dstr_cd && data?.manage_no) {
|
||||
fetchAdditionalData(data.adst_dstr_cd, data.manage_no)
|
||||
.then(response => {
|
||||
console.log('additionalResponse', response);
|
||||
setMntrngsData(response || []);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('추가 데이터 로딩 실패:', error);
|
||||
setMntrngsData(false);
|
||||
});
|
||||
}
|
||||
return;
|
||||
case '우수토실':
|
||||
setButtonChk(true)
|
||||
break;
|
||||
@@ -122,11 +192,33 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
setTableData(data);
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('데이터 로딩 중 오류:', error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, [featureId]);
|
||||
}, [featureId, processedData]);
|
||||
|
||||
// 🎯 추가 데이터는 별도 useEffect로 비동기 로딩
|
||||
useEffect(() => {
|
||||
if (layerNm === '중점우수토실' && featureData?.values_) {
|
||||
const data = featureData.values_;
|
||||
|
||||
if (data?.adst_dstr_cd && data?.manage_no) {
|
||||
// 🎯 추가 데이터를 비동기로 로딩 (UI 블로킹 없음)
|
||||
fetchAdditionalData(data.adst_dstr_cd, data.manage_no)
|
||||
.then(response => {
|
||||
console.log('추가 데이터 로딩 완료:', response);
|
||||
setMntrngsData(response || []);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('추가 데이터 최종 로딩 실패:', error);
|
||||
setMntrngsData(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [layerNm, featureData?.values_, fetchAdditionalData]);
|
||||
|
||||
// 저장 시 모달 띄우기
|
||||
const handleSaveClick = () => {
|
||||
@@ -142,6 +234,25 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
setIsModalOpen(false); // 모달 닫기
|
||||
};
|
||||
|
||||
// 🎯 모달 열기/닫기 함수들
|
||||
const openModalInfil = () => {
|
||||
setBtnTxt("Infil");
|
||||
setIsModalInfil(true);
|
||||
};
|
||||
|
||||
const closeModalInfil = () => {
|
||||
setIsModalInfil(false);
|
||||
};
|
||||
|
||||
const openModalRdii = () => {
|
||||
setBtnTxt("RDII");
|
||||
setIsModalRdii(true);
|
||||
};
|
||||
|
||||
const closeModalRdii = () => {
|
||||
setIsModalRdii(false);
|
||||
};
|
||||
|
||||
const btnClickEvent = async () => {
|
||||
const bodyData: Record<string, any> = {}
|
||||
if (buttonChk && contentRef.current) {
|
||||
@@ -174,21 +285,45 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 레이어명에 따라 상세페이지 렌더링
|
||||
const ContentComponent = layerNm ? getLayerContentComponent(layerNm) : null;
|
||||
|
||||
return (
|
||||
<div id="popup" className="absolute top-0 right-0 w-[350px] h-[calc(100vh-10rem)] bg-white border-r border-gray-300 flex flex-col overflow-hidden transition-all duration-300 z-[50]">
|
||||
<div className="card-header bg-primary flex items-center justify-between p-4">
|
||||
<div className="flex mx-3 flex-col">
|
||||
<h3 className="text-2xl font-medium text-white text-label">{layerNm} 정보</h3>
|
||||
<div className="flex items-center">
|
||||
<h3 className="text-2xl font-medium text-white text-label whitespace-nowrap">{layerNm} 정보</h3>
|
||||
{/* <div className="font-medium text-white text-label">(00구 00리 하수관로)</div> */}
|
||||
</div>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="text-white hover:text-gray-700 focus:outline-none"
|
||||
aria-label="닫기"
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
|
||||
<div className="flex items-center space-x-3">
|
||||
{/* 🎯 하수관로일 때만 Infil/RDII 버튼 표시 */}
|
||||
{layerNm === '하수관로' && (
|
||||
<>
|
||||
<Button
|
||||
className="px-2 py-1 text-xl text-blue-600 border border-blue-600 rounded hover:bg-gray-700"
|
||||
color="white"
|
||||
onClick={openModalInfil}
|
||||
>
|
||||
Infil
|
||||
</Button>
|
||||
<Button
|
||||
className="px-2 py-1 text-xl text-gray-600 border border-gray-600 rounded hover:bg-gray-700"
|
||||
color="white"
|
||||
onClick={openModalRdii}
|
||||
>
|
||||
RDII
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
onClick={onClose}
|
||||
className="text-white hover:text-gray-300 focus:outline-none ml-2"
|
||||
>
|
||||
✕
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="overflow-y-auto overflow-x-hidden flex-1" ref={contentRef}>
|
||||
<VerticalTable
|
||||
@@ -226,6 +361,22 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
||||
{/* 🎯 InfilChart 및 RdiiChart 컴포넌트 추가 */}
|
||||
<InfilChart
|
||||
btnTxt={btnTxt}
|
||||
isModalOpen={isModalInfil}
|
||||
setIsModalOpen={setIsModalInfil}
|
||||
closeModal={closeModalInfil}
|
||||
pplMngNo={pplMngNo}
|
||||
/>
|
||||
<RdiiChart
|
||||
btnTxt={btnTxt}
|
||||
isModalOpen={isModalRdii}
|
||||
setIsModalOpen={setIsModalRdii}
|
||||
closeModal={closeModalRdii}
|
||||
pplMngNo={pplMngNo}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user