230 lines
7.2 KiB
TypeScript
230 lines
7.2 KiB
TypeScript
import {useState, useEffect} from 'react';
|
|
import { getDcData } from '@/components/lib/api';
|
|
|
|
const ADDR_URL = process.env.NEXT_PUBLIC_ADDR_URL;
|
|
|
|
export type Folder = {
|
|
clsfSystmSn: string;
|
|
upClsfSystmSn: string;
|
|
clsfSystmNm: string;
|
|
children: Folder[];
|
|
};
|
|
|
|
export type FlattenedFolder = {
|
|
[key: string]: string|number|undefined;
|
|
};
|
|
|
|
type SelectDataType = {
|
|
text: string;
|
|
val: string;
|
|
sido?: string; // 시도 코드 (선택 사항)
|
|
}
|
|
|
|
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 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);
|
|
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) => {
|
|
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<SelectDataType[]> => {
|
|
try {
|
|
const response = await fetch(`${ADDR_URL}/api/v1/addr/city`, { method: "GET", headers: { accept: "application/json" } });
|
|
if (!response.ok) throw new Error(`시도 데이터 오류: ${response.status}`);
|
|
const res = await response.json();
|
|
const city = res.data;
|
|
const cityCd = city.map((item: any) => ({
|
|
val: item.adstDstrCd,
|
|
text: item.sido,
|
|
}));
|
|
cityCd.unshift({ val: '0', text: '전체' });
|
|
return cityCd;
|
|
} catch (error) {
|
|
console.error('시도 데이터를 가져오는데 실패했습니다:', error);
|
|
return [{ val: '0', text: '전체', sido: '0' }];
|
|
}
|
|
};
|
|
|
|
export const useSggCd = () => {
|
|
const [data, setData] = useState<SelectDataType[]>([]);
|
|
|
|
useEffect(() => {
|
|
const fetch = async () => {
|
|
const result = await getSggCd();
|
|
if (result) {
|
|
setData(result);
|
|
}
|
|
};
|
|
fetch();
|
|
console.log("useSggCd호출");
|
|
}, []);
|
|
return data;
|
|
};
|
|
|
|
// 시군구 데이터
|
|
export const getSggCd = async (): Promise<SelectDataType[]> => {
|
|
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<SelectDataType[]>([]);
|
|
|
|
useEffect(() => {
|
|
const fetch = async () => {
|
|
const result = await getCityCd();
|
|
if (result) {
|
|
setData(result);
|
|
}
|
|
};
|
|
fetch();
|
|
console.log("useCityCd호출");
|
|
}, []);
|
|
return data;
|
|
};
|
|
|