Merge branch 'iipbs/sn/ii' into iipbs/sn/dev
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import FeatureClickEventPopup from './featureClickEventPopup';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import { UiModal, UiTable, DatePickerRange } from '@common/business_components/ui';
|
||||
import { UiModal, UiTable, DatePickerRange, SelectBox } from '@common/business_components/ui';
|
||||
import { Button, Input, Label } from '@common/components';
|
||||
import { UiTable2 } from '@common/business_components/ui/table/index-2';
|
||||
import { UITab2 } from '@common/business_components/ui/tab/index-2';
|
||||
@@ -11,8 +10,9 @@ import { SidoSigunguSelectBox } from '@/components/ui/SidoSigunguSelectBox';
|
||||
import { MsSwagePplCol2, SwtrmtFcltCol2, SwtrmtPrcsZoneCol2, MsSwageMhlCol2, ExclnSewagePumpCol2, stofcbrCol2 } from './components/common/table';
|
||||
import LoadingOverlay from '@/components/ui/LoadingBar';
|
||||
//import { useDcTree, flattenFolders, useSggCd, useCityCd } from './components/searchModalReportApi';
|
||||
import { useDcTree,flattenFolders, useSggCd, useCityCd, addFileName, getFileDownload } from './components/searchModalReportApi';
|
||||
import { useDcTree, flattenFolders, useSggCd, useCityCd, addFileName, getFileDownload } from './components/searchModalReportApi';
|
||||
import { useCityCdStore, type SelectDataType } from './commonStore';
|
||||
import { MS_SWAGE_PPL_USE_CODES, MS_SWAGE_PPL_CODES, MS_SWAGE_MHL_USE_CODES } from '../map/components/common/table';
|
||||
|
||||
const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`;
|
||||
|
||||
@@ -95,8 +95,10 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
const [tableCount, setTableCount] = useState<number>(0);
|
||||
const [curPage, setCurPage] = useState(1);
|
||||
const [basicType, setBasicType] = useState(BASIC_TYPES[0]?.val ?? "");
|
||||
const [ctpvCd, setCtpvCd] = useState('0');
|
||||
const [sigungu, setSigungu] = useState('0');
|
||||
const [시도, set시도] = useState(0);
|
||||
const [시군구, set시군구] = useState(0);
|
||||
const [ctpvCd, setCtpvCd] = useState('0');
|
||||
const [sigungu, setSigungu] = useState('0');
|
||||
//const [swageProcessingZone, set처리구역] = useState("");
|
||||
const [gubun, setGubun] = useState(""); // 하수정비기본계획 report
|
||||
// 날짜 상태 선언
|
||||
@@ -104,8 +106,8 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
const [시작2, set시작2] = useState("");
|
||||
const [종료1, set종료1] = useState("");
|
||||
const [종료2, set종료2] = useState("");
|
||||
const [변수1, set변수1] = useState("");
|
||||
const [변수2, set변수2] = useState("");
|
||||
const [변수1, set변수1] = useState<string>("");
|
||||
const [변수2, set변수2] = useState<string>("");
|
||||
const [변수3, set변수3] = useState("");
|
||||
const [변수4, set변수4] = useState("");
|
||||
// 시작, 종료, 경과년도
|
||||
@@ -121,7 +123,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
const [가동개시_종료_일, set가동개시_종료_일] = useState('');
|
||||
const [fromDate, setFromDate] = useState(() => { const date = new Date(); date.setDate(date.getDate() - 7); return date })
|
||||
const [toDate, setToDate] = useState(new Date())
|
||||
const [filteredSiguns, setFilteredSiguns] = useState<SelectDataType[]>([{ val: '0', text: '전체', sido: '0' }]);
|
||||
const [filteredSiguns, setFilteredSiguns] = useState<SelectDataType[]>([{ val: '0', text: '전체', sido: '0' }]);
|
||||
|
||||
// 로딩바
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
@@ -129,7 +131,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
const sidos = useCityCd();
|
||||
const siguns = useSggCd();
|
||||
const reportOriginData = useDcTree(""); //:Folder[]
|
||||
|
||||
|
||||
// 오늘 날짜 구하기
|
||||
const today = new Date();
|
||||
const todayYear = today.getFullYear().toString();
|
||||
@@ -162,7 +164,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
else if (basicType === 'tb_ms_swage_pmstn') dynamicHeadlist = ExclnSewagePumpCol2; // 하수펌프장
|
||||
else if (basicType === 'tb_ms_stofcbr') dynamicHeadlist = stofcbrCol2; // 우수토실
|
||||
|
||||
|
||||
|
||||
// 조회 버튼 클릭 시 1페이지로 이동하도록 수정
|
||||
const handleSearch = () => {
|
||||
setCurPage(1); // 페이지를 1로 초기화
|
||||
@@ -187,17 +189,17 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const handleCtpvCdChange = (val: string|number) => { // 하수도정비기본계획.시도
|
||||
const handleCtpvCdChange = (val: string | number) => { // 하수도정비기본계획.시도
|
||||
const sidoOption = sidos.find((n) => n.val === val);
|
||||
setCtpvCd(String(val));
|
||||
if (val !== '0') {
|
||||
const filterSiguns = siguns.filter(item => item.sido === sidoOption?.text);
|
||||
filterSiguns.unshift({ val: '0', text: '전체', sido: '0' });
|
||||
filterSiguns.unshift({ val: '0', text: '전체', sido: '0' });
|
||||
setFilteredSiguns(filterSiguns);
|
||||
}
|
||||
}
|
||||
setSigungu("0");
|
||||
setGubun("");
|
||||
setYearFilter({시작: "",종료: "",});
|
||||
setYearFilter({ 시작: "", 종료: "", });
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
@@ -215,6 +217,8 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
set가동개시_종료_월("");
|
||||
set가동개시_시작_일("");
|
||||
set가동개시_종료_일("");
|
||||
set시도(0);
|
||||
set시군구(0);
|
||||
setCtpvCd('0');
|
||||
setSigungu('0');
|
||||
setYearFilter({
|
||||
@@ -237,7 +241,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
}
|
||||
}, [curPage]);
|
||||
|
||||
|
||||
|
||||
// 검색 API 호출 함수
|
||||
const fetchFilteredData = async () => {
|
||||
setIsLoading(true); // 로딩 시작
|
||||
@@ -248,6 +252,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
size: '10',
|
||||
sort: 'string',
|
||||
});
|
||||
console.log('basicType', basicType);
|
||||
|
||||
let cqlFilters: string[] = [];
|
||||
if (activeTab === 'basic') {
|
||||
@@ -272,27 +277,27 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
if (ctpvCd !== "0") { // 시도검색
|
||||
const sidoOption = sidos.find((n) => n.val === ctpvCd);
|
||||
filterReportData = filterReportData.filter(item => item.sido === sidoOption?.text);
|
||||
}
|
||||
}
|
||||
if (sigungu !== "0") { // 시군구검색
|
||||
const sigunguOption = filteredSiguns.find((n) => n.val === sigungu);
|
||||
filterReportData = filterReportData.filter(item => item.sigungu === sigunguOption?.text);
|
||||
}
|
||||
if (yearFilter.시작 != "" && yearFilter.종료 == "") //승인년도검색
|
||||
filterReportData = filterReportData.filter(item => (item.approvalYear)? item.approvalYear >= yearFilter.시작+"년" : null);
|
||||
if (yearFilter.시작 == "" && yearFilter.종료 != "")
|
||||
filterReportData = filterReportData.filter(item => (item.approvalYear)? item.approvalYear <= yearFilter.종료+"년" : null);
|
||||
filterReportData = filterReportData.filter(item => (item.approvalYear) ? item.approvalYear >= yearFilter.시작 + "년" : null);
|
||||
if (yearFilter.시작 == "" && yearFilter.종료 != "")
|
||||
filterReportData = filterReportData.filter(item => (item.approvalYear) ? item.approvalYear <= yearFilter.종료 + "년" : null);
|
||||
if (yearFilter.시작 != "" && yearFilter.종료 != "") {
|
||||
filterReportData = filterReportData.filter(item => {
|
||||
return (item.approvalYear)? item.approvalYear >= yearFilter.시작+"년" && item.approvalYear <= yearFilter.종료+"년": null;
|
||||
return (item.approvalYear) ? item.approvalYear >= yearFilter.시작 + "년" && item.approvalYear <= yearFilter.종료 + "년" : null;
|
||||
});
|
||||
}
|
||||
if (gubun !== "") { // 구분검색
|
||||
filterReportData = filterReportData.filter(item => (item.plantZoneGugun)? String(item.plantZoneGugun).includes(String(gubun)) : null);
|
||||
filterReportData = filterReportData.filter(item => (item.plantZoneGugun) ? String(item.plantZoneGugun).includes(String(gubun)) : null);
|
||||
}
|
||||
console.log('report count:', filterReportData.length);
|
||||
setTableCount(filterReportData.length || 0);
|
||||
filterReportData = filterReportData.slice((curPage-1)*10, curPage*10); // paging
|
||||
filterReportData = filterReportData?.map((item, index)=>({...item, no:(curPage-1)*10+index+1}));
|
||||
filterReportData = filterReportData.slice((curPage - 1) * 10, curPage * 10); // paging
|
||||
filterReportData = filterReportData?.map((item, index) => ({ ...item, no: (curPage - 1) * 10 + index + 1 }));
|
||||
//const fileList = await getDcFile("CLS20250530000041");
|
||||
addFileName(filterReportData).then(data => {
|
||||
filterReportData = data;
|
||||
@@ -378,6 +383,11 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
cqlFilters.push(`fclt_cpct BETWEEN ${시작1} AND ${종료1}`);
|
||||
else if (시작1) cqlFilters.push(`fclt_cpct >= ${시작1}`);
|
||||
else if (종료1) cqlFilters.push(`fclt_cpct <= ${종료1}`);
|
||||
// 처리구역 면적
|
||||
if (시작2 && 종료2)
|
||||
cqlFilters.push(`prcsZoneAreaSum BETWEEN ${시작2} AND ${종료2}`);
|
||||
else if (시작2) cqlFilters.push(`prcsZoneAreaSum >= ${시작2}`);
|
||||
else if (종료2) cqlFilters.push(`prcsZoneAreaSum <= ${종료2}`);
|
||||
// 하수처리시설명
|
||||
if (변수1) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${변수1}%'`);
|
||||
return cqlFilters;
|
||||
@@ -386,8 +396,8 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
// 하수처리구역용 CQL 필터 생성
|
||||
const zoneCqlFilters = () => {
|
||||
const cqlFilters: string[] = [];
|
||||
if (ctpvCd) cqlFilters.push(`ctpv_cd='${ctpvCd}'`);
|
||||
if (sigungu) cqlFilters.push(`sgg_cd='${sigungu}'`);
|
||||
if (시도) cqlFilters.push(`ctpv_cd='${시도}'`);
|
||||
if (시군구) cqlFilters.push(`sgg_cd='${시군구}'`);
|
||||
if (변수1) cqlFilters.push(`swtrmt_zone_nm ILIKE '%${변수1}%'`);
|
||||
if (변수2) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${변수2}%'`);
|
||||
return cqlFilters;
|
||||
@@ -412,8 +422,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
cqlFilters.push(
|
||||
`instl_ymd >= '${startDate}' and instl_ymd <= '${endDate}'`,
|
||||
);
|
||||
// if (변수1) cqlFilters.push(`경과년도='${변수1}'`);
|
||||
if (변수2) cqlFilters.push(`usg_cd='${변수2}'`);
|
||||
if (변수1) cqlFilters.push(`usg_cd='${변수1}'`);
|
||||
// 구경(mm) 범위
|
||||
if (시작1 && 종료1) cqlFilters.push(`swage_mh_diam BETWEEN ${시작1} AND ${종료1}`);
|
||||
else if (시작1) cqlFilters.push(`swage_mh_diam >= ${시작1}`);
|
||||
@@ -447,7 +456,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
cqlFilters.push(`daily_prcs_cpct BETWEEN ${시작1} AND ${종료1}`);
|
||||
else if (시작1) cqlFilters.push(`daily_prcs_cpct >= ${시작1}`);
|
||||
else if (종료1) cqlFilters.push(`daily_prcs_cpct <= ${종료1}`);
|
||||
// 우수양수능력 범위
|
||||
// 양수능력 범위
|
||||
if (시작2 && 종료2)
|
||||
cqlFilters.push(`excln_wpmp_ablt BETWEEN ${시작2} AND ${종료2}`);
|
||||
else if (시작2) cqlFilters.push(`excln_wpmp_ablt >= ${시작2}`);
|
||||
@@ -514,7 +523,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
// 설치년도 범위
|
||||
if (ctpvCd) cqlFilters.push(`ctpv_cd='${ctpvCd}'`);
|
||||
if (sigungu) cqlFilters.push(`sgg_cd='${sigungu}'`);
|
||||
|
||||
|
||||
return cqlFilters;
|
||||
};
|
||||
|
||||
@@ -583,38 +592,32 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
}}
|
||||
/>
|
||||
</div> */}
|
||||
{/* 용도코드 */}
|
||||
<Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
용도코드
|
||||
</Label>
|
||||
<Input
|
||||
className="mr-8 w-[100px] !text-xl placeholder:text-center"
|
||||
placeholder="입력"
|
||||
{/* 용도 */}
|
||||
<SelectBox2
|
||||
className="w-60 mr-8 z-[102]"
|
||||
selectClass="rounded-lg bg-white text-xl"
|
||||
label="용도"
|
||||
selectArray={MS_SWAGE_PPL_USE_CODES}
|
||||
value={변수1}
|
||||
onChange={(e) => {
|
||||
// 숫자만 입력 허용
|
||||
const val = e.target.value.replace(/[^0-9]/g, "");
|
||||
set변수1(val);
|
||||
onSelectValue={(val) => {
|
||||
set변수1(String(val));
|
||||
}}
|
||||
/>
|
||||
{/* 재질코드 */}
|
||||
<Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
재질코드
|
||||
</Label>
|
||||
<Input
|
||||
className="mr-8 w-[100px] !text-xl placeholder:text-center"
|
||||
placeholder="입력"
|
||||
{/* 재질 */}
|
||||
<SelectBox2
|
||||
className="w-60 mr-8 z-[102]"
|
||||
selectClass="rounded-lg bg-white text-xl"
|
||||
label="재질"
|
||||
selectArray={MS_SWAGE_PPL_CODES}
|
||||
value={변수2}
|
||||
onChange={(e) => {
|
||||
// 숫자만 입력 허용
|
||||
const val = e.target.value.replace(/[^0-9]/g, "");
|
||||
set변수2(val);
|
||||
onSelectValue={(val) => {
|
||||
set변수2(String(val));
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center mb-2">
|
||||
{/* 행정읍면동코드 */}
|
||||
<Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
{/* <Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
행정읍면동코드
|
||||
</Label>
|
||||
<Input
|
||||
@@ -626,7 +629,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
const val = e.target.value.replace(/[^0-9]/g, "");
|
||||
set변수3(val);
|
||||
}}
|
||||
/>
|
||||
/> */}
|
||||
{/* 관경 */}
|
||||
<Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
관경(mm)
|
||||
@@ -700,7 +703,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
/>
|
||||
{/* 시설용량 */}
|
||||
<Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
시설용량
|
||||
시설용량(㎥/d)
|
||||
</Label>
|
||||
<Input
|
||||
className="w-[100px] !text-xl placeholder:text-center"
|
||||
@@ -723,6 +726,33 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
set종료1(val);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-2 flex items-center">
|
||||
{/* 처리구역 면적 */}
|
||||
<Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
처리구역 면적(m²)
|
||||
</Label>
|
||||
<Input
|
||||
className="w-[100px] !text-xl placeholder:text-center"
|
||||
placeholder="입력"
|
||||
value={시작2}
|
||||
onChange={(e) => {
|
||||
// 숫자만 입력 허용
|
||||
const val = e.target.value.replace(/[^0-9]/g, "");
|
||||
set시작2(val);
|
||||
}}
|
||||
/>
|
||||
<span className="mx-2 text-xl font-semibold">~</span>
|
||||
<Input
|
||||
className="mr-8 w-[100px] !text-xl placeholder:text-center"
|
||||
placeholder="입력"
|
||||
value={종료2}
|
||||
onChange={(e) => {
|
||||
// 숫자만 입력 허용
|
||||
const val = e.target.value.replace(/[^0-9]/g, "");
|
||||
set종료2(val);
|
||||
}}
|
||||
/>
|
||||
{/* 하수처리시설명 */}
|
||||
<Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
하수처리시설명
|
||||
@@ -743,13 +773,13 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
<div className="mb-3">
|
||||
<div className="mb-2 flex items-center">
|
||||
<SidoSigunguSelectBox
|
||||
sido={ctpvCd}
|
||||
sigungu={sigungu}
|
||||
sido={시도}
|
||||
sigungu={시군구}
|
||||
onSidoChange={(sidoId) => {
|
||||
setCtpvCd(sidoId);
|
||||
setSigungu(0);
|
||||
set시도(sidoId);
|
||||
set시군구(0);
|
||||
}}
|
||||
onSigunguChange={setSigungu}
|
||||
onSigunguChange={set시군구}
|
||||
/>
|
||||
<Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
하수처리구역명
|
||||
@@ -808,18 +838,15 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
setYearFilter({ ...yearFilter, 경과년도: val });
|
||||
}}
|
||||
/> */}
|
||||
{/* 용도코드 */}
|
||||
<Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
용도코드
|
||||
</Label>
|
||||
<Input
|
||||
className="mr-8 w-[100px] !text-xl placeholder:text-center"
|
||||
placeholder="입력"
|
||||
{/* 용도 */}
|
||||
<SelectBox2
|
||||
className="w-60 mr-8 z-[102]"
|
||||
selectClass="rounded-lg bg-white text-xl"
|
||||
label="용도"
|
||||
selectArray={MS_SWAGE_MHL_USE_CODES}
|
||||
value={변수1}
|
||||
onChange={(e) => {
|
||||
// 숫자만 입력 허용
|
||||
const val = e.target.value.replace(/[^0-9]/g, "");
|
||||
set변수1(val);
|
||||
onSelectValue={(val) => {
|
||||
set변수1(String(val));
|
||||
}}
|
||||
/>
|
||||
{/* 하수맨홀 구경 */}
|
||||
@@ -876,7 +903,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
/> */}
|
||||
{/* 일일처리용량 - 오수맨홀 */}
|
||||
<Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
일일처리용량
|
||||
일일처리용량(㎥)
|
||||
</Label>
|
||||
<Input
|
||||
className="w-[100px] !text-xl placeholder:text-center"
|
||||
@@ -899,9 +926,9 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
set종료1(val);
|
||||
}}
|
||||
/>
|
||||
{/* 우수양수능력 - 우수맨홀 */}
|
||||
{/* 양수능력 - 우수맨홀 */}
|
||||
<Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
우수양수능력
|
||||
양수능력(m²/d)
|
||||
</Label>
|
||||
<Input
|
||||
className="w-[100px] !text-xl placeholder:text-center"
|
||||
@@ -1058,21 +1085,21 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
{/* 시도, 시군구, 하수처리구역 한 줄 */}
|
||||
<div className="mb-6 flex items-center">
|
||||
<SelectBox2
|
||||
className="w-[150px] mr-8"
|
||||
selectClass="rounded-lg bg-white"
|
||||
label="시도"
|
||||
selectArray={sidos}
|
||||
value={ctpvCd}
|
||||
onSelectValue={handleCtpvCdChange}
|
||||
/>
|
||||
<SelectBox2
|
||||
className="w-48"
|
||||
selectClass="w-48 rounded-lg bg-white truncate"
|
||||
label="시군구"
|
||||
selectArray={filteredSiguns}
|
||||
value={sigungu}
|
||||
onSelectValue={val => setSigungu(String(val))}
|
||||
/>
|
||||
className="w-[150px] mr-8"
|
||||
selectClass="rounded-lg bg-white"
|
||||
label="시도"
|
||||
selectArray={sidos}
|
||||
value={ctpvCd}
|
||||
onSelectValue={handleCtpvCdChange}
|
||||
/>
|
||||
<SelectBox2
|
||||
className="w-48"
|
||||
selectClass="w-48 rounded-lg bg-white truncate"
|
||||
label="시군구"
|
||||
selectArray={filteredSiguns}
|
||||
value={sigungu}
|
||||
onSelectValue={val => setSigungu(String(val))}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div className="flex items-center gap-4">
|
||||
@@ -1095,7 +1122,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
endLabel=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
{/* 조회 버튼 중앙 정렬 */}
|
||||
<div className="absolute bottom-4 right-4 mr-2">
|
||||
<Button className="text-base py-2" onClick={handleSearch}>조회</Button>
|
||||
@@ -1133,7 +1160,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
pageSize={tableData.length < 10 ? tableData.length : 10}
|
||||
total={tableCount}
|
||||
children={undefined}
|
||||
cellClick={(activeTab!=='report')?handleCellClick:handleReportCellClick}
|
||||
cellClick={(activeTab !== 'report') ? handleCellClick : handleReportCellClick}
|
||||
onPageChange={setCurPage}
|
||||
resetPageNo={false}
|
||||
cur={curPage}
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
import { MS_SWAGE_PPL_USE_CODES, MS_SWAGE_PPL_CODES, MS_SWAGE_MHL_CODES, MS_SWAGE_MHL_USE_CODES, DRTW_SEWAGE_PUMP_USE_CODES } from './table';
|
||||
|
||||
interface CodeMapperProps {
|
||||
layerName: string;
|
||||
data: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 레이어별 코드 변환 함수
|
||||
* @param layerName - 레이어 이름
|
||||
* @param data - 변환할 데이터 객체
|
||||
* @returns 변환된 데이터 객체
|
||||
*/
|
||||
export const codeMapper = ({ layerName, data }: CodeMapperProps): any => {
|
||||
if (!data) return data;
|
||||
|
||||
const processedData = { ...data };
|
||||
|
||||
switch (layerName) {
|
||||
case '하수관로':
|
||||
// usg_cd 값 변환 (용도코드)
|
||||
if (processedData.usg_cd) {
|
||||
const usageCodeItem = MS_SWAGE_PPL_USE_CODES.find(
|
||||
code => code.val === processedData.usg_cd.trim()
|
||||
);
|
||||
if (usageCodeItem) {
|
||||
processedData.usg_cd = usageCodeItem.text;
|
||||
}
|
||||
}
|
||||
|
||||
// mqlt_cd 값 변환 (재질코드)
|
||||
if (processedData.mqlt_cd) {
|
||||
const materialCodeItem = MS_SWAGE_PPL_CODES.find(
|
||||
code => code.val === processedData.mqlt_cd.trim()
|
||||
);
|
||||
if (materialCodeItem) {
|
||||
processedData.mqlt_cd = materialCodeItem.text;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '하수맨홀':
|
||||
// usg_cd 값 변환 (용도코드)
|
||||
if (processedData.usg_cd) {
|
||||
const usageCodeItem = MS_SWAGE_MHL_USE_CODES.find(
|
||||
code => code.val === processedData.usg_cd.trim()
|
||||
);
|
||||
if (usageCodeItem) {
|
||||
processedData.usg_cd = usageCodeItem.text;
|
||||
}
|
||||
}
|
||||
|
||||
// mqlt_cd 값 변환 (재질코드)
|
||||
if (processedData.mqlt_cd) {
|
||||
const materialCodeItem = MS_SWAGE_MHL_CODES.find(
|
||||
code => code.val === processedData.mqlt_cd.trim()
|
||||
);
|
||||
if (materialCodeItem) {
|
||||
processedData.mqlt_cd = materialCodeItem.text;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '하수펌프장':
|
||||
// usg_cd 값 변환 (용도코드)
|
||||
if (processedData.usg_cd) {
|
||||
const usageCodeItem = DRTW_SEWAGE_PUMP_USE_CODES.find(
|
||||
code => code.val === processedData.usg_cd.trim()
|
||||
);
|
||||
if (usageCodeItem) {
|
||||
processedData.usg_cd = usageCodeItem.text;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '우수토실':
|
||||
// prrtymngYn 값 변환 (중점여부)
|
||||
if (processedData.prrtymngYn) {
|
||||
if (processedData.prrtymngYn === 'Y') {
|
||||
processedData.prrtymngYn = '중점우수토실';
|
||||
} else if (processedData.prrtymngYn === 'N') {
|
||||
processedData.prrtymngYn = '우수토실';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '중점우수토실':
|
||||
if (processedData.manage_no) {
|
||||
processedData.mqlt_cd = processedData.manage_no;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// 다른 레이어는 변환하지 않음
|
||||
break;
|
||||
}
|
||||
|
||||
return processedData;
|
||||
};
|
||||
|
||||
/**
|
||||
* 저장 시 코드 역변환 함수 (한글 → 코드)
|
||||
* @param layerName - 레이어 이름
|
||||
* @param data - 역변환할 데이터 객체
|
||||
* @returns 역변환된 데이터 객체
|
||||
*/
|
||||
export const reverseCodeMapper = ({ layerName, data }: CodeMapperProps): any => {
|
||||
if (!data) return data;
|
||||
|
||||
const processedData = { ...data };
|
||||
|
||||
switch (layerName) {
|
||||
case '하수맨홀':
|
||||
// mqlt_cd 값 역변환 (텍스트 → 코드)
|
||||
if (processedData.mqlt_cd && typeof processedData.mqlt_cd === 'string') {
|
||||
const materialCodeItem = MS_SWAGE_MHL_CODES.find(
|
||||
code => code.text === processedData.mqlt_cd.trim()
|
||||
);
|
||||
if (materialCodeItem) {
|
||||
processedData.mqlt_cd = materialCodeItem.val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '우수토실':
|
||||
// prrtymngYn 값 역변환 (텍스트 → Y/N)
|
||||
if (processedData.prrtymngYn) {
|
||||
if (processedData.prrtymngYn === '중점우수토실') {
|
||||
processedData.prrtymngYn = 'Y';
|
||||
} else if (processedData.prrtymngYn === '우수토실') {
|
||||
processedData.prrtymngYn = 'N';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '하수펌프장':
|
||||
// usg_cd 값 역변환 (텍스트 → 코드)
|
||||
if (processedData.usg_cd && typeof processedData.usg_cd === 'string') {
|
||||
const usageCodeItem = DRTW_SEWAGE_PUMP_USE_CODES.find(
|
||||
code => code.text === processedData.usg_cd.trim()
|
||||
);
|
||||
if (usageCodeItem) {
|
||||
processedData.usg_cd = usageCodeItem.val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return processedData;
|
||||
};
|
||||
|
||||
// 기본 내보내기
|
||||
export default { codeMapper, reverseCodeMapper };
|
||||
@@ -6,8 +6,8 @@ export const MsSwagePplCol = [
|
||||
{ id: 'mapsht_no', title: '도엽번호' },
|
||||
{ id: 'pdmt', title: '관경(mm)' },
|
||||
{ id: 'prlg', title: '연장(m)' },
|
||||
{ id: 'usg_cd', title: '용도코드' },
|
||||
{ id: 'mqlt_cd', title: '재질코드' },
|
||||
{ id: 'usg_cd', title: '용도' },
|
||||
{ id: 'mqlt_cd', title: '재질' },
|
||||
{ id: 'avg_grdn', title: '평균구배(m/m)' },
|
||||
{ id: 'drtw_mltv_area', title: '오수배수면적(m²)' },
|
||||
{ id: 'excln_mltv_area', title: '우수배수면적(m²)' },
|
||||
@@ -63,7 +63,6 @@ export const MS_SWAGE_PPL_USE_CODES = [
|
||||
{ val: "SBA003", text: "우수관" },
|
||||
{ val: "SBA004", text: "오수관" },
|
||||
{ val: "SBA999", text: "기타" },
|
||||
{ val: "그 외", text: "미분류" },
|
||||
];
|
||||
// 하수관로 재질 코드표
|
||||
export const MS_SWAGE_PPL_CODES = [
|
||||
@@ -260,7 +259,6 @@ export const MS_SWAGE_PPL_CODES = [
|
||||
{ val: "MOP948", text: "PE다중벽관" },
|
||||
{ val: "MOP977", text: "전주용입상관" },
|
||||
{ val: "MOP978", text: "MD관" },
|
||||
{ val: "그 외", text: "미분류" },
|
||||
];
|
||||
|
||||
// 하수처리시설
|
||||
@@ -378,7 +376,7 @@ export const MsSwageMhlCol = [
|
||||
// { id: 'fclty_shp_cd', title: '시설물형태코드' },
|
||||
// { id: 'mhl_knd_cd', title: '맨홀종류코드' },
|
||||
{ id: 'swage_mh_diam', title: '하수맨홀구경(mm)' },
|
||||
{ id: 'mqlt_cd', title: '재질코드' },
|
||||
{ id: 'mqlt_cd', title: '재질' },
|
||||
{ id: 'wdth_len', title: '가로길이(m)' },
|
||||
{ id: 'vrtc_len', title: '세로길이(m)' },
|
||||
// { id: 'ang_dir', title: '표고' },
|
||||
@@ -563,13 +561,12 @@ export const DRTW_SEWAGE_PUMP_USE_CODES = [
|
||||
{ val: "SBE900", text: "오수배제" },
|
||||
{ val: "SBE901", text: "우수배제" },
|
||||
{ val: "SBE999", text: "기타" },
|
||||
{ val: "그 외", text: "미분류" },
|
||||
];
|
||||
|
||||
// 우수토실
|
||||
export const stofcbrCol = [
|
||||
// { id: 'ftre_smbol_cd', title: '지형지물부호코드' },
|
||||
{ id: 'pbadms_emd_cd', title: '시설관리번호' },
|
||||
{ id: 'fclt_mng_no', title: '시설관리번호' },
|
||||
// { id: 'pbadms_emd_cd', title: '행정읍면동코드' },
|
||||
{ id: 'mapsht_no', title: '도엽번호' },
|
||||
// { id: 'mng_inst_cd', title: '관리기관코드' },
|
||||
|
||||
@@ -60,12 +60,11 @@ const MsSwagePpl = ({ featureData, onSaveClick }: { featureData: any, onSaveClic
|
||||
return (
|
||||
<>
|
||||
<VerticalTable
|
||||
headName='자체 입력정보'
|
||||
headName='입력정보'
|
||||
tableData={featureData ? [formData] : []}
|
||||
headlist={inputColumn}
|
||||
pageSize={20}
|
||||
total={0}
|
||||
children={undefined}
|
||||
cellClick={undefined}
|
||||
isEditable={true}
|
||||
onPageChange={function (page: number): void {
|
||||
|
||||
@@ -184,7 +184,7 @@ const Ssc = ({ featureData, isMainSsc, rainMeasureData, onSaveClick }: {
|
||||
<div>
|
||||
{!isMainSsc && (
|
||||
<VerticalTable
|
||||
headName='자체 입력정보'
|
||||
headName='입력정보'
|
||||
tableData={featureData ? [formData] : []}
|
||||
headlist={inputColumn}
|
||||
pageSize={0}
|
||||
|
||||
@@ -38,7 +38,7 @@ const sewagePump = ({ featureData, isDrtwSewagePump, onSaveClick }: { featureDat
|
||||
|
||||
return (
|
||||
<VerticalTable
|
||||
headName='자체 입력정보'
|
||||
headName='입력정보'
|
||||
tableData={featureData ? [formData] : []}
|
||||
headlist={isDrtwSewagePump ? drtwInputColumn : exclnInputColumn}
|
||||
pageSize={0}
|
||||
|
||||
@@ -32,7 +32,7 @@ const Smh = ({ featureData, onSaveClick }: { featureData: any, onSaveClick?: ()
|
||||
|
||||
return (
|
||||
<VerticalTable
|
||||
headName='자체 입력정보'
|
||||
headName='입력정보'
|
||||
tableData={featureData ? [formData] : []}
|
||||
headlist={inputColumn}
|
||||
pageSize={20}
|
||||
|
||||
@@ -10,7 +10,7 @@ const StormWaterPump = ({ featureData }: { featureData: Record<string, any> }) =
|
||||
const filteredData = featureData && Object.entries(featureData).filter(([key]) => validKey.includes(key)).reduce((obj: Record<string, any>, [key, value]) => { obj[key] = value; return obj; }, {});
|
||||
return (
|
||||
<VerticalTable
|
||||
headName='자체 입력정보'
|
||||
headName='입력정보'
|
||||
tableData={[filteredData]}
|
||||
headlist={inputColumn}
|
||||
pageSize={0}
|
||||
|
||||
@@ -11,18 +11,20 @@ import InfilChart from './components/popupComponent/chart/infilChart';
|
||||
import RdiiChart from './components/popupComponent/chart/rdiiChart';
|
||||
import { useInfilChartModalStore, useRdiiChartModalStore } from "./components/popupComponent/chartModalStore";
|
||||
import { formatDisplayData } from '@/components/lib/utils/formatDisplayValue';
|
||||
import { codeMapper } from "./components/common/codeMapper";
|
||||
|
||||
|
||||
// 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 [layerNm, setLayerNm] = useState<string>(""); // 레이어 이름 상태
|
||||
const [layerSpecificNm, setLayerSpecificNm] = useState<string>(""); // 레이어 이름 상태
|
||||
const [tableData, setTableData] = useState<any>(null); // 피처 데이터
|
||||
const [rainMeasureData, setRainMeasureData] = useState<any[]>([]); // 강우/측정 측정 정보
|
||||
const [headlist, setHeadlist] = useState<{ id: string; title: string; }[]>([]); // 컬럼리스트 변경상태
|
||||
const [headlist2, setHeadlist2] = useState<{ id: string; title: string; }[]>([]); // 컬럼리스트 변경상태
|
||||
const [buttonChk, setButtonChk] = useState(true)
|
||||
const [fetchData, setfetchData] = useState<any>(); // api 호출여부
|
||||
const [fetchData, setFetchData] = useState<any>(); // api 호출여부
|
||||
const contentRef = useRef<HTMLDivElement>(null);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false); // 모달 열기 상태
|
||||
const [isMainSsc, setIsMainSsc] = useState(false); // 중점우수토실 여부
|
||||
@@ -55,7 +57,7 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
const getSelectedLayers = () => {
|
||||
let result = null;
|
||||
const layers = gisMap.getLayers().getArray(); // gisMap에서 모든 레이어 가져오기
|
||||
let featureLayer: { get: (key: string) => any }; // 피처가 속한 레이어를 찾기 위한 변수
|
||||
let featureLayer: { get: (key: string) => any } = { get: (key: string) => null }; // 피처가 속한 레이어를 찾기 위한 변수
|
||||
layers.forEach((layer: any) => {
|
||||
const source = layer.getSource();
|
||||
if (source && source.hasFeature && featureData
|
||||
@@ -133,10 +135,48 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
// 🎯 기본 데이터 포맷팅
|
||||
const formattedData = formatDisplayData(data);
|
||||
|
||||
setfetchData(formattedData);
|
||||
if (featureData.values_.fclt_mng_no) setLayerSpecificNm(featureData.values_.fclt_mng_no);
|
||||
else if (featureData.values_.swtrmt_fclt_cd) setLayerSpecificNm(featureData.values_.swtrmt_fclt_cd);
|
||||
else setLayerSpecificNm(featureData.values_.manage_no);
|
||||
setFetchData(formattedData);
|
||||
setTableData(formattedData);
|
||||
|
||||
switch (selectedLayerName) {
|
||||
case '하수관로':
|
||||
setHeadlist(MsSwagePplCol)
|
||||
setButtonChk(true)
|
||||
|
||||
// ✅ codeMapper 사용하여 API 결과도 변환
|
||||
setTableData(codeMapper({
|
||||
layerName: selectedLayerName,
|
||||
data: { ...formattedData }
|
||||
}));
|
||||
// setFetchData(mappedData);
|
||||
// setTableData(mappedData);
|
||||
break;
|
||||
case '하수맨홀':
|
||||
setHeadlist(MsSwageMhlCol)
|
||||
setButtonChk(true)
|
||||
|
||||
// ✅ codeMapper 사용하여 API 결과도 변환
|
||||
setTableData(codeMapper({
|
||||
layerName: selectedLayerName,
|
||||
data: { ...formattedData }
|
||||
}));
|
||||
// setFetchData(mappedData);
|
||||
// setTableData(mappedData);
|
||||
break;
|
||||
case '하수펌프장':
|
||||
setHeadlist(ExclnSewagePumpCol)
|
||||
setButtonChk(true)
|
||||
|
||||
setTableData(codeMapper({
|
||||
layerName: selectedLayerName,
|
||||
data: { ...formattedData }
|
||||
}));
|
||||
// setFetchData(mappedData);
|
||||
// setTableData(mappedData);
|
||||
break;
|
||||
case '하수처리시설':
|
||||
setHeadlist(SwtrmtFcltCol);
|
||||
setButtonChk(false)
|
||||
@@ -145,6 +185,11 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
setHeadlist(SwtrmtPrcsZoneCol)
|
||||
setButtonChk(false)
|
||||
break;
|
||||
case '우수토실':
|
||||
setHeadlist(stofcbrCol)
|
||||
setButtonChk(true)
|
||||
setIsMainSsc(false)
|
||||
break;
|
||||
case '중점우수토실':
|
||||
setHeadlist(untrtSwgRainCol1)
|
||||
setHeadlist2(untrtSwgRainCol2)
|
||||
@@ -153,51 +198,33 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
// 🎯 processedData도 포맷팅하여 설정
|
||||
const processedFormattedData = formatDisplayData(processedData);
|
||||
|
||||
setfetchData([processedFormattedData])
|
||||
setFetchData([processedFormattedData])
|
||||
setTableData(processedFormattedData);
|
||||
// setIsLoading(false); // 기본 렌더링 완료
|
||||
|
||||
setTableData(codeMapper({
|
||||
layerName: selectedLayerName,
|
||||
data: { ...processedFormattedData }
|
||||
}));
|
||||
|
||||
// 강우/측정 정보 데이터 호출
|
||||
if (data?.chmbr_xcnts && data?.chmbr_ydnts) {
|
||||
fetchRainMeasureData(data.chmbr_xcnts, data.chmbr_ydnts)
|
||||
if (tableData?.chmbr_xcnts && tableData?.chmbr_ydnts) {
|
||||
fetchRainMeasureData(tableData.chmbr_xcnts, tableData.chmbr_ydnts)
|
||||
.then(response => {
|
||||
console.log('additionalResponse', response);
|
||||
setRainMeasureData(response || []);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('추가 데이터 로딩 실패:', error);
|
||||
setRainMeasureData(false);
|
||||
setRainMeasureData([]);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case '우수토실':
|
||||
setHeadlist(stofcbrCol)
|
||||
setButtonChk(true)
|
||||
setIsMainSsc(false)
|
||||
break;
|
||||
case '하수관로':
|
||||
setHeadlist(MsSwagePplCol)
|
||||
setButtonChk(true)
|
||||
break;
|
||||
// case '오수펌프':
|
||||
// setButtonChk(true)
|
||||
// break;
|
||||
// case '빗물펌프':
|
||||
// setButtonChk(true)
|
||||
// break;
|
||||
case '하수펌프장':
|
||||
setHeadlist(ExclnSewagePumpCol)
|
||||
setButtonChk(true)
|
||||
break;
|
||||
case '하수맨홀':
|
||||
setHeadlist(MsSwageMhlCol)
|
||||
setButtonChk(true)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// API 엔드포인트 선택
|
||||
// 자체입력정보 API 엔드포인트 선택
|
||||
let apiEndpoint = '';
|
||||
const getFeatureId = featureId.toString().split('.').pop() || null;
|
||||
if (selectedLayerName === '하수관로') apiEndpoint = `v1/fcltppl/${getFeatureId}`;
|
||||
@@ -214,35 +241,13 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
if (result) {
|
||||
console.log('API 데이터 로드 성공:', result);
|
||||
|
||||
// 하수맨홀인 경우 용도코드를 텍스트로 변환
|
||||
if (selectedLayerName === '하수맨홀') {
|
||||
const processedData = { ...result };
|
||||
// ✅ codeMapper 사용하여 API 결과도 변환
|
||||
const processedApiData = codeMapper({
|
||||
layerName: selectedLayerName,
|
||||
data: { ...result, ...tableData }
|
||||
});
|
||||
|
||||
// mqlt_cd 값 변환 (재질코드)
|
||||
if (processedData.mqlt_cd) {
|
||||
const materialCodeItem = MS_SWAGE_MHL_CODES.find(
|
||||
code => code.val === processedData.mqlt_cd.trim()
|
||||
);
|
||||
if (materialCodeItem) {
|
||||
processedData.mqlt_cd = `${materialCodeItem.text}`;
|
||||
}
|
||||
}
|
||||
|
||||
setfetchData(processedData);
|
||||
} // 🎯 우수토실인 경우 prrtymngYn 값 변환
|
||||
else if (selectedLayerName === '우수토실' && data) {
|
||||
const processedData = { ...result, ...data };
|
||||
|
||||
// prrtymngYn 값 변환
|
||||
if (processedData.prrtymngYn === 'Y') processedData.prrtymngYn = '중점우수토실';
|
||||
else if (processedData.prrtymngYn === 'N') processedData.prrtymngYn = '우수토실';
|
||||
|
||||
console.log('processedData', processedData);
|
||||
|
||||
setfetchData(processedData);
|
||||
} else {
|
||||
setfetchData(result);
|
||||
}
|
||||
setFetchData(processedApiData);
|
||||
}
|
||||
} catch (apiError) {
|
||||
console.error('API 데이터 로딩 중 오류:', apiError);
|
||||
@@ -256,7 +261,7 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
fetchData();
|
||||
}, [featureId, processedData]);
|
||||
|
||||
// 🎯 추가 데이터 API 호출 함수 (독립적으로 실행)
|
||||
// 🎯 추가 데이터 API 호출 함수
|
||||
const fetchRainMeasureData = useCallback(async (chmbrXcnts: string, chmbrYdnts: string) => {
|
||||
if (!chmbrXcnts || !chmbrYdnts) {
|
||||
console.warn('추가 데이터 호출 실패: 필수 매개변수 누락', { chmbrXcnts, chmbrYdnts });
|
||||
@@ -320,7 +325,7 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('추가 데이터 최종 로딩 실패:', error);
|
||||
setRainMeasureData(false);
|
||||
setRainMeasureData([]);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -394,7 +399,7 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
|
||||
if (result) {
|
||||
alert('저장되었습니다');
|
||||
setfetchData(result.data || result);
|
||||
setFetchData(result.data || result);
|
||||
} else {
|
||||
alert('저장에 실패했습니다');
|
||||
console.error('API 응답 오류:', result);
|
||||
@@ -413,8 +418,13 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
<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 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> */}
|
||||
<h3 className="text-2xl font-medium text-white text-label whitespace-nowrap mr-4">{layerNm}
|
||||
{tableData?.usg_cd && (
|
||||
<>
|
||||
({tableData.usg_cd})
|
||||
</>
|
||||
)} 정보 <br />관리번호 : {layerSpecificNm}
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-3">
|
||||
@@ -437,7 +447,7 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
)}
|
||||
<Button
|
||||
onClick={onClose}
|
||||
className="text-white hover:text-gray-300 focus:outline-none ml-2"
|
||||
className="text-white hover:text-gray-300 focus:outline-none"
|
||||
>
|
||||
✕
|
||||
</Button>
|
||||
|
||||
@@ -13,6 +13,12 @@ import { excelToFlowRateData, excelToMatchingResultData, excelToTimePatternData
|
||||
import BaseLayout from '../BaseLayout'
|
||||
import { validateMultipleFiles, FILE_EXTENSIONS, type FileValidationConfig } from '../../fileValidation';
|
||||
import { validateBasicSelectionsWithAlert } from '../../selectionValidation';
|
||||
import { tokenManager } from '@/entities/auth/lib/token-manager';
|
||||
import { AUTH_USER_ID } from "@/shared/config";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { ENDPOINT } from "@common/components/config";
|
||||
import { getUserInfo } from "@common/components/api";
|
||||
|
||||
|
||||
const formSchema = z.object({
|
||||
managenm: z.string(),
|
||||
@@ -41,6 +47,22 @@ interface ApiSelectOption {
|
||||
}
|
||||
|
||||
const IrSetting = () => {
|
||||
const [input1, setInput1] = useState('');
|
||||
const [input2, setInput2] = useState('');
|
||||
const [select1, setSelect1] = useState('0'); // 환경청코드
|
||||
const [select2, setSelect2] = useState('0'); // 시도코드
|
||||
const [select3, setSelect3] = useState<ApiSelectOption>({ val: '0', text: '전체' }); // 시군구 상태를 객체로 변경
|
||||
const [select4, setSelect4] = useState<string | number>('0'); // 하수처리장코드
|
||||
const [select5, setSelect5] = useState<string | number>('0'); // 하수처리구역코드
|
||||
const [formResetKey, setFormResetKey] = useState(0); // FileUploadForm 리셋을 위한 key 상태
|
||||
const [isLoadingResult, setIsLoadingResult] = useState<boolean>(false); // 로딩 상태
|
||||
|
||||
const { data: userInfo } = useQuery({
|
||||
queryKey: [ENDPOINT.USER_SERVICE.USERS],
|
||||
queryFn: () => getUserInfo(),
|
||||
enabled: true,
|
||||
});
|
||||
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
@@ -68,15 +90,6 @@ const IrSetting = () => {
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
return `${year}${month}`;
|
||||
});
|
||||
const [input1, setInput1] = useState('');
|
||||
const [input2, setInput2] = useState('');
|
||||
const [select1, setSelect1] = useState('0'); // 환경청코드
|
||||
const [select2, setSelect2] = useState('0'); // 시도코드
|
||||
const [select3, setSelect3] = useState<ApiSelectOption>({ val: '0', text: '전체' }); // 시군구 상태를 객체로 변경
|
||||
const [select4, setSelect4] = useState<string | number>('0'); // 하수처리장코드
|
||||
const [select5, setSelect5] = useState<string | number>('0'); // 하수처리구역코드
|
||||
const [formResetKey, setFormResetKey] = useState(0); // FileUploadForm 리셋을 위한 key 상태
|
||||
const [isLoadingResult, setIsLoadingResult] = useState<boolean>(false); // 로딩 상태
|
||||
|
||||
// 폼 초기화 함수
|
||||
const resetAllForms = () => {
|
||||
@@ -298,6 +311,8 @@ const IrSetting = () => {
|
||||
aplcnYm: selectedDate, // 적용연월
|
||||
drtwSwtcRt: parseFloat(input1) || null, // 오수전환율 (숫자로 변환)
|
||||
anlsInfo: input2, // 분석정보
|
||||
rgtr: tokenManager.getToken(AUTH_USER_ID) || null, // 등록자 (사용자 ID)
|
||||
rgtrNm: userInfo?.userName, // 등록자 (사용자 ID)
|
||||
atflCd: file1?.atflCd, // 첨부파일CD (오수관망도)
|
||||
atflId: file1?.atflId, // 첨부파일ID (오수관망도)
|
||||
atflInpNm: file1?.file?.name, // 오수관망도 파일명
|
||||
|
||||
@@ -15,6 +15,11 @@ import { excelToMatchingResultData, excelToRainData } from '@/components/lib/uti
|
||||
import { EditableFormTable, type EditableTableHeadItem } from '../../../components/ui/EditableFormTable'
|
||||
import { validateMultipleFiles, FILE_EXTENSIONS, type FileValidationConfig } from '../../fileValidation';
|
||||
import { validateBasicSelectionsWithAlert } from '../../selectionValidation';
|
||||
import { tokenManager } from '@/entities/auth/lib/token-manager';
|
||||
import { AUTH_USER_ID } from "@/shared/config";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { ENDPOINT } from "@common/components/config";
|
||||
import { getUserInfo } from "@common/components/api";
|
||||
|
||||
|
||||
// zod 스키마 정의
|
||||
@@ -115,6 +120,12 @@ export default function RTKForm() {
|
||||
const [select4, setSelect4] = useState<string | number>('0'); // 하수처리장 (swageTmplntCd)
|
||||
const [select5, setSelect5] = useState<string | number>('0'); // 하수처리구역 (swtrmtZoneCd)
|
||||
|
||||
const { data: userInfo } = useQuery({
|
||||
queryKey: [ENDPOINT.USER_SERVICE.USERS],
|
||||
queryFn: () => getUserInfo(),
|
||||
enabled: true,
|
||||
});
|
||||
|
||||
// form 인스턴스 생성
|
||||
const form = useForm<FormSchemaType>({
|
||||
resolver: zodResolver(formSchema),
|
||||
@@ -328,6 +339,8 @@ export default function RTKForm() {
|
||||
|
||||
drtwSwtcRt: parseFloat(formData.rate || "0"), // 오수전환율
|
||||
anlsInfo: formData.analysisInfo, // 분석정보
|
||||
rgtr: tokenManager.getToken(AUTH_USER_ID) || null, // 등록자 (사용자 ID)
|
||||
rgtrNm: userInfo?.userName, // 등록자 (사용자 ID)
|
||||
|
||||
tbSnRcptrMhlMpng: matchingResultData, // 수용가-맨홀 매칭결과
|
||||
tbSnRainData: rainData, // 강우자료
|
||||
|
||||
@@ -92,6 +92,8 @@ const Result = () => {
|
||||
|
||||
const handleSearchButtonClick = async (customFormValues?: Partial<ResultFormValues>) => {
|
||||
setIsLoadingResult(true);
|
||||
setResetSelection(true);
|
||||
|
||||
const formValues = customFormValues || form.getValues(); // react-hook-form에서 현재 값 가져오기
|
||||
console.log("formValues", formValues);
|
||||
|
||||
@@ -156,8 +158,10 @@ const Result = () => {
|
||||
};
|
||||
});
|
||||
|
||||
// setTableData(data.content || []);
|
||||
// setTotalData(tableData.length);
|
||||
// 선택된 행 초기화
|
||||
setSelectedRowData(null);
|
||||
setSelectedRowIndex(undefined);
|
||||
|
||||
setTableData(dataWithRowNumber);
|
||||
setTotalData(dataWithRowNumber.length);
|
||||
console.log("response:", data);
|
||||
@@ -170,6 +174,7 @@ const Result = () => {
|
||||
setTableData([]);
|
||||
setTotalData(0);
|
||||
}
|
||||
setResetSelection(false);
|
||||
};
|
||||
|
||||
// 테이블 셀 클릭 핸들러 추가
|
||||
@@ -264,9 +269,6 @@ const Result = () => {
|
||||
};
|
||||
await handleSearchButtonClick(customFormValues);
|
||||
|
||||
// 선택된 행 초기화
|
||||
setSelectedRowData(null);
|
||||
setSelectedRowIndex(undefined);
|
||||
setIsLoadingResult(false);
|
||||
|
||||
alert('삭제가 완료되었습니다.');
|
||||
|
||||
@@ -83,12 +83,13 @@ const Result = () => {
|
||||
const [resetSelection, setResetSelection] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
// setCurPage(1);
|
||||
handleSearchButtonClick();
|
||||
}, [])
|
||||
// setCurPage(1);
|
||||
handleSearchButtonClick();
|
||||
}, [])
|
||||
|
||||
const handleSearchButtonClick = async (customFormValues?: Partial<ResultFormValues>) => {
|
||||
setIsLoadingResult(true);
|
||||
setResetSelection(true);
|
||||
const formValues = customFormValues || form.getValues(); // react-hook-form에서 현재 값 가져오기
|
||||
console.log("formValues", formValues);
|
||||
|
||||
@@ -154,8 +155,11 @@ const Result = () => {
|
||||
scsYn: item.scsYn === null || item.scsYn === undefined ? 'N' : item.scsYn // scsYn이 null이면 'N'으로 변경
|
||||
};
|
||||
});
|
||||
// setTableData(data.content || []);
|
||||
// setTotalData(tableData.length);
|
||||
|
||||
// 선택된 행 초기화
|
||||
setSelectedRowData(null);
|
||||
setSelectedRowIndex(undefined);
|
||||
|
||||
setTableData(dataWithRowNumber);
|
||||
setTotalData(dataWithRowNumber.length);
|
||||
console.log("response:", data);
|
||||
@@ -167,7 +171,10 @@ const Result = () => {
|
||||
alert("분석결과 조회 중 오류가 발생했습니다.");
|
||||
setTableData([]);
|
||||
setTotalData(0);
|
||||
setSelectedRowData(null);
|
||||
setSelectedRowIndex(undefined);
|
||||
}
|
||||
setResetSelection(false);
|
||||
};
|
||||
|
||||
// 테이블 셀 클릭 핸들러 추가
|
||||
@@ -265,16 +272,11 @@ const Result = () => {
|
||||
};
|
||||
await handleSearchButtonClick(customFormValues);
|
||||
|
||||
// 선택된 행 초기화
|
||||
setSelectedRowData(null);
|
||||
setSelectedRowIndex(undefined);
|
||||
setIsLoadingResult(false);
|
||||
|
||||
alert('삭제가 완료되었습니다.');
|
||||
|
||||
setTimeout(() => {
|
||||
setResetSelection(false);
|
||||
}, 100);
|
||||
setResetSelection(false);
|
||||
} catch (error) {
|
||||
setIsLoadingResult(false);
|
||||
console.error("분석결과 파일 삭제 중 오류 발생:", error);
|
||||
@@ -282,7 +284,7 @@ const Result = () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<BaseLayout
|
||||
|
||||
@@ -26,10 +26,12 @@ const Page = () => {
|
||||
const [totalData, setTotalData] = useState(0) //총 데이터 수
|
||||
const [isLoading, setIsLoading] = useState(true) //로딩 상태
|
||||
const [isModalOpen, setIsModalOpen] = useState(false) // 모달 상태
|
||||
const [resetSelection, setResetSelection] = useState<boolean>(false); // 선택 초기화 상태
|
||||
|
||||
// 조회
|
||||
const fetchData = async () => {
|
||||
setIsLoading(true)
|
||||
setResetSelection(true);
|
||||
// searchCmmnCd('SITEKNDCD')
|
||||
try {
|
||||
const { data, total } = await searchData('v1/sbmrgPrevnt', {
|
||||
@@ -54,6 +56,7 @@ const Page = () => {
|
||||
setAtflId('');
|
||||
setSbmrgPrevntBizSn('');
|
||||
setIsLoading(false);
|
||||
setResetSelection(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +88,9 @@ const Page = () => {
|
||||
fetchData()
|
||||
}
|
||||
}
|
||||
else {
|
||||
alert('삭제에 실패했습니다.')
|
||||
}
|
||||
}
|
||||
|
||||
// 현황 등록
|
||||
@@ -97,8 +103,8 @@ const Page = () => {
|
||||
atflId: id,
|
||||
sbmrgPrevntBizNm: fileName
|
||||
})
|
||||
if (data) {
|
||||
alert('파일이 등록되었습니다.');
|
||||
if (data) {
|
||||
alert('파일이 등록되었습니다.');
|
||||
setIsModalOpen(false);
|
||||
fetchData();
|
||||
}
|
||||
@@ -183,6 +189,7 @@ const Page = () => {
|
||||
}
|
||||
}}
|
||||
onPageChange={async (page: number) => { setCurPage(page); await fetchData() }}
|
||||
resetSelection={resetSelection}
|
||||
/>
|
||||
</ListDiv>
|
||||
{/* 파일 업로드 모달 */}
|
||||
|
||||
@@ -24,10 +24,12 @@ const Page = () => {
|
||||
const [totalData, setTotalData] = useState(0) //총 데이터 수
|
||||
const [isLoading, setIsLoading] = useState(true) //로딩 상태
|
||||
const [isModalOpen, setIsModalOpen] = useState(false) // 모달 상태
|
||||
const [resetSelection, setResetSelection] = useState<boolean>(false); // 선택 초기화 상태
|
||||
|
||||
// 데이터 조회
|
||||
const fetchData = async () => {
|
||||
setIsLoading(true)
|
||||
setResetSelection(true);
|
||||
try {
|
||||
const { data, total } = await searchData('v1/dcrpPpl', {
|
||||
fromRegDt: formatDate(fromDate),
|
||||
@@ -51,6 +53,7 @@ const Page = () => {
|
||||
setAtflId('');
|
||||
setDcrpPplMtncBizSn('');
|
||||
setIsLoading(false)
|
||||
setResetSelection(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,6 +185,7 @@ const Page = () => {
|
||||
}
|
||||
}}
|
||||
onPageChange={async (page: number) => { setCurPage(page); await fetchData() }}
|
||||
resetSelection={resetSelection}
|
||||
/>
|
||||
</ListDiv>
|
||||
{/* 파일 업로드 모달 */}
|
||||
|
||||
@@ -49,12 +49,6 @@ export function UiTable({ tableData, headlist, pageSize, total, headName, childr
|
||||
}
|
||||
}, [resetSelection]);
|
||||
|
||||
// 테이블 데이터가 변경될 때마다 선택된 행 초기화하는 useEffect 추가
|
||||
useEffect(() => {
|
||||
// 새로운 데이터가 로드되면 선택 상태 초기화
|
||||
setIdx(-1);
|
||||
}, [tableData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (headerRef.current) {
|
||||
setHeaderHeight(headerRef.current.offsetHeight-5);
|
||||
|
||||
Reference in New Issue
Block a user