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.
+
Если вы получили это письмо, значит настройки уведомлений работают корректно.
+
+
Информация о тесте:
+
+ - Получатель: ${emailTo}
+ - Отправитель: Администратор
+ - Время: ${new Date().toLocaleString('ru-RU')}
+
+
+
+
+
+
+ `
+ );
+
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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) => {