BillCare 초기 소스 등록

비즈케어 홈즈 홈상품 운용관리(BillCare) 프론트/백엔드/Docker 구성을 exdev git에 등록합니다.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Macbook
2026-07-12 05:05:17 +09:00
commit 03cd93e1f2
160 changed files with 47915 additions and 0 deletions
@@ -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;
}
}