"; echo "
"; echo "

🚀 FKI Asset Data Migration

"; echo "

[이미지 기반 부서 계층 구조] 및 [실제 데이터] 일괄 구축을 시작합니다.


"; 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 "

✔ Existing data cleared.

"; // 2. 부서 계층 구조(Hierarchy) 구축 echo "

⏳ Seeding Department Hierarchy...

"; $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 "
$name (ID: $id)
"; 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 "

✔ Hierarchy seeded successfully.


"; // 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 "

⏳ Migrating Users & Mapping to Hierarchy...

"; $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 "

✔ " . count($users_raw) . " users processed.

"; // 5. 노트북 모델 & 자산 등록 echo "

⏳ Processing Laptop Assets with Detailed Specs...

"; // 테이블 스키마 상세 사양 컬럼 확장 $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 "

✔ Laptop assets imported with all detailed specs.

"; // 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 "

🎉 Data Migration & Hierarchy Seeding Completed!

"; echo "

대시보드로 이동

"; } catch (Exception $e) { if ($db->inTransaction()) $db->rollBack(); echo "

❌ Critical Error: " . $e->getMessage() . "

"; } echo "
"; ?>