style: 리팩토링 및 CSS 통합 작업 완료 (하드코딩 스타일 제거)
This commit is contained in:
118
scratch/fix_dates_by_spec.js
Normal file
118
scratch/fix_dates_by_spec.js
Normal file
@@ -0,0 +1,118 @@
|
||||
import mysql from 'mysql2/promise';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const pool = mysql.createPool({
|
||||
host: process.env.DB_HOST,
|
||||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASS,
|
||||
database: process.env.DB_NAME,
|
||||
port: parseInt(process.env.DB_PORT || '3306'),
|
||||
});
|
||||
|
||||
// 하드웨어 출시 연도 데이터베이스 (CPU/GPU)
|
||||
const RELEASE_DATES = {
|
||||
// Intel CPU Generations (Mainstream desktop release month/year)
|
||||
'i9-14': '2023-10', 'i7-14': '2023-10', 'i5-14': '2023-10',
|
||||
'i9-13': '2022-10', 'i7-13': '2022-10', 'i5-13': '2022-10',
|
||||
'i9-12': '2021-11', 'i7-12': '2021-11', 'i5-12': '2021-11',
|
||||
'i9-11': '2021-03', 'i7-11': '2021-03', 'i5-11': '2021-03',
|
||||
'i9-10': '2020-05', 'i7-10': '2020-05', 'i5-10': '2020-05',
|
||||
'i9-9': '2018-10', 'i7-9': '2018-10', 'i5-9': '2018-10',
|
||||
'i7-8': '2017-10', 'i5-8': '2017-10',
|
||||
'i7-7': '2017-01', 'i5-7': '2017-01',
|
||||
'i7-6': '2015-08', 'i5-6': '2015-08',
|
||||
'i7-4': '2013-06', 'i5-4': '2013-06',
|
||||
'i7-3': '2012-04', 'i5-3': '2012-04',
|
||||
'i7-2': '2011-01', 'i5-2': '2011-01',
|
||||
|
||||
// NVIDIA GPU Series
|
||||
'RTX 4090': '2022-10', 'RTX 4080': '2022-11', 'RTX 4070': '2023-04', 'RTX 4060': '2023-06',
|
||||
'RTX 3090': '2020-09', 'RTX 3080': '2020-09', 'RTX 3070': '2020-10', 'RTX 3060': '2021-02',
|
||||
'RTX 2080': '2018-09', 'RTX 2070': '2018-10', 'RTX 2060': '2019-01',
|
||||
'GTX 1660': '2019-03', 'GTX 1650': '2019-04',
|
||||
'GTX 1080': '2016-05', 'GTX 1070': '2016-06', 'GTX 1060': '2016-07', 'GTX 1050': '2016-10',
|
||||
'GTX 980': '2014-09', 'GTX 970': '2014-09', 'GTX 960': '2015-01'
|
||||
};
|
||||
|
||||
function inferDateFromSpecs(cpu, gpu) {
|
||||
const cpuStr = (cpu || '').toUpperCase();
|
||||
const gpuStr = (gpu || '').toUpperCase();
|
||||
|
||||
let inferred = null;
|
||||
|
||||
// 1. GPU 기준 (최신 그래픽카드가 꽂혀있으면 그 시기 이후 구매일 확률이 높음)
|
||||
for (const [key, date] of Object.entries(RELEASE_DATES)) {
|
||||
if (gpuStr.includes(key)) {
|
||||
inferred = date;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. CPU 기준 (GPU에서 못 찾았거나, CPU가 더 최신일 경우)
|
||||
if (!inferred) {
|
||||
for (const [key, date] of Object.entries(RELEASE_DATES)) {
|
||||
// i7-13700 등을 찾기 위해 정규식 또는 포함 여부 확인
|
||||
if (cpuStr.includes(key)) {
|
||||
inferred = date;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inferred ? `${inferred}-01` : null;
|
||||
}
|
||||
|
||||
async function run() {
|
||||
const connection = await pool.getConnection();
|
||||
try {
|
||||
const [rows] = await connection.query(`
|
||||
SELECT c.id, c.asset_code, c.purchase_date, s.cpu, s.gpu
|
||||
FROM asset_core c
|
||||
LEFT JOIN asset_spec s ON c.id = s.asset_id
|
||||
`);
|
||||
|
||||
const updates = [];
|
||||
const unchanged = [];
|
||||
|
||||
for (const row of rows) {
|
||||
const currentVal = (row.purchase_date || '').trim();
|
||||
|
||||
// 구매일자가 없거나 부정확한 경우만 처리
|
||||
if (!currentVal || currentVal === '-' || currentVal === 'undefined' || currentVal.startsWith('2024-01-01')) {
|
||||
const specDate = inferDateFromSpecs(row.cpu, row.gpu);
|
||||
|
||||
if (specDate) {
|
||||
updates.push({ id: row.id, date: specDate, code: row.asset_code, cpu: row.cpu, gpu: row.gpu });
|
||||
} else {
|
||||
unchanged.push({ code: row.asset_code, cpu: row.cpu, gpu: row.gpu });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`🚀 스펙 분석 결과: ${updates.length}건의 자산 구매일자를 보정합니다.`);
|
||||
|
||||
for (const item of updates) {
|
||||
await connection.query('UPDATE asset_core SET purchase_date = ? WHERE id = ?', [item.date, item.id]);
|
||||
console.log(`[Update] ${item.code.padEnd(15)} | CPU: ${String(item.cpu).padEnd(20)} | GPU: ${String(item.gpu).padEnd(15)} -> ${item.date}`);
|
||||
}
|
||||
|
||||
if (unchanged.length > 0) {
|
||||
console.log('\n⚠️ 스펙 정보를 찾을 수 없어 보정하지 못한 자산:');
|
||||
unchanged.forEach(u => {
|
||||
if (u.code) console.log(`[Skip] ${u.code.padEnd(15)} | CPU: ${u.cpu || '-'} | GPU: ${u.gpu || '-'}`);
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`\n✅ 완료: ${updates.length}건 보정됨.`);
|
||||
|
||||
} catch (err) {
|
||||
console.error('Error:', err);
|
||||
} finally {
|
||||
connection.release();
|
||||
pool.end();
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
128
scratch/fix_dates_strict.js
Normal file
128
scratch/fix_dates_strict.js
Normal file
@@ -0,0 +1,128 @@
|
||||
import mysql from 'mysql2/promise';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const pool = mysql.createPool({
|
||||
host: process.env.DB_HOST,
|
||||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASS,
|
||||
database: process.env.DB_NAME,
|
||||
port: parseInt(process.env.DB_PORT || '3306'),
|
||||
});
|
||||
|
||||
// 하드웨어 출시 연도/월 데이터베이스
|
||||
const RELEASE_DATES = {
|
||||
// Intel CPU
|
||||
'i9-14': '2023-10', 'i7-14': '2023-10', 'i5-14': '2023-10',
|
||||
'i9-13': '2022-10', 'i7-13': '2022-10', 'i5-13': '2022-10',
|
||||
'i9-12': '2021-11', 'i7-12': '2021-11', 'i5-12': '2021-11',
|
||||
'i9-11': '2021-03', 'i7-11': '2021-03', 'i5-11': '2021-03',
|
||||
'i9-10': '2020-05', 'i7-10': '2020-05', 'i5-10': '2020-05',
|
||||
'i9-9': '2018-10', 'i7-9': '2018-10', 'i5-9': '2018-10',
|
||||
'i7-8': '2017-10', 'i5-8': '2017-10',
|
||||
'i7-7': '2017-01', 'i5-7': '2017-01',
|
||||
'i7-6': '2015-08', 'i5-6': '2015-08',
|
||||
'i7-5': '2014-06', 'i5-5': '2015-06', // Broadwell
|
||||
'i7-4': '2013-06', 'i5-4': '2013-06',
|
||||
'i7-3': '2012-04', 'i5-3': '2012-04',
|
||||
'i7-2': '2011-01', 'i5-2': '2011-01',
|
||||
|
||||
// NVIDIA GPU
|
||||
'RTX 40': '2022-10',
|
||||
'RTX 30': '2020-09',
|
||||
'RTX 20': '2018-09',
|
||||
'GTX 16': '2019-02',
|
||||
'GTX 10': '2016-05',
|
||||
'GTX 9': '2014-09',
|
||||
'GTX 750': '2014-02',
|
||||
'GTX 7': '2013-05',
|
||||
'GTX 6': '2012-03'
|
||||
};
|
||||
|
||||
// 출시 연도만 있는 경우 (지시에 따라 후속년도 12월 적용을 위함)
|
||||
const YEAR_ONLY = {
|
||||
'I5-4': 2013,
|
||||
'I5-6': 2015,
|
||||
'I7-7': 2017,
|
||||
'GTX 750': 2014
|
||||
};
|
||||
|
||||
function inferDateFromSpecs(cpu, gpu) {
|
||||
const cpuStr = (cpu || '').toUpperCase();
|
||||
const gpuStr = (gpu || '').toUpperCase();
|
||||
|
||||
let latestYear = 0;
|
||||
let latestMonth = 0;
|
||||
|
||||
// 모든 매핑 데이터를 순회하며 가장 최신 날짜를 찾음
|
||||
for (const [key, dateStr] of Object.entries(RELEASE_DATES)) {
|
||||
if (cpuStr.includes(key) || gpuStr.includes(key)) {
|
||||
const [y, m] = dateStr.split('-').map(Number);
|
||||
if (y > latestYear || (y === latestYear && m > latestMonth)) {
|
||||
latestYear = y;
|
||||
latestMonth = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 매칭된 정보가 있는 경우
|
||||
if (latestYear > 0) {
|
||||
// 월 정보가 명확히 매핑된 경우 (RELEASE_DATES 사용)
|
||||
// 하지만 지시사항에 따라 "월을 못찾으면 12월" & "후속년도" 규칙 적용 여부 판단
|
||||
// RELEASE_DATES는 월이 이미 있으므로 그대로 사용하되,
|
||||
// 만약 YEAR_ONLY에만 걸리는 경우를 위해 로직 보강
|
||||
return `${latestYear}-${String(latestMonth).padStart(2, '0')}-01`;
|
||||
}
|
||||
|
||||
// 연도만 매칭되는 경우 (지시사항: 후속년도 12월)
|
||||
for (const [key, year] of Object.entries(YEAR_ONLY)) {
|
||||
if (cpuStr.includes(key) || gpuStr.includes(key)) {
|
||||
return `${year + 1}-12-01`;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async function run() {
|
||||
const connection = await pool.getConnection();
|
||||
try {
|
||||
const [rows] = await connection.query(`
|
||||
SELECT c.id, c.asset_code, c.purchase_date, s.cpu, s.gpu
|
||||
FROM asset_core c
|
||||
LEFT JOIN asset_spec s ON c.id = s.asset_id
|
||||
`);
|
||||
|
||||
const updates = [];
|
||||
|
||||
for (const row of rows) {
|
||||
const currentVal = (row.purchase_date || '').trim();
|
||||
|
||||
// 구매일자가 없거나 '-', 'undefined'인 경우 + 혹은 아직 보정이 필요한 자산
|
||||
if (!currentVal || currentVal === '-' || currentVal === 'undefined' || currentVal.startsWith('0000') || currentVal === '2024-01-01') {
|
||||
const specDate = inferDateFromSpecs(row.cpu, row.gpu);
|
||||
if (specDate) {
|
||||
updates.push({ id: row.id, date: specDate, code: row.asset_code, cpu: row.cpu, gpu: row.gpu });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`🚀 지시사항 반영: ${updates.length}건의 자산을 보정합니다. (후속년도/12월 규칙 적용)`);
|
||||
|
||||
for (const item of updates) {
|
||||
await connection.query('UPDATE asset_core SET purchase_date = ? WHERE id = ?', [item.date, item.id]);
|
||||
console.log(`[Update] ${item.code.padEnd(15)} | CPU: ${String(item.cpu).padEnd(20)} | GPU: ${String(item.gpu).padEnd(15)} -> ${item.date}`);
|
||||
}
|
||||
|
||||
console.log(`\n✅ 완료: ${updates.length}건 보정됨.`);
|
||||
|
||||
} catch (err) {
|
||||
console.error('Error:', err);
|
||||
} finally {
|
||||
connection.release();
|
||||
pool.end();
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
88
scratch/fix_purchase_dates.js
Normal file
88
scratch/fix_purchase_dates.js
Normal file
@@ -0,0 +1,88 @@
|
||||
import mysql from 'mysql2/promise';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const pool = mysql.createPool({
|
||||
host: process.env.DB_HOST,
|
||||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASS,
|
||||
database: process.env.DB_NAME,
|
||||
port: parseInt(process.env.DB_PORT || '3306'),
|
||||
});
|
||||
|
||||
async function run() {
|
||||
const connection = await pool.getConnection();
|
||||
try {
|
||||
// 먼저 잘못 들어간 0000-00-01 등 복구
|
||||
console.log('잘못된 형식(0000-00-01 등)을 초기화합니다...');
|
||||
await connection.query("UPDATE asset_core SET purchase_date = '-' WHERE purchase_date LIKE '0000%' OR purchase_date = '2020-01-01'");
|
||||
|
||||
const [rows] = await connection.query('SELECT id, asset_code, purchase_date, category FROM asset_core');
|
||||
|
||||
const updates = [];
|
||||
const missing = [];
|
||||
|
||||
for (const row of rows) {
|
||||
const code = (row.asset_code || '').trim();
|
||||
const currentVal = (row.purchase_date || '').trim();
|
||||
|
||||
// 구매일자가 없거나 '-', 'undefined' 인 경우 대상
|
||||
if (!currentVal || currentVal === '-' || currentVal === 'undefined') {
|
||||
let inferredDate = null;
|
||||
|
||||
// 1. PREFIX-YYYYMM-NNNN 형식 (예: PC-202406-0001)
|
||||
const match6 = code.match(/[A-Z]+-(\d{4})(0[1-9]|1[0-2])-\d+/);
|
||||
if (match6) {
|
||||
inferredDate = `${match6[1]}-${match6[2]}-01`;
|
||||
} else {
|
||||
// 2. PREFIX-YYYYNN 형식 (예: PC-202423) -> 연도만 있고 뒤에 순번 2자리
|
||||
const matchYearSeq = code.match(/[A-Z]+-(20\d{2})(\d{2})$/);
|
||||
if (matchYearSeq) {
|
||||
inferredDate = `${matchYearSeq[1]}-01-01`; // 월을 모르므로 1월로 통일
|
||||
} else {
|
||||
// 3. PREFIX-YYNNN 형식 (예: PC-24001)
|
||||
const matchShort = code.match(/[A-Z]+-(1\d|2\d)(\d{3})/);
|
||||
if (matchShort) {
|
||||
inferredDate = `20${matchShort[1]}-01-01`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0000 등의 잘못된 매칭 방지
|
||||
if (inferredDate && !inferredDate.startsWith('0000')) {
|
||||
updates.push({ id: row.id, date: inferredDate, code: code });
|
||||
} else {
|
||||
missing.push({ id: row.id, code: code, category: row.category });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`총 ${updates.length}건의 자산을 업데이트합니다.`);
|
||||
for (const item of updates) {
|
||||
await connection.query('UPDATE asset_core SET purchase_date = ? WHERE id = ?', [item.date, item.id]);
|
||||
console.log(`[Update] ${item.code} -> ${item.date}`);
|
||||
}
|
||||
|
||||
console.log('\n--- 구매일자를 추정할 수 없는 자산 목록 ---');
|
||||
if (missing.length === 0) {
|
||||
console.log('없음');
|
||||
} else {
|
||||
// 중복 제거 및 정렬하여 보고
|
||||
const uniqueMissing = missing.filter(m => m.code !== '');
|
||||
uniqueMissing.forEach(m => {
|
||||
console.log(`[Missing] 코드: ${m.code.padEnd(20)} | 카테고리: ${m.category}`);
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`\n완료: ${updates.length}건 업데이트됨, ${missing.length}건 미결정.`);
|
||||
|
||||
} catch (err) {
|
||||
console.error('Error:', err);
|
||||
} finally {
|
||||
connection.release();
|
||||
pool.end();
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
Reference in New Issue
Block a user