Files
frontend/apps/sn/app/(map-layout)/map/searchModal/searchModalReportApi.ts
T
2025-08-13 15:17:45 +09:00

199 lines
6.2 KiB
TypeScript

import { useState, useEffect } from 'react';
import { getDcData } from '@/components/lib/api';
import { create } from 'zustand';
export type Folder = {
clsfSystmSn: string;
upClsfSystmSn: string;
clsfSystmNm: string;
children: Folder[];
};
export type FlattenedFolder = {
[key: string]: string | number | undefined;
};
export type SelectDataType = {
text: string;
val: string;
sido?: string; // 시도 코드 (선택 사항)
}
export type ReportDataFile = {
no: number;
fileTitle: string;
regDt: string;
fileSn: string;
filePath: string;
}
const isYear = (value: string): boolean => {
return /^[0-9]{4}년$/.test(value);
};
export const reportGubuns = [{ val: '0', text: '전체' }, { val: '1', text: '보고서' }
, { val: '2', text: '요약보고서' }, { val: '3', text: '부록' }, { val: '4', text: '기타' }];
/**
* Flatten a hierarchical folder structure into a flat array.
* @param data - The hierarchical folder data to flatten.
* @returns An array of flattened folders with their paths and levels.
*/
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: "plantZoneGubun", 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);
});
}
}
if (data && data.length > 0 && data[0]?.clsfSystmNm == "기본계획") { // data가 비어있지 않고 children이 있는 경우에만 처리
data.forEach((root) => traverse(root, {}, 0));
} else {
data.forEach((root) => traverse(root, {}, 1));
}
return result;
}
export const getDcTree = async (clsfSystmNm: string) => {
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);
}
console.log("useDcTree호출");
console.log("clsfSystmNm:", clsfSystmNm, "data:", result);
};
fetch();
}, [clsfSystmNm]);
return data;
};
export const getDcFiles = async (clsfSystmSn: string) : Promise<ReportDataFile[]> => {
if (!clsfSystmSn) {
console.error("clsfSystmSn is required to get files.");
return [];
}
const queryString = 'clsfSystmSn=' + clsfSystmSn;
const result = await getDcData(`/api/v1/dc/file${queryString ? `?${queryString}` : ''}`);
return result;
};
export const useDcFiles = (clsfSystmNm: string) => {
const [data, setData] = useState<ReportDataFile[]>([]);
useEffect(() => {
const fetch = async () => {
const result = await getDcFiles(clsfSystmNm);
if (result) {
setData(result);
}
console.log("useDcFiles 호출");
console.log("clsfSystmNm:", clsfSystmNm, "data:", result);
};
fetch();
}, [clsfSystmNm]);
return data;
};
// 파일 이름 추가
export const addFileName = async (data: FlattenedFolder[]) => {
const fileReportData = await Promise.all(
data.map(async (item) => {
const fileArr: ReportDataFile[] = await getDcFiles(String(item.clsfSystmSn));
let result:FlattenedFolder;
if (fileArr.length > 0) {
const f = fileArr[0];
const fCount = fileArr.length;
result = { ...item, fileName: f?.fileTitle+" 외 "+fCount+"건", regDate: f?.regDt, fileSn: f?.fileSn, filePath: f?.filePath };
} else {
result = { ...item, fileName: "", regDate: "", fileSn: "", filePath: "" };
}
return result;
})
);
return fileReportData;
};
export const getDcFileprcs = async (fileSn: string) => {
const queryString = 'fileSn=' + fileSn;
const result = await getDcData(`/api/v1/dc/fileprcs${queryString ? `?${queryString}` : ''}`);
return result;
};
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 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, filePath: string) => {
if (filePath === "") alert("filePath 정보 없으므로 다운로드 불가:filesn" + fileSn);
const blobData = await getDcFileDownload(filePath); // 실제 다운로드 API
fileDownload(blobData, fileName);
}
interface ModalStore {
isOpen: boolean;
setIsOpen: (open: boolean) => void;
}
export const useReportFileModalStore = create<ModalStore>((set) => ({
isOpen: false,
setIsOpen: (open: boolean) => set({ isOpen: open }),
}));