feat: HW 모달 UI 고도화 및 자산 분류 체계 개편

This commit is contained in:
2026-06-09 13:56:05 +09:00
parent 3ab587d342
commit 4b408b0640
5 changed files with 241 additions and 303 deletions

View File

@@ -9,6 +9,12 @@ dotenv.config();
const app = express();
app.use(cors());
app.use(express.json({ limit: '50mb' }));
app.use('/uploads', express.static('uploads')); // 업로드 파일 정적 서빙
// uploads 폴더가 없으면 생성
if (!fs.existsSync('uploads')) {
fs.mkdirSync('uploads');
}
// MySQL Pool Configuration
const pool = mysql.createPool({
@@ -327,6 +333,30 @@ app.post('/api/maps/save', (req, res) => {
} catch (err) { handleError(res, err, 'SAVE MAPS'); }
});
// 7. File Upload API (Base64)
app.post('/api/upload', (req, res) => {
try {
const { fileName, fileData } = req.body;
if (!fileName || !fileData) return res.status(400).json({ error: 'FileName and FileData are required' });
// base64 데이터에서 실제 바이너리 추출
const base64Data = fileData.replace(/^data:.*;base64,/, "");
const buffer = Buffer.from(base64Data, 'base64');
// 고유한 파일명 생성 (타임스탬프 결합)
const timestamp = Date.now();
const safeFileName = `${timestamp}_${fileName.replace(/[^a-zA-Z0-9._-]/g, '_')}`;
const filePath = `uploads/${safeFileName}`;
fs.writeFileSync(filePath, buffer);
console.log(`파일 업로드 성공: ${filePath}`);
res.json({ success: true, filePath: `/${filePath}`, fileName: safeFileName });
} catch (err) {
handleError(res, err, 'FILE UPLOAD');
}
});
app.listen(3000, '0.0.0.0', () => {
console.log('📡 ITAM BACKEND SERVER RUNNING ON PORT 3000 (V3 Normalized)');
});