diff --git a/api.php b/api.php index ba32148..e3e5416 100644 --- a/api.php +++ b/api.php @@ -363,6 +363,141 @@ WHERE a.current_user_id = ?"; echo json_encode(['success' => true]); break; + case 'download_laptop_template': + header('Content-Type: text/csv; charset=utf-8'); + header('Content-Disposition: attachment; filename="FKI_Laptop_Import_Template.csv"'); + + // UTF-8 BOM to prevent Excel encoding issues + echo "\xEF\xBB\xBF"; + + $headers = ['자산관리번호', '시리얼번호', 'IP주소', '상태', '비고', '취득일', '정격입출력', '옵션', 'CPU', 'NPU', 'RAM', 'HDD0모델', 'HDD0용량', 'HDD1모델', 'HDD1용량', '임시배정명', '노트북모델명', '배정사용자명']; + $sample = ['0020010000245', '5CD0221MH9', '192.168.1.100', 'stock', '신규 구매 노트북', '2026-06-01', '20V / 3.25A', '지문인식, 백라이트', 'i5-1335U', '없음', '16GB', 'Imation NVMe M.2 1TB', '1TB', '슬롯없음', '슬롯없음', '업무용(TEMP_44666b)', 'HP 노트북 15S-FQ1005TU', '김건희']; + + echo implode(',', $headers) . "\n"; + echo implode(',', $sample) . "\n"; + exit; + + case 'bulk_add_laptop_assets': + $data = json_decode(file_get_contents('php://input'), true); + $assets = $data['assets'] ?? []; + + if (empty($assets)) { + echo json_encode(['success' => false, 'error' => '등록할 자산 데이터가 없습니다.']); + break; + } + + $db->beginTransaction(); + try { + $check_stmt = $db->prepare("SELECT id FROM laptop_assets WHERE asset_tag = ?"); + + $insert_stmt = $db->prepare("INSERT INTO laptop_assets ( + asset_tag, model_id, current_user_id, status, serial_number, purchase_date, ip_address, + 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, remarks + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + + $log_stmt = $db->prepare("INSERT INTO asset_history (asset_id, log_type, user_name, action_date, note) VALUES (?, 'assignment', ?, ?, '대량 가져오기로 배정됨')"); + + $inserted_count = 0; + $duplicates = []; + + foreach ($assets as $asset) { + $asset_tag = trim($asset['asset_tag'] ?? ''); + if (empty($asset_tag)) continue; + + // Check duplicate + $check_stmt->execute([$asset_tag]); + if ($check_stmt->fetch()) { + $duplicates[] = $asset_tag; + continue; + } + + // Get model details if model_id is specified + $manufacturer = ''; + $vendor = ''; + $product_name = ''; + $model_id = $asset['model_id'] ?: null; + if ($model_id) { + $m_stmt = $db->prepare("SELECT manufacturer, vendor, product_name FROM laptop_models WHERE id = ?"); + $m_stmt->execute([$model_id]); + $m_data = $m_stmt->fetch(); + if ($m_data) { + $manufacturer = $m_data['manufacturer'] ?? ''; + $vendor = $m_data['vendor'] ?? ''; + $product_name = $m_data['product_name'] ?? ''; + } + } + + // Get user name if current_user_id is specified + $assigned_user_name = $asset['assigned_user_name'] ?? ''; + $current_user_id = $asset['current_user_id'] ?: null; + if ($current_user_id) { + $u_stmt = $db->prepare("SELECT name FROM users WHERE id = ?"); + $u_stmt->execute([$current_user_id]); + $assigned_user_name = $u_stmt->fetchColumn() ?: ''; + } + + $status = ($asset['status'] ?? '') ?: ($current_user_id ? 'assigned' : 'stock'); + if ($status === 'stock' && empty($assigned_user_name)) { + $assigned_user_name = '업무용(TEMP_44666b)'; + } + + $insert_stmt->execute([ + $asset_tag, + $model_id, + $current_user_id, + $status, + $asset['serial_number'] ?? '', + $asset['purchase_date'] ?? '', + $asset['ip_address'] ?? null, + $asset['cpu'] ?? '', + $asset['npu'] ?? '', + $asset['hdd0_model'] ?? '', + $asset['hdd0_capacity'] ?? '', + $asset['hdd1_model'] ?? '', + $asset['hdd1_capacity'] ?? '', + $asset['ram'] ?? '', + $asset['asset_status'] ?? '', + $assigned_user_name, + $asset['fixed_ip'] ?? '', + $asset['options'] ?? '', + $asset['power_rating'] ?? '', + $manufacturer, + $vendor, + $product_name, + $asset['remarks'] ?? '' + ]); + + $new_id = $db->lastInsertId(); + + if ($assigned_user_name && $status === 'assigned') { + $log_stmt->execute([$new_id, $assigned_user_name, date('Y-m-d')]); + } + + $inserted_count++; + } + + if ($inserted_count === 0 && !empty($duplicates)) { + $db->rollBack(); + echo json_encode(['success' => false, 'error' => '중복된 자산 번호만 포함되어 있어 등록되지 않았습니다: ' . implode(', ', $duplicates)]); + break; + } + + $db->commit(); + + $msg = "총 {$inserted_count}대의 노트북 자산이 일괄 등록되었습니다."; + if (!empty($duplicates)) { + $msg .= " (중복 자산 제외: " . implode(', ', $duplicates) . ")"; + } + + echo json_encode(['success' => true, 'message' => $msg]); + + } catch (Exception $e) { + $db->rollBack(); + echo json_encode(['success' => false, 'error' => '자산 일괄 등록 중 오류가 발생했습니다: ' . $e->getMessage()]); + } + break; + case 'update_asset_remarks': $data = json_decode(file_get_contents('php://input'), true); $stmt = $db->prepare("UPDATE laptop_assets SET remarks = ? WHERE id = ?"); diff --git a/laptops.php b/laptops.php index d0acc88..f4b8c5d 100644 --- a/laptops.php +++ b/laptops.php @@ -58,6 +58,14 @@ 엑셀 내보내기 + + + + + 엑셀/CSV 가져오기 + 자산 등록 @@ -589,6 +597,198 @@ + + + + + + + + + + + + + 엑셀/CSV 일괄 등록 + Bulk Laptop Assets Import + + + + + + + + + + + + + + 01. 표준 포맷 다운로드 + 대량 등록용 표준 CSV 한글 양식을 다운로드하여 작성해 주세요. + + + 양식 파일 받기 (.CSV) + + + + + + 02. 파일 인코딩 선택 + 업로드한 파일에서 한글이 깨진다면 인코딩 방식을 맞춤 조정해 주세요. + + + + MS Excel 한글 깨짐 방지 (EUC-KR) 적용 + + + + + + 03. CSV 파일 가져오기 + 준비된 노트북 자산 목록 파일을 첨부해 주세요. + + + + + 파일 첨부하기 + + + + + + + + + + 가져온 데이터 실시간 매핑 테이블 + + 총 대 자산 대기 중 + + + + + + + + + 표준 포맷 파일을 업로드하면 이곳에 매핑 화면이 나타납니다. + + + + + + + + + 자산관리번호 + 기기 정보 (S/N / IP) + + 노트북 모델 연동 (현재값 매핑) + + + 배정 사용자 (현재값 매핑) + + 임시배정명 (STOCK) + 작업 + + + + + + + + + + + S/N + + + + IP + + + + + + + 모델 선택 (미지정시 사양 연동 제한) + + + + + + 파일 기재명: + + + + + + + 미배정 (재고 상태) + + + + + + 파일 기재명: + + + + + + + + + + + + + + + + + + + + + + + + + 취소 + + + 일괄 등록 완료 + + + + +
Bulk Laptop Assets Import
대량 등록용 표준 CSV 한글 양식을 다운로드하여 작성해 주세요.
업로드한 파일에서 한글이 깨진다면 인코딩 방식을 맞춤 조정해 주세요.
준비된 노트북 자산 목록 파일을 첨부해 주세요.
표준 포맷 파일을 업로드하면 이곳에 매핑 화면이 나타납니다.