From 89e6d0e2360840d65152e7bfe6835db547c36be6 Mon Sep 17 00:00:00 2001 From: ljpark Date: Fri, 11 Jul 2025 12:03:13 +0900 Subject: [PATCH 1/4] =?UTF-8?q?middleware=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/sn/app/(map-layout)/map/SearchModal.tsx | 22 +++++++++++-------- .../map/components/searchModalReportApi.ts | 4 ++-- apps/sn/middleware.ts | 7 ++++-- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/apps/sn/app/(map-layout)/map/SearchModal.tsx b/apps/sn/app/(map-layout)/map/SearchModal.tsx index 35c5a445a..82e1485fc 100644 --- a/apps/sn/app/(map-layout)/map/SearchModal.tsx +++ b/apps/sn/app/(map-layout)/map/SearchModal.tsx @@ -11,7 +11,7 @@ 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 { getDcTree,useDcTree,flattenFolders, useSggCd, useCityCd } from './components/searchModalReportApi'; +import { getDcTree,useDcTree,flattenFolders, useSggCd, useCityCd,getDcFile } from './components/searchModalReportApi'; import { useCityCdStore, type SelectDataType } from './commonStore'; const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`; @@ -180,14 +180,17 @@ const SearchModal: React.FC = ({ } }; - const handleCtpvCdChange = (val: string|number) => { + const handleCtpvCdChange = (val: string|number) => { // 하수도정비기본계획.시도 const sidoOption = sidos.find((n) => n.val === val); setCtpvCd(String(val)); - if (val !== '0' && sidoOption) { - const filterSiguns = siguns.filter(item => item.sido === sidoOption.text); + 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(() => { @@ -259,15 +262,15 @@ const SearchModal: React.FC = ({ //const reportOriginData = await getDcTree('경기도'); const reportData = flattenFolders(reportOriginData); let filterReportData = reportData; - if (ctpvCd !== "0") { + if (ctpvCd !== "0") { // 시도검색 const sidoOption = sidos.find((n) => n.val === ctpvCd); filterReportData = filterReportData.filter(item => item.sido === sidoOption?.text); } - if (sigungu !== "0") { + if (sigungu !== "0") { // 시군구검색 const sigunguOption = filteredSiguns.find((n) => n.val === sigungu); filterReportData = filterReportData.filter(item => item.sigungu === sigunguOption?.text); } - if (yearFilter.시작 != "" && yearFilter.종료 == "") + 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); @@ -276,7 +279,7 @@ const SearchModal: React.FC = ({ return (item.approvalYear)? item.approvalYear >= yearFilter.시작+"년" && item.approvalYear <= yearFilter.종료+"년": null; }); } - if (gubun !== "") { + if (gubun !== "") { // 구분검색 filterReportData = filterReportData.filter(item => (item.plantZoneGugun)? String(item.plantZoneGugun).includes(String(gubun)) : null); } console.log('report count:', filterReportData.length); @@ -284,7 +287,8 @@ const SearchModal: React.FC = ({ filterReportData = filterReportData.slice((curPage-1)*10, curPage*10); // paging filterReportData = filterReportData?.map((item, index)=>({...item, no:(curPage-1)*10+index+1})); setTableData(filterReportData || []); - + const fileList = await getDcFile("CLS20250530000041"); + console.log(fileList); } else { console.log('API URL:', `${API_URL}/v1/fclts?${queryParams.toString()}`); const res = await axios.get(`${API_URL}/v1/fclts?${queryParams.toString()}`); diff --git a/apps/sn/app/(map-layout)/map/components/searchModalReportApi.ts b/apps/sn/app/(map-layout)/map/components/searchModalReportApi.ts index e4af3a127..93c0b6b13 100644 --- a/apps/sn/app/(map-layout)/map/components/searchModalReportApi.ts +++ b/apps/sn/app/(map-layout)/map/components/searchModalReportApi.ts @@ -71,8 +71,8 @@ export const useSggCd = () => { } }; fetch(); + console.log("useSggCd호출"); }, []); - return data; }; export const useCityCd = () => { @@ -86,8 +86,8 @@ export const useCityCd = () => { } }; fetch(); + console.log("useCityCd호출"); }, []); - return data; }; diff --git a/apps/sn/middleware.ts b/apps/sn/middleware.ts index d69ef5513..8fe638ebe 100644 --- a/apps/sn/middleware.ts +++ b/apps/sn/middleware.ts @@ -102,8 +102,11 @@ export function middleware(req: NextRequest) { if (pathname.startsWith("/dc-service")) { const requestHeaders = new Headers(req.headers); - const newUrl = `${RSONE_DC_URL}${pathname}`; - + const decodedParams = Array.from(searchParams.entries()) + .map(([key, value]) => `${key}=${decodeURIComponent(value)}`) + .join("&"); + + const newUrl = `${RSONE_DC_URL}${pathname}${decodedParams ? `?${decodedParams}` : ""}`; console.log( `[Middleware] Rewriting from '/dc-service' path to: ${newUrl}`, ); From b66b3a9b557734ef7ddbddf3185cae0572ca0da4 Mon Sep 17 00:00:00 2001 From: ljpark Date: Mon, 14 Jul 2025 12:52:45 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=EC=9D=BC=EB=8B=A8=20=EB=8B=A4=EC=9A=B4?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EC=84=B1=EA=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/sn/app/(map-layout)/map/SearchModal.tsx | 33 ++- .../map/components/searchModalReportApi.ts | 255 ++++++++++-------- 2 files changed, 171 insertions(+), 117 deletions(-) diff --git a/apps/sn/app/(map-layout)/map/SearchModal.tsx b/apps/sn/app/(map-layout)/map/SearchModal.tsx index 82e1485fc..610803a4f 100644 --- a/apps/sn/app/(map-layout)/map/SearchModal.tsx +++ b/apps/sn/app/(map-layout)/map/SearchModal.tsx @@ -11,7 +11,7 @@ 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 { getDcTree,useDcTree,flattenFolders, useSggCd, useCityCd,getDcFile } from './components/searchModalReportApi'; +import { getDcTree,useDcTree,flattenFolders, useSggCd, useCityCd,getDcFile,addFileName,getDcFileDownload } from './components/searchModalReportApi'; import { useCityCdStore, type SelectDataType } from './commonStore'; const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`; @@ -130,7 +130,7 @@ const SearchModal: React.FC = ({ const sidos = useCityCd(); const siguns = useSggCd(); - const reportOriginData = useDcTree(""); + const reportOriginData = useDcTree(""); //:Folder[] // 오늘 날짜 구하기 const today = new Date(); @@ -179,6 +179,26 @@ const SearchModal: React.FC = ({ onOpenChange(false); // SearchModal 닫기 } }; + // 하수도정비기본계획.table cellClick + const handleReportCellClick = (index: number, headId?: string) => { + console.log(index); + const reportData = tableData[index]; + console.log(reportData); + const fileName = reportData.fileName; + if (reportData.filePath) { + console.log(reportData.filePath); + getDcFileDownload(reportData.filePath).then((data) => { + const url = window.URL.createObjectURL(data); + const link = document.createElement('a'); + link.href = url; + link.download = fileName; // 원하는 파일명 지정 + document.body.appendChild(link); + link.click(); + link.remove(); + window.URL.revokeObjectURL(url); + }); + } + }; const handleCtpvCdChange = (val: string|number) => { // 하수도정비기본계획.시도 const sidoOption = sidos.find((n) => n.val === val); @@ -286,9 +306,12 @@ const SearchModal: React.FC = ({ 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})); + //const fileList = await getDcFile("CLS20250530000041"); + addFileName(filterReportData).then(data => { + filterReportData = data; + setTableData(filterReportData || []); + }); setTableData(filterReportData || []); - const fileList = await getDcFile("CLS20250530000041"); - console.log(fileList); } else { console.log('API URL:', `${API_URL}/v1/fclts?${queryParams.toString()}`); const res = await axios.get(`${API_URL}/v1/fclts?${queryParams.toString()}`); @@ -1117,7 +1140,7 @@ const SearchModal: React.FC = ({ pageSize={tableData.length < 10 ? tableData.length : 10} total={tableCount} children={undefined} - cellClick={handleCellClick} + cellClick={(activeTab!=='report')?handleCellClick:handleReportCellClick} onPageChange={setCurPage} resetPageNo={false} cur={curPage} diff --git a/apps/sn/app/(map-layout)/map/components/searchModalReportApi.ts b/apps/sn/app/(map-layout)/map/components/searchModalReportApi.ts index 93c0b6b13..f26f6cbb2 100644 --- a/apps/sn/app/(map-layout)/map/components/searchModalReportApi.ts +++ b/apps/sn/app/(map-layout)/map/components/searchModalReportApi.ts @@ -1,18 +1,17 @@ import {useState, useEffect} from 'react'; import { getDcData } from '@/components/lib/api'; -import { json } from 'stream/consumers'; const ADDR_URL = process.env.NEXT_PUBLIC_ADDR_URL; -type Folder = { +export type Folder = { clsfSystmSn: string; upClsfSystmSn: string; clsfSystmNm: string; children: Folder[]; }; -type FlattenedFolder = { - [key: string]: string|number; +export type FlattenedFolder = { + [key: string]: string|number|undefined; }; type SelectDataType = { @@ -21,27 +20,126 @@ type SelectDataType = { sido?: string; // 시도 코드 (선택 사항) } - // 시군구 데이터 -export const getSggCd = async (): Promise => { - try { - const response = await fetch(`${ADDR_URL}/api/v1/addr/sgg`, { method: "GET", headers: { accept: "application/json" } }); - if (!response.ok) throw new Error(`시군구 데이터 오류: ${response.status}`); - const res = await response.json(); - const sgg = res.data; - const sggCd = sgg.map((item: any) => ({ - val: item.adstDstrCd, - sido: item.sido, - text: item.gugun, - })); - sggCd.unshift({ val: '0', text: '전체' }); // "전체" 옵션 추가 - return sggCd; - } catch (error) { - console.error('시군구 데이터를 가져오는데 실패했습니다:', error); - return [{ val: '0', text: '전체', sido: '0' }]; - } - }; +type ReportDataFile = { + no : number; + fileTitle : string; + regDt : string; + fileSn : string; + filePath : string; +} +const isYear = (value: string): boolean => { + return /^[0-9]{4}년$/.test(value); +}; - // 시도 데이터 +export function flattenFolders(data: Folder[]): FlattenedFolder[] { + const result: FlattenedFolder[] = []; + const exceptNodeNm = ["부분","통합","전체"]; + const addNodeNm = ["보고서","요약보고서","부록","기타"]; // level5 + const columnNms: { [key: number]: string } = { 0: "root", 1:"sido", 2:"sigungu", 3:"approvalYear" + ,4:"plantZoneGugun", 5:"reportGubun", 7:"fileName", 8:"regDate" }; + + function traverse( + node: Folder, + path: { [key: string]: string| number }, + level: number + ) { + if (level === 2 && isYear(node.clsfSystmNm)) { + level++; + } + if (level === 4 && addNodeNm.includes(node.clsfSystmNm)) { + level++; // 레벨을 증가시켜 하위값에 추가되도록 함. + } + + const newPath = { + ...path, + [`${columnNms[level]}`]: node.clsfSystmNm, + }; + + if (node.children.length === 0) { + newPath.no = result.length + 1; + newPath.clsfSystmSn = node.clsfSystmSn; // 파일 조회를 위한 고유번호 + result.push(newPath); + } else { + if (level === 4) { + if (exceptNodeNm.includes(node.clsfSystmNm)) { + level--; // 제외할 노드 이름인 경우, 현재의 레벨에 하위값이 써지도록 함. + } + } + node.children.forEach((child) => { + traverse(child, newPath, level + 1); + }); + } + } + + data.forEach((root) => traverse(root, {}, 0)); + console.log(result.slice(0, 10)); + return result; +} + +export const getDcTree = async (clsfSystmNm:string) => { + //const cityName = encodeURIComponent(clsfSystmNm); + const queryString = 'clsfSystmNm='+clsfSystmNm; + console.log("getDcTree queryString:", queryString); + //const result = await getDcData(`/api/v1/dc/clsf${queryString ? `?${queryString}` : ''}`); + const result = await getDcData("/api/v1/dc/clsf?clsfSystmNm=" + clsfSystmNm); + return result; +}; +export const useDcTree = (clsfSystmNm:string) => { + const [data, setData] = useState([]); + + useEffect(() => { + const fetch = async () => { + const result = await getDcTree(clsfSystmNm); + if (result) { + setData(result); + } + }; + fetch(); + console.log("useDcTree호출"); + }, [clsfSystmNm]); + + return data; +}; +export const getDcFile = async (clsfSystmSn:string) => { + const queryString = 'clsfSystmSn='+clsfSystmSn; + const result = await getDcData(`/api/v1/dc/file${queryString ? `?${queryString}` : ''}`); + return result; +}; +export const getDcFileprcs = async (fileSn:string) => { + const queryString = 'fileSn='+fileSn; + console.log("getDcTree queryString:", queryString); + const result = await getDcData(`/api/v1/dc/fileprcs${queryString ? `?${queryString}` : ''}`); + return result; +}; + +export const addFileName = async (data:FlattenedFolder[]) => { + const fileReportData = await Promise.all( + data.map(async (item) => { + const filenameArr:ReportDataFile[] = await getDcFile(String(item.clsfSystmSn)); + const f = filenameArr[0]; + const result = {...item, fileName:f?.fileTitle, regDate:f?.regDt, fileSn:f?.fileSn, filePath:""}; + if (f !== undefined && f.fileSn !== "") { + const fprcs = await getDcFileprcs(f?.fileSn); + if (fprcs.length>0) + result.filePath = fprcs[0].filePath; + } + return result; + }) + ); + return fileReportData; +} +export const getDcFileDownload = async (filePath:string) => { + const queryString = 'filePath='+ encodeURIComponent(filePath); + const response = await fetch(`/dc-service/api/v1/dc/file/download?${queryString}`, { + method: 'GET', + }); + if (!response.ok) { + throw new Error(`File download failed: ${response.status}`); + } + const blob = await response.blob(); // PDF, image 등은 blob으로 받아야 함 + return blob; +}; +// 시도 데이터 export const getCityCd = async (): Promise => { try { const response = await fetch(`${ADDR_URL}/api/v1/addr/city`, { method: "GET", headers: { accept: "application/json" } }); @@ -75,6 +173,27 @@ export const useSggCd = () => { }, []); return data; }; + +// 시군구 데이터 +export const getSggCd = async (): Promise => { + try { + const response = await fetch(`${ADDR_URL}/api/v1/addr/sgg`, { method: "GET", headers: { accept: "application/json" } }); + if (!response.ok) throw new Error(`시군구 데이터 오류: ${response.status}`); + const res = await response.json(); + const sgg = res.data; + const sggCd = sgg.map((item: any) => ({ + val: item.adstDstrCd, + sido: item.sido, + text: item.gugun, + })); + sggCd.unshift({ val: '0', text: '전체' }); // "전체" 옵션 추가 + return sggCd; + } catch (error) { + console.error('시군구 데이터를 가져오는데 실패했습니다:', error); + return [{ val: '0', text: '전체', sido: '0' }]; + } +}; + export const useCityCd = () => { const [data, setData] = useState([]); @@ -91,91 +210,3 @@ export const useCityCd = () => { return data; }; -const isYear = (value: string): boolean => { - return /^[0-9]{4}년$/.test(value); -}; - - export function flattenFolders(data: Folder[]): FlattenedFolder[] { - const result: FlattenedFolder[] = []; - const exceptNodeNm = ["부분","통합","전체"]; - const addNodeNm = ["보고서","요약보고서","부록","기타"]; // level5 - const columnNms: { [key: number]: string } = { 0: "root", 1:"sido", 2:"sigungu", 3:"approvalYear" - ,4:"plantZoneGugun", 5:"reportGubun", 7:"fileName", 8:"regDate" }; - - function traverse( - node: Folder, - path: { [key: string]: string| number }, - level: number - ) { - if (level === 2 && isYear(node.clsfSystmNm)) { - level++; - } - if (level === 4 && addNodeNm.includes(node.clsfSystmNm)) { - level++; // 레벨을 증가시켜 하위값에 추가되도록 함. - } - - const newPath = { - ...path, - [`${columnNms[level]}`]: node.clsfSystmNm, - }; - - if (node.children.length === 0) { - newPath.no = result.length + 1; - newPath.clsfSystmSn = node.clsfSystmSn; // 파일 조회를 위한 고유번호 - result.push(newPath); - } else { - if (level === 4) { - if (exceptNodeNm.includes(node.clsfSystmNm)) { - level--; // 제외할 노드 이름인 경우, 현재의 레벨에 하위값이 써지도록 함. - } - } - node.children.forEach((child) => { - traverse(child, newPath, level + 1); - }); - } - } - - data.forEach((root) => traverse(root, {}, 0)); - console.log(result.slice(0, 10)); - return result; - } - - -export const getDcTree = async (clsfSystmNm:string) => { - const cityName = encodeURIComponent(clsfSystmNm); - const queryString = 'clsfSystmNm='+cityName; - console.log("getDcTree queryString:", queryString); - //const result = await getDcData(`/api/v1/dc/clsf${queryString ? `?${queryString}` : ''}`); - const result = await getDcData("/api/v1/dc/clsf?clsfSystmNm=" + clsfSystmNm); - return result; -}; -export const useDcTree = (clsfSystmNm:string) => { - const [data, setData] = useState([]); - - useEffect(() => { - const fetch = async () => { - const result = await getDcTree(clsfSystmNm); - if (result) { - setData(result); - } - }; - fetch(); - }, [clsfSystmNm]); - - return data; -}; -export const getDcFile = async (clsfSystmSn:string) => { - const queryString = 'clsfSystmNm='+clsfSystmSn; - console.log("getDcTree queryString:", queryString); - const result = await getDcData(`/api/v1/dc/file${queryString ? `?${queryString}` : ''}`); - return result; -}; -export const addDcFileName = async(data: any) => { - const updated = await Promise.all( - data.map(async (item) => { - const fileName = await getDcFile(item.systmSn); - return { ...item, fileName }; - }) - ); - return updated; -} From 892249b04805c98ca3bc5f32b4ca77b172c1106d Mon Sep 17 00:00:00 2001 From: yschoi Date: Mon, 14 Jul 2025 13:04:34 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=EB=A7=88=EC=A7=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/sn/app/(map-layout)/map/SearchModal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/sn/app/(map-layout)/map/SearchModal.tsx b/apps/sn/app/(map-layout)/map/SearchModal.tsx index 35c5a445a..d77543201 100644 --- a/apps/sn/app/(map-layout)/map/SearchModal.tsx +++ b/apps/sn/app/(map-layout)/map/SearchModal.tsx @@ -979,7 +979,7 @@ const SearchModal: React.FC = ({ )} {/* 운영정보 탭 */} {activeTab === 'operation' && ( -
+
= ({ )} {/* 하수도정비기본계획보고서 탭 */} {activeTab === 'report' && ( -
+
{/* 시도, 시군구, 하수처리구역 한 줄 */}
Date: Mon, 14 Jul 2025 14:44:49 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EC=86=8D=EB=8F=84=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/sn/app/(map-layout)/map/SearchModal.tsx | 19 ++----- .../map/components/searchModalReportApi.ts | 49 +++++++++++++------ 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/apps/sn/app/(map-layout)/map/SearchModal.tsx b/apps/sn/app/(map-layout)/map/SearchModal.tsx index 821907b87..4cace8cc0 100644 --- a/apps/sn/app/(map-layout)/map/SearchModal.tsx +++ b/apps/sn/app/(map-layout)/map/SearchModal.tsx @@ -11,7 +11,7 @@ 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 { getDcTree,useDcTree,flattenFolders, useSggCd, useCityCd,getDcFile,addFileName,getDcFileDownload } from './components/searchModalReportApi'; +import { useDcTree,flattenFolders, useSggCd, useCityCd, addFileName, getFileDownload } from './components/searchModalReportApi'; import { useCityCdStore, type SelectDataType } from './commonStore'; const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`; @@ -180,23 +180,12 @@ const SearchModal: React.FC = ({ } }; // 하수도정비기본계획.table cellClick - const handleReportCellClick = (index: number, headId?: string) => { + const handleReportCellClick = (index: number) => { console.log(index); const reportData = tableData[index]; - console.log(reportData); const fileName = reportData.fileName; - if (reportData.filePath) { - console.log(reportData.filePath); - getDcFileDownload(reportData.filePath).then((data) => { - const url = window.URL.createObjectURL(data); - const link = document.createElement('a'); - link.href = url; - link.download = fileName; // 원하는 파일명 지정 - document.body.appendChild(link); - link.click(); - link.remove(); - window.URL.revokeObjectURL(url); - }); + if (reportData.fileSn !== "") { + getFileDownload(reportData.fileSn, fileName); } }; diff --git a/apps/sn/app/(map-layout)/map/components/searchModalReportApi.ts b/apps/sn/app/(map-layout)/map/components/searchModalReportApi.ts index f26f6cbb2..9d1ae43e0 100644 --- a/apps/sn/app/(map-layout)/map/components/searchModalReportApi.ts +++ b/apps/sn/app/(map-layout)/map/components/searchModalReportApi.ts @@ -105,6 +105,22 @@ export const getDcFile = async (clsfSystmSn:string) => { const result = await getDcData(`/api/v1/dc/file${queryString ? `?${queryString}` : ''}`); return result; }; +export const addFileName = async (data:FlattenedFolder[]) => { + const fileReportData = await Promise.all( + data.map(async (item) => { + const filenameArr:ReportDataFile[] = await getDcFile(String(item.clsfSystmSn)); + const f = filenameArr[0]; + const result = {...item, fileName:f?.fileTitle, regDate:f?.regDt, fileSn:f?.fileSn, filePath:""}; + // if (f !== undefined && f.fileSn !== "") { + // const fprcs = await getDcFileprcs(f?.fileSn); + // if (fprcs.length>0) + // result.filePath = fprcs[0].filePath; + // } + return result; + }) + ); + return fileReportData; +} export const getDcFileprcs = async (fileSn:string) => { const queryString = 'fileSn='+fileSn; console.log("getDcTree queryString:", queryString); @@ -112,22 +128,6 @@ export const getDcFileprcs = async (fileSn:string) => { return result; }; -export const addFileName = async (data:FlattenedFolder[]) => { - const fileReportData = await Promise.all( - data.map(async (item) => { - const filenameArr:ReportDataFile[] = await getDcFile(String(item.clsfSystmSn)); - const f = filenameArr[0]; - const result = {...item, fileName:f?.fileTitle, regDate:f?.regDt, fileSn:f?.fileSn, filePath:""}; - if (f !== undefined && f.fileSn !== "") { - const fprcs = await getDcFileprcs(f?.fileSn); - if (fprcs.length>0) - result.filePath = fprcs[0].filePath; - } - return result; - }) - ); - return fileReportData; -} export const getDcFileDownload = async (filePath:string) => { const queryString = 'filePath='+ encodeURIComponent(filePath); const response = await fetch(`/dc-service/api/v1/dc/file/download?${queryString}`, { @@ -139,6 +139,23 @@ export const getDcFileDownload = async (filePath:string) => { const blob = await response.blob(); // PDF, image 등은 blob으로 받아야 함 return blob; }; +export const fileDownload = (data:Blob, fileName:string) => { // Blob데이터 임시link로 연결 + const url = window.URL.createObjectURL(data); + const link = document.createElement('a'); + link.href = url; + link.download = fileName; // 원하는 파일명 지정 + document.body.appendChild(link); + link.click(); + link.remove(); + window.URL.revokeObjectURL(url); +} +export const getFileDownload = async (fileSn:string, fileName:string) => { + const fileprcsData = await getDcFileprcs(fileSn); // filePath 조회 + if (fileprcsData?.length === 0 ) { alert("filePath 조회 오류"); } + if (fileprcsData[0].filePath === "") alert("filePath 정보 없으므로 다운로드 불가"); + const blobData = await getDcFileDownload(fileprcsData[0].filePath); // 실제 다운로드 API + fileDownload(blobData, fileName); +} // 시도 데이터 export const getCityCd = async (): Promise => { try {