- 상세 모달 레이아웃 개선: 모델명과 메인보드 동일 행 배치, 중복 메인보드 필드 제거 - OS 컬럼 스키마 매핑 및 상세 모달 입력 폼 추가 - 모든 하드웨어(서버 포함)에서 HDD 1~4 노출되도록 pc-only 속성 제거 - 서버 리스트 뷰 레이아웃 개선: 자산유형(asset_type) 컬럼 추가 및 너비 조정 - 서버 리스트 모델/메인보드 통합 컬럼 노출 로직 개선 (model_name 우선 표시) - 자산코드 일괄 재부여 스크립트(batch_reformat_codes.js) 추가 및 유니크 제약조건 회피 로직 반영
125 lines
4.5 KiB
JavaScript
125 lines
4.5 KiB
JavaScript
import mysql from 'mysql2/promise';
|
|
import dotenv from 'dotenv';
|
|
|
|
dotenv.config();
|
|
|
|
const TYPE_PREFIX_MAP = {
|
|
'서버': 'SVR', '가상서버(VM)': 'VM', '워크스테이션': 'WKS', '서버PC': 'PC',
|
|
'개인PC': 'PC', '공용PC': 'PC', '노트북': 'NBK', '태블릿': 'TAB',
|
|
'NAS': 'NAS', 'DAS': 'DAS', '스토리지': 'STO', '스토리지 렉': 'STO',
|
|
'스위치': 'NET', '방화벽': 'NET', '공유기': 'NET', '허브': 'NET', '네트워크': 'NET',
|
|
'모니터': 'MNT', '프린터': 'PRT', '스캐너': 'SCN', '복합기': 'MFP', '빔프로젝터': 'PRJ', '화상회의장비': 'VCF', '업무지원장비': 'EQP',
|
|
'CPU': 'CPU', 'HDD': 'HDD', 'RAM': 'RAM', 'GPU': 'GPU', 'SSD': 'SSD', '메인보드': 'MBD', '파워서플라이': 'PWR', '쿨러': 'CLR', '케이스': 'CAS', 'PC부품': 'PRT',
|
|
'드론': 'DRO', '측량장비': 'SUR', '보조기기': 'SUR', '공간정보장비': 'SUR',
|
|
'책상': 'FRN', '의자': 'FRN', '캐비닛': 'FRN', '사무가구': 'FRN',
|
|
'구독SW': 'SW', '영구SW': 'SW', '외부': 'SW', '내부': 'INT',
|
|
'선물': 'GFT', 'VIP': 'VIP'
|
|
};
|
|
|
|
function formatPurchaseDate(date) {
|
|
if (!date) return '000000';
|
|
let s = String(date).replace(/[^0-9]/g, '');
|
|
if (s.length >= 6) {
|
|
return s.substring(0, 6);
|
|
}
|
|
return '000000';
|
|
}
|
|
|
|
async function reformatAllCodes() {
|
|
const connection = await mysql.createConnection({
|
|
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')
|
|
});
|
|
|
|
try {
|
|
const tables = [
|
|
'asset_pc', 'asset_server', 'asset_network', 'asset_storage',
|
|
'asset_equipment', 'asset_survey', 'asset_pc_parts', 'asset_office_supplies',
|
|
'asset_sw_external', 'asset_sw_internal', 'asset_vip'
|
|
];
|
|
|
|
let allAssets = [];
|
|
|
|
for (const table of tables) {
|
|
try {
|
|
const [rows] = await connection.query(`SELECT * FROM ${table}`);
|
|
allAssets = allAssets.concat(rows.map(r => ({ ...r, sourceTable: table })));
|
|
} catch (err) {
|
|
if (err.code === 'ER_NO_SUCH_TABLE') {
|
|
console.log(`Skipping missing table: ${table}`);
|
|
} else {
|
|
console.error(`Error querying ${table}:`, err.message);
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log(`Total assets loaded: ${allAssets.length}`);
|
|
|
|
// Process each asset
|
|
const processed = allAssets.map(a => {
|
|
// 1. Determine prefix
|
|
let prefix = 'AST';
|
|
if (a.asset_type && TYPE_PREFIX_MAP[a.asset_type]) {
|
|
prefix = TYPE_PREFIX_MAP[a.asset_type];
|
|
} else if (a.category && TYPE_PREFIX_MAP[a.category]) {
|
|
prefix = TYPE_PREFIX_MAP[a.category];
|
|
} else if (a.sourceTable === 'asset_sw_external') prefix = 'SW';
|
|
else if (a.sourceTable === 'asset_sw_internal') prefix = 'INT';
|
|
|
|
// 2. Determine YYYYMM
|
|
const dateStr = a.purchase_date || a.start_date || ''; // start_date for SW
|
|
const yyyymm = formatPurchaseDate(dateStr);
|
|
|
|
return { ...a, prefix, yyyymm };
|
|
});
|
|
|
|
// Group by Prefix
|
|
const groups = {};
|
|
processed.forEach(a => {
|
|
if (!groups[a.prefix]) groups[a.prefix] = [];
|
|
groups[a.prefix].push(a);
|
|
});
|
|
|
|
// Start renaming
|
|
for (const prefix in groups) {
|
|
const items = groups[prefix];
|
|
|
|
// Sort logic to maintain some order (by date then id)
|
|
items.sort((a, b) => {
|
|
if (a.yyyymm !== b.yyyymm) return a.yyyymm.localeCompare(b.yyyymm);
|
|
return String(a.id).localeCompare(String(b.id));
|
|
});
|
|
|
|
console.log(`Processing group ${prefix}: ${items.length} items`);
|
|
|
|
// Temporary rename to avoid UNIQUE constraint conflicts during sequential updates
|
|
for (const item of items) {
|
|
const tempCode = `TEMP-${Math.random().toString(36).substring(2, 10)}-${item.id}`;
|
|
await connection.query(`UPDATE ${item.sourceTable} SET asset_code = ? WHERE id = ?`, [tempCode, item.id]);
|
|
}
|
|
|
|
for (let i = 0; i < items.length; i++) {
|
|
const item = items[i];
|
|
const serial = String(i + 1).padStart(4, '0'); // SVR-202209-0001
|
|
|
|
// Some formats might want 3 or 4 digits. Defaulting to 4.
|
|
const newCode = `${prefix}-${item.yyyymm}-${serial}`;
|
|
|
|
await connection.query(`UPDATE ${item.sourceTable} SET asset_code = ? WHERE id = ?`, [newCode, item.id]);
|
|
}
|
|
}
|
|
|
|
console.log('✅ Asset codes reformatted successfully.');
|
|
|
|
} catch (err) {
|
|
console.error('❌ Reformatting failed:', err);
|
|
} finally {
|
|
await connection.end();
|
|
}
|
|
}
|
|
|
|
reformatAllCodes();
|