import { apiClient } from "./client"; export interface FileInfo { id: string; name: string; size: number; type: string; extension: string; uploadedAt: string; lastModified: string; serverPath?: string; serverFilename?: string; } export interface FileUploadResponse { success: boolean; message: string; files: FileInfo[]; } export interface FileDownloadParams { fileId: string; serverFilename: string; originalName: string; } /** * 파일 업로드 */ export const uploadFiles = async (files: FileList): Promise => { const formData = new FormData(); Array.from(files).forEach((file) => { formData.append("files", file); }); const response = await apiClient.post("/files/upload", formData, { headers: { "Content-Type": undefined, // axios가 자동으로 multipart/form-data를 설정하도록 }, }); return response.data; }; /** * 파일 다운로드 */ export const downloadFile = async (params: FileDownloadParams): Promise => { try { console.log("📥 downloadFile 호출:", params); const response = await apiClient.get(`/files/download/${params.fileId}`, { params: { serverFilename: params.serverFilename, originalName: params.originalName, }, responseType: "blob", // 파일 다운로드를 위해 blob 타입으로 설정 }); console.log("📥 다운로드 응답:", response); // Blob URL 생성 const blob = new Blob([response.data]); const url = window.URL.createObjectURL(blob); // 다운로드 링크 생성 및 클릭 const link = document.createElement("a"); link.href = url; link.download = params.originalName; document.body.appendChild(link); link.click(); // 정리 document.body.removeChild(link); window.URL.revokeObjectURL(url); } catch (error) { console.error("파일 다운로드 오류:", error); throw new Error("파일 다운로드에 실패했습니다."); } }; /** * 파일 삭제 */ export const deleteFile = async (fileId: string, serverFilename: string): Promise => { const response = await apiClient.delete(`/files/${fileId}`, { data: { serverFilename }, }); if (!response.data.success) { throw new Error(response.data.message || "파일 삭제에 실패했습니다."); } }; /** * 파일 정보 조회 */ export const getFileInfo = async (fileId: string, serverFilename: string) => { const response = await apiClient.get(`/files/info/${fileId}`, { params: { serverFilename }, }); return response.data; }; /** * 파일 업로드 및 JSON 데이터 생성 * InteractiveScreenViewer에서 사용할 통합 함수 */ export const uploadFilesAndCreateData = async (files: FileList) => { try { // 1. 파일 업로드 const uploadResponse = await uploadFiles(files); if (!uploadResponse.success) { throw new Error(uploadResponse.message); } // 2. JSON 데이터 구조 생성 const fileData = { files: uploadResponse.files.map((file) => ({ id: file.id, name: file.name, size: file.size, type: file.type, extension: file.extension, uploadedAt: file.uploadedAt, lastModified: file.lastModified, serverFilename: file.serverFilename, // 다운로드에 필요 })), totalCount: uploadResponse.files.length, totalSize: uploadResponse.files.reduce((sum, file) => sum + file.size, 0), lastModified: new Date().toISOString(), }; return { success: true, data: fileData, message: uploadResponse.message, }; } catch (error) { console.error("파일 업로드 및 데이터 생성 오류:", error); throw error; } }; /** * 테이블 연결된 파일 조회 */ export const getLinkedFiles = async ( tableName: string, recordId: string, ): Promise<{ success: boolean; files: any[]; totalCount: number; targetObjid: string; }> => { try { console.log("📎 연결된 파일 조회:", { tableName, recordId }); const response = await apiClient.get(`/files/linked/${tableName}/${recordId}`); console.log("✅ 연결된 파일 조회 성공:", response.data); return response.data; } catch (error) { console.error("연결된 파일 조회 오류:", error); throw new Error("연결된 파일 조회에 실패했습니다."); } }; /** * 파일 미리보기 URL 생성 */ export const getFilePreviewUrl = (fileId: string): string => { const baseUrl = process.env.NEXT_PUBLIC_API_URL || "/api"; return `${baseUrl}/files/preview/${fileId}`; }; /** * 파일 다운로드 URL 생성 */ export const getFileDownloadUrl = (fileId: string): string => { const baseUrl = process.env.NEXT_PUBLIC_API_URL || "/api"; return `${baseUrl}/files/download/${fileId}`; }; /** * 직접 파일 경로 URL 생성 (정적 파일 서빙) */ export const getDirectFileUrl = (filePath: string): string => { const baseUrl = process.env.NEXT_PUBLIC_API_URL?.replace("/api", "") || ""; return `${baseUrl}${filePath}`; };