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[])],
};
}
}