BillCare 초기 소스 등록
비즈케어 홈즈 홈상품 운용관리(BillCare) 프론트/백엔드/Docker 구성을 exdev git에 등록합니다. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user