false, 'error' => 'No file uploaded']); exit; } $file = $_FILES['file']; $ext = pathinfo($file['name'], PATHINFO_EXTENSION); $allowed = ['jpg', 'jpeg', 'png', 'gif', 'webp']; if (!in_array(strtolower($ext), $allowed)) { echo json_encode(['success' => false, 'error' => 'Invalid file type']); exit; } $filename = time() . '_' . uniqid() . '.' . $ext; $targetDir = __DIR__ . '/../assets/images/chat/'; if (!is_dir($targetDir)) { mkdir($targetDir, 0777, true); } $targetPath = $targetDir . $filename; if (move_uploaded_file($file['tmp_name'], $targetPath)) { $imageUrl = '/assets/images/chat/' . $filename; $message = ''; if (isset($_SESSION['admin_id'])) { $user_id = $_POST['user_id'] ?? 0; $ip = $_POST['ip_address'] ?? ''; $sender = 'admin'; $admin_id = $_SESSION['admin_id']; $stmt = db()->prepare("INSERT INTO messages (user_id, admin_id, sender, message, ip_address) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([$user_id, $admin_id, $sender, $message, $ip]); } else { $user_id = $_SESSION['user_id'] ?? 0; $ip = getRealIP(); $stmt = db()->prepare("INSERT INTO messages (user_id, sender, message, ip_address) VALUES (?, ?, ?, ?)"); $stmt->execute([$user_id, 'user', $message, $ip]); } echo json_encode(['success' => true, 'url' => $imageUrl]); } else { echo json_encode(['success' => false, 'error' => 'Failed to move uploaded file']); } exit; } if ($action === 'get_messages') { $user_id = $_SESSION['user_id'] ?? 0; $target_user_id = $_GET['user_id'] ?? $user_id; $target_ip = $_GET['ip'] ?? getRealIP(); // If admin is requesting, we use the provided user_id and ip if (isset($_SESSION['admin_id'])) { $stmt = db()->prepare("SELECT * FROM messages WHERE (user_id = ? AND user_id != 0) OR (user_id = 0 AND ip_address = ?) ORDER BY created_at ASC"); $stmt->execute([$target_user_id, $target_ip]); } else { // User requesting their own messages $stmt = db()->prepare("SELECT * FROM messages WHERE (user_id = ? AND user_id != 0) OR (user_id = 0 AND ip_address = ?) ORDER BY created_at ASC"); $stmt->execute([$user_id, getRealIP()]); } $messages = $stmt->fetchAll(); echo json_encode($messages); exit; } if ($action === 'send_message') { $message = $_POST['message'] ?? ''; if (!$message) exit(json_encode(['success' => false])); $user_id = $_SESSION['user_id'] ?? 0; $ip = getRealIP(); $stmt = db()->prepare("INSERT INTO messages (user_id, sender, message, ip_address) VALUES (?, ?, ?, ?)"); $stmt->execute([$user_id, 'user', $message, $ip]); $newId = db()->lastInsertId(); echo json_encode(['success' => true, 'id' => $newId]); exit; } if ($action === 'admin_send') { $message = $_POST['message'] ?? ''; $user_id = $_POST['user_id'] ?? 0; $target_ip = $_POST['ip_address'] ?? ''; if (!$message) exit(json_encode(['success' => false])); $admin_id = $_SESSION['admin_id'] ?? 1; $sender = 'admin'; $stmt = db()->prepare("INSERT INTO messages (user_id, admin_id, sender, message, ip_address) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([$user_id, $admin_id, $sender, $message, $target_ip]); $newId = db()->lastInsertId(); echo json_encode(['success' => true, 'id' => $newId]); exit; } if ($action === 'ping') { $user_id = $_SESSION['user_id'] ?? 0; $ip = getRealIP(); $stmt = db()->prepare("INSERT INTO chat_visitors (user_id, ip_address) VALUES (?, ?) ON DUPLICATE KEY UPDATE last_ping = CURRENT_TIMESTAMP"); $stmt->execute([$user_id, $ip]); echo json_encode(['success' => true]); exit; } if ($action === 'admin_get_all') { // Get distinct users/IPs who have messaged or pinged // Combine messages and visitors to show even those who haven't messaged yet $stmt = db()->query(" SELECT combined.user_id, combined.ip_address, COALESCE(m.message, '用户已进入聊天室') as message, COALESCE(m.created_at, combined.last_activity) as created_at, u.username, u.uid, r.remark FROM ( SELECT user_id, ip_address, MAX(created_at) as last_activity FROM messages GROUP BY user_id, ip_address UNION SELECT user_id, ip_address, last_ping as last_activity FROM chat_visitors ) combined LEFT JOIN ( SELECT user_id, ip_address, message, created_at FROM messages WHERE id IN (SELECT MAX(id) FROM messages GROUP BY user_id, ip_address) ) m ON (combined.user_id = m.user_id AND combined.ip_address = m.ip_address) LEFT JOIN users u ON combined.user_id = u.id LEFT JOIN chat_remarks r ON (combined.user_id = r.user_id AND combined.ip_address = r.ip_address) WHERE combined.last_activity > DATE_SUB(NOW(), INTERVAL 24 HOUR) ORDER BY created_at DESC "); echo json_encode($stmt->fetchAll()); exit; } if ($action === 'save_remark') { if (!isset($_SESSION['admin_id'])) exit(json_encode(['success' => false, 'error' => 'Unauthorized'])); $user_id = $_POST['user_id'] ?? 0; $ip = $_POST['ip_address'] ?? ''; $remark = $_POST['remark'] ?? ''; $stmt = db()->prepare("INSERT INTO chat_remarks (user_id, ip_address, remark) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE remark = ?"); $stmt->execute([$user_id, $ip, $remark, $remark]); echo json_encode(['success' => true]); exit; } if ($action === 'get_remark') { if (!isset($_SESSION['admin_id'])) exit(json_encode(['success' => false, 'error' => 'Unauthorized'])); $user_id = $_GET['user_id'] ?? 0; $ip = $_GET['ip'] ?? ''; $stmt = db()->prepare("SELECT remark FROM chat_remarks WHERE user_id = ? AND ip_address = ?"); $stmt->execute([$user_id, $ip]); $remark = $stmt->fetchColumn() ?: ''; echo json_encode(['success' => true, 'remark' => $remark]); exit; }