Files
sam-react-prod/src/lib/utils/fileDownload.ts

71 lines
2.1 KiB
TypeScript
Raw Normal View History

/**
*
*
* API: GET /api/v1/files/{id}/download
* 프록시: GET /api/proxy/files/{id}/download
*/
/**
* ID로
* @param fileId ID
* @param fileName (, )
*/
export async function downloadFileById(fileId: number, fileName?: string): Promise<void> {
try {
const response = await fetch(`/api/proxy/files/${fileId}/download`);
if (!response.ok) {
throw new Error(`다운로드 실패: ${response.status}`);
}
const blob = await response.blob();
// 파일명이 없으면 Content-Disposition 헤더에서 추출 시도
let downloadFileName = fileName;
if (!downloadFileName) {
const contentDisposition = response.headers.get('Content-Disposition');
if (contentDisposition) {
const match = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
if (match && match[1]) {
downloadFileName = match[1].replace(/['"]/g, '');
// URL 디코딩 (한글 파일명 처리)
try {
downloadFileName = decodeURIComponent(downloadFileName);
} catch {
// 디코딩 실패 시 그대로 사용
}
}
}
}
// 그래도 없으면 기본 파일명
if (!downloadFileName) {
downloadFileName = `file_${fileId}`;
}
// Blob URL 생성 및 다운로드 트리거
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = downloadFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
} catch (error) {
console.error('[fileDownload] 다운로드 오류:', error);
throw error;
}
}
/**
* ()
* @param filePath
*/
export function openFileInNewTab(filePath: string): void {
// 백엔드 파일 서빙 URL 구성
const baseUrl = process.env.NEXT_PUBLIC_API_URL || '';
const fileUrl = `${baseUrl}/storage/${filePath}`;
window.open(fileUrl, '_blank');
}