feat: migrate ServerPC data to asset_pc, enhance filters with location, and standardize page headers
- 서버PC 자산을 asset_pc 테이블로 통합 마이그레이션 및 스키마 확장 (위치, IP 정보 복구 완료) - 하드웨어 자산 페이지의 구매법인 필터를 자산위치 필터로 교체 및 동적 데이터 바인딩 적용 - 모든 자산 리스트 페이지 상단에 설명(Description) 필드 추가 및 헤더 표준화 - 상세 모달 내 삭제 버튼 기능 구현 및 서버PC 용도 필드 노출 오류 수정 - 현 사용조직 필터 리스트가 비어있던 DOM 셀렉터 버그 수정
This commit is contained in:
83
restore_server_pc_data.js
Normal file
83
restore_server_pc_data.js
Normal file
@@ -0,0 +1,83 @@
|
||||
import mysql from 'mysql2/promise';
|
||||
import dotenv from 'dotenv';
|
||||
import xlsx from 'xlsx';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
async function restoreData() {
|
||||
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 {
|
||||
console.log('🔄 Restoring ServerPC metadata (Final Attempt)...');
|
||||
|
||||
// 1. Excel 로드
|
||||
const workbook = xlsx.readFile('server_db.xlsx');
|
||||
const sheetName = workbook.SheetNames[0];
|
||||
const excelRows = xlsx.utils.sheet_to_json(workbook.Sheets[sheetName]);
|
||||
|
||||
// 2. DB에서 현재 서버PC 데이터 로드
|
||||
const [dbAssets] = await connection.query(
|
||||
"SELECT id, memo, asset_code FROM asset_pc WHERE asset_type = '서버PC'"
|
||||
);
|
||||
|
||||
console.log(`📊 DB: ${dbAssets.length} assets, Excel: ${excelRows.length} rows.`);
|
||||
|
||||
for (const asset of dbAssets) {
|
||||
// 메모에서 "서버코드 : [ID]" 패턴 추출
|
||||
// 인코딩 문제로 깨져 보일 수 있으므로 유연하게 매칭 ( jh-idc-001 패턴 찾기 )
|
||||
const memo = asset.memo || '';
|
||||
const match = memo.match(/[a-z]+-idc-[0-9]+/i);
|
||||
const serverCode = match ? match[0] : null;
|
||||
|
||||
if (!serverCode) {
|
||||
console.log(` ❓ Could not find server code in memo for asset ${asset.asset_code}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Excel에서 해당 서버코드 찾기 (memo 필드 안에 포함되어 있음)
|
||||
const matchedExcelRow = excelRows.find(r =>
|
||||
r.memo && r.memo.includes(serverCode)
|
||||
);
|
||||
|
||||
if (matchedExcelRow) {
|
||||
const updateData = {
|
||||
location: matchedExcelRow.location,
|
||||
location_detail: matchedExcelRow.location_detail,
|
||||
ip_address: matchedExcelRow.ip_address,
|
||||
ip_address_2: matchedExcelRow.ip_address_2,
|
||||
remote_tool: matchedExcelRow.remote_tool,
|
||||
remote_id: matchedExcelRow.remote_id,
|
||||
remote_pw: matchedExcelRow.remote_pw,
|
||||
monitoring: matchedExcelRow.monitoring,
|
||||
asset_purpose: matchedExcelRow.asset_purpose
|
||||
};
|
||||
|
||||
const setClause = Object.keys(updateData).map(key => `\`${key}\` = ?`).join(', ');
|
||||
const values = [...Object.values(updateData), asset.id];
|
||||
|
||||
await connection.query(
|
||||
`UPDATE asset_pc SET ${setClause} WHERE id = ?`,
|
||||
values
|
||||
);
|
||||
console.log(` ✅ Restored: ${asset.asset_code} (Code: ${serverCode})`);
|
||||
} else {
|
||||
console.log(` ⚠️ No Excel match for server code: ${serverCode}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('🎉 Restoration completed!');
|
||||
|
||||
} catch (err) {
|
||||
console.error('❌ Restoration failed:', err);
|
||||
} finally {
|
||||
await connection.end();
|
||||
}
|
||||
}
|
||||
|
||||
restoreData();
|
||||
Reference in New Issue
Block a user