/** * πŸ“„ useBasicTab Hook * 검색 λͺ¨λ‹¬ 기본정보 νƒ­ ν›… * * - ν•„ν„°λ§λœ μ‹œμ„€λ¬Ό 데이터 쑰회 및 ν¬λ§·νŒ… * - ν…Œμ΄λΈ” μ…€ 클릭 μ‹œ 지도 ν”Όμ²˜ 선택 및 쀌 κΈ°λŠ₯ * - μ—‘μ…€ λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯ (ν•œκΈ€ 헀더 지원) * - CQL ν•„ν„° 생성을 ν†΅ν•œ 쿼리 쑰건 μ„€μ • * - Zustandλ₯Ό ν†΅ν•œ μƒνƒœ 관리 및 λ‘œλ”© 처리 * - 데이터 λ§€ν•‘ 및 μ½”λ“œ λ³€ν™˜ (μ‹œλ„/μ‹œκ΅°κ΅¬, μš©λ„ λ“±) * * πŸ”— μ‚¬μš© API * - 관망도 μ‹œμ„€λ¬Ό λͺ©λ‘ 쑰회: GET /api/v1/fclts (sewerage-service) */ import { downloadExcelWithKoreanHeaders } from '@common/business_components/ui'; import { MS_SWAGE_PPL_USE_CODES, MS_SWAGE_PPL_CODES, MS_SWAGE_PPL_SHAPE, MS_SWAGE_MHL_CODES, MS_SWAGE_MHL_USE_CODES, FldngWtlvMapExcelCol, 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 { fldngWtlvMapCqlFilters } from './fldngWtlvMap'; import { swageMhlCqlFilters } from './swageMhl'; import { swagePmstnCqlFilters } from './swagePmstn'; import { stofcbrCqlFilters } from './stofcbr'; import { postPopupMessageAndClose } from '@/features/windowPopup/lib/popupMessage'; import { WINDOW_POPUP_MESSAGE_TYPE } from '@/features/windowPopup/model/types'; import type { UiTableSort } from '@common/business_components/ui'; const isPopupWindow = () => typeof window !== "undefined" && !!window.opener && window.location.pathname.startsWith("/popup/"); const DISABLED_BASIC_SORT_KEYS = new Set(['flow_direction_basis']); const resolveBasicSort = (basicType: string, sort?: UiTableSort) => { if (!sort) return undefined; if (basicType === 'tb_ms_swage_ppl' && DISABLED_BASIC_SORT_KEYS.has(sort.key)) { return undefined; } return sort; }; export default function useBasicTab() { const { basicType, tableData, curPage, todayYear, todayMonth, todayDate, setIsSearchModalOpen, setTableData, setTableCount, setIsLoading, } = useSearchModalStore(); const { ctpv, sgg } = useStore(); const fetchBasicFilteredData = async (requestedSort?: UiTableSort) => { const activeSort = resolveBasicSort(basicType, requestedSort ?? useSearchModalStore.getState().sort); let cqlFilters: string[] = []; const queryParams = new URLSearchParams({ lyrTypeNm: basicType, page: `${curPage - 1}`, size: '10', }); if (basicType === 'tb_ms_swage_ppl') queryParams.set('includeFlowDirectionBasis', 'true'); if (activeSort) queryParams.set('sort', `${activeSort.key},${activeSort.direction}`); 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_fldng_wtlv_map') cqlFilters = fldngWtlvMapCqlFilters(); // μΉ¨μˆ˜ν”μ λ„ 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 totalCount = Number(res.count ?? 0); // 🎯 각 μ•„μ΄ν…œμ„ κ°œλ³„μ μœΌλ‘œ ν¬λ§·νŒ…ν•˜λ©΄μ„œ 일련번호 μΆ”κ°€ 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 ?? item?.stdgCd ?? formattedItem?.stdgCd ?? '')?.trim(); if (!ctpvCd && code) ctpvCd = code.slice(0, 2); if (!sggCd && code) sggCd = code.slice(0, 5); } const matchedMqltCode = basicType === 'tb_ms_swage_ppl' ? MS_SWAGE_PPL_CODES.find(code => code.val === item?.mqltCd?.trim()) // ν•˜μˆ˜κ΄€λ‘œ 재질 : basicType === 'tb_ms_swage_mhl' ? MS_SWAGE_MHL_CODES.find(code => code.val === item?.mqltCd?.trim()) // 맨홀 재질 : undefined; const matchedMhlUsgCode = MS_SWAGE_MHL_USE_CODES.find(code => code.val === item?.usgCd); // 맨홀 μš©λ„ const matchedPplShpCode = MS_SWAGE_PPL_SHAPE.find(code => code.val === item?.fcltyShpCd); // ν•˜μˆ˜κ΄€λ‘œ μ‹œμ„€λ¬Όν˜•νƒœμ½”λ“œ 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: activeSort?.key === 'rowNumber' && activeSort.direction === 'desc' ? totalCount - ((curPage - 1) * 10 + index) : (curPage - 1) * 10 + index + 1, scsYn: item.scsYn === null || item.scsYn === undefined ? 'N' : item?.scsYn, // scsYn이 null이면 'N'으둜 λ³€κ²½ mqltCd: matchedMqltCode ? matchedMqltCode.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 || '-', fcltyShpCd: matchedPplShpCode? matchedPplShpCode.text : item?.fcltyShpCd, }; }); setTableData(dataWithRowNumber); setTableCount(totalCount); }; // 기본정보 ν…Œμ΄λΈ” cellClick ν•Έλ“€λŸ¬ const handleBasicCellClick = async (index?: number | undefined, headId?: String) => { if (typeof index === "number") { const row = tableData[index]; if (isPopupWindow()) { postPopupMessageAndClose( WINDOW_POPUP_MESSAGE_TYPE.MAP_SEARCH_SELECT_FEATURE, { layerNm: row.lyrTypeNm, fid: String(row.fid), }, ); return; } setIsLoading(true); 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', }); if (basicType === 'tb_ms_swage_ppl') queryParams.set('includeFlowDirectionBasis', 'true'); const activeSort = resolveBasicSort(basicType, useSearchModalStore.getState().sort); if (activeSort) queryParams.set('sort', `${activeSort.key},${activeSort.direction}`); 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:Q1"; 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_fldng_wtlv_map': { // μΉ¨μˆ˜ν”μ λ„ cqlFilters = fldngWtlvMapCqlFilters(); headerMapping = FldngWtlvMapExcelCol; headerRange = "A1:O1"; 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 pplMqltCdMap = new Map(MS_SWAGE_PPL_CODES.map(code => [code.val?.trim(), code.text])); const pplShpCdMap = new Map(MS_SWAGE_PPL_SHAPE.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])); let 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 ?? item?.stdgCd ?? formattedItem?.stdgCd ?? '')?.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 ?? '-', vrtcLen: formattedItem.vrtcLen ?? item.vrtcLen ?? '-', wdthLen: formattedItem.wdthLen ?? item.wdthLen ?? '-', fcltyShpCd: pplShpCdMap.get(item?.fcltyShpCd?.trim()) || item.fcltyShpCd || formattedItem.fcltyShpCd || '-', mqltCd: pplMqltCdMap.get(item?.mqltCd?.trim()) || item.mqltCd || formattedItem.mqltCd || '-', }; } 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_fldng_wtlv_map': { // μΉ¨μˆ˜ν”μ λ„ return { fldngYr: formattedItem.fldngYr ?? item.fldngYr ?? '-', fldngDstrNm: formattedItem.fldngDstrNm ?? item.fldngDstrNm ?? '-', ctpvNm: ctpvMap.get(ctpvCd) ?? formattedItem.ctpvNm ?? '-', sggNm: sggMap.get(sggCd) ?? formattedItem.sggNm ?? '-', bgngYmd: formattedItem.bgngYmd ?? item.bgngYmd ?? '-', fldngBgngHm: formattedItem.fldngBgngHm ?? item.fldngBgngHm ?? '-', endYmd: formattedItem.endYmd ?? item.endYmd ?? '-', fldngEndHm: formattedItem.fldngEndHm ?? item.fldngEndHm ?? '-', fldngHr: formattedItem.fldngHr ?? item.fldngHr ?? '-', fldngDstrctNm: formattedItem.fldngDstrctNm ?? item.fldngDstrctNm ?? '-', fldngCsDtlCd: formattedItem.fldngCsDtlCd ?? item.fldngCsDtlCd ?? '-', avgFldngWtlv: formattedItem.avgFldngWtlv ?? item.avgFldngWtlv ?? '-', fldngArea: formattedItem.fldngArea ?? item.fldngArea ?? '-', exmnYr: formattedItem.exmnYr ?? item.exmnYr ?? '-', damAmt: formattedItem.damAmt ?? item.damAmt ?? '-', }; } 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 }; };