1120 lines
No EOL
49 KiB
PHP
1120 lines
No EOL
49 KiB
PHP
<?php
|
|
require_once 'config.php';
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
session_start();
|
|
|
|
$action = $_GET['action'] ?? '';
|
|
|
|
// 로그인 세션 체크 (login 액션 제외)
|
|
$public_actions = ['login'];
|
|
if (!isset($_SESSION['admin_id']) && !in_array($action, $public_actions)) {
|
|
http_response_code(401);
|
|
echo json_encode(['success' => false, 'error' => 'Unauthorized']);
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
switch ($action) {
|
|
case 'login':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$login_id = $data['login_id'] ?? '';
|
|
$password = $data['password'] ?? '';
|
|
|
|
$stmt = $db->prepare("SELECT * FROM administrators WHERE login_id = ?");
|
|
$stmt->execute([$login_id]);
|
|
$admin = $stmt->fetch();
|
|
|
|
if ($admin && password_verify($password, $admin['password_hash'])) {
|
|
$_SESSION['admin_id'] = $admin['id'];
|
|
$_SESSION['admin_login_id'] = $admin['login_id'];
|
|
$_SESSION['admin_name'] = $admin['admin_name'];
|
|
echo json_encode(['success' => true]);
|
|
} else {
|
|
echo json_encode(['success' => false, 'error' => '아이디 또는 비밀번호가 일치하지 않습니다.']);
|
|
}
|
|
break;
|
|
|
|
case 'logout':
|
|
session_destroy();
|
|
echo json_encode(['success' => true]);
|
|
break;
|
|
|
|
case 'get_admins':
|
|
$stmt = $db->query("SELECT id, login_id, admin_name, created_at FROM administrators ORDER BY id ASC");
|
|
echo json_encode($stmt->fetchAll());
|
|
break;
|
|
|
|
case 'add_admin':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$stmt = $db->prepare("INSERT INTO administrators (login_id, password_hash, admin_name) VALUES (?, ?, ?)");
|
|
$stmt->execute([
|
|
$data['login_id'],
|
|
password_hash($data['password'], PASSWORD_DEFAULT),
|
|
$data['admin_name']
|
|
]);
|
|
echo json_encode(['success' => true]);
|
|
break;
|
|
|
|
case 'update_admin_password':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$stmt = $db->prepare("UPDATE administrators SET password_hash = ? WHERE id = ?");
|
|
$stmt->execute([
|
|
password_hash($data['password'], PASSWORD_DEFAULT),
|
|
$data['id']
|
|
]);
|
|
echo json_encode(['success' => true]);
|
|
break;
|
|
|
|
case 'delete_admin':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
if ($data['id'] == $_SESSION['admin_id']) {
|
|
echo json_encode(['success' => false, 'error' => '자기 자신은 삭제할 수 없습니다.']);
|
|
break;
|
|
}
|
|
$stmt = $db->prepare("DELETE FROM administrators WHERE id = ?");
|
|
$stmt->execute([$data['id']]);
|
|
echo json_encode(['success' => true]);
|
|
break;
|
|
case 'get_dashboard_stats':
|
|
// Laptops
|
|
$laptop_total = $db->query("SELECT COUNT(*) FROM laptop_assets WHERE status != 'disposed'")->fetchColumn();
|
|
$laptop_assigned = $db->query("SELECT COUNT(*) FROM laptop_assets WHERE status = 'assigned'")->fetchColumn();
|
|
$laptop_disposed = $db->query("SELECT COUNT(*) FROM laptop_assets WHERE status = 'disposed'")->fetchColumn();
|
|
|
|
// Cards
|
|
$card_total = $db->query("SELECT COUNT(*) FROM access_cards")->fetchColumn();
|
|
$card_assigned = $db->query("SELECT COUNT(*) FROM access_cards WHERE status = 'assigned'")->fetchColumn();
|
|
|
|
// MFP
|
|
$mfp_total = $db->query("SELECT COUNT(*) FROM mfp_accounts")->fetchColumn();
|
|
$mfp_active = $db->query("SELECT COUNT(*) FROM mfp_accounts WHERE status = 'active'")->fetchColumn();
|
|
|
|
// Users
|
|
$users_general = $db->query("SELECT COUNT(*) FROM users WHERE accounting_type = '일반회계'")->fetchColumn();
|
|
$users_special = $db->query("SELECT COUNT(*) FROM users WHERE accounting_type = '특별회계'")->fetchColumn();
|
|
|
|
echo json_encode([
|
|
'laptops' => ['total' => (int) $laptop_total, 'assigned' => (int) $laptop_assigned, 'disposed' => (int) $laptop_disposed],
|
|
'cards' => ['total' => (int) $card_total, 'assigned' => (int) $card_assigned],
|
|
'mfp' => ['total' => (int) $mfp_total, 'active' => (int) $mfp_active],
|
|
'users' => ['general' => (int) $users_general, 'special' => (int) $users_special]
|
|
]);
|
|
break;
|
|
|
|
case 'get_users':
|
|
$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,
|
|
(SELECT asset_tag FROM laptop_assets WHERE current_user_id = u.id ORDER BY id DESC LIMIT 1) as laptop_tag,
|
|
(SELECT purchase_date FROM laptop_assets WHERE current_user_id = u.id ORDER BY id DESC LIMIT 1) as laptop_purchase_date,
|
|
(SELECT m.model_name FROM laptop_assets a JOIN laptop_models m ON a.model_id = m.id WHERE a.current_user_id = u.id ORDER
|
|
BY a.id DESC LIMIT 1) as laptop_model_name,
|
|
(SELECT COUNT(*) FROM laptop_assets WHERE rental_user_id = u.id) as rental_count
|
|
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";
|
|
$stmt = $db->prepare($query);
|
|
$stmt->execute(['search' => "%$search%"]);
|
|
} else {
|
|
$stmt = $db->query($query);
|
|
}
|
|
echo json_encode($stmt->fetchAll());
|
|
break;
|
|
|
|
case 'add_user':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$status = $data['status'] ?? 'active';
|
|
$department_id = $data['department_id'] ?: null;
|
|
$emp_id = $data['emp_id'];
|
|
|
|
// Duplicate emp_id check
|
|
$check = $db->prepare("SELECT id FROM users WHERE emp_id = ?");
|
|
$check->execute([$emp_id]);
|
|
if ($check->fetch()) {
|
|
echo json_encode(['success' => false, 'error' => "이미 존재하는 사번({$emp_id})입니다."]);
|
|
break;
|
|
}
|
|
|
|
// Auto-relocate based on status
|
|
if ($status === 'on_leave' || $status === 'retired') {
|
|
$dept_name = ($status === 'on_leave') ? '휴직' : '퇴사';
|
|
$target_dept = $db->query("SELECT id FROM departments WHERE name = '$dept_name'")->fetchColumn();
|
|
if ($target_dept)
|
|
$department_id = $target_dept;
|
|
}
|
|
|
|
try {
|
|
$stmt = $db->prepare("INSERT INTO users (emp_id, name, department_id, position, email, phone, mobile, accounting_type,
|
|
status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
$stmt->execute([
|
|
$emp_id,
|
|
$data['name'],
|
|
$department_id,
|
|
$data['position'],
|
|
$data['email'],
|
|
$data['phone'] ?? '',
|
|
$data['mobile'],
|
|
$data['accounting_type'],
|
|
$status
|
|
]);
|
|
echo json_encode(['success' => true]);
|
|
} catch (Exception $e) {
|
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
|
}
|
|
break;
|
|
|
|
case 'update_user':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$status = $data['status'];
|
|
$department_id = $data['department_id'] ?: null;
|
|
$emp_id = $data['emp_id'];
|
|
$user_id = $data['id'];
|
|
|
|
// Duplicate emp_id check (excluding current user)
|
|
$check = $db->prepare("SELECT id FROM users WHERE emp_id = ? AND id != ?");
|
|
$check->execute([$emp_id, $user_id]);
|
|
if ($check->fetch()) {
|
|
echo json_encode(['success' => false, 'error' => "이미 존재하는 사번({$emp_id})입니다."]);
|
|
break;
|
|
}
|
|
|
|
// Auto-relocate based on status
|
|
if ($status === 'on_leave' || $status === 'retired') {
|
|
$dept_name = ($status === 'on_leave') ? '휴직' : '퇴사';
|
|
$target_dept = $db->query("SELECT id FROM departments WHERE name = '$dept_name'")->fetchColumn();
|
|
if ($target_dept)
|
|
$department_id = $target_dept;
|
|
}
|
|
|
|
try {
|
|
$stmt = $db->prepare("UPDATE users SET emp_id = ?, name = ?, department_id = ?, position = ?, email = ?, phone = ?,
|
|
mobile = ?, accounting_type = ?, status = ? WHERE id = ?");
|
|
$stmt->execute([
|
|
$emp_id,
|
|
$data['name'],
|
|
$department_id,
|
|
$data['position'],
|
|
$data['email'],
|
|
$data['phone'] ?? '',
|
|
$data['mobile'],
|
|
$data['accounting_type'],
|
|
$status,
|
|
$user_id
|
|
]);
|
|
echo json_encode(['success' => true]);
|
|
} catch (Exception $e) {
|
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
|
}
|
|
break;
|
|
|
|
case 'get_laptops':
|
|
$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_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 '%업무용%' OR a.current_user_id IS NULL)";
|
|
echo json_encode($db->query($query)->fetchAll());
|
|
break;
|
|
|
|
case 'update_rental':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$startDate = $data['rental_start_date'] ?: date('Y-m-d');
|
|
|
|
$stmt = $db->prepare("UPDATE laptop_assets SET
|
|
rental_user_id = ?,
|
|
rental_user_name = ?,
|
|
rental_start_date = ?,
|
|
rental_end_scheduled = ?,
|
|
rental_reason = ?,
|
|
rental_peripherals = ?,
|
|
remarks = ?
|
|
WHERE id = ?");
|
|
$stmt->execute([
|
|
$data['rental_user_id'] ?? null,
|
|
$data['rental_user_name'],
|
|
$startDate,
|
|
$data['rental_end_scheduled'] ?? null,
|
|
$data['rental_reason'] ?? '',
|
|
$data['rental_peripherals'] ?? '',
|
|
$data['remarks'] ?? '',
|
|
$data['id']
|
|
]);
|
|
|
|
// Log the rental action
|
|
$peripherals = $data['rental_peripherals'] ? "\n부속품: " . $data['rental_peripherals'] : "";
|
|
$note = "사유: " . ($data['rental_reason'] ?? '없음') . $peripherals;
|
|
$log_stmt = $db->prepare("INSERT INTO asset_history (asset_id, log_type, user_name, action_date, note) VALUES (?,
|
|
'rental', ?, ?, ?)");
|
|
$log_stmt->execute([$data['id'], $data['rental_user_name'], $startDate, $note]);
|
|
|
|
echo json_encode(['success' => true]);
|
|
break;
|
|
|
|
case 'return_rental':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$asset = $db->query("SELECT * FROM laptop_assets WHERE id = " . (int) $data['id'])->fetch();
|
|
|
|
if ($asset) {
|
|
// 반납 처리: 임대 정보는 초기화하되 비고(remarks)는 유지
|
|
$stmt = $db->prepare("UPDATE laptop_assets SET
|
|
rental_user_id = NULL,
|
|
rental_user_name = NULL,
|
|
rental_start_date = NULL,
|
|
rental_end_scheduled = NULL,
|
|
rental_reason = NULL,
|
|
rental_peripherals = NULL
|
|
WHERE id = ?");
|
|
$stmt->execute([$data['id']]);
|
|
|
|
// Log return
|
|
$log_stmt = $db->prepare("INSERT INTO asset_history (asset_id, log_type, user_name, action_date, note) VALUES (?,
|
|
'return', ?, ?, ?)");
|
|
$log_stmt->execute([$data['id'], $asset['rental_user_name'], date('Y-m-d'), '반납 완료']);
|
|
}
|
|
echo json_encode(['success' => true]);
|
|
break;
|
|
|
|
case 'get_user_rentals':
|
|
$user_id = (int) $_GET['user_id'];
|
|
$query = "SELECT a.*, m.model_name, m.manufacturer
|
|
FROM laptop_assets a
|
|
JOIN laptop_models m ON a.model_id = m.id
|
|
WHERE a.rental_user_id = ?";
|
|
$stmt = $db->prepare($query);
|
|
$stmt->execute([$user_id]);
|
|
echo json_encode($stmt->fetchAll());
|
|
break;
|
|
|
|
case 'update_asset_remarks':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$stmt = $db->prepare("UPDATE laptop_assets SET remarks = ? WHERE id = ?");
|
|
$stmt->execute([$data['remarks'] ?? '', $data['id']]);
|
|
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;
|
|
|
|
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, 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 = ?, 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;
|
|
|
|
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);
|
|
$asset_tag = trim($data['asset_tag'] ?? '');
|
|
|
|
// Duplicate check
|
|
$check = $db->prepare("SELECT id FROM laptop_assets WHERE asset_tag = ?");
|
|
$check->execute([$asset_tag]);
|
|
if ($check->fetch()) {
|
|
echo json_encode(['success' => false, 'error' => "이미 존재하는 자산번호({$asset_tag})입니다."]);
|
|
break;
|
|
}
|
|
|
|
$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, disposal_recipient, disposal_date, real_user, disposal_user_id
|
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
$stmt->execute([
|
|
$data['asset_tag'],
|
|
$data['model_id'],
|
|
$data['current_user_id'] ?: null,
|
|
$data['status'] ?: ($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['disposal_recipient'] ?? null,
|
|
$data['disposal_date'] ?? null,
|
|
$data['real_user'] ?? null,
|
|
$data['disposal_user_id'] ?? 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();
|
|
|
|
// Auto-relocate based on status if needed (optional)
|
|
|
|
// If assigned_user_name is missing but current_user_id exists, try to fill it for logging
|
|
if (empty($data['assigned_user_name']) && !empty($data['current_user_id'])) {
|
|
$u_stmt = $db->prepare("SELECT name FROM users WHERE id = ?");
|
|
$u_stmt->execute([$data['current_user_id']]);
|
|
$data['assigned_user_name'] = $u_stmt->fetchColumn() ?: '';
|
|
}
|
|
|
|
$asset_tag = trim($data['asset_tag'] ?? '');
|
|
$asset_id = $data['id'];
|
|
|
|
// Duplicate check (excluding current asset)
|
|
$check = $db->prepare("SELECT id FROM laptop_assets WHERE asset_tag = ? AND id != ?");
|
|
$check->execute([$asset_tag, $asset_id]);
|
|
if ($check->fetch()) {
|
|
echo json_encode(['success' => false, 'error' => "이미 존재하는 자산번호({$asset_tag})입니다."]);
|
|
break;
|
|
}
|
|
|
|
$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 = ?, disposal_recipient = ?, disposal_date = ?, real_user = ?, disposal_user_id = ?
|
|
WHERE id = ?");
|
|
$stmt->execute([
|
|
$data['asset_tag'],
|
|
$data['model_id'],
|
|
$data['current_user_id'] ?: null,
|
|
$data['status'] ?: ($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['disposal_recipient'] ?? null,
|
|
$data['disposal_date'] ?? null,
|
|
$data['real_user'] ?? null,
|
|
$data['disposal_user_id'] ?? null,
|
|
$data['id']
|
|
]);
|
|
|
|
// Auto-log assignment change
|
|
$new_name = $data['assigned_user_name'] ?: '';
|
|
$old_name = $old_asset['assigned_user_name'] ?? '';
|
|
if ($new_name !== $old_name) {
|
|
$log_stmt = $db->prepare("INSERT INTO asset_history (asset_id, log_type, user_name, action_date) VALUES (?, 'assignment', ?, ?)");
|
|
$log_stmt->execute([$data['id'], $new_name ?: '재고(반납)', date('Y-m-d')]);
|
|
}
|
|
|
|
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);
|
|
$new_name = $data['name'];
|
|
$parent_id = $data['parent_id'] ?: null;
|
|
$dept_id = $data['id'];
|
|
$merge_target_id = $data['merge_target_id'] ?? null;
|
|
|
|
if ($merge_target_id) {
|
|
// Scenario: Merge members to an existing department with the same name
|
|
$db->prepare("UPDATE users SET department_id = ? WHERE department_id = ?")->execute([$merge_target_id, $dept_id]);
|
|
// Recursively move children? For now, we delete the source dept after merging members
|
|
$db->prepare("DELETE FROM departments WHERE id = ?")->execute([$dept_id]);
|
|
echo json_encode(['success' => true, 'merged' => true]);
|
|
} else {
|
|
// Check if a department with the same name exists under the same parent (excluding itself)
|
|
$check_stmt = $db->prepare("SELECT id FROM departments WHERE name = ? AND parent_id IS ? AND id != ?");
|
|
$check_stmt->execute([$new_name, $parent_id, $dept_id]);
|
|
$existing = $check_stmt->fetch();
|
|
|
|
if ($existing) {
|
|
echo json_encode(['success' => false, 'conflict' => true, 'existing_id' => $existing['id']]);
|
|
} else {
|
|
$stmt = $db->prepare("UPDATE departments SET name = ?, parent_id = ? WHERE id = ?");
|
|
$stmt->execute([$new_name, $parent_id, $dept_id]);
|
|
echo json_encode(['success' => true]);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'delete_dept':
|
|
$dept_id = $_GET['id'];
|
|
|
|
// Find FKI Root
|
|
$fki_root = $db->query("SELECT id FROM departments WHERE name = '한국경제인협회' AND parent_id IS NULL LIMIT 1")->fetch();
|
|
$fki_root_id = $fki_root ? $fki_root['id'] : null;
|
|
|
|
// 1. Find the '미소속' department under FKI Root
|
|
$miso_id = $db->query("SELECT id FROM departments WHERE name = '미소속' AND parent_id IS " . ($fki_root_id ?: 'NULL') . "
|
|
LIMIT 1")->fetchColumn();
|
|
|
|
if (!$miso_id) {
|
|
$db->prepare("INSERT INTO departments (name, parent_id, level) VALUES ('미소속', ?, 1)")->execute([$fki_root_id]);
|
|
$miso_id = $db->lastInsertId();
|
|
}
|
|
|
|
// 2. Get current dept info for re-parenting children
|
|
$current_dept = $db->prepare("SELECT parent_id FROM departments WHERE id = ?");
|
|
$current_dept->execute([$dept_id]);
|
|
$parent_info = $current_dept->fetch();
|
|
$target_new_parent = $parent_info ? $parent_info['parent_id'] : null;
|
|
|
|
// 3. Move members to '미소속'
|
|
$db->prepare("UPDATE users SET department_id = ? WHERE department_id = ?")->execute([$miso_id, $dept_id]);
|
|
|
|
// 4. Move child departments to its grandparent (re-parenting) to avoid FK constraint violation
|
|
$db->prepare("UPDATE departments SET parent_id = ? WHERE parent_id = ?")->execute([$target_new_parent, $dept_id]);
|
|
|
|
// 5. Delete the department
|
|
$db->prepare("DELETE FROM departments WHERE id = ?")->execute([$dept_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_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 = [];
|
|
$log_msg = "";
|
|
|
|
if ($newStatus) {
|
|
$updates[] = "status = ?";
|
|
$params[] = $newStatus;
|
|
if ($newStatus === 'stock') {
|
|
$updates[] = "current_user_id = NULL";
|
|
$updates[] = "assigned_user_name = '업무용(TEMP_44666b)'";
|
|
$log_msg = "일괄 상태 변경: 재고 (업무용 지정)";
|
|
} elseif ($newStatus === 'disposed') {
|
|
$updates[] = "current_user_id = NULL";
|
|
$updates[] = "assigned_user_name = NULL";
|
|
$updates[] = "disposal_date = '" . date('Y-m-d') . "'";
|
|
$log_msg = "일괄 상태 변경: 매각됨";
|
|
} elseif ($newStatus === 'assigned') {
|
|
$log_msg = "일괄 상태 변경: 직원배정";
|
|
}
|
|
}
|
|
if ($newModelId) {
|
|
$updates[] = "model_id = ?";
|
|
$params[] = $newModelId;
|
|
$log_msg .= ($log_msg ? ", " : "") . "일괄 모델 변경(ID: $newModelId)";
|
|
}
|
|
|
|
if (empty($updates)) {
|
|
echo json_encode(['success' => false, 'error' => 'No updates specified']);
|
|
break;
|
|
}
|
|
|
|
$placeholders = implode(",", array_fill(0, count($ids), "?"));
|
|
$sql = "UPDATE laptop_assets SET " . implode(", ", $updates) . " WHERE id IN ($placeholders)";
|
|
$stmt = $db->prepare($sql);
|
|
$stmt->execute(array_merge($params, $ids));
|
|
|
|
// 히스토리 일괄 기록
|
|
if ($log_msg) {
|
|
$history_sql = "INSERT INTO asset_history (asset_id, log_type, user_name, action_date, note) VALUES (?, 'bulk_update', '시스템(일괄)', ?, ?)";
|
|
$h_stmt = $db->prepare($history_sql);
|
|
foreach ($ids as $id) {
|
|
$h_stmt->execute([$id, date('Y-m-d'), $log_msg]);
|
|
}
|
|
}
|
|
|
|
echo json_encode(['success' => true]);
|
|
break;
|
|
|
|
case 'bulk_delete_laptops':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$ids = $data['ids'];
|
|
if (empty($ids)) {
|
|
echo json_encode(['success' => false, 'error' => 'No items selected']);
|
|
break;
|
|
}
|
|
$placeholders = implode(",", array_fill(0, count($ids), "?"));
|
|
$db->prepare("DELETE FROM laptop_assets WHERE id IN ($placeholders)")->execute($ids);
|
|
// 관련 히스토리도 삭제? 보통 자산 삭제시에는 히스토리도 함께 날리거나 남김. 여기선 DB 정합성을 위해 연쇄 삭제는 안하더라도 자산은 사라짐.
|
|
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_delete_models':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$ids = $data['ids'];
|
|
if (empty($ids)) {
|
|
echo json_encode(['success' => false, 'error' => 'No items selected']);
|
|
break;
|
|
}
|
|
try {
|
|
$db->beginTransaction();
|
|
$placeholders = implode(",", array_fill(0, count($ids), "?"));
|
|
|
|
// 1. 해당 모델을 참조 중인 자산들의 연결 고리 해제 (ID 참조를 NULL로 변경)
|
|
$stmt1 = $db->prepare("UPDATE laptop_assets SET model_id = NULL WHERE model_id IN ($placeholders)");
|
|
$stmt1->execute($ids);
|
|
|
|
// 2. 노트북 모델 마스터 정보 삭제
|
|
$stmt2 = $db->prepare("DELETE FROM laptop_models WHERE id IN ($placeholders)");
|
|
$stmt2->execute($ids);
|
|
|
|
$db->commit();
|
|
echo json_encode(['success' => true]);
|
|
} catch (Exception $e) {
|
|
$db->rollBack();
|
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
|
}
|
|
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;
|
|
}
|
|
|
|
// Enhanced logic: if status is changed to leave/retired, override dept
|
|
if ($newStatus === 'on_leave' || $newStatus === 'retired') {
|
|
$dept_name = ($newStatus === 'on_leave') ? '휴직' : '퇴사';
|
|
$target_dept = $db->query("SELECT id FROM departments WHERE name = '$dept_name'")->fetchColumn();
|
|
if ($target_dept)
|
|
$newDeptId = $target_dept;
|
|
}
|
|
|
|
$sql = "UPDATE users SET ";
|
|
$params = [];
|
|
$updates = [];
|
|
if ($newStatus) {
|
|
$updates[] = "status = ?";
|
|
$params[] = $newStatus;
|
|
}
|
|
if ($newDeptId) {
|
|
$updates[] = "department_id = ?";
|
|
$params[] = $newDeptId;
|
|
}
|
|
$newPosition = $data['position'] ?? null;
|
|
if ($newPosition) {
|
|
$updates[] = "position = ?";
|
|
$params[] = $newPosition;
|
|
}
|
|
|
|
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;
|
|
|
|
case 'archive_users':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$userIds = $data['user_ids'];
|
|
if (empty($userIds)) {
|
|
echo json_encode(['success' => false, 'error' => 'No users selected']);
|
|
break;
|
|
}
|
|
|
|
$db->beginTransaction();
|
|
try {
|
|
$placeholders = implode(',', array_fill(0, count($userIds), '?'));
|
|
// Copy to archive
|
|
$db->prepare("INSERT INTO users_archive (id, emp_id, name, department_id, position, email, phone, mobile, accounting_type, status)
|
|
SELECT id, emp_id, name, department_id, position, email, phone, mobile, accounting_type, status FROM users WHERE id IN ($placeholders)")
|
|
->execute($userIds);
|
|
// Delete from original
|
|
$db->prepare("DELETE FROM users WHERE id IN ($placeholders)")->execute($userIds);
|
|
$db->commit();
|
|
echo json_encode(['success' => true]);
|
|
} catch (Exception $e) {
|
|
$db->rollBack();
|
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
|
}
|
|
break;
|
|
|
|
case 'get_archived_users':
|
|
$query = "SELECT u.*, dp.path as dept_name
|
|
FROM users_archive u
|
|
LEFT JOIN (
|
|
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 * FROM dept_path
|
|
) dp ON u.department_id = dp.id
|
|
ORDER BY u.archived_at DESC";
|
|
echo json_encode($db->query($query)->fetchAll());
|
|
break;
|
|
|
|
case 'restore_users':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$userIds = $data['user_ids'];
|
|
if (empty($userIds)) {
|
|
echo json_encode(['success' => false, 'error' => 'No users selected']);
|
|
break;
|
|
}
|
|
|
|
$db->beginTransaction();
|
|
try {
|
|
$placeholders = implode(',', array_fill(0, count($userIds), '?'));
|
|
// Restore to users
|
|
$db->prepare("INSERT INTO users (id, emp_id, name, department_id, position, email, phone, mobile, accounting_type, status)
|
|
SELECT id, emp_id, name, department_id, position, email, phone, mobile, accounting_type, status FROM users_archive WHERE id IN ($placeholders)")
|
|
->execute($userIds);
|
|
// Delete from archive
|
|
$db->prepare("DELETE FROM users_archive WHERE id IN ($placeholders)")->execute($userIds);
|
|
$db->commit();
|
|
echo json_encode(['success' => true]);
|
|
} catch (Exception $e) {
|
|
$db->rollBack();
|
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
|
}
|
|
break;
|
|
|
|
case 'bulk_delete_users':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$userIds = $data['user_ids'];
|
|
if (empty($userIds)) {
|
|
echo json_encode(['success' => false, 'error' => 'No users selected']);
|
|
break;
|
|
}
|
|
$placeholders = implode(',', array_fill(0, count($userIds), '?'));
|
|
$db->prepare("DELETE FROM users WHERE id IN ($placeholders)")->execute($userIds);
|
|
echo json_encode(['success' => true]);
|
|
break;
|
|
|
|
case 'export_users_csv':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$userIds = $data['user_ids'] ?? [];
|
|
$columns = $data['columns'] ?? []; // ['name' => '이름', 'emp_id' => '사번', ...]
|
|
|
|
if (empty($columns)) {
|
|
echo json_encode(['success' => false, 'error' => '내보낼 컬럼을 선택해주세요.']);
|
|
break;
|
|
}
|
|
|
|
// 전체 유저 정보 조회 (기본 쿼리 재사용)
|
|
$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,
|
|
(SELECT asset_tag FROM laptop_assets WHERE current_user_id = u.id ORDER BY id DESC LIMIT 1) as laptop_tag
|
|
FROM users u
|
|
LEFT JOIN dept_path dp ON u.department_id = dp.id";
|
|
|
|
if (!empty($userIds)) {
|
|
$placeholders = implode(',', array_fill(0, count($userIds), '?'));
|
|
$query .= " WHERE u.id IN ($placeholders)";
|
|
$stmt = $db->prepare($query);
|
|
$stmt->execute($userIds);
|
|
} else {
|
|
$stmt = $db->query($query);
|
|
}
|
|
|
|
$users = $stmt->fetchAll();
|
|
|
|
// CSV 스트림 생성
|
|
header('Content-Type: text/csv; charset=utf-8');
|
|
header('Content-Disposition: attachment; filename=직원_마스터_리스트_' . date('Ymd_His') . '.csv');
|
|
|
|
$output = fopen('php://output', 'w');
|
|
|
|
// Zero-Mojibake: BOM (Byte Order Mark) 삽입
|
|
fwrite($output, "\xEF\xBB\xBF");
|
|
|
|
// 헤더 작성
|
|
fputcsv($output, array_values($columns));
|
|
|
|
// 데이터 작성
|
|
foreach ($users as $user) {
|
|
$row = [];
|
|
foreach (array_keys($columns) as $key) {
|
|
$val = $user[$key] ?? '';
|
|
// 상태 값 한글 변환
|
|
if ($key === 'status') {
|
|
$val = match ($val) {
|
|
'active' => '재직',
|
|
'retired' => '퇴사',
|
|
'on_leave' => '휴직',
|
|
'classification' => '분류',
|
|
default => $val
|
|
};
|
|
}
|
|
$row[] = $val;
|
|
}
|
|
fputcsv($output, $row);
|
|
}
|
|
fclose($output);
|
|
exit;
|
|
|
|
case 'get_general_rentals':
|
|
$query = "SELECT r.*, GROUP_CONCAT(i.item_name, ', ') as items
|
|
FROM general_rentals r
|
|
LEFT JOIN general_rental_items i ON r.id = i.rental_id
|
|
GROUP BY r.id
|
|
ORDER BY r.id DESC";
|
|
echo json_encode($db->query($query)->fetchAll());
|
|
break;
|
|
|
|
case 'add_general_rental':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$startDate = $data['rental_start_date'] ?: date('Y-m-d');
|
|
|
|
$db->beginTransaction();
|
|
try {
|
|
$stmt = $db->prepare("INSERT INTO general_rentals (user_id, user_name, rental_start_date, rental_reason, status) VALUES
|
|
(?, ?, ?, ?, 'rented')");
|
|
$stmt->execute([
|
|
$data['user_id'] ?? null,
|
|
$data['user_name'],
|
|
$startDate,
|
|
$data['rental_reason'] ?? ''
|
|
]);
|
|
$rentalId = $db->lastInsertId();
|
|
|
|
if (!empty($data['items'])) {
|
|
$itemStmt = $db->prepare("INSERT INTO general_rental_items (rental_id, item_name) VALUES (?, ?)");
|
|
foreach ($data['items'] as $itemName) {
|
|
if (trim($itemName)) {
|
|
$itemStmt->execute([$rentalId, trim($itemName)]);
|
|
}
|
|
}
|
|
}
|
|
$db->commit();
|
|
echo json_encode(['success' => true]);
|
|
} catch (Exception $e) {
|
|
$db->rollBack();
|
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
|
}
|
|
break;
|
|
|
|
case 'get_settings':
|
|
$settings = $db->query("SELECT key_name, value FROM system_settings")->fetchAll(PDO::FETCH_KEY_PAIR);
|
|
echo json_encode(['success' => true, 'settings' => $settings]);
|
|
break;
|
|
|
|
case 'update_settings':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$stmt = $db->prepare("INSERT OR REPLACE INTO system_settings (key_name, value) VALUES (?, ?)");
|
|
foreach ($data['settings'] as $key => $value) {
|
|
$stmt->execute([$key, (string) $value]);
|
|
}
|
|
echo json_encode(['success' => true]);
|
|
break;
|
|
|
|
case 'return_general_rental':
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$returnDate = date('Y-m-d');
|
|
$stmt = $db->prepare("UPDATE general_rentals SET status = 'returned', rental_return_date = ? WHERE id = ?");
|
|
$stmt->execute([$returnDate, $data['id']]);
|
|
echo json_encode(['success' => true]);
|
|
break;
|
|
|
|
default:
|
|
echo json_encode(['error' => 'Invalid action']);
|
|
break;
|
|
}
|
|
} catch (Exception $e) {
|
|
http_response_code(500);
|
|
echo json_encode(['error' => $e->getMessage()]);
|
|
} |