import * as fs from 'fs'; // dummyData.ts를 읽어와서 dummyPCs 파싱 const content = fs.readFileSync('c:/Project/HM ITAM/src/core/dummyData.ts', 'utf-8'); // export const dummyPCs: any[] = [ ... ]; 패턴 추출 const match = content.match(/export const dummyPCs: any\[\] = (\[[\s\S]*?\]);/); if (!match) { console.error('Failed to parse dummyPCs from dummyData.ts'); process.exit(1); } const dummyPCs = JSON.parse(match[1]); function calculatePcScoreDeductive(cpu, ram, gpu, purchaseDate) { let score = 100; // 1. CPU 등급 감점 const cpuUpper = (cpu || '').toUpperCase(); let cpuDeduction = 0; if (cpuUpper.includes('I9') || cpuUpper.includes('RYZEN 9') || cpuUpper.includes('RYZEN9')) { cpuDeduction = 0; } else if (cpuUpper.includes('I7') || cpuUpper.includes('RYZEN 7') || cpuUpper.includes('RYZEN7')) { cpuDeduction = 5; } else if (cpuUpper.includes('I5') || cpuUpper.includes('RYZEN 5') || cpuUpper.includes('RYZEN5')) { cpuDeduction = 15; } else if (cpuUpper.includes('I3') || cpuUpper.includes('RYZEN 3') || cpuUpper.includes('RYZEN3')) { cpuDeduction = 25; } else { cpuDeduction = 30; } score -= cpuDeduction; // 2. CPU 세대 감점 let genDeduction = 0; let intelMatch = cpuUpper.match(/I\d-?(\d+)/); let gen = 0; if (intelMatch && intelMatch[1]) { const numStr = intelMatch[1]; if (numStr.length === 5) gen = parseInt(numStr.substring(0, 2), 10); else if (numStr.length === 4) gen = parseInt(numStr.substring(0, 1), 10); } let amdMatch = cpuUpper.match(/RYZEN\s?\d\s?-?(\d+)/); let amdGen = 0; if (amdMatch && amdMatch[1] && !intelMatch) { const numStr = amdMatch[1]; if (numStr.length === 4) amdGen = parseInt(numStr.substring(0, 1), 10); } if (intelMatch) { if (gen >= 12) genDeduction = 0; else if (gen >= 10) genDeduction = 5; else if (gen >= 8) genDeduction = 10; else genDeduction = 15; } else if (amdMatch) { if (amdGen >= 5) genDeduction = 0; else if (amdGen >= 3) genDeduction = 5; else genDeduction = 10; } else { genDeduction = 15; } score -= genDeduction; // 3. RAM 용량 감점 const ramUpper = (ram || '').toUpperCase(); const ramMatch = ramUpper.match(/(\d+)\s*GB/); let ramDeduction = 25; if (ramMatch && ramMatch[1]) { const ramVal = parseInt(ramMatch[1], 10); if (ramVal >= 32) ramDeduction = 0; else if (ramVal >= 16) ramDeduction = 10; else if (ramVal >= 8) ramDeduction = 20; else ramDeduction = 25; } score -= ramDeduction; // 4. GPU 성능 감점 const gpuUpper = (gpu || '').toUpperCase(); let gpuDeduction = 25; if (!gpuUpper || gpuUpper === '-' || gpuUpper.trim() === '') { gpuDeduction = 25; } else if ( gpuUpper.includes('RTX 4090') || gpuUpper.includes('RTX 4080') || gpuUpper.includes('RTX 4070') || gpuUpper.includes('RTX A5000') || gpuUpper.includes('RTX A6000') || gpuUpper.includes('RTX A4000') ) { gpuDeduction = 0; } else if ( gpuUpper.includes('RTX 3070') || gpuUpper.includes('RTX 3060') || gpuUpper.includes('RTX 2060') || gpuUpper.includes('RTX A2000') || gpuUpper.includes('RTX A3000') || gpuUpper.includes('QUADRO') ) { gpuDeduction = 5; } else if ( gpuUpper.includes('GTX 1660') || gpuUpper.includes('GTX 1080') || gpuUpper.includes('GTX 1070') || gpuUpper.includes('GTX 1060') || gpuUpper.includes('RX 6700') || gpuUpper.includes('RX 6600') ) { gpuDeduction = 15; } else { gpuDeduction = 25; } score -= gpuDeduction; // 5. 연식(노후도) 감점 let age = 0; if (purchaseDate && purchaseDate !== '-') { let normalized = purchaseDate.replace(/\./g, '-').trim(); if (/^\d{6}$/.test(normalized)) { normalized = `${normalized.substring(0, 4)}-${normalized.substring(4, 6)}`; } const purchase = new Date(normalized); if (!isNaN(purchase.getTime())) { const mockToday = new Date('2026-05-31'); const diffMs = mockToday.getTime() - purchase.getTime(); age = diffMs / (1000 * 60 * 60 * 24 * 365.25); age = Math.max(0, parseFloat(age.toFixed(1))); } } let ageDeduction = 0; if (age < 1) ageDeduction = 0; else if (age < 2) ageDeduction = 3; else if (age < 3) ageDeduction = 6; else if (age < 4) ageDeduction = 9; else if (age < 5) ageDeduction = 12; else ageDeduction = 15; score -= ageDeduction; return Math.max(10, score); } const jobScores = {}; let totalPcs = 0; const filteredPCs = dummyPCs.filter(pc => pc.user_position !== '재고PC'); filteredPCs.forEach(pc => { const job = pc.user_position || '미분류'; const score = calculatePcScoreDeductive(pc.cpu, pc.ram, pc.gpu, pc.purchase_date); if (!jobScores[job]) { jobScores[job] = { total: 0, count: 0 }; } jobScores[job].total += score; jobScores[job].count += 1; totalPcs++; }); console.log('--- Job Averages (Deductive 100-point) ---'); const sortedJobs = Object.keys(jobScores).map(job => { const avg = jobScores[job].total / jobScores[job].count; return { job, avg: parseFloat(avg.toFixed(1)), count: jobScores[job].count }; }).sort((a, b) => b.avg - a.avg); sortedJobs.forEach((item, index) => { console.log(`${index + 1}. ${item.job}: Avg=${item.avg}점, Count=${item.count}대`); }); console.log('Total PCs (excluding Stock):', totalPcs);