Files
ITAM/scratch/restore_and_merge_users.cjs
이태훈 621b05a890
Some checks failed
ITAM Code Check / build-and-config-check (push) Successful in 18s
ITAM Docker Build Check / docker-build-check (push) Failing after 21s
chore: clean up build artifacts, temporary excel locks, duplicate plans, and commit current project state
2026-06-22 11:26:26 +09:00

93 lines
3.5 KiB
JavaScript

const XLSX = require('xlsx');
const mysql = require('mysql2/promise');
const dotenv = require('dotenv');
const path = require('path');
dotenv.config({ path: path.join(__dirname, '../.env') });
const { DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT } = process.env;
async function restoreAndMerge() {
const connection = await mysql.createConnection({
host: DB_HOST,
user: DB_USER,
password: DB_PASS,
database: DB_NAME,
port: parseInt(DB_PORT || '3306')
});
console.log('🔄 데이터 복구 및 병합 시작...');
// 1. 백업 파일에서 기존 데이터(212건) 로드
const workbookBackup = XLSX.readFile('backupDB_20260602.xlsx');
const oldUsers = XLSX.utils.sheet_to_json(workbookBackup.Sheets['system_users']);
// 2. 신규 파일에서 데이터(987건) 로드
const workbookNew = XLSX.readFile('system_User (20260615).xlsx');
const newUsers = XLSX.utils.sheet_to_json(workbookNew.Sheets[workbookNew.SheetNames[0]]);
console.log(`기본 백업 데이터: ${oldUsers.length}`);
console.log(`신규 추가 데이터: ${newUsers.length}`);
// 테이블 비우기 (실수를 바로잡기 위해 다시 시작)
await connection.query('DELETE FROM system_users');
const insertedEmpNos = new Set();
let restoreCount = 0;
let addCount = 0;
// 3. 기존 데이터 복구 (ID 보존 시도)
for (const user of oldUsers) {
const { id, emp_no, user_name, dept_name, position, status, created_at } = user;
// 엑셀 날짜 처리 (숫자로 되어 있을 경우)
let finalCreatedAt = created_at;
if (typeof created_at === 'number') {
const date = new Date((created_at - 25569) * 86400 * 1000);
finalCreatedAt = date.toISOString().replace('T', ' ').substring(0, 19);
}
try {
await connection.query(
'INSERT INTO system_users (id, emp_no, user_name, dept_name, position, status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)',
[id, String(emp_no), user_name, dept_name, position, status, finalCreatedAt]
);
insertedEmpNos.add(String(emp_no));
restoreCount++;
} catch (err) {
console.error(`❌ 복구 실패 (emp_no: ${emp_no}):`, err.message);
}
}
// 4. 신규 데이터 추가 (중복 제외)
for (let i = 0; i < newUsers.length; i++) {
const user = newUsers[i];
const { emp_no, user_name, dept_name, position, status } = user;
const strEmpNo = String(emp_no);
if (insertedEmpNos.has(strEmpNo)) {
continue; // 이미 복구된 데이터는 스킵
}
// 신규 데이터용 ID 생성 (기존 ID와 겹치지 않게 'NEW_' 접두어 또는 시퀀스 사용)
// 여기서는 단순히 시퀀스로 처리 (최대 ID 확인 후 +1 하는 방식이 좋으나 여기선 간단히)
const id = `USR_N_${String(i + 1).padStart(4, '0')}`;
const createdAt = new Date().toISOString().replace('T', ' ').substring(0, 19);
try {
await connection.query(
'INSERT INTO system_users (id, emp_no, user_name, dept_name, position, status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)',
[id, strEmpNo, user_name, dept_name, position, status, createdAt]
);
addCount++;
} catch (err) {
console.error(`❌ 추가 실패 (emp_no: ${emp_no}):`, err.message);
}
}
console.log(`✅ 복구 완료: 기존 ${restoreCount}건 복구, 신규 ${addCount}건 추가 (총 ${restoreCount + addCount}건)`);
await connection.end();
}
restoreAndMerge().catch(console.error);