diff --git a/api.php b/api.php index 5699898..b2e7bd4 100644 --- a/api.php +++ b/api.php @@ -101,6 +101,37 @@ try { echo json_encode($db->query($query)->fetchAll()); break; + case 'get_rental_laptops': + $query = "SELECT a.*, m.model_name, m.manufacturer, m.product_name + FROM laptop_assets a + LEFT JOIN laptop_models m ON a.model_id = m.id + WHERE a.assigned_user_name LIKE '%업무용%'"; + echo json_encode($db->query($query)->fetchAll()); + break; + + case 'update_rental': + $data = json_decode(file_get_contents('php://input'), true); + $stmt = $db->prepare("UPDATE laptop_assets SET rental_user_name = ? WHERE id = ?"); + $stmt->execute([$data['rental_user_name'], $data['id']]); + + // Log the rental action + if ($data['rental_user_name']) { + $log_stmt = $db->prepare("INSERT INTO asset_history (asset_id, log_type, user_name, action_date) VALUES (?, 'rental', ?, ?)"); + $log_stmt->execute([$data['id'], $data['rental_user_name'], date('Y-m-d')]); + } + echo json_encode(['success' => true]); + break; + + case 'get_asset_history': + $asset_id = $_GET['asset_id']; + $rental_logs = $db->query("SELECT * FROM asset_history WHERE asset_id = $asset_id AND log_type = 'rental' ORDER BY id DESC LIMIT 20")->fetchAll(); + $assign_logs = $db->query("SELECT * FROM asset_history WHERE asset_id = $asset_id AND log_type = 'assignment' ORDER BY id DESC LIMIT 20")->fetchAll(); + echo json_encode([ + 'rental' => $rental_logs, + 'assignment' => $assign_logs + ]); + break; + case 'get_cards': echo json_encode($db->query("SELECT * FROM access_cards")->fetchAll()); break; @@ -143,15 +174,66 @@ try { 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'] ?? '']); + $stmt = $db->prepare("INSERT INTO laptop_models ( + model_name, manufacturer, specs, cpu, npu, hdd0_model, hdd0_capacity, + hdd1_model, hdd1_capacity, ram, asset_status, assigned_user, fixed_ip, + remarks, options, power_rating, purchase_date, vendor, product_name + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([ + $data['model_name'], + $data['manufacturer'], + $data['specs'] ?? '', + $data['cpu'] ?? '', + $data['npu'] ?? '', + $data['hdd0_model'] ?? '', + $data['hdd0_capacity'] ?? '', + $data['hdd1_model'] ?? '', + $data['hdd1_capacity'] ?? '', + $data['ram'] ?? '', + $data['asset_status'] ?? '', + $data['assigned_user'] ?? '', + $data['fixed_ip'] ?? '', + $data['remarks'] ?? '', + $data['options'] ?? '', + $data['power_rating'] ?? '', + $data['purchase_date'] ?? '', + $data['vendor'] ?? '', + $data['product_name'] ?? '' + ]); 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']]); + $stmt = $db->prepare("UPDATE laptop_models SET + model_name = ?, manufacturer = ?, specs = ?, cpu = ?, npu = ?, + hdd0_model = ?, hdd0_capacity = ?, hdd1_model = ?, hdd1_capacity = ?, + ram = ?, asset_status = ?, assigned_user = ?, fixed_ip = ?, + remarks = ?, options = ?, power_rating = ?, purchase_date = ?, + vendor = ?, product_name = ? + WHERE id = ?"); + $stmt->execute([ + $data['model_name'], + $data['manufacturer'], + $data['specs'] ?? '', + $data['cpu'] ?? '', + $data['npu'] ?? '', + $data['hdd0_model'] ?? '', + $data['hdd0_capacity'] ?? '', + $data['hdd1_model'] ?? '', + $data['hdd1_capacity'] ?? '', + $data['ram'] ?? '', + $data['asset_status'] ?? '', + $data['assigned_user'] ?? '', + $data['fixed_ip'] ?? '', + $data['remarks'] ?? '', + $data['options'] ?? '', + $data['power_rating'] ?? '', + $data['purchase_date'] ?? '', + $data['vendor'] ?? '', + $data['product_name'] ?? '', + $data['id'] + ]); echo json_encode(['success' => true]); break; @@ -172,22 +254,11 @@ try { 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 = $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, last_confirmed_date + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([ $data['asset_tag'], $data['model_id'], @@ -196,8 +267,79 @@ try { $data['serial_number'], $data['purchase_date'], $data['ip_address'] ?? null, + $data['cpu'] ?? '', + $data['npu'] ?? '', + $data['hdd0_model'] ?? '', + $data['hdd0_capacity'] ?? '', + $data['hdd1_model'] ?? '', + $data['hdd1_capacity'] ?? '', + $data['ram'] ?? '', + $data['asset_status'] ?? '', + $data['assigned_user_name'] ?? '', + $data['fixed_ip'] ?? '', + $data['options'] ?? '', + $data['power_rating'] ?? '', + $data['manufacturer'] ?? '', + $data['vendor'] ?? '', + $data['product_name'] ?? '', + $data['remarks'] ?? '', + $data['last_confirmed_date'] ?? null + ]); + $new_asset_id = $db->lastInsertId(); + if ($data['assigned_user_name']) { + $log_stmt = $db->prepare("INSERT INTO asset_history (asset_id, log_type, user_name, action_date) VALUES (?, 'assignment', ?, ?)"); + $log_stmt->execute([$new_asset_id, $data['assigned_user_name'], date('Y-m-d')]); + } + echo json_encode(['success' => true]); + break; + + case 'update_laptop_asset': + $data = json_decode(file_get_contents('php://input'), true); + + // Get old data for logging comparison + $old_stmt = $db->prepare("SELECT assigned_user_name FROM laptop_assets WHERE id = ?"); + $old_stmt->execute([$data['id']]); + $old_asset = $old_stmt->fetch(); + + $stmt = $db->prepare("UPDATE laptop_assets SET + 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 = ?, last_confirmed_date = ? + 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['cpu'] ?? '', + $data['npu'] ?? '', + $data['hdd0_model'] ?? '', + $data['hdd0_capacity'] ?? '', + $data['hdd1_model'] ?? '', + $data['hdd1_capacity'] ?? '', + $data['ram'] ?? '', + $data['asset_status'] ?? '', + $data['assigned_user_name'] ?? '', + $data['fixed_ip'] ?? '', + $data['options'] ?? '', + $data['power_rating'] ?? '', + $data['manufacturer'] ?? '', + $data['vendor'] ?? '', + $data['product_name'] ?? '', + $data['remarks'] ?? '', + $data['last_confirmed_date'] ?? null, $data['id'] ]); + + // Auto-log assignment change + if ($data['assigned_user_name'] && $data['assigned_user_name'] !== ($old_asset['assigned_user_name'] ?? '')) { + $log_stmt = $db->prepare("INSERT INTO asset_history (asset_id, log_type, user_name, action_date) VALUES (?, 'assignment', ?, ?)"); + $log_stmt->execute([$data['id'], $data['assigned_user_name'], date('Y-m-d')]); + } + echo json_encode(['success' => true]); break; @@ -231,6 +373,122 @@ try { echo json_encode(['success' => true]); break; + case 'bulk_update_laptops': + $data = json_decode(file_get_contents('php://input'), true); + $ids = $data['ids']; + $newStatus = $data['status'] ?? null; + $newModelId = $data['model_id'] ?? null; + if (empty($ids)) { + echo json_encode(['success' => false, 'error' => 'No items selected']); + break; + } + $updates = []; + $params = []; + if ($newStatus) { + $updates[] = "status = ?"; + $params[] = $newStatus; + } + if ($newModelId) { + $updates[] = "model_id = ?"; + $params[] = $newModelId; + } + if (empty($updates)) { + echo json_encode(['success' => false, 'error' => 'No updates specified']); + break; + } + $sql = "UPDATE laptop_assets SET " . implode(", ", $updates) . " WHERE id IN (" . implode(",", array_fill(0, count($ids), "?")) . ")"; + $stmt = $db->prepare($sql); + $stmt->execute(array_merge($params, $ids)); + echo json_encode(['success' => true]); + break; + + case 'bulk_update_cards': + $data = json_decode(file_get_contents('php://input'), true); + $ids = $data['ids']; + $newStatus = $data['status'] ?? null; + $newCardType = $data['card_type'] ?? null; + if (empty($ids)) { + echo json_encode(['success' => false, 'error' => 'No items selected']); + break; + } + $updates = []; + $params = []; + if ($newStatus) { + $updates[] = "status = ?"; + $params[] = $newStatus; + } + if ($newCardType) { + $updates[] = "card_type = ?"; + $params[] = $newCardType; + } + if (empty($updates)) { + echo json_encode(['success' => false, 'error' => 'No updates specified']); + break; + } + $sql = "UPDATE access_cards SET " . implode(", ", $updates) . " WHERE id IN (" . implode(",", array_fill(0, count($ids), "?")) . ")"; + $stmt = $db->prepare($sql); + $stmt->execute(array_merge($params, $ids)); + echo json_encode(['success' => true]); + break; + + case 'bulk_update_mfp': + $data = json_decode(file_get_contents('php://input'), true); + $ids = $data['ids']; + $newStatus = $data['status'] ?? null; + $newPurpose = $data['purpose'] ?? null; + if (empty($ids)) { + echo json_encode(['success' => false, 'error' => 'No items selected']); + break; + } + $updates = []; + $params = []; + if ($newStatus) { + $updates[] = "status = ?"; + $params[] = $newStatus; + } + if ($newPurpose) { + $updates[] = "purpose = ?"; + $params[] = $newPurpose; + } + if (empty($updates)) { + echo json_encode(['success' => false, 'error' => 'No updates specified']); + break; + } + $sql = "UPDATE mfp_accounts SET " . implode(", ", $updates) . " WHERE id IN (" . implode(",", array_fill(0, count($ids), "?")) . ")"; + $stmt = $db->prepare($sql); + $stmt->execute(array_merge($params, $ids)); + echo json_encode(['success' => true]); + break; + + case 'bulk_update_models': + $data = json_decode(file_get_contents('php://input'), true); + $ids = $data['ids']; + $newManufacturer = $data['manufacturer'] ?? null; + $newProductName = $data['product_name'] ?? null; + if (empty($ids)) { + echo json_encode(['success' => false, 'error' => 'No items selected']); + break; + } + $updates = []; + $params = []; + if ($newManufacturer) { + $updates[] = "manufacturer = ?"; + $params[] = $newManufacturer; + } + if ($newProductName) { + $updates[] = "product_name = ?"; + $params[] = $newProductName; + } + if (empty($updates)) { + echo json_encode(['success' => false, 'error' => 'No updates specified']); + break; + } + $sql = "UPDATE laptop_models SET " . implode(", ", $updates) . " WHERE id IN (" . implode(",", array_fill(0, count($ids), "?")) . ")"; + $stmt = $db->prepare($sql); + $stmt->execute(array_merge($params, $ids)); + echo json_encode(['success' => true]); + break; + case 'bulk_update_users': $data = json_decode(file_get_contents('php://input'), true); $userIds = $data['user_ids']; diff --git a/cards.php b/cards.php index 179c650..ced6352 100644 --- a/cards.php +++ b/cards.php @@ -31,16 +31,51 @@
보안실 연동 임시 출입증 및 NFC ID 관리
- + +| + + | 카드 번호 | 카드 종류 @@ -52,19 +87,23 @@ | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
+
+ |
+
+ |
+
|
-
+ |
|
-
+ |
|
-
+ |
function cardManagement() {
return {
- cards: [], showModal: false, isEdit: false, formData: { id: '', card_number: '', card_type: '', nfc_id: '' },
+ cards: [],
+ showModal: false,
+ isEdit: false,
+ selectedIds: [],
+ bulkStatus: '',
+ bulkCardType: '',
+ formData: { id: '', card_number: '', card_type: '', nfc_id: '' },
init() { this.fetchCards(); },
fetchCards() {
const scrollPos = window.scrollY;
@@ -115,6 +160,30 @@
this.$nextTick(() => window.scrollTo(0, scrollPos));
});
},
+ toggleSelectAll(checked) {
+ this.selectedIds = checked ? this.cards.map(c => c.id) : [];
+ },
+ applyBulkUpdate() {
+ if (this.selectedIds.length === 0) return;
+ if (!this.bulkStatus && !this.bulkCardType) { alert('변경할 항목을 선택해주세요.'); return; }
+
+ fetch('api.php?action=bulk_update_cards', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ ids: this.selectedIds,
+ status: this.bulkStatus,
+ card_type: this.bulkCardType
+ })
+ }).then(res => res.json()).then(data => {
+ if (data.success) {
+ this.selectedIds = [];
+ this.bulkStatus = '';
+ this.bulkCardType = '';
+ this.fetchCards();
+ }
+ });
+ },
editCard(card) {
this.isEdit = true;
this.formData = { ...card };
diff --git a/db_init.php b/db_init.php
index 3b038b4..083b5b3 100644
--- a/db_init.php
+++ b/db_init.php
@@ -201,20 +201,49 @@ try {
echo " | ✔ " . count($users_raw) . " users processed. "; // 5. 노트북 모델 & 자산 등록 - echo "⏳ Processing Laptop Assets... "; + echo "⏳ Processing Laptop Assets with Detailed Specs... "; - // 테이블 스키마에 스펙 컬럼이 없다면 추가 (최초 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) { /* 이미 존재하면 무시 */ + // 테이블 스키마 상세 사양 컬럼 확장 + $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 (?, ?)"); - $asset_stmt = $db->prepare("INSERT INTO laptop_assets (asset_tag, model_id, current_user_id, status, serial_number, purchase_date, cpu, ram, storage) 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'); @@ -233,22 +262,20 @@ try { 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'; + $internal_status = $current_user_id ? 'assigned' : 'stock'; if (strpos($user_name, '업무용') !== false || strpos($user_name, '임시') !== false) { - $status = 'stock'; // 공용/업무용은 재고로 간주하거나 별도 상태 부여 가능 + $internal_status = 'stock'; } $p_date = trim($row['취득일자'] ?? ''); @@ -258,24 +285,49 @@ try { $p_date = "{$parts[2]}-{$parts[0]}-{$parts[1]}"; } - // 스펙 정보 추출 + // 상세 사양 매핑 $cpu = $row['CPU'] ?? $row['프로세서'] ?? ''; - $ram = $row['RAM'] ?? ''; - $storage = $row['HDD 0 / 설치 값'] ?? ''; + $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, - $status, + $internal_status, $row['시리얼넘버/EX'], $p_date, + $remarks, $cpu, - $ram, - $storage + $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 specs. "; + echo "✔ Laptop assets imported with all detailed specs. "; // 6. 기타 계정 정보 $mfp_raw = getCSV($files['mfp']); diff --git a/laptops.php b/laptops.php index 9fa86eb..e8195eb 100644 --- a/laptops.php +++ b/laptops.php @@ -52,42 +52,125 @@ + +
+
+
+
+
+
+
+ 개 선택됨
+
+
+
+ 일괄 변경:
+
+
+
+
+
|