This commit is contained in:
Professional 2025-05-26 19:07:11 +07:00
parent a9be72450c
commit 88037f2bf5
2 changed files with 110 additions and 31 deletions

View File

@ -138,7 +138,6 @@ const toggleUserActive = async (req, res) => {
await user.save(); await user.save();
// Получаем глобальный массив активных пользователей из server.js // Получаем глобальный массив активных пользователей из server.js
// Это напрямую обращается к глобальной переменной в server.js
const activeUsers = req.app.get('activeUsers') || []; const activeUsers = req.app.get('activeUsers') || [];
console.log(`[AdminController] Активные пользователи:`, activeUsers); console.log(`[AdminController] Активные пользователи:`, activeUsers);
@ -147,22 +146,40 @@ const toggleUserActive = async (req, res) => {
if (wasActive && !user.isActive) { if (wasActive && !user.isActive) {
console.log(`[AdminController] Блокировка пользователя ${userId}. Причина: ${reason || 'Не указана'}`); console.log(`[AdminController] Блокировка пользователя ${userId}. Причина: ${reason || 'Не указана'}`);
// Создаем объект с информацией о блокировке
const blockData = {
message: 'Ваш аккаунт был заблокирован администратором.',
reason: reason || 'Нарушение правил сервиса',
timestamp: new Date().toISOString(),
blocked: true,
userId: user._id.toString()
};
// Отправляем глобальное событие блокировки всем клиентам
// Это обеспечит получение уведомления даже если в activeUsers неактуальная информация
io.emit('global_user_blocked', {
userId: user._id.toString(),
timestamp: new Date().toISOString()
});
// Ищем пользователя среди активных пользователей // Ищем пользователя среди активных пользователей
const userSockets = activeUsers.filter(u => u.userId === userId); const userSockets = activeUsers.filter(u => u.userId === userId);
console.log(`[AdminController] Найдено активных записей пользователя: ${userSockets.length}`); console.log(`[AdminController] Найдено активных записей пользователя: ${userSockets.length}`);
// Пытаемся отправить уведомление через все возможные сокеты
let notificationSent = false;
if (userSockets.length > 0) { if (userSockets.length > 0) {
userSockets.forEach(userSocket => { for (const userSocket of userSockets) {
try { try {
// Безопасно получаем сокет и проверяем его существование
if (io.sockets && io.sockets.sockets) {
const socket = io.sockets.sockets.get(userSocket.socketId); const socket = io.sockets.sockets.get(userSocket.socketId);
if (socket) {
if (socket && socket.connected) {
console.log(`[AdminController] Отправка уведомления о блокировке на сокет: ${userSocket.socketId}`); console.log(`[AdminController] Отправка уведомления о блокировке на сокет: ${userSocket.socketId}`);
socket.emit("account_blocked", { socket.emit("account_blocked", blockData);
message: 'Ваш аккаунт был заблокирован администратором.', notificationSent = true;
reason: reason || 'Нарушение правил сервиса',
timestamp: new Date().toISOString(),
blocked: true
});
// Принудительно отключаем сокет // Принудительно отключаем сокет
setTimeout(() => { setTimeout(() => {
@ -174,15 +191,36 @@ const toggleUserActive = async (req, res) => {
} }
}, 500); }, 500);
} else { } else {
console.log(`[AdminController] Не найден объект сокета для ID: ${userSocket.socketId}`); console.log(`[AdminController] Сокет не найден или не подключен для ID: ${userSocket.socketId}`);
}
} else {
console.log(`[AdminController] Коллекция сокетов недоступна`);
} }
} catch (socketError) { } catch (socketError) {
console.error(`[AdminController] Ошибка при обработке сокета ${userSocket.socketId}:`, socketError); console.error(`[AdminController] Ошибка при обработке сокета ${userSocket.socketId}:`, socketError);
} }
}); }
} else { } else {
console.log(`[AdminController] Пользователь ${userId} не найден в активных соединениях`); console.log(`[AdminController] Пользователь ${userId} не найден в активных соединениях`);
} }
// Очищаем устаревшие записи в списке активных пользователей
try {
const updatedActiveUsers = activeUsers.filter(u => {
// Оставляем записи, которые не принадлежат заблокированному пользователю
return u.userId !== userId;
});
// Обновляем список активных пользователей
req.app.set('activeUsers', updatedActiveUsers);
console.log(`[AdminController] Список активных пользователей обновлен, удалены записи для ${userId}`);
} catch (error) {
console.error(`[AdminController] Ошибка при обновлении списка активных пользователей:`, error);
}
if (!notificationSent) {
console.log(`[AdminController] Уведомление о блокировке не было отправлено напрямую, но было отправлено глобальное уведомление`);
}
} }
// Если пользователь был неактивным и теперь разблокируется // Если пользователь был неактивным и теперь разблокируется
else if (!wasActive && user.isActive) { else if (!wasActive && user.isActive) {
@ -201,8 +239,6 @@ const toggleUserActive = async (req, res) => {
}; };
// Отправляем событие разблокировки всем клиентам (анонимно) // Отправляем событие разблокировки всем клиентам (анонимно)
// Это необходимо, чтобы клиент, который залогинен с другого устройства,
// также получил уведомление о разблокировке
io.emit('global_user_unblocked', { io.emit('global_user_unblocked', {
userId: user._id.toString(), userId: user._id.toString(),
timestamp: new Date().toISOString() timestamp: new Date().toISOString()
@ -210,24 +246,36 @@ const toggleUserActive = async (req, res) => {
// Ищем пользователя среди активных пользователей (на случай, если он онлайн с другим аккаунтом) // Ищем пользователя среди активных пользователей (на случай, если он онлайн с другим аккаунтом)
const userSockets = activeUsers.filter(u => u.userId === userId); const userSockets = activeUsers.filter(u => u.userId === userId);
let notificationSent = false;
if (userSockets.length > 0) { if (userSockets.length > 0) {
userSockets.forEach(userSocket => { for (const userSocket of userSockets) {
try { try {
// Безопасно получаем сокет и проверяем его существование
if (io.sockets && io.sockets.sockets) {
const socket = io.sockets.sockets.get(userSocket.socketId); const socket = io.sockets.sockets.get(userSocket.socketId);
if (socket) {
if (socket && socket.connected) {
console.log(`[AdminController] Отправка уведомления о разблокировке на сокет: ${userSocket.socketId}`); console.log(`[AdminController] Отправка уведомления о разблокировке на сокет: ${userSocket.socketId}`);
socket.emit("account_unblocked", unblockInfo); socket.emit("account_unblocked", unblockInfo);
notificationSent = true;
} else { } else {
console.log(`[AdminController] Не найден объект сокета для ID: ${userSocket.socketId}`); console.log(`[AdminController] Сокет не найден или не подключен для ID: ${userSocket.socketId}`);
}
} else {
console.log(`[AdminController] Коллекция сокетов недоступна`);
} }
} catch (socketError) { } catch (socketError) {
console.error(`[AdminController] Ошибка при обработке сокета ${userSocket.socketId}:`, socketError); console.error(`[AdminController] Ошибка при обработке сокета ${userSocket.socketId}:`, socketError);
} }
}); }
} else { } else {
console.log(`[AdminController] Пользователь ${userId} не найден в активных соединениях для отправки уведомления о разблокировке`); console.log(`[AdminController] Пользователь ${userId} не найден в активных соединениях для отправки уведомления о разблокировке`);
} }
if (!notificationSent) {
console.log(`[AdminController] Уведомление о разблокировке не было отправлено напрямую, но было отправлено глобальное уведомление`);
}
} }
res.json({ res.json({

View File

@ -145,6 +145,37 @@ export const connectSocket = () => {
} }
}); });
// Обработчик глобальной блокировки
socket.on('global_user_blocked', (data) => {
console.log('[SocketService] Получено глобальное уведомление о блокировке пользователя:', data);
// Проверяем, относится ли это к нашему пользователю
if (user.value && user.value._id === data.userId) {
console.log('[SocketService] Это уведомление относится к текущему пользователю');
wasAccountBlocked = true;
// Вызываем обработчик блокировки для немедленного выхода
if (typeof handleAccountBlocked === 'function') {
try {
// Создаем объект с данными блокировки
const blockData = {
message: 'Ваш аккаунт был заблокирован администратором.',
timestamp: data.timestamp,
userId: data.userId,
blocked: true,
blockType: 'global_notification'
};
handleAccountBlocked(blockData);
} catch (error) {
console.error('[SocketService] Ошибка при обработке глобальной блокировки:', error);
// Аварийный выход в случае ошибки
window.location.href = '/login?blocked=true';
}
}
}
});
return socket; return socket;
} else { } else {
console.warn('[SocketService] Не удалось подключиться: пользователь не аутентифицирован или нет ID.'); console.warn('[SocketService] Не удалось подключиться: пользователь не аутентифицирован или нет ID.');