diff --git a/admin-server.js b/admin-server.js index 5c85f9f..a4eee1a 100644 --- a/admin-server.js +++ b/admin-server.js @@ -853,4 +853,427 @@ router.get('/admin/export', requireAdmin, async (req, res) => { } }); +// Получение профилей пользователей с настройками уведомлений +router.get('/admin/user-profiles', requireAdmin, async (req, res) => { + try { + const { getDb } = require('./database'); + const db = getDb(); + + const query = ` + SELECT + u.id, + u.login, + u.name, + u.email as user_email, + u.role, + u.auth_type, + u.groups, + u.created_at, + u.last_login, + us.email_notifications, + us.notification_email, + us.telegram_notifications, + us.telegram_chat_id, + us.vk_notifications, + us.vk_user_id, + us.updated_at as settings_updated_at + FROM users u + LEFT JOIN user_settings us ON u.id = us.user_id + ORDER BY u.name + `; + + db.all(query, [], (err, profiles) => { + if (err) { + console.error('Ошибка получения профилей пользователей:', err); + return res.status(500).json({ error: 'Ошибка сервера' }); + } + res.json(profiles); + }); + } catch (error) { + console.error('Ошибка:', error); + res.status(500).json({ error: 'Ошибка сервера' }); + } +}); + +// Получение конкретного профиля пользователя +router.get('/admin/user-profiles/:id', requireAdmin, async (req, res) => { + try { + const { getDb } = require('./database'); + const db = getDb(); + const userId = req.params.id; + + const query = ` + SELECT + u.id, + u.login, + u.name, + u.email as user_email, + u.role, + u.auth_type, + u.groups, + u.created_at, + u.last_login, + us.email_notifications, + us.notification_email, + us.telegram_notifications, + us.telegram_chat_id, + us.vk_notifications, + us.vk_user_id, + us.created_at as settings_created_at, + us.updated_at as settings_updated_at + FROM users u + LEFT JOIN user_settings us ON u.id = us.user_id + WHERE u.id = ? + `; + + db.get(query, [userId], (err, profile) => { + if (err) { + console.error('Ошибка получения профиля пользователя:', err); + return res.status(500).json({ error: 'Ошибка сервера' }); + } + + if (!profile) { + return res.status(404).json({ error: 'Пользователь не найден' }); + } + + res.json(profile); + }); + } catch (error) { + console.error('Ошибка:', error); + res.status(500).json({ error: 'Ошибка сервера' }); + } +}); + +// Обновление настроек уведомлений пользователя (для админа) +router.put('/admin/user-profiles/:id/notification-settings', requireAdmin, async (req, res) => { + try { + const { getDb } = require('./database'); + const db = getDb(); + const userId = req.params.id; + const { + email_notifications, + notification_email, + telegram_notifications, + telegram_chat_id, + vk_notifications, + vk_user_id + } = req.body; + + // Валидация email + if (email_notifications && notification_email) { + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!emailRegex.test(notification_email)) { + return res.status(400).json({ error: 'Неверный формат email' }); + } + } + + // Проверяем существование записи + db.get("SELECT id FROM user_settings WHERE user_id = ?", [userId], (err, existing) => { + if (err) { + console.error('Ошибка проверки настроек:', err); + return res.status(500).json({ error: 'Ошибка сервера' }); + } + + if (existing) { + // Обновляем существующие настройки + db.run( + `UPDATE user_settings SET + email_notifications = ?, + notification_email = ?, + telegram_notifications = ?, + telegram_chat_id = ?, + vk_notifications = ?, + vk_user_id = ?, + updated_at = CURRENT_TIMESTAMP + WHERE user_id = ?`, + [ + email_notifications ? 1 : 0, + notification_email || '', + telegram_notifications ? 1 : 0, + telegram_chat_id || '', + vk_notifications ? 1 : 0, + vk_user_id || '', + userId + ], + function(updateErr) { + if (updateErr) { + console.error('Ошибка обновления настроек:', updateErr); + return res.status(500).json({ error: 'Ошибка сервера' }); + } + + // Логируем действие + const { logActivity } = require('./database'); + if (logActivity) { + logActivity(0, req.session.user.id, 'USER_SETTINGS_UPDATED', `Админ обновил настройки уведомлений пользователя ${userId}`); + } + + console.log(`✅ Админ обновил настройки пользователя ${userId}`); + res.json({ success: true, message: 'Настройки уведомлений обновлены' }); + } + ); + } else { + // Создаем новые настройки + db.run( + `INSERT INTO user_settings + (user_id, email_notifications, notification_email, + telegram_notifications, telegram_chat_id, + vk_notifications, vk_user_id) + VALUES (?, ?, ?, ?, ?, ?, ?)`, + [ + userId, + email_notifications ? 1 : 0, + notification_email || '', + telegram_notifications ? 1 : 0, + telegram_chat_id || '', + vk_notifications ? 1 : 0, + vk_user_id || '' + ], + function(insertErr) { + if (insertErr) { + console.error('Ошибка создания настроек:', insertErr); + return res.status(500).json({ error: 'Ошибка сервера' }); + } + + // Логируем действие + const { logActivity } = require('./database'); + if (logActivity) { + logActivity(null, req.session.user.id, 'USER_SETTINGS_CREATED', `Админ создал настройки уведомлений пользователя ${userId}`); + } + + console.log(`✅ Админ создал настройки пользователя ${userId}`); + res.json({ success: true, message: 'Настройки уведомлений созданы' }); + } + ); + } + }); + + } catch (error) { + console.error('Ошибка:', error); + res.status(500).json({ error: 'Ошибка сервера' }); + } +}); + +// Массовое обновление email уведомлений для нескольких пользователей +router.post('/admin/bulk-email-settings', requireAdmin, async (req, res) => { + try { + const { getDb } = require('./database'); + const db = getDb(); + const { users, email_notifications, notification_email } = req.body; + + if (!Array.isArray(users) || users.length === 0) { + return res.status(400).json({ error: 'Выберите пользователей' }); + } + + if (email_notifications && !notification_email) { + return res.status(400).json({ error: 'Укажите email для уведомлений' }); + } + + // Валидация email + if (email_notifications && notification_email) { + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!emailRegex.test(notification_email)) { + return res.status(400).json({ error: 'Неверный формат email' }); + } + } + + const results = { + success: 0, + failed: 0, + errors: [] + }; + + // Обновляем каждого пользователя в транзакции + db.serialize(() => { + db.run("BEGIN TRANSACTION"); + + users.forEach(userId => { + // Проверяем существование записи + db.get("SELECT id FROM user_settings WHERE user_id = ?", [userId], (err, existing) => { + if (err) { + results.failed++; + results.errors.push({ userId, error: err.message }); + return; + } + + if (existing) { + // Обновляем существующие настройки + db.run( + `UPDATE user_settings SET + email_notifications = ?, + notification_email = ?, + updated_at = CURRENT_TIMESTAMP + WHERE user_id = ?`, + [ + email_notifications ? 1 : 0, + email_notifications ? notification_email : '', + userId + ], + function(updateErr) { + if (updateErr) { + results.failed++; + results.errors.push({ userId, error: updateErr.message }); + } else { + results.success++; + } + } + ); + } else { + // Создаем новые настройки с значениями по умолчанию + db.run( + `INSERT INTO user_settings + (user_id, email_notifications, notification_email, + telegram_notifications, telegram_chat_id, + vk_notifications, vk_user_id) + VALUES (?, ?, ?, 0, '', 0, '')`, + [ + userId, + email_notifications ? 1 : 0, + email_notifications ? notification_email : '' + ], + function(insertErr) { + if (insertErr) { + results.failed++; + results.errors.push({ userId, error: insertErr.message }); + } else { + results.success++; + } + } + ); + } + }); + }); + + setTimeout(() => { + db.run("COMMIT", (commitErr) => { + if (commitErr) { + console.error('Ошибка коммита транзакции:', commitErr); + return res.status(500).json({ error: 'Ошибка транзакции' }); + } + + // Логируем действие + const { logActivity } = require('./database'); + if (logActivity) { + logActivity(null, req.session.user.id, 'BULK_SETTINGS_UPDATED', + `Админ массово обновил настройки для ${users.length} пользователей`); + } + + console.log(`✅ Массовое обновление: успешно ${results.success}, ошибок ${results.failed}`); + res.json({ + success: true, + message: 'Настройки обновлены', + results + }); + }); + }, 1000); + }); + + } catch (error) { + console.error('Ошибка:', error); + res.status(500).json({ error: 'Ошибка сервера' }); + } +}); + +// Отправка тестового уведомления пользователю +router.post('/admin/user-profiles/:id/test-notification', requireAdmin, async (req, res) => { + try { + const { getDb } = require('./database'); + const db = getDb(); + const userId = req.params.id; + const notificationType = req.body.notification_type || 'test'; + + // Получаем информацию о пользователе + db.get(` + SELECT u.id, u.name, u.email, us.email_notifications, us.notification_email + FROM users u + LEFT JOIN user_settings us ON u.id = us.user_id + WHERE u.id = ? + `, [userId], async (err, user) => { + if (err) { + console.error('Ошибка получения пользователя:', err); + return res.status(500).json({ error: 'Ошибка сервера' }); + } + + if (!user) { + return res.status(404).json({ error: 'Пользователь не найден' }); + } + + // Проверяем, включены ли email уведомления + if (!user.email_notifications) { + return res.status(400).json({ error: 'Email уведомления отключены у пользователя' }); + } + + const emailTo = user.notification_email || user.email; + if (!emailTo) { + return res.status(400).json({ error: 'У пользователя не указан email' }); + } + + // Отправляем тестовое уведомление + const emailNotifications = require('./email-notifications'); + const emailSent = await emailNotifications.sendEmailNotification( + emailTo, + 'Тестовое уведомление от School CRM', + ` + + + + + + +
+
+

✅ Тестовое уведомление

+
+
+

Здравствуйте, ${user.name}!

+

Это тестовое уведомление от системы School CRM.

+

Если вы получили это письмо, значит настройки уведомлений работают корректно.

+
+

Информация о тесте:

+ +
+ +
+ + + ` + ); + + if (emailSent) { + // Логируем действие + const { logActivity } = require('./database'); + if (logActivity) { + logActivity(null, req.session.user.id, 'TEST_NOTIFICATION_SENT', + `Админ отправил тестовое уведомление пользователю ${user.name} (${emailTo})`); + } + + res.json({ + success: true, + message: 'Тестовое уведомление отправлено', + email: emailTo + }); + } else { + res.status(500).json({ error: 'Не удалось отправить уведомление' }); + } + }); + + } catch (error) { + console.error('Ошибка:', error); + res.status(500).json({ error: 'Ошибка сервера' }); + } +}); + module.exports = router; \ No newline at end of file diff --git a/public/admin-profiles.html b/public/admin-profiles.html new file mode 100644 index 0000000..a4ce210 --- /dev/null +++ b/public/admin-profiles.html @@ -0,0 +1,1242 @@ + + + + + + + Профили пользователей - School CRM + + + + +
+
+

Профили пользователей

+ +
+ + + +
+
+
+

Список профилей пользователей

+ +
+ +
+ + + +
+ +
+ + + + + + + + + + + + + + + + + +
ПользовательРольEmail уведомленийСтатусПоследний входДействия
+ Загрузка профилей... +
+
+
+ + +
+
+ + + + + +
+ + + + \ No newline at end of file diff --git a/server.js b/server.js index b34f3d7..d07573f 100644 --- a/server.js +++ b/server.js @@ -550,6 +550,13 @@ app.get('/admin', (req, res) => { } res.sendFile(path.join(__dirname, 'public/admin.html')); }); +// Страница профилей пользователей (только для админов) +app.get('/admin/profiles', (req, res) => { + if (!req.session.user || req.session.user.role !== 'admin') { + return res.status(403).send('Доступ запрещен'); + } + res.sendFile(path.join(__dirname, 'public/admin-profiles.html')); +}); // API для получения настроек уведомлений пользователя app.get('/api/user/settings', requireAuth, async (req, res) => {