03cd93e1f2
비즈케어 홈즈 홈상품 운용관리(BillCare) 프론트/백엔드/Docker 구성을 exdev git에 등록합니다. Co-authored-by: Cursor <cursoragent@cursor.com>
86 lines
3.3 KiB
Java
86 lines
3.3 KiB
Java
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;
|
|
}
|
|
}
|