import { useEffect, useState } from 'react'; import { downloadExcelWithKoreanHeaders } from '@common/business_components/ui'; import axios from 'axios'; import { MS_SWAGE_PPL_USE_CODES, MS_SWAGE_MHL_CODES, MS_SWAGE_MHL_USE_CODES, MsSwagePplExcelCol, SwtrmtFcltExcelCol, SwtrmtPrcsZoneExcelCol, MsSwageMhlExcelCol, ExclnSewagePumpExcelCol, stofcbrExcelCol } from '../components/common/table'; import { getData } from "@/components/lib/api"; import { BASIC_TYPES } from './basicTab'; import { formatDisplayData } from '@/components/lib/utils/formatDisplayValue'; import useStore from '../../../store/useStore'; import GisApp from "@common/business_components/ui/map/lib/gis.core"; import { confirmToast } from '@/components/ui/toast' import { toast } from "react-hot-toast"; import useSearchModalStore from '../../../store/useSearchModalStore'; import { swagePplCqlFilters } from './swagePpl'; import { swagePrcsFcltCqlFilters } from './swagePrcsFclt'; import { swagePrcsZoneCqlFilters } from './swagePrcsZone'; import { swageMhlCqlFilters } from './swageMhl'; import { swagePmstnCqlFilters } from './swagePmstn'; import { stofcbrCqlFilters } from './stofcbr'; export default function useBasicTab() { const { basicType, tableData, curPage, todayYear, todayMonth, todayDate, setIsSearchModalOpen, setTableData, setTableCount, setIsLoading, } = useSearchModalStore(); const { ctpv, sgg } = useStore(); const fetchBasicFilteredData = async () => { let cqlFilters: string[] = []; const queryParams = new URLSearchParams({ lyrTypeNm: basicType, page: `${curPage - 1}`, size: '10', sort: 'string', }); if (basicType === 'tb_ms_swage_ppl') cqlFilters = swagePplCqlFilters(); // 하수관로 else if (basicType === 'tb_il_swage_prcs_fclt') cqlFilters = swagePrcsFcltCqlFilters(); // 하수처리시설 else if (basicType === 'tb_ms_swage_prcs_zone') cqlFilters = swagePrcsZoneCqlFilters(); // 하수처리구역 else if (basicType === 'tb_ms_swage_mhl') cqlFilters = swageMhlCqlFilters(); // 하수맨홀 else if (basicType === 'tb_ms_swage_pmstn') cqlFilters = swagePmstnCqlFilters(); // 하수펌프장 else if (basicType === 'tb_ms_stofcbr') cqlFilters = stofcbrCqlFilters(); // 우수토실 if (cqlFilters.length > 0) queryParams.append('cqlFiter', cqlFilters.join(' and ')); const res = await getData(`v1/fclts?${queryParams.toString()}`); // const res = await axios.get(`${API_URL}/v1/fclts?${queryParams.toString()}`); console.log('fetch res', res); console.log('fetch res.data', res.data); console.log('fetch res.count', res.count); console.log('fetch res.length', res.length); // 🎯 각 아이템을 개별적으로 포맷팅하면서 일련번호 추가 const dataWithRowNumber = (res.data || []).map((item: any, index: number) => { // 🎯 먼저 각 아이템을 포맷팅 const formattedItem = formatDisplayData(item); let ctpvCd = item?.ctpvNm ?? formattedItem?.ctpvNm ?? ''; let sggCd = item?.sggNm ?? formattedItem?.sggNm ?? ''; if (!ctpvCd || !sggCd) { const code = String(item?.pbadmsEmdCd ?? formattedItem?.pbadmsEmdCd ?? '')?.trim(); if (!ctpvCd && code) ctpvCd = code.slice(0, 2); if (!sggCd && code) sggCd = code.slice(0, 5); } const matchedMhlCode = MS_SWAGE_MHL_CODES.find(code => code.val === item?.mqltCd?.trim()); const matchedMhlUsgCode = MS_SWAGE_MHL_USE_CODES.find(code => code.val === item?.usgCd); const ctpvNm = ctpv.find(code => code.val.trim() === ctpvCd)?.text || item?.ctpvNm; const sggNm = sgg.find(code => code.val.trim() === sggCd)?.text || item?.sggNm; const usgCdObj = MS_SWAGE_PPL_USE_CODES.find(code => code.val === item?.usgCd?.trim()); // 추가 처리 및 일련번호 추가 return { ...formattedItem, rowNumber: (curPage - 1) * 10 + index + 1, // 1부터 시작하는 일련번호 추가 scsYn: item.scsYn === null || item.scsYn === undefined ? 'N' : item?.scsYn, // scsYn이 null이면 'N'으로 변경 mqltCd: matchedMhlCode ? matchedMhlCode.text : item?.mqltCd, usgCd: matchedMhlUsgCode ? matchedMhlUsgCode.text : (usgCdObj ? usgCdObj.text : item?.usgCd), ctpvNm: ctpvNm ?? '-', sggNm: sggNm ?? '-', swtrmt_zone_nm: item.swtrmtZoneNm || item.swtrmt_zone_nm || '-', }; }); setTableData(dataWithRowNumber); setTableCount(res.count || []); }; // 기본정보 테이블 cellClick 핸들러 const handleBasicCellClick = async (index?: number | undefined, headId?: String) => { if (typeof index === "number") { setIsLoading(true); const row = tableData[index]; const layerNm = row.lyrTypeNm; const fid = row.fid; const core = GisApp.Module.layer as any; await core.showSearchResultsFromGeoJSON(layerNm, fid); setIsLoading(false); setIsSearchModalOpen(false); // SearchModal 닫기 } }; // 기본정보 Excel 다운로드 핸들러 const basicExcelDownload = async () => { if (tableData.length === 0) { alert("다운로드 할 Excel 파일이 없습니다.\n조회 후 다시 시도해주세요."); return; } toast.dismiss("global-confirm-toast"); confirmToast( "파일 다운로드에는 2분 내외의 시간이 소요될 수 있습니다.\n파일 다운로드를 진행하시겠습니까?", onDownload ?? (() => { }), "text-xl font-medium text-gray-800" ); async function onDownload() { setIsLoading(true); try { const queryParams = new URLSearchParams({ lyrTypeNm: basicType, size: '10000', }); let cqlFilters: string[] = []; let headerMapping: { [key: string]: string } = {}; let headerRange: string = "A1:F1"; switch (basicType) { case 'tb_ms_swage_ppl': { // 하수관로 cqlFilters = swagePplCqlFilters() headerMapping = MsSwagePplExcelCol; headerRange = "A1:M1"; break; } case 'tb_il_swage_prcs_fclt': { // 하수처리시설 cqlFilters = swagePrcsFcltCqlFilters(); headerMapping = SwtrmtFcltExcelCol; headerRange = "A1:J1"; break; } case 'tb_ms_swage_prcs_zone': { // 하수처리구역 cqlFilters = swagePrcsZoneCqlFilters(); headerMapping = SwtrmtPrcsZoneExcelCol; headerRange = "A1:D1"; break; } case 'tb_ms_swage_mhl': { // 하수맨홀 cqlFilters = swageMhlCqlFilters(); headerMapping = MsSwageMhlExcelCol; headerRange = "A1:J1"; break; } case 'tb_ms_swage_pmstn': { // 하수펌프장 cqlFilters = swagePmstnCqlFilters(); headerMapping = ExclnSewagePumpExcelCol; headerRange = "A1:J1"; break; } case 'tb_ms_stofcbr': { // 우수토실 cqlFilters = stofcbrCqlFilters(); headerMapping = stofcbrExcelCol; headerRange = "A1:H1"; break; } } if (cqlFilters.length > 0) queryParams.append('cqlFiter', cqlFilters.join(' and ')); const res = await getData(`v1/fclts?${queryParams.toString()}`); const mhlUsgCdMap = new Map(MS_SWAGE_MHL_USE_CODES.map(code => [code.val?.trim(), code.text])); const pplUsgCdMap = new Map(MS_SWAGE_PPL_USE_CODES.map(code => [code.val?.trim(), code.text])); const ctpvMap = new Map(ctpv.map(code => [code.val?.trim(), code.text])); const sggMap = new Map(sgg.map(code => [code.val?.trim(), code.text])); const mappedContent = (res.data || []).map((item: any) => { const formattedItem = formatDisplayData(item); let ctpvCd = item?.ctpvCd ?? formattedItem?.ctpvCd ?? ''; let sggCd = item?.sggCd ?? formattedItem?.sggCd ?? ''; if (!ctpvCd || !sggCd) { const code = String(item?.pbadmsEmdCd ?? formattedItem?.pbadmsEmdCd ?? '')?.trim(); if (!ctpvCd && code) ctpvCd = code.slice(0, 2); if (!sggCd && code) sggCd = code.slice(0, 5); } // trim 한 번만 수행 const trimmedUsgCd = item?.usgCd?.trim(); // const trimmedMqltCd = item?.mqltCd?.trim(); switch (basicType) { case 'tb_ms_swage_ppl': { // 하수관로 return { fcltMngNo: formattedItem.fcltMngNo ?? item.fcltMngNo ?? '-', instMngNo: formattedItem.instMngNo ?? item.instMngNo ?? '-', ctpvNm: ctpvMap.get(ctpvCd) ?? item.ctpvNm ?? '-', sggNm: sggMap.get(sggCd) ?? item.sggNm ?? '-', swtrmt_zone_nm: formattedItem.swtrmt_zone_nm ?? item.swtrmt_zone_nm ?? '-', instlYmd: formattedItem.instlYmd ?? item.instlYmd ?? '-', usgCd: pplUsgCdMap.get(trimmedUsgCd) || item.usgCd || formattedItem.usgCd || '-', pdmtVl: formattedItem.pdmtVl ?? item.pdmtVl ?? '-', prlgVl: formattedItem.prlgVl ?? item.prlgVl ?? '-', tmptDpth: formattedItem.tmptDpth ?? item.tmptDpth ?? '-', tmptMhlMngNo: formattedItem.tmptMhlMngNo ?? item.tmptMhlMngNo ?? '-', scendDpth: formattedItem.scendDpth ?? item.scendDpth ?? '-', scendMhlMngNo: formattedItem.scendMhlMngNo ?? item.scendMhlMngNo ?? '-', }; } case 'tb_il_swage_prcs_fclt': { // 하수처리시설 return { swtrmtFcltNm: formattedItem.swtrmtFcltNm ?? item.swtrmtFcltNm ?? '-', fcltCpct: formattedItem.fcltCpct ?? item.fcltCpct ?? '-', rgnExpln: formattedItem.rgnExpln ?? item.rgnExpln ?? '-', oprtngStrtYmd: formattedItem.oprtngStrtYmd ?? item.oprtngStrtYmd ?? '-', laeNm: formattedItem.laeNm ?? item.laeNm ?? '-', sareaNm: formattedItem.sareaNm ?? item.sareaNm ?? '-', rvrNm: formattedItem.rvrNm ?? item.rvrNm ?? '-', dschgWtstNm: formattedItem.dschgWtstNm ?? item.dschgWtstNm ?? '-', swtrmtPpltnCnt: formattedItem.swtrmtPpltnCnt ?? item.swtrmtPpltnCnt ?? '-', rprsMsrcCn: formattedItem.rprsMsrcCn ?? item.rprsMsrcCn ?? '-' }; } case 'tb_ms_swage_prcs_zone': { // 하수처리구역 return { swtrmtZoneNm: formattedItem.swtrmtZoneNm ?? item.swtrmtZoneNm ?? '-', ctpvNm: ctpvMap.get(ctpvCd) ?? formattedItem.ctpvNm ?? '-', sggNm: sggMap.get(sggCd) ?? formattedItem.sggNm ?? '-', swtrmtFcltNm: formattedItem.swtrmtFcltNm ?? item.swtrmtFcltNm ?? '-' }; } case 'tb_ms_swage_mhl': { // 하수맨홀 return { fcltMngNo: formattedItem.fcltMngNo ?? item.fcltMngNo ?? '-', ctpvNm: ctpvMap.get(ctpvCd) ?? formattedItem.ctpvNm ?? '-', sggNm: sggMap.get(sggCd) ?? formattedItem.sggNm ?? '-', instlYmd: formattedItem.instlYmd ?? item.instlYmd ?? '-', usgCd: mhlUsgCdMap.get(trimmedUsgCd) || item.usgCd || formattedItem.usgCd || '-', swageMhlDiamVl: formattedItem.swageMhlDiamVl ?? item.swageMhlDiamVl ?? '-', wdthLen: formattedItem.wdthLen ?? item.wdthLen ?? '-', vrtcLen: formattedItem.vrtcLen ?? item.vrtcLen ?? '-', altdVl: formattedItem.altdVl ?? item.altdVl ?? '-', dpthlVl: formattedItem.dpthlVl ?? item.dpthlVl ?? '-' }; } case 'tb_ms_swage_pmstn': { // 하수펌프장 return { fcltMngNo: formattedItem.fcltMngNo ?? item.fcltMngNo ?? '-', ctpvNm: ctpvMap.get(ctpvCd) ?? formattedItem.ctpvNm ?? '-', sggNm: sggMap.get(sggCd) ?? formattedItem.sggNm ?? '-', swagePmstnNm: formattedItem.swagePmstnNm ?? item.swagePmstnNm ?? '-', instlYmd: formattedItem.instlYmd ?? item.instlYmd ?? '-', dailyPrcsCpct: formattedItem.dailyPrcsCpct ?? item.dailyPrcsCpct ?? '-', maxImpndCpct: formattedItem.maxImpndCpct ?? item.maxImpndCpct ?? '-', altdVl: formattedItem.altdVl ?? item.altdVl ?? '-', wtlvVl: formattedItem.wtlvVl ?? item.wtlvVl ?? '-', exclnWpmpAbltVl: formattedItem.exclnWpmpAbltVl ?? item.exclnWpmpAbltVl ?? '-' }; } case 'tb_ms_stofcbr': { // 우수토실 return { fcltMngNo: formattedItem.fcltMngNo ?? item.fcltMngNo ?? '-', mapshtNo: formattedItem.mapshtNo ?? item.mapshtNo ?? '-', ctpvNm: ctpvMap.get(ctpvCd) ?? formattedItem.ctpvNm ?? '-', sggNm: sggMap.get(sggCd) ?? formattedItem.sggNm ?? '-', instlYmd: formattedItem.instlYmd ?? item.instlYmd ?? '-', worflwWallHgt: formattedItem.worflwWallHgt ?? item.worflwWallHgt ?? '-', swageMhlMngNo: formattedItem.swageMhlMngNo ?? item.swageMhlMngNo ?? '-', drtnAngl: formattedItem.drtnAngl ?? item.drtnAngl ?? '-' }; } } }); // 선택된 행 데이터를 Excel 다운로드 형식으로 변환 const excelData = mappedContent; // 배열로 감싸서 전달 // 파일명 생성 (분석번호 기반) const label = BASIC_TYPES.find((type) => type.val === basicType)?.text const fileName = `${label} 조회 결과_${todayYear}${todayMonth}${todayDate}`; await downloadExcelWithKoreanHeaders({ data: excelData as JSON[], fileName: fileName, sheetNameArray: [fileName], headerRange: headerRange, headerMapping: headerMapping }); setIsLoading(false); } catch (error) { setIsLoading(false); console.error("Excel 다운로드 중 오류 발생:", error); alert("Excel 다운로드 중 오류가 발생했습니다. 다시 시도해주세요."); } } }; return { fetchBasicFilteredData, handleBasicCellClick, basicExcelDownload }; };