ERP-node/frontend/lib/api/globalFile.ts

184 lines
5.3 KiB
TypeScript

import { FileInfo } from "./file";
export interface GlobalFileInfo extends FileInfo {
uploadPage: string;
uploadTime: string;
componentId: string;
screenId?: number;
accessible: boolean;
}
/**
* 전역 파일 저장소 관리 클래스
* 페이지 간 파일 공유를 위한 클라이언트 사이드 파일 레지스트리
*/
export class GlobalFileManager {
private static readonly STORAGE_KEY = "globalFileRegistry";
private static readonly SESSION_STORAGE_KEY = "globalFileRegistrySession";
/**
* 전역 파일 저장소 가져오기
*/
static getRegistry(): Record<string, GlobalFileInfo> {
if (typeof window === "undefined") return {};
// 1. 메모리에서 먼저 확인
if ((window as any).globalFileRegistry) {
return (window as any).globalFileRegistry;
}
// 2. sessionStorage에서 확인 (세션 동안 유지)
const sessionData = sessionStorage.getItem(this.SESSION_STORAGE_KEY);
if (sessionData) {
try {
const parsedData = JSON.parse(sessionData);
(window as any).globalFileRegistry = parsedData;
return parsedData;
} catch (error) {
console.warn("세션 파일 데이터 파싱 실패:", error);
}
}
// 3. localStorage에서 확인 (영구 저장)
const localData = localStorage.getItem(this.STORAGE_KEY);
if (localData) {
try {
const parsedData = JSON.parse(localData);
(window as any).globalFileRegistry = parsedData;
return parsedData;
} catch (error) {
console.warn("로컬 파일 데이터 파싱 실패:", error);
}
}
return {};
}
/**
* 파일을 전역 저장소에 등록
*/
static registerFile(fileInfo: GlobalFileInfo): void {
if (typeof window === "undefined") return;
const registry = this.getRegistry();
registry[fileInfo.objid] = fileInfo;
// 메모리, 세션, 로컬스토리지에 모두 저장
(window as any).globalFileRegistry = registry;
sessionStorage.setItem(this.SESSION_STORAGE_KEY, JSON.stringify(registry));
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(registry));
console.log(`🌐 파일 등록됨: ${fileInfo.savedFileName} (총 ${Object.keys(registry).length}개)`);
}
/**
* 여러 파일을 한번에 등록
*/
static registerFiles(
files: FileInfo[],
context: {
uploadPage: string;
componentId: string;
screenId?: number;
},
): void {
files.forEach((file) => {
const globalFileInfo: GlobalFileInfo = {
...file,
uploadPage: context.uploadPage,
uploadTime: new Date().toISOString(),
componentId: context.componentId,
screenId: context.screenId,
accessible: true,
};
this.registerFile(globalFileInfo);
});
}
/**
* 모든 접근 가능한 파일 목록 가져오기
*/
static getAllAccessibleFiles(): GlobalFileInfo[] {
const registry = this.getRegistry();
return Object.values(registry).filter((file) => file.accessible);
}
/**
* 특정 페이지에서 업로드된 파일들 가져오기
*/
static getFilesByPage(pagePath: string): GlobalFileInfo[] {
const registry = this.getRegistry();
return Object.values(registry).filter((file) => file.uploadPage === pagePath && file.accessible);
}
/**
* 특정 화면에서 업로드된 파일들 가져오기
*/
static getFilesByScreen(screenId: number): GlobalFileInfo[] {
const registry = this.getRegistry();
return Object.values(registry).filter((file) => file.screenId === screenId && file.accessible);
}
/**
* 파일 검색 (이름으로)
*/
static searchFiles(query: string): GlobalFileInfo[] {
const registry = this.getRegistry();
const lowerQuery = query.toLowerCase();
return Object.values(registry).filter(
(file) =>
file.accessible &&
(file.realFileName?.toLowerCase().includes(lowerQuery) ||
file.savedFileName?.toLowerCase().includes(lowerQuery)),
);
}
/**
* 파일을 접근 불가능하게 설정 (삭제 대신)
*/
static setFileAccessible(fileId: string, accessible: boolean): void {
const registry = this.getRegistry();
if (registry[fileId]) {
registry[fileId].accessible = accessible;
// 저장소 업데이트
(window as any).globalFileRegistry = registry;
sessionStorage.setItem(this.SESSION_STORAGE_KEY, JSON.stringify(registry));
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(registry));
}
}
/**
* 전역 저장소 초기화
*/
static clearRegistry(): void {
if (typeof window === "undefined") return;
(window as any).globalFileRegistry = {};
sessionStorage.removeItem(this.SESSION_STORAGE_KEY);
localStorage.removeItem(this.STORAGE_KEY);
console.log("🧹 전역 파일 저장소 초기화됨");
}
/**
* 저장소 상태 정보
*/
static getRegistryInfo(): {
totalFiles: number;
accessibleFiles: number;
pages: string[];
screens: number[];
} {
const registry = this.getRegistry();
const files = Object.values(registry);
return {
totalFiles: files.length,
accessibleFiles: files.filter((f) => f.accessible).length,
pages: [...new Set(files.map((f) => f.uploadPage))],
screens: [...new Set(files.map((f) => f.screenId).filter(Boolean) as number[])],
};
}
}