package com.bizcare.agent; import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.nio.file.*; import java.util.UUID; /** 공통 파일 저장소 — billing_react FileStorageService 이식. */ @Service class FileStorageService { private final Path baseDir; FileStorageService(@Value("${app.upload-dir:./storage/uploads}") String uploadDir) { this.baseDir = Paths.get(uploadDir).toAbsolutePath().normalize(); } @PostConstruct void init() { try { Files.createDirectories(baseDir); } catch (IOException e) { throw new IllegalStateException("업로드 디렉터리를 생성할 수 없습니다: " + baseDir, e); } } String store(String subDir, MultipartFile file) { if (file == null || file.isEmpty()) return null; try { Path dir = baseDir.resolve(subDir).normalize(); if (!dir.startsWith(baseDir)) throw new IllegalArgumentException("잘못된 저장 경로입니다."); Files.createDirectories(dir); String original = file.getOriginalFilename() == null ? "file" : file.getOriginalFilename(); String safe = original.replaceAll("[/\\\\]", "_").replaceAll("[\\r\\n\\t]", ""); if (safe.length() > 200) { String ext = safe.contains(".") ? safe.substring(safe.lastIndexOf('.')) : ""; safe = UUID.randomUUID().toString().replace("-", "") + ext; } Path target = dir.resolve(safe); if (Files.exists(target)) { safe = UUID.randomUUID().toString().substring(0, 8) + "_" + safe; target = dir.resolve(safe); } file.transferTo(target); return subDir + "/" + safe; } catch (IOException e) { throw new IllegalStateException("파일 저장 중 오류가 발생하였습니다.", e); } } Resource loadAsResource(String relativePath) { try { Path file = baseDir.resolve(relativePath).normalize(); if (!file.startsWith(baseDir)) throw new IllegalArgumentException("잘못된 파일 경로입니다."); Resource resource = new UrlResource(file.toUri()); if (!resource.exists() || !resource.isReadable()) { throw new IllegalArgumentException("파일을 찾을 수 없습니다."); } return resource; } catch (java.net.MalformedURLException e) { throw new IllegalArgumentException("파일을 찾을 수 없습니다."); } } void delete(String relativePath) { if (relativePath == null || relativePath.isBlank()) return; try { Path file = baseDir.resolve(relativePath).normalize(); if (file.startsWith(baseDir)) Files.deleteIfExists(file); } catch (IOException ignored) { } } static String displayName(String relativePath) { if (relativePath == null) return ""; int idx = relativePath.lastIndexOf('/'); return idx >= 0 ? relativePath.substring(idx + 1) : relativePath; } }