feat, fix:

- 운영정보 업무구분으로 조회 기능 구현
- 용도, 재질 코드 -> 이름으로 수정
- DetailTable 페이지네이션 수정
This commit is contained in:
swcho
2025-07-23 12:01:41 +09:00
parent 6660c85150
commit 406ce4056a
2 changed files with 224 additions and 88 deletions
@@ -39,14 +39,13 @@ const MsSwagePpl = ({ featureData, onSaveClick }: { featureData: any, onSaveClic
{ lwpoCd: "203", lwpoCdNm: "청소, 준설" },
{ lwpoCd: "204", lwpoCdNm: "단순보수" },
];
// const BIZ_TY_CD = useBizByFcltStore(state => state.BIZ_TY_CD);
const BIZ_TY_CD = [
{ lwpoCd: "SV", lwpoCdNm: "용역" },
{ lwpoCd: "SF", lwpoCdNm: "자체" },
{ lwpoCd: "SC", lwpoCdNm: "공사" },
];
console.log('BIZ_SE_CD', BIZ_SE_CD);
// 마운트 및 업데이트 시 API 호출
useEffect(() => {
@@ -29,15 +29,20 @@ const BASIC_TYPES = [
{ val: "tb_ms_swage_prcs_zone", text: "하수처리구역" },
{ val: "tb_ms_swage_mhl", text: "하수맨홀" },
{ val: "tb_ms_swage_pmstn", text: "하수펌프장" },
// { val: "tb_ms_swage_psmtn_1", text: "오수펌프" },
// { val: "tb_ms_swage_psmtn_2", text: "빗물펌프" },
{ val: "tb_ms_stofcbr", text: "우수토실" },
];
// 운영정보 '구분' 선택 목록
// const WORK_TYPES = [
// { val: "maintenance", text: "보수 및 갱신" },
// { val: "cleaning", text: "청소 및 준설" },
// { val: "inspection", text: "점검 및 진단" },
// ];
const WORK_TYPES = [
{ val: "maintenance", text: "보수 및 갱신" },
{ val: "cleaning", text: "청소 및 준설" },
{ val: "inspection", text: "점검 및 진단" },
{ val: "200", text: "보수 및 갱신(개대체)" },
{ val: "201", text: "보수 및 갱신(유지보수)" },
{ val: "204", text: "보수 및 갱신(단순보수)" },
{ val: "100", text: "점검 및 진단" },
{ val: "203", text: "청소 및 준설" },
];
// 운영정보 - 사업 현황
@@ -90,6 +95,25 @@ const reportTableHeadlist = [
{ id: "fileName", title: "파일명" },
{ id: "regDate", title: "등록일자" },
];
// const BIZ_SE_CD = useBizByFcltStore(state => state.BIZ_SE_CD);
const BIZ_SE_CD = [
{ lwpoCd: "100", lwpoCdNm: "관로기술진단" },
{ lwpoCd: "200", lwpoCdNm: "개대체" },
{ lwpoCd: "201", lwpoCdNm: "유지보수" },
{ lwpoCd: "203", lwpoCdNm: "청소, 준설" },
{ lwpoCd: "204", lwpoCdNm: "단순보수" },
];
// const BIZ_TY_CD = useBizByFcltStore(state => state.BIZ_TY_CD);
const BIZ_TY_CD = [
{ lwpoCd: "0", lwpoCdNm: "전체" },
{ lwpoCd: "SV", lwpoCdNm: "용역" },
{ lwpoCd: "SF", lwpoCdNm: "자체" },
{ lwpoCd: "SC", lwpoCdNm: "공사" },
];
const BIZ_TY_CD_SELECT_ARRAY = BIZ_TY_CD.map(item => ({
val: item.lwpoCd,
text: item.lwpoCdNm,
}));
// 날짜 조합 함수
const getDateString = (
@@ -122,9 +146,11 @@ const SearchModal: React.FC<SearchModalProps> = ({
const [showTable, setShowTable] = useState(false);
const [tableData, setTableData] = useState<any[]>([]);
const [detailTableData, setDetailTableData] = useState<any[]>([]);
const [tableCount, setTableCount] = useState<number>(0);
const [detailTableCount, setDetailTableCount] = useState<number>(0);
const [tableCount, setTableCount] = useState(0);
const [detailTableCount, setDetailTableCount] = useState(0);
const [curPage, setCurPage] = useState(1);
const [detailCurPage, setDetailCurPage] = useState(1);
const [detailBizId, setDetailBizId] = useState(0);
const [시도, set시도] = useState(0);
const [시군구, set시군구] = useState(0);
const [ctpvCd, setCtpvCd] = useState('0');
@@ -136,8 +162,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<string>("");
const [변수2, set변수2] = useState<string>("");
const [변수1, set변수1] = useState("");
const [변수2, set변수2] = useState("");
const [변수3, set변수3] = useState("");
const [변수4, set변수4] = useState("");
// 시작, 종료, 경과년도
@@ -159,6 +185,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
// 로딩바
const [isLoading, setIsLoading] = useState(false);
const [isDetailLoading, setIsDetailLoading] = useState(false);
const sidos = useCityCd();
const siguns = useSggCd();
@@ -185,20 +212,6 @@ const SearchModal: React.FC<SearchModalProps> = ({
// });
// };
// const BIZ_TY_CD = useBizByFcltStore(state => state.BIZ_TY_CD);
const BIZ_TY_CD = [
{ lwpoCd: "0", lwpoCdNm: "전체" },
{ lwpoCd: "SV", lwpoCdNm: "용역" },
{ lwpoCd: "SF", lwpoCdNm: "자체" },
{ lwpoCd: "SC", lwpoCdNm: "공사" },
];
console.log('BIZ_TY_CD', BIZ_TY_CD);
const BIZ_TY_CD_SELECT_ARRAY = BIZ_TY_CD.map(item => ({
val: item.lwpoCd,
text: item.lwpoCdNm,
}));
const dynamicHeadlist = useMemo(() => {
if (activeTab === 'basic') {
if (basicType === 'tb_ms_swage_ppl') return MsSwagePplCol2;
@@ -218,65 +231,16 @@ const SearchModal: React.FC<SearchModalProps> = ({
const dynamicHeadlist2 = useMemo(() => {
if (activeTab === 'operation') {
if (workType === 'maintenance') return operationMaintenanceTableHeadlist;
if (workType === 'cleaning') return operationCleaningTableHeadlist;
if (workType === 'inspection') return operationInspectionTableHeadlist;
if (workType === '200') return operationMaintenanceTableHeadlist;
if (workType === '201') return operationMaintenanceTableHeadlist;
if (workType === '204') return operationMaintenanceTableHeadlist;
if (workType === '100') return operationCleaningTableHeadlist;
if (workType === '203') return operationInspectionTableHeadlist;
}
return [];
}, [activeTab, workType]);
// 조회 버튼 클릭 시 1페이지로 이동하도록 수정
const handleSearch = () => {
setCurPage(1); // 페이지를 1로 초기화
fetchFilteredData();
setShowTable(true);
};
// 기본정보 테이블 cellClick 핸들러
const handleBasicCellClick = (index?: number | undefined, headId?: String) => {
if (typeof index === "number") {
onFeatureSelect(tableData[index % 10]); // 10은 page size 하드 코딩한 숫자
onOpenChange(false); // SearchModal 닫기
}
};
// 운영정보 테이블 cellClick 핸들러
const handleOperationCellClick = async (index?: number | undefined, headId?: String) => {
if (typeof index === "number") {
const res = await getData(`v1/bizInfo/fclts?bizId=${tableData[index % 5].bizId}`);
console.log('운영정보 cellClick 데이터:', res);
console.log('운영정보 length:', res.data.length);
setDetailTableData(res.data || []);
setDetailTableCount(res.count || 0);
}
};
// 하수도정비기본계획 테이블 cellClick 핸들러
const handleReportCellClick = (index: number | undefined, headId?: String) => {
console.log(index);
if (typeof index === "number" && tableData[index]) {
const reportData = tableData[index];
const fileName = reportData.fileName;
const filePath = reportData.filePath;
if (reportData.fileSn !== "") {
getFileDownload(reportData.fileSn, fileName, filePath);
}
}
};
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' });
setFilteredSiguns(filterSiguns);
}
setSigungu("0");
setGubun("");
setYearFilter({ 시작: "", 종료: "", });
}
useEffect(() => {
// filterParams 초기화
set시작1("");
@@ -318,12 +282,15 @@ const SearchModal: React.FC<SearchModalProps> = ({
// 페이지 변경 시마다 데이터 fetch
useEffect(() => {
// showTable이 true일 때만 fetch (최초 렌더 방지)
if (showTable) {
fetchFilteredData(); // 실제 API 사용 시
// fetchDummyData(); // 더미 데이터 사용 시
}
if (showTable) fetchFilteredData();
}, [curPage]);
// 페이지 변경 시마다 데이터 fetch
useEffect(() => {
// showTable이 true일 때만 fetch (최초 렌더 방지)
if (showTable) handleOperationPageNation(Number(detailBizId));
}, [detailCurPage]);
// 검색 API 호출 함수
const fetchFilteredData = async () => {
@@ -379,14 +346,74 @@ const SearchModal: React.FC<SearchModalProps> = ({
RequestDTO.fromflfmtEndYmd = startDate;
RequestDTO.toflfmtEndYmd = endDate;
// let allContent: any[] = [];
// let totalCount = 0;
// if (workType === 'maintenance') {
// const codes = ['200', '201', '204'];
// for (const code of codes) {
// RequestDTO.bizSeCd = code;
// const params = new URLSearchParams(RequestDTO).toString();
// console.log('API URL:', `/v1/bizInfo?${params}`);
// const res = await getData(`v1/bizInfo?${params}`);
// console.log('필터링된 API 결과(개수):', res.totalElements);
// console.log('필터링된 API 결과(데이터):', res.content);
// const mappedContent = (res.content || []).map((item: any) => {
// const matched = BIZ_TY_CD.find(code => code.lwpoCd === item.bizTyCd);
// return {
// ...item,
// bizTyCd: matched ? matched.lwpoCdNm : item.bizTyCd,
// };
// });
// allContent = allContent.concat(mappedContent);
// totalCount += res.totalElements || 0;
// }
// setTableData(allContent);
// setTableCount(totalCount);
// } else {
// if (workType === 'cleaning') {
// RequestDTO.bizSeCd = '203';
// } else if (workType === 'inspection') {
// RequestDTO.bizSeCd = '100';
// }
// const params = new URLSearchParams(RequestDTO).toString();
// console.log('API URL:', `/v1/bizInfo?${params}`);
// const res = await getData(`v1/bizInfo?${params}`);
// console.log('필터링된 API 결과(개수):', res.totalElements);
// console.log('필터링된 API 결과(데이터):', res.content);
// const mappedContent = (res.content || []).map((item: any) => {
// const matched = BIZ_TY_CD.find(code => code.lwpoCd === item.bizTyCd);
// return {
// ...item,
// bizTyCd: matched ? matched.lwpoCdNm : item.bizTyCd,
// };
// });
// setTableData(mappedContent || []);
// setTableCount(res.totalElements || 0);
// }
RequestDTO.bizSeCd = workType;
const params = new URLSearchParams(RequestDTO).toString();
console.log('API URL:', `/v1/bizInfo?${params}`);
const res = await getData(`v1/bizInfo?${params}`);
console.log('필터링된 API 결과(개수):', res.totalElements);
console.log('필터링된 API 결과(데이터):', res.content);
setTableData(res.content || []);
const mappedContent = (res.content || []).map((item: any) => {
const matched = BIZ_TY_CD.find(code => code.lwpoCd === item.bizTyCd);
return {
...item,
bizTyCd: matched ? matched.lwpoCdNm : item.bizTyCd,
};
});
setTableData(mappedContent || []);
setTableCount(res.totalElements || 0);
setDetailTableData([]);
setDetailTableCount(0);
} else if (activeTab === 'report') {
//const reportOriginData = await getDcTree('경기도');
@@ -591,6 +618,116 @@ const SearchModal: React.FC<SearchModalProps> = ({
return cqlFilters;
};
// 조회 버튼 클릭 시 1페이지로 이동 및 데이터 초기화
const handleSearch = () => {
setCurPage(1); // 페이지를 1로 초기화
setDetailCurPage(1); // 페이지를 1로 초기화
fetchFilteredData();
setShowTable(true);
};
// 기본정보 테이블 cellClick 핸들러
const handleBasicCellClick = (index?: number | undefined, headId?: String) => {
if (typeof index === "number") {
onFeatureSelect(tableData[index % 10]); // 10은 page size 하드 코딩한 숫자
onOpenChange(false); // SearchModal 닫기
}
};
// 운영정보 테이블 cellClick 핸들러
const handleOperationCellClick = async (index?: number | undefined, headId?: String) => {
if (typeof index === "number") {
setIsDetailLoading(true);
setDetailBizId(tableData[index].bizId);
setDetailCurPage(1); // 상세 페이지 초기화
try {
const RequestDTO: Record<string, string> = {
page: `${detailCurPage - 1}`,
size: '5',
bizId: tableData[index % 5].bizId,
};
const res = await getData(`v1/bizInfo/fclts?${new URLSearchParams(RequestDTO).toString()}`);
console.log('운영정보 cellClick 데이터:', res);
console.log('운영정보 length:', res.data.length);
const mappedData = (res.data || []).map((item: any) => {
const usgCdObj = MS_SWAGE_PPL_USE_CODES.find(code => code.val === item.usgCd.trim());
const mqltCdObj = MS_SWAGE_PPL_CODES.find(code => code.val === item.mqltCd.trim());
return {
...item,
usgCd: usgCdObj ? usgCdObj.text : item.usgCd,
mqltCd: mqltCdObj ? mqltCdObj.text : item.mqltCd,
};
});
setDetailTableData(mappedData);
setDetailTableCount(res.count || 0);
} catch (error) {
console.error('운영정보 cellClick 에러:', error);
} finally {
setIsDetailLoading(false);
}
}
};
// 운영정보 디테일 테이블 페이지네이션 핸들러
const handleOperationPageNation = async (index?: number | undefined) => {
if (typeof index === "number") {
setIsDetailLoading(true);
try {
const RequestDTO: Record<string, string> = {
page: `${detailCurPage - 1}`,
size: '5',
bizId: String(detailBizId),
};
const res = await getData(`v1/bizInfo/fclts?${new URLSearchParams(RequestDTO).toString()}`);
console.log('운영정보 페이지네이션 데이터:', res);
console.log('운영정보 페이지네이션 length:', res.data.length);
const mappedData = (res.data || []).map((item: any) => {
const usgCdObj = MS_SWAGE_PPL_USE_CODES.find(code => code.val === item.usgCd.trim());
const mqltCdObj = MS_SWAGE_PPL_CODES.find(code => code.val === item.mqltCd.trim());
return {
...item,
usgCd: usgCdObj ? usgCdObj.text : item.usgCd,
mqltCd: mqltCdObj ? mqltCdObj.text : item.mqltCd,
};
});
setDetailTableData(mappedData);
setDetailTableCount(res.count || 0);
} catch (error) {
console.error('운영정보 페이지네이션 에러:', error);
} finally {
setIsDetailLoading(false);
}
}
};
// 하수도정비기본계획 테이블 cellClick 핸들러
const handleReportCellClick = (index: number | undefined, headId?: String) => {
console.log(index);
if (typeof index === "number" && tableData[index]) {
const reportData = tableData[index];
const fileName = reportData.fileName;
const filePath = reportData.filePath;
if (reportData.fileSn !== "") {
getFileDownload(reportData.fileSn, fileName, filePath);
}
}
};
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' });
setFilteredSiguns(filterSiguns);
}
setSigungu("0");
setGubun("");
setYearFilter({ 시작: "", 종료: "", });
}
const renderBody = () => (
<>
{/* 탭 영역 */}
@@ -997,7 +1134,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
<div className="relative flex flex-col border rounded-lg p-6 mt-4 w-full h-[10vh]">
<div className="flex items-center mb-3">
<SelectBox2
className="w-60 mr-8"
className="w-80 mr-8"
selectClass="rounded-lg bg-white text-xl"
label="업무구분"
selectArray={WORK_TYPES.map((w) => ({
@@ -1104,7 +1241,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
<LoadingOverlay isLoading={isLoading} />
<UiTable
headName={(() => {
const label = WORK_TYPES.find((type) => type.val === workType)?.text
const label = BASIC_TYPES.find((type) => type.val === basicType)?.text
return (<>{label} 조회 결과 ({tableCount})건</>);
})()
}
@@ -1145,7 +1282,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
<div className="h-[35vh] w-full overflow-hidden rounded-lg border">
<div className="flex-1 px-2 pb-2">
<LoadingOverlay isLoading={isLoading} />
<LoadingOverlay isLoading={isDetailLoading} />
<UiTable
headName={(() => {
const label = WORK_TYPES.find((type) => type.val === workType)?.text
@@ -1157,7 +1294,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
pageSize={5}
total={detailTableCount}
cellClick={undefined}
onPageChange={setCurPage}
onPageChange={setDetailCurPage}
resetPageNo={false}
/>
</div>