출입증 관리
+보안실 연동 임시 출입증 및 NFC ID 관리
+| 카드 번호 + | +카드 종류 + (임시 네이밍) | +NFC ID + (Serial) | +상태 + | +
|---|---|---|---|
| + + | ++ + | ++ + | ++ + | +
diff --git a/.gitignore b/.gitignore index 13ff7bc..b577822 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ # [업로드 방지] 로컬 테스트 파일들이 GitLab으로 올라가지 않게 함 -dda/ +dda/, ex/ *.sqlite *.db \ No newline at end of file diff --git a/analyze_dept.php b/analyze_dept.php new file mode 100644 index 0000000..931369f --- /dev/null +++ b/analyze_dept.php @@ -0,0 +1,52 @@ += 17) { // ensure enough columns + $combined = array_combine($header, array_slice($row, 0, count($header))); + $company = trim($combined['회사'] ?? ''); + $parent = trim($combined['상위 항목'] ?? ''); + $dept = trim($combined['부서'] ?? ''); + + // Clean parent name (remove (...) part) + $parentClean = preg_replace('/\s*\(.*?\)$/', '', $parent); + + if ($company) { + if (!isset($hierarchy[$company])) + $hierarchy[$company] = []; + if ($parentClean) { + if (!isset($hierarchy[$company][$parentClean])) + $hierarchy[$company][$parentClean] = []; + if ($dept && $dept !== $parentClean) { + $hierarchy[$company][$parentClean][] = $dept; + } + } + } + } +} + +foreach ($hierarchy as $company => $parents) { + echo "🏢 " . $company . "\n"; + foreach ($parents as $parent => $depts) { + echo " 📂 " . $parent . "\n"; + $uniqueDepts = array_unique($depts); + foreach ($uniqueDepts as $d) { + echo " 📄 " . $d . "\n"; + } + } + echo "\n"; +} +?> \ No newline at end of file diff --git a/api.php b/api.php index 485cd9f..5699898 100644 --- a/api.php +++ b/api.php @@ -32,13 +32,21 @@ try { echo json_encode([ 'laptops' => ['total' => (int) $laptop_total, 'assigned' => (int) $laptop_assigned], 'cards' => ['total' => (int) $card_total, 'assigned' => (int) $card_assigned], - 'mfp' => ['total' => (int) $mfp_total, 'assigned' => (int) $mfp_active], + 'mfp' => ['total' => (int) $mfp_total, 'active' => (int) $mfp_active], 'users' => ['general' => (int) $users_general, 'special' => (int) $users_special] ]); break; case 'get_users': - $query = "SELECT u.*, d.name as dept_name FROM users u LEFT JOIN departments d ON u.department_id = d.id"; + $query = "WITH RECURSIVE dept_path(id, path) AS ( + SELECT id, name FROM departments WHERE parent_id IS NULL + UNION ALL + SELECT d.id, dp.path || ' > ' || d.name + FROM departments d JOIN dept_path dp ON d.parent_id = dp.id + ) + SELECT u.*, dp.path as dept_name + FROM users u + LEFT JOIN dept_path dp ON u.department_id = dp.id"; $search = $_GET['search'] ?? ''; if ($search) { $query .= " WHERE u.name LIKE :search OR u.emp_id LIKE :search OR u.email LIKE :search"; @@ -50,14 +58,215 @@ try { echo json_encode($stmt->fetchAll()); break; + case 'add_user': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("INSERT INTO users (emp_id, name, department_id, position, email, phone, mobile, accounting_type, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([ + $data['emp_id'], + $data['name'], + $data['department_id'], + $data['position'], + $data['email'], + $data['phone'] ?? '', + $data['mobile'], + $data['accounting_type'], + $data['status'] ?? 'active' + ]); + echo json_encode(['success' => true]); + break; + + case 'update_user': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("UPDATE users SET emp_id = ?, name = ?, department_id = ?, position = ?, email = ?, phone = ?, mobile = ?, accounting_type = ?, status = ? WHERE id = ?"); + $stmt->execute([ + $data['emp_id'], + $data['name'], + $data['department_id'], + $data['position'], + $data['email'], + $data['phone'] ?? '', + $data['mobile'], + $data['accounting_type'], + $data['status'], + $data['id'] + ]); + echo json_encode(['success' => true]); + break; + case 'get_laptops': - $query = "SELECT a.*, m.model_name, m.manufacturer, u.name as user_name + $query = "SELECT a.*, m.model_name, m.manufacturer, m.specs, m.processor, m.ram, m.storage, u.name as user_name FROM laptop_assets a LEFT JOIN laptop_models m ON a.model_id = m.id LEFT JOIN users u ON a.current_user_id = u.id"; echo json_encode($db->query($query)->fetchAll()); break; + case 'get_cards': + echo json_encode($db->query("SELECT * FROM access_cards")->fetchAll()); + break; + + case 'add_card': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("INSERT INTO access_cards (card_number, card_type, nfc_id, status) VALUES (?, ?, ?, ?)"); + $stmt->execute([$data['card_number'], $data['card_type'], $data['nfc_id'], 'available']); + echo json_encode(['success' => true]); + break; + + case 'update_card': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("UPDATE access_cards SET card_number = ?, card_type = ?, nfc_id = ? WHERE id = ?"); + $stmt->execute([$data['card_number'], $data['card_type'], $data['nfc_id'], $data['id']]); + echo json_encode(['success' => true]); + break; + + case 'get_mfp': + echo json_encode($db->query("SELECT * FROM mfp_accounts")->fetchAll()); + break; + + case 'add_mfp': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("INSERT INTO mfp_accounts (account_id, account_pw, purpose, status) VALUES (?, ?, ?, ?)"); + $stmt->execute([$data['account_id'], $data['account_pw'], $data['purpose'], 'active']); + echo json_encode(['success' => true]); + break; + + case 'update_mfp': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("UPDATE mfp_accounts SET account_id = ?, account_pw = ?, purpose = ? WHERE id = ?"); + $stmt->execute([$data['account_id'], $data['account_pw'], $data['purpose'], $data['id']]); + echo json_encode(['success' => true]); + break; + + case 'get_models': + echo json_encode($db->query("SELECT * FROM laptop_models ORDER BY manufacturer, model_name")->fetchAll()); + break; + + case 'add_model': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("INSERT INTO laptop_models (model_name, manufacturer, specs) VALUES (?, ?, ?)"); + $stmt->execute([$data['model_name'], $data['manufacturer'], $data['specs'] ?? '']); + echo json_encode(['success' => true]); + break; + + case 'update_model': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("UPDATE laptop_models SET model_name = ?, manufacturer = ?, specs = ? WHERE id = ?"); + $stmt->execute([$data['model_name'], $data['manufacturer'], $data['specs'] ?? '', $data['id']]); + echo json_encode(['success' => true]); + break; + + case 'get_departments': + $sql = "WITH RECURSIVE dept_path(id, name, path, level, parent_id) AS ( + SELECT id, name, name, level, parent_id FROM departments WHERE parent_id IS NULL + UNION ALL + SELECT d.id, d.name, dp.path || ' > ' || d.name, d.level, d.parent_id + FROM departments d + JOIN dept_path dp ON d.parent_id = dp.id + ) + SELECT dp.*, + (SELECT COUNT(*) FROM users WHERE department_id = dp.id) as member_count + FROM dept_path dp + ORDER BY path"; + echo json_encode($db->query($sql)->fetchAll()); + break; + + case 'add_laptop_asset': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("INSERT INTO laptop_assets (asset_tag, model_id, current_user_id, status, serial_number, purchase_date, ip_address) VALUES (?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([ + $data['asset_tag'], + $data['model_id'], + $data['current_user_id'] ?: null, + $data['current_user_id'] ? 'assigned' : 'stock', + $data['serial_number'], + $data['purchase_date'], + $data['ip_address'] ?? null + ]); + echo json_encode(['success' => true]); + break; + + case 'update_laptop_asset': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("UPDATE laptop_assets SET asset_tag = ?, model_id = ?, current_user_id = ?, status = ?, serial_number = ?, purchase_date = ?, ip_address = ? WHERE id = ?"); + $stmt->execute([ + $data['asset_tag'], + $data['model_id'], + $data['current_user_id'] ?: null, + $data['current_user_id'] ? 'assigned' : 'stock', + $data['serial_number'], + $data['purchase_date'], + $data['ip_address'] ?? null, + $data['id'] + ]); + echo json_encode(['success' => true]); + break; + + case 'add_dept': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("INSERT INTO departments (name, parent_id, level) VALUES (?, ?, ?)"); + $stmt->execute([$data['name'], $data['parent_id'] ?: null, $data['level'] ?: 1]); + echo json_encode(['success' => true]); + break; + + case 'update_dept': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("UPDATE departments SET name = ?, parent_id = ? WHERE id = ?"); + $stmt->execute([$data['name'], $data['parent_id'] ?: null, $data['id']]); + echo json_encode(['success' => true]); + break; + + case 'get_dept_users': + $dept_id = $_GET['dept_id']; + $stmt = $db->prepare("SELECT id, name, emp_id, position FROM users WHERE department_id = ?"); + $stmt->execute([$dept_id]); + echo json_encode($stmt->fetchAll()); + break; + + case 'reassign_user': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("UPDATE users SET department_id = ? WHERE id = ?"); + foreach ($data['user_ids'] as $u_id) { + $stmt->execute([$data['new_dept_id'], $u_id]); + } + echo json_encode(['success' => true]); + break; + + case 'bulk_update_users': + $data = json_decode(file_get_contents('php://input'), true); + $userIds = $data['user_ids']; + $newStatus = $data['status'] ?? null; + $newDeptId = $data['department_id'] ?? null; + + if (empty($userIds)) { + echo json_encode(['success' => false, 'error' => 'No users selected']); + break; + } + + $sql = "UPDATE users SET "; + $params = []; + $updates = []; + if ($newStatus) { + $updates[] = "status = ?"; + $params[] = $newStatus; + } + if ($newDeptId) { + $updates[] = "department_id = ?"; + $params[] = $newDeptId; + } + + if (empty($updates)) { + echo json_encode(['success' => false, 'error' => 'No updates specified']); + break; + } + + $sql .= implode(", ", $updates) . " WHERE id IN (" . implode(",", array_fill(0, count($userIds), "?")) . ")"; + $params = array_merge($params, $userIds); + + $stmt = $db->prepare($sql); + $stmt->execute($params); + echo json_encode(['success' => true]); + break; + default: echo json_encode(['error' => 'Invalid action']); break; diff --git a/cards.php b/cards.php new file mode 100644 index 0000000..179c650 --- /dev/null +++ b/cards.php @@ -0,0 +1,140 @@ + + + +
+ + +보안실 연동 임시 출입증 및 NFC ID 관리
+| 카드 번호 + | +카드 종류 + (임시 네이밍) | +NFC ID + (Serial) | +상태 + | +
|---|---|---|---|
| + + | ++ + | ++ + | ++ + | +
[이미지 기반 부서 계층 구조] 및 [실제 데이터] 일괄 구축을 시작합니다.
✔ Existing data cleared.
"; - // [B] 직원 마스터 (users) - $db->exec("DROP TABLE IF EXISTS users"); - $db->exec("CREATE TABLE users ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - emp_id TEXT UNIQUE, - name TEXT NOT NULL, - department_id INTEGER, - position TEXT, - email TEXT, - phone TEXT, - mobile TEXT, - status TEXT DEFAULT 'active', - accounting_type TEXT DEFAULT '일반회계', - spare_1 TEXT, spare_2 TEXT, spare_3 TEXT, spare_4 TEXT, spare_5 TEXT, - FOREIGN KEY(department_id) REFERENCES departments(id) - )"); + // 2. 부서 계층 구조(Hierarchy) 구축 + echo "⏳ Seeding Department Hierarchy...
"; + $dept_map = []; // name => id - // [C] 모델 마스터 (laptop_models) - $db->exec("DROP TABLE IF EXISTS laptop_models"); - $db->exec("CREATE TABLE laptop_models ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - model_name TEXT NOT NULL, - manufacturer TEXT, - spare_1 TEXT, spare_2 TEXT, spare_3 TEXT, spare_4 TEXT, spare_5 TEXT - )"); - - // [D] 노트북 실물 (laptop_assets) - $db->exec("DROP TABLE IF EXISTS laptop_assets"); - $db->exec("CREATE TABLE laptop_assets ( - asset_tag TEXT PRIMARY KEY, - model_id INTEGER, - current_user_id INTEGER, - status TEXT DEFAULT 'stock', - serial_number TEXT, - purchase_date DATE, - spare_1 TEXT, spare_2 TEXT, spare_3 TEXT, spare_4 TEXT, spare_5 TEXT, - FOREIGN KEY(model_id) REFERENCES laptop_models(id), - FOREIGN KEY(current_user_id) REFERENCES users(id) - )"); - - // [E] 임시 출입증 (access_cards) - $db->exec("DROP TABLE IF EXISTS access_cards"); - $db->exec("CREATE TABLE access_cards ( - card_number TEXT PRIMARY KEY, - card_type TEXT, - nfc_id TEXT, - status TEXT DEFAULT 'available', - spare_1 TEXT, spare_2 TEXT, spare_3 TEXT, spare_4 TEXT, spare_5 TEXT - )"); - - // [F] 복합기 계정 (mfp_accounts) - $db->exec("DROP TABLE IF EXISTS mfp_accounts"); - $db->exec("CREATE TABLE mfp_accounts ( - account_id TEXT PRIMARY KEY, - account_pw TEXT, - purpose TEXT, - status TEXT DEFAULT 'active', - spare_1 TEXT, spare_2 TEXT, spare_3 TEXT, spare_4 TEXT, spare_5 TEXT - )"); - - echo "✔ Tables created successfully with spare columns.
"; - - // --- 2. 레거시 데이터 주입 (CSV 기반 데이터) --- - - // 2.1 부서 데이터 (ID, 이름, 레벨) - $depts = [ - [1, '경제조사팀', 1], - [3, '연구총괄대표', 1], - [4, '기획혁신본부', 1], - [5, '미구주협력팀', 1], - [6, '기획혁신팀', 1], - [7, '글로벌리스크팀', 1], - [8, '아태협력팀', 1], - [10, '기업제도팀', 1], - [11, '자산운영팀', 1], - [12, '미래전략TF', 1], - [13, '인사·지원팀', 1], - [14, '미래전략팀', 1], - [16, '국제본부', 1], - [17, '회원서비스팀', 1], - [18, '대외협력팀', 1], - [21, '커뮤니케이션본부', 1], - [23, '경제산업본부', 1], - [24, '경영지원본부', 1], - [25, '산업정책팀', 1], - [26, '국제협력팀', 1], - [28, '총무팀', 1], - [30, 'ESG팀', 1], - [31, '홍보팀', 1], - [32, '전략기획실', 1], - [36, '회원팀', 1], - [39, '기업정책팀', 1], - [40, '인재경영팀', 1] - ]; - $stmt = $db->prepare("INSERT INTO departments (id, name, level) VALUES (?, ?, ?)"); - foreach ($depts as $d) - $stmt->execute($d); - - // 2.2 직원 데이터 (FKI_TEMP 발급 로직 포함) - $users_data = [ - ['FKI20426', '한호', 1, '책임', 'hanpodosa@fki.or.kr', '02-3771-0426', '010-8563-9285'], - ['FKI24208', '정철', 3, '원장', 'cchung@fki.or.kr', NULL, NULL], - ['FKI04454', '김주태', 36, '수석', 'equilia@fki.or.kr', '02-3771-0454', '010-8539-8217'], - ['FKI00377', '이소원', 40, '수석', 'swlee@fki.or.kr', '02-3771-0377', '010-8720-8106'], - ['FKI13517', '전종대', 21, '책임', 'jdjun@fki.or.kr', '02-3771-0443', '010-9016-2668'], - ['FKI02001', '이태규', 18, '선임연구위원', 'tklee@fki.or.kr', '02-3771-0041', '010-3787-8269'], - ['FKI11638', '김다미', 17, '연구원', 'sdamis@fki.or.kr', '02-3771-0389', '010-9006-7600'] - ]; - - $user_stmt = $db->prepare("INSERT INTO users (emp_id, name, department_id, position, email, phone, mobile) VALUES (?, ?, ?, ?, ?, ?, ?)"); - foreach ($users_data as $u) { - $emp_id = $u[0]; - if (!$emp_id) { - // 이후 시퀀스로 대체하거나 임시 발급 - $emp_id = 'FKI_TEMP_' . bin2hex(random_bytes(4)); - } - $user_stmt->execute([$emp_id, $u[1], $u[2], $u[3], $u[4], $u[5], $u[6]]); + 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 "✔ Hierarchy seeded successfully.
⏳ 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...
"; + + // 테이블 스키마에 스펙 컬럼이 없다면 추가 (최초 1회만) + try { + $db->exec("ALTER TABLE laptop_assets ADD COLUMN cpu TEXT"); + $db->exec("ALTER TABLE laptop_assets ADD COLUMN ram TEXT"); + $db->exec("ALTER TABLE laptop_assets ADD COLUMN storage TEXT"); + } catch (Exception $e) { /* 이미 존재하면 무시 */ + } + + $laptops_raw = getCSV($files['laptops']); + $model_map = []; $model_stmt = $db->prepare("INSERT INTO laptop_models (model_name, manufacturer) VALUES (?, ?)"); - foreach ($models as $m) - $model_stmt->execute($m); + $asset_stmt = $db->prepare("INSERT INTO laptop_assets (asset_tag, model_id, current_user_id, status, serial_number, purchase_date, cpu, ram, storage) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); - // 2.4 노트북 자산 - $assets = [ - ['160003779', 1, 1, 'assigned', 'KVGY99YTC001Q4', '2024-01-23'], - ['160003774', 1, 2, 'assigned', 'KVGY99YTC001P1', '2024-01-23'], - ['160003823', 3, 3, 'assigned', '593491HXC00078', '2024-05-19'] - ]; - $asset_stmt = $db->prepare("INSERT INTO laptop_assets (asset_tag, model_id, current_user_id, status, serial_number, purchase_date) VALUES (?, ?, ?, ?, ?, ?)"); - foreach ($assets as $a) - $asset_stmt->execute($a); + 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(); + } - // 2.5 출입증 & 복합기 - $db->exec("INSERT INTO access_cards (card_number, card_type, nfc_id) VALUES ('FKI_244', 'Research 01', 'A3D9D7CD')"); - $db->exec("INSERT INTO mfp_accounts (account_id, account_pw, purpose) VALUES ('Audit03', 'Audit03', 'Audit Team')"); + $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']; + } + } + + $status = $current_user_id ? 'assigned' : 'stock'; + if (strpos($user_name, '업무용') !== false || strpos($user_name, '임시') !== false) { + $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['프로세서'] ?? ''; + $ram = $row['RAM'] ?? ''; + $storage = $row['HDD 0 / 설치 값'] ?? ''; + + $asset_stmt->execute([ + $row['자산관리번호'], + $model_map[$model_name], + $current_user_id, + $status, + $row['시리얼넘버/EX'], + $p_date, + $cpu, + $ram, + $storage + ]); + } + echo "✔ Laptop assets imported with 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 "✔ Migration completed successfully!
"; - echo ""; + echo "🎉 Data Migration & Hierarchy Seeding Completed!
"; + echo ""; } catch (Exception $e) { if ($db->inTransaction()) $db->rollBack(); - echo "❌ Error: " . $e->getMessage() . "
"; + echo "❌ Critical Error: " . $e->getMessage() . "
"; } -echo "조직 계층 구조를 시각화하고 부서원을 관리합니다.
+| 부서명 + (계층구조) | +인원수 + | +관리 + | +
|---|---|---|
|
+
+
+
+
+
+
+
+
+ |
+ + + | ++ + | +
임시 출입증 총 대여 현황
+일반회계 0
+특별회계 0
노트북 실사
자산태그/배정현황
보안실 연동
-준비 중
+출입증 관리
+보안실 연동 데이터
환경 설정
-준비 중
+복합기 계정
+임시 계정/pw 관리
| 자산번호 + | +기기 정보 / 사양 | +IP 주소 / 시리얼 | +배정 사용자 | +취득일 | +상태 | +
|---|---|---|---|---|---|
| + + | +
+
+
+
+
+ CPU
+ RAM
+ DISK
+ |
+ + + + | +
+
+
+
+
+ 배정 대기
+ |
+ + | + + | +
등록된 노트북 자산이 없습니다.
임시/공용 복합기 계정 및 비밀번호 관리
+| 계정 ID + | ++ Password | +사용 목적 + | +상태 + | +
|---|---|---|---|
|
+
+
+
+
+
+ |
+ + + | ++ | ++ + | +