356 lines
No EOL
14 KiB
PHP
356 lines
No EOL
14 KiB
PHP
<?php
|
|
/**
|
|
* db_init.php
|
|
* FKI 자산 관리 시스템 데이터베이스 초기화 및 [ex] 폴더 내 실제 데이터 일괄 가입
|
|
* 부서 계정구조(Hierarchy) 반영 버전
|
|
*/
|
|
|
|
require_once 'config.php';
|
|
|
|
// 실행 시간 제한 해제
|
|
set_time_limit(600);
|
|
|
|
echo "<!DOCTYPE html><html lang='ko'><head><meta charset='utf-8'><title>System Data Migration (Hierarchy)</title>
|
|
<style>body{font-family:'Pretendard', sans-serif;background:#f8fafc;padding:2rem;color:#1e293b;}
|
|
.log-card{background:#fff;padding:1.5rem;border-radius:1rem;box-shadow:0 10px 15px -3px rgba(0,0,0,0.1);max-width:900px;margin:0 auto;}
|
|
.success{color:#059669; font-weight:bold;} .info{color:#2563eb;} .error{color:#dc2626;}
|
|
.hierarchy-log{font-size:0.85rem; background:#f1f5f9; padding:1rem; border-radius:0.5rem; margin:1rem 0; font-family:monospace;}
|
|
hr{border:0; border-top:1px solid #e2e8f0; margin:1.5rem 0;}
|
|
</style></head><body>";
|
|
echo "<div class='log-card'>";
|
|
echo "<h1>🚀 FKI Asset Data Migration</h1>";
|
|
echo "<p class='info'>[이미지 기반 부서 계층 구조] 및 [실제 데이터] 일괄 구축을 시작합니다.</p><hr>";
|
|
|
|
try {
|
|
$db->beginTransaction();
|
|
|
|
// 1. 테이블 초기화
|
|
$db->exec("DELETE FROM laptop_assets");
|
|
$db->exec("DELETE FROM users");
|
|
$db->exec("DELETE FROM departments");
|
|
$db->exec("DELETE FROM laptop_models");
|
|
$db->exec("DELETE FROM access_cards");
|
|
$db->exec("DELETE FROM mfp_accounts");
|
|
$db->exec("DELETE FROM sqlite_sequence WHERE name IN ('users', 'departments', 'laptop_models', 'access_cards', 'mfp_accounts')");
|
|
|
|
echo "<p class='success'>✔ Existing data cleared.</p>";
|
|
|
|
// 2. 부서 계층 구조(Hierarchy) 구축
|
|
echo "<p class='info'>⏳ Seeding Department Hierarchy...</p>";
|
|
$dept_map = []; // name => id
|
|
|
|
function seedDept($db, $name, $parentId = null, $level = 1, &$map)
|
|
{
|
|
$stmt = $db->prepare("INSERT INTO departments (name, parent_id, level) VALUES (?, ?, ?)");
|
|
$stmt->execute([$name, $parentId, $level]);
|
|
$id = $db->lastInsertId();
|
|
$map[$name] = $id;
|
|
echo "<div style='margin-left: " . ($level * 15) . "px'>↳ <span class='success'>$name</span> (ID: $id)</div>";
|
|
return $id;
|
|
}
|
|
|
|
$rootId = seedDept($db, '한국경제인협회', null, 0, $dept_map);
|
|
$vcId = seedDept($db, '부회장', $rootId, 1, $dept_map);
|
|
|
|
// 연구총괄
|
|
$rgId = seedDept($db, '연구총괄', $vcId, 2, $dept_map);
|
|
$keriId = seedDept($db, '한국경제연구원', $rgId, 3, $dept_map);
|
|
|
|
$ebId = seedDept($db, '경제본부', $keriId, 4, $dept_map);
|
|
seedDept($db, '경제조사팀', $ebId, 5, $dept_map);
|
|
seedDept($db, '기업제도팀', $ebId, 5, $dept_map);
|
|
seedDept($db, '민생경제팀', $ebId, 5, $dept_map);
|
|
|
|
$gsId = seedDept($db, '성장전략실', $keriId, 4, $dept_map);
|
|
seedDept($db, '산업혁신팀', $gsId, 5, $dept_map);
|
|
seedDept($db, '뉴K-산업팀', $gsId, 5, $dept_map);
|
|
|
|
$ercId = seedDept($db, '경제연구센터', $keriId, 4, $dept_map);
|
|
seedDept($db, '미래전략팀', $ercId, 5, $dept_map);
|
|
seedDept($db, '글로벌리스크팀', $ercId, 5, $dept_map);
|
|
seedDept($db, '기업가정신발전소', $ercId, 5, $dept_map);
|
|
|
|
// 국제본부
|
|
$ibId = seedDept($db, '국제본부', $vcId, 2, $dept_map);
|
|
seedDept($db, '미주통상팀', $ibId, 3, $dept_map);
|
|
seedDept($db, '아시아중동팀', $ibId, 3, $dept_map);
|
|
seedDept($db, '유럽아프리카팀', $ibId, 3, $dept_map);
|
|
|
|
// 기획운영총괄
|
|
$popId = seedDept($db, '기획운영총괄', $vcId, 2, $dept_map);
|
|
$phbId = seedDept($db, '기획혁신본부', $popId, 3, $dept_map);
|
|
seedDept($db, '기획혁신팀', $phbId, 4, $dept_map);
|
|
seedDept($db, '인사지원팀', $phbId, 4, $dept_map);
|
|
seedDept($db, '자산운영팀', $phbId, 4, $dept_map);
|
|
seedDept($db, '사업지원TF', $phbId, 4, $dept_map);
|
|
|
|
$sgoId = seedDept($db, '지속가능경영실', $popId, 3, $dept_map);
|
|
seedDept($db, '회원서비스팀', $sgoId, 4, $dept_map);
|
|
seedDept($db, 'CSV팀', $sgoId, 4, $dept_map);
|
|
|
|
$proId = seedDept($db, '홍보실', $popId, 3, $dept_map);
|
|
seedDept($db, '홍보팀', $proId, 4, $dept_map);
|
|
seedDept($db, '뉴미디어팀', $proId, 4, $dept_map);
|
|
|
|
seedDept($db, '대외협력실', $vcId, 2, $dept_map);
|
|
seedDept($db, '컴플라이언스팀', $vcId, 2, $dept_map);
|
|
|
|
echo "<p class='success'>✔ Hierarchy seeded successfully.</p><hr>";
|
|
|
|
// 3. 경로 설정
|
|
$base_path = "d:/Docker/jasan/ex/한경협 자산관리/";
|
|
$files = [
|
|
'users' => $base_path . "한경협 직원 일람 2e9d19d26c9f414cb65e38320a21f912_all.csv",
|
|
'laptops' => $base_path . "노트북 재고 관리 9bfda0e18dbd461dbc736fcaa6268fa2_all.csv",
|
|
'mfp' => $base_path . "복합기 임시계정 현황 a66109272b8842ce99b8c2b4820b188e_all.csv",
|
|
'cards' => $base_path . "FKI 임시출입증 사용 현황 6dead1286b0447df88f8c1199ae3c4a1_all.csv"
|
|
];
|
|
|
|
// CSV 파싱 함수 (인코딩 대응)
|
|
function getCSV($path)
|
|
{
|
|
if (!file_exists($path))
|
|
return [];
|
|
$content = file_get_contents($path);
|
|
if (!mb_check_encoding($content, 'UTF-8')) {
|
|
$content = mb_convert_encoding($content, 'UTF-8', 'EUC-KR');
|
|
}
|
|
$content = preg_replace('/^\xEF\xBB\xBF/', '', $content); // Remove BOM
|
|
$lines = explode("\n", str_replace("\r", "", $content));
|
|
$headerLine = array_shift($lines);
|
|
if (!$headerLine)
|
|
return [];
|
|
$header = str_getcsv($headerLine);
|
|
$data = [];
|
|
foreach ($lines as $line) {
|
|
if (trim($line) === '')
|
|
continue;
|
|
$row = str_getcsv($line);
|
|
if (count($row) == count($header)) {
|
|
$combined = array_combine($header, $row);
|
|
if (isset($combined['이름']) && trim($combined['이름']) === '') {
|
|
$combined['이름'] = 'Unnamed_' . bin2hex(random_bytes(2));
|
|
}
|
|
$data[] = $combined;
|
|
}
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
// 4. 직원 등록 및 부서 매핑
|
|
echo "<p class='info'>⏳ Migrating Users & Mapping to Hierarchy...</p>";
|
|
$users_raw = getCSV($files['users']);
|
|
$user_map = []; // name => [id, emp_id] (for laptop matching with double check)
|
|
|
|
// 추가적인 맵핑 로직 (CSV 명칭 -> 이미지 계층 구조 명칭)
|
|
$name_aliases = [
|
|
'인사·지원팀' => '인사지원팀',
|
|
'미래전략TF' => '미래전략팀',
|
|
'경제연구실' => '경제본부',
|
|
'연구총괄대표 한국경제연구원' => '한국경제연구원',
|
|
'경제산업본부' => '경제본부',
|
|
'지속가능성장본부' => '지속가능경영실',
|
|
'컴플라이언스' => '컴플라이언스팀',
|
|
'민생경제TF' => '민생경제팀'
|
|
];
|
|
|
|
$user_stmt = $db->prepare("INSERT INTO users (emp_id, name, department_id, position, email, mobile, status, duty) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
|
$dept_insert_stmt = $db->prepare("INSERT INTO departments (name, parent_id, level) VALUES (?, ?, ?)");
|
|
|
|
foreach ($users_raw as $row) {
|
|
$raw_dept = trim($row['부서'] ?? '');
|
|
if ($raw_dept == '')
|
|
$raw_dept = '미소속';
|
|
|
|
// Alias 변환
|
|
$target_dept = $name_aliases[$raw_dept] ?? $raw_dept;
|
|
|
|
if (!isset($dept_map[$target_dept])) {
|
|
// 없는 부서라면 루트 아래에 생성
|
|
$dept_insert_stmt->execute([$target_dept, $rootId, 1]);
|
|
$dept_map[$target_dept] = $db->lastInsertId();
|
|
}
|
|
|
|
$emp_id = trim($row['사번'] ?? '') ?: 'TEMP_' . bin2hex(random_bytes(3));
|
|
$status_raw = trim($row['재직구분'] ?? '');
|
|
$status = 'active';
|
|
if ($status_raw === '퇴직' || $status_raw === '퇴사')
|
|
$status = 'retired';
|
|
elseif ($status_raw === '휴직')
|
|
$status = 'on_leave';
|
|
|
|
$user_stmt->execute([
|
|
$emp_id,
|
|
$row['이름'],
|
|
$dept_map[$target_dept],
|
|
$row['직위'] ?? '',
|
|
$row['메일'] ?? '',
|
|
$row['개인핸드폰번호'] ?? '',
|
|
$status,
|
|
$row['직책'] ?? ''
|
|
]);
|
|
|
|
$new_user_id = $db->lastInsertId();
|
|
// 중복 이름 대응을 위해 사번 정보도 함께 저장
|
|
$user_map[$row['이름']][] = [
|
|
'id' => $new_user_id,
|
|
'emp_id' => $emp_id,
|
|
'dept' => $raw_dept
|
|
];
|
|
}
|
|
echo "<p class='success'>✔ " . count($users_raw) . " users processed.</p>";
|
|
|
|
// 5. 노트북 모델 & 자산 등록
|
|
echo "<p class='info'>⏳ Processing Laptop Assets with Detailed Specs...</p>";
|
|
|
|
// 테이블 스키마 상세 사양 컬럼 확장
|
|
$spec_columns = [
|
|
'cpu' => 'TEXT',
|
|
'npu' => 'TEXT',
|
|
'hdd0_model' => 'TEXT',
|
|
'hdd0_capacity' => 'TEXT',
|
|
'hdd1_model' => 'TEXT',
|
|
'hdd1_capacity' => 'TEXT',
|
|
'ram' => 'TEXT',
|
|
'asset_status' => 'TEXT',
|
|
'assigned_user_name' => 'TEXT',
|
|
'fixed_ip' => 'TEXT',
|
|
'options' => 'TEXT',
|
|
'power_rating' => 'TEXT',
|
|
'manufacturer' => 'TEXT',
|
|
'vendor' => 'TEXT',
|
|
'product_name' => 'TEXT'
|
|
];
|
|
|
|
foreach ($spec_columns as $col => $type) {
|
|
try {
|
|
$db->exec("ALTER TABLE laptop_assets ADD COLUMN $col $type");
|
|
} catch (Exception $e) { /* 컬럼 이미 존재 시 무시 */
|
|
}
|
|
}
|
|
|
|
$laptops_raw = getCSV($files['laptops']);
|
|
$model_map = [];
|
|
$model_stmt = $db->prepare("INSERT INTO laptop_models (model_name, manufacturer) VALUES (?, ?)");
|
|
|
|
// 확장된 INSERT 문
|
|
$asset_sql = "INSERT INTO laptop_assets (
|
|
asset_tag, model_id, current_user_id, status, serial_number, purchase_date, remarks,
|
|
cpu, npu, hdd0_model, hdd0_capacity, hdd1_model, hdd1_capacity, ram,
|
|
asset_status, assigned_user_name, fixed_ip, options, power_rating, manufacturer, vendor, product_name
|
|
) VALUES (
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
?, ?, ?, ?, ?, ?, ?, ?
|
|
)";
|
|
$asset_stmt = $db->prepare($asset_sql);
|
|
|
|
foreach ($laptops_raw as $row) {
|
|
$model_name = trim($row['자산명'] ?? $row['모델명'] ?? 'Unknown Model');
|
|
$manufacturer = trim($row['제조사'] ?? 'Unknown');
|
|
if (!isset($model_map[$model_name])) {
|
|
$model_stmt->execute([$model_name, $manufacturer]);
|
|
$model_map[$model_name] = $db->lastInsertId();
|
|
}
|
|
|
|
$user_name = trim($row['사람'] ?? '');
|
|
$raw_emp_id = trim($row['한경협 사번'] ?? '');
|
|
$current_user_id = NULL;
|
|
|
|
if ($user_name && isset($user_map[$user_name])) {
|
|
$candidates = $user_map[$user_name];
|
|
if (count($candidates) === 1) {
|
|
$current_user_id = $candidates[0]['id'];
|
|
} else {
|
|
foreach ($candidates as $c) {
|
|
if ($raw_emp_id && $c['emp_id'] === $raw_emp_id) {
|
|
$current_user_id = $c['id'];
|
|
break;
|
|
}
|
|
}
|
|
if (!$current_user_id)
|
|
$current_user_id = $candidates[0]['id'];
|
|
}
|
|
}
|
|
|
|
$internal_status = $current_user_id ? 'assigned' : 'stock';
|
|
if (strpos($user_name, '업무용') !== false || strpos($user_name, '임시') !== false) {
|
|
$internal_status = 'stock';
|
|
}
|
|
|
|
$p_date = trim($row['취득일자'] ?? '');
|
|
if ($p_date && strpos($p_date, '/') !== false) {
|
|
$parts = explode('/', $p_date);
|
|
if (count($parts) == 3)
|
|
$p_date = "{$parts[2]}-{$parts[0]}-{$parts[1]}";
|
|
}
|
|
|
|
// 상세 사양 매핑
|
|
$cpu = $row['CPU'] ?? $row['프로세서'] ?? '';
|
|
$npu = $row['NPU'] ?? '';
|
|
$hdd0_model = $row['HDD 0 / 타입'] ?? '';
|
|
$hdd0_capacity = $row['HDD 0 / 설치 값'] ?? '';
|
|
$hdd1_model = $row['HDD 1 / 타입'] ?? '';
|
|
$hdd1_capacity = $row['HDD 1 / 설치 값'] ?? '';
|
|
$ram_val = $row['RAM'] ?? '';
|
|
$asset_status = $row['자산상태'] ?? '';
|
|
$assigned_user_name = $row['배정 사용자'] ?? '';
|
|
$fixed_ip = $row['고정IP'] ?? $row['고정 IP'] ?? '';
|
|
$options = $row['옵션'] ?? '';
|
|
$power_rating = $row['정격입력/출력'] ?? '';
|
|
$vendor = $row['판매사'] ?? '';
|
|
$product_name = $row['품명'] ?? '';
|
|
$remarks = $row['비고'] ?? $row['특기사항'] ?? '';
|
|
|
|
$asset_stmt->execute([
|
|
$row['자산관리번호'],
|
|
$model_map[$model_name],
|
|
$current_user_id,
|
|
$internal_status,
|
|
$row['시리얼넘버/EX'],
|
|
$p_date,
|
|
$remarks,
|
|
$cpu,
|
|
$npu,
|
|
$hdd0_model,
|
|
$hdd0_capacity,
|
|
$hdd1_model,
|
|
$hdd1_capacity,
|
|
$ram_val,
|
|
$asset_status,
|
|
$assigned_user_name,
|
|
$fixed_ip,
|
|
$options,
|
|
$power_rating,
|
|
$manufacturer,
|
|
$vendor,
|
|
$product_name
|
|
]);
|
|
}
|
|
echo "<p class='success'>✔ Laptop assets imported with all detailed specs.</p>";
|
|
|
|
// 6. 기타 계정 정보
|
|
$mfp_raw = getCSV($files['mfp']);
|
|
$mfp_stmt = $db->prepare("INSERT INTO mfp_accounts (account_id, account_pw, purpose) VALUES (?, ?, ?)");
|
|
foreach ($mfp_raw as $row) {
|
|
$mfp_stmt->execute([$row['이름'], $row['패스워드'], $row['사용 목적']]);
|
|
}
|
|
|
|
$cards_raw = getCSV($files['cards']);
|
|
$card_stmt = $db->prepare("INSERT INTO access_cards (card_number, card_type, nfc_id) VALUES (?, ?, ?)");
|
|
foreach ($cards_raw as $row) {
|
|
$card_stmt->execute([$row['보안실 넘버링'], $row['임시 네이밍'], $row['NFC Sireal']]);
|
|
}
|
|
|
|
$db->commit();
|
|
echo "<hr><p class='success' style='font-size:1.5rem;'>🎉 Data Migration & Hierarchy Seeding Completed!</p>";
|
|
echo "<p><a href='index.php' style='display:inline-block; background:#2563eb; color:#fff; padding:0.8rem 2rem; border-radius:0.5rem; text-decoration:none; font-weight:bold;'>대시보드로 이동</a></p>";
|
|
|
|
} catch (Exception $e) {
|
|
if ($db->inTransaction())
|
|
$db->rollBack();
|
|
echo "<p class='error'>❌ Critical Error: " . $e->getMessage() . "</p>";
|
|
}
|
|
|
|
echo "</div></body></html>";
|
|
?>
|