чистка
This commit is contained in:
@@ -1,383 +0,0 @@
|
|||||||
// group-management.js
|
|
||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
|
|
||||||
function setupGroupManagement(app, db) {
|
|
||||||
|
|
||||||
// Middleware для проверки администратора
|
|
||||||
function requireAdmin(req, res, next) {
|
|
||||||
if (!req.session.user || req.session.user.role !== 'admin') {
|
|
||||||
return res.status(403).json({ error: 'Недостаточно прав' });
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// API для получения всех групп
|
|
||||||
router.get('/api/groups', requireAdmin, (req, res) => {
|
|
||||||
db.all(`
|
|
||||||
SELECT g.*,
|
|
||||||
COUNT(DISTINCT ugm.user_id) as member_count
|
|
||||||
FROM user_groups g
|
|
||||||
LEFT JOIN user_group_memberships ugm ON g.id = ugm.group_id
|
|
||||||
GROUP BY g.id
|
|
||||||
ORDER BY g.name
|
|
||||||
`, [], (err, groups) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка получения групп:', err);
|
|
||||||
return res.status(500).json({ error: 'Ошибка получения групп' });
|
|
||||||
}
|
|
||||||
res.json(groups || []);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// API для получения одной группы с участниками
|
|
||||||
router.get('/api/groups/:groupId', requireAdmin, (req, res) => {
|
|
||||||
const { groupId } = req.params;
|
|
||||||
|
|
||||||
db.get(`
|
|
||||||
SELECT g.*,
|
|
||||||
COUNT(DISTINCT ugm.user_id) as member_count
|
|
||||||
FROM user_groups g
|
|
||||||
LEFT JOIN user_group_memberships ugm ON g.id = ugm.group_id
|
|
||||||
WHERE g.id = ?
|
|
||||||
GROUP BY g.id
|
|
||||||
`, [groupId], (err, group) => {
|
|
||||||
if (err || !group) {
|
|
||||||
return res.status(404).json({ error: 'Группа не найдена' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Получаем участников группы
|
|
||||||
db.all(`
|
|
||||||
SELECT u.id, u.login, u.name, u.email, u.role
|
|
||||||
FROM users u
|
|
||||||
JOIN user_group_memberships ugm ON u.id = ugm.user_id
|
|
||||||
WHERE ugm.group_id = ?
|
|
||||||
ORDER BY u.name
|
|
||||||
`, [groupId], (err, members) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка получения участников:', err);
|
|
||||||
return res.status(500).json({ error: 'Ошибка получения участников' });
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
...group,
|
|
||||||
members: members || []
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// API для создания новой группы
|
|
||||||
router.post('/api/groups', requireAdmin, (req, res) => {
|
|
||||||
const { name, description, color, can_approve_documents } = req.body;
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
return res.status(400).json({ error: 'Название группы обязательно' });
|
|
||||||
}
|
|
||||||
|
|
||||||
db.run(`
|
|
||||||
INSERT INTO user_groups (name, description, color, can_approve_documents)
|
|
||||||
VALUES (?, ?, ?, ?)
|
|
||||||
`, [
|
|
||||||
name.trim(),
|
|
||||||
description || '',
|
|
||||||
color || '#3498db',
|
|
||||||
can_approve_documents ? 1 : 0
|
|
||||||
], function(err) {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка создания группы:', err);
|
|
||||||
return res.status(500).json({
|
|
||||||
error: 'Ошибка создания группы',
|
|
||||||
details: err.message.includes('UNIQUE') ? 'Группа с таким названием уже существует' : err.message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
groupId: this.lastID,
|
|
||||||
message: 'Группа создана успешно'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// API для обновления группы
|
|
||||||
router.put('/api/groups/:groupId', requireAdmin, (req, res) => {
|
|
||||||
const { groupId } = req.params;
|
|
||||||
const { name, description, color, can_approve_documents } = req.body;
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
return res.status(400).json({ error: 'Название группы обязательно' });
|
|
||||||
}
|
|
||||||
|
|
||||||
db.run(`
|
|
||||||
UPDATE user_groups
|
|
||||||
SET name = ?, description = ?, color = ?, can_approve_documents = ?, updated_at = CURRENT_TIMESTAMP
|
|
||||||
WHERE id = ?
|
|
||||||
`, [
|
|
||||||
name.trim(),
|
|
||||||
description || '',
|
|
||||||
color || '#3498db',
|
|
||||||
can_approve_documents ? 1 : 0,
|
|
||||||
groupId
|
|
||||||
], function(err) {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка обновления группы:', err);
|
|
||||||
return res.status(500).json({
|
|
||||||
error: 'Ошибка обновления группы',
|
|
||||||
details: err.message.includes('UNIQUE') ? 'Группа с таким названием уже существует' : err.message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.changes === 0) {
|
|
||||||
return res.status(404).json({ error: 'Группа не найдена' });
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
message: 'Группа обновлена успешно'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// API для удаления группы
|
|
||||||
router.delete('/api/groups/:groupId', requireAdmin, (req, res) => {
|
|
||||||
const { groupId } = req.params;
|
|
||||||
|
|
||||||
db.run(`DELETE FROM user_groups WHERE id = ?`, [groupId], function(err) {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка удаления группы:', err);
|
|
||||||
return res.status(500).json({ error: 'Ошибка удаления группы' });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.changes === 0) {
|
|
||||||
return res.status(404).json({ error: 'Группа не найдена' });
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
message: 'Группа удалена успешно'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// API для добавления пользователя в группу
|
|
||||||
router.post('/api/groups/:groupId/members', requireAdmin, (req, res) => {
|
|
||||||
const { groupId } = req.params;
|
|
||||||
const { userId } = req.body;
|
|
||||||
|
|
||||||
if (!userId) {
|
|
||||||
return res.status(400).json({ error: 'ID пользователя обязательно' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверяем существование группы и пользователя
|
|
||||||
db.get(`SELECT id FROM user_groups WHERE id = ?`, [groupId], (err, group) => {
|
|
||||||
if (err || !group) {
|
|
||||||
return res.status(404).json({ error: 'Группа не найдена' });
|
|
||||||
}
|
|
||||||
|
|
||||||
db.get(`SELECT id FROM users WHERE id = ?`, [userId], (err, user) => {
|
|
||||||
if (err || !user) {
|
|
||||||
return res.status(404).json({ error: 'Пользователь не найден' });
|
|
||||||
}
|
|
||||||
|
|
||||||
db.run(`
|
|
||||||
INSERT OR IGNORE INTO user_group_memberships (user_id, group_id)
|
|
||||||
VALUES (?, ?)
|
|
||||||
`, [userId, groupId], function(err) {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка добавления пользователя в группу:', err);
|
|
||||||
return res.status(500).json({ error: 'Ошибка добавления пользователя в группу' });
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
message: 'Пользователь добавлен в группу'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// API для удаления пользователя из группы
|
|
||||||
router.delete('/api/groups/:groupId/members/:userId', requireAdmin, (req, res) => {
|
|
||||||
const { groupId, userId } = req.params;
|
|
||||||
|
|
||||||
db.run(`
|
|
||||||
DELETE FROM user_group_memberships
|
|
||||||
WHERE user_id = ? AND group_id = ?
|
|
||||||
`, [userId, groupId], function(err) {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка удаления пользователя из группы:', err);
|
|
||||||
return res.status(500).json({ error: 'Ошибка удаления пользователя из группы' });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.changes === 0) {
|
|
||||||
return res.status(404).json({ error: 'Пользователь не найден в группе' });
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
message: 'Пользователь удален из группы'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// API для получения всех пользователей с их группами
|
|
||||||
router.get('/api/users-with-groups', requireAdmin, (req, res) => {
|
|
||||||
db.all(`
|
|
||||||
SELECT u.id, u.login, u.name, u.email, u.role,
|
|
||||||
GROUP_CONCAT(DISTINCT g.name) as group_names,
|
|
||||||
GROUP_CONCAT(DISTINCT g.id) as group_ids
|
|
||||||
FROM users u
|
|
||||||
LEFT JOIN user_group_memberships ugm ON u.id = ugm.user_id
|
|
||||||
LEFT JOIN user_groups g ON ugm.group_id = g.id
|
|
||||||
WHERE u.role IN ('admin', 'teacher')
|
|
||||||
GROUP BY u.id
|
|
||||||
ORDER BY u.name
|
|
||||||
`, [], (err, users) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка получения пользователей с группами:', err);
|
|
||||||
return res.status(500).json({ error: 'Ошибка получения данных' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Преобразуем строки в массивы
|
|
||||||
const formattedUsers = users.map(user => ({
|
|
||||||
...user,
|
|
||||||
group_names: user.group_names ? user.group_names.split(',') : [],
|
|
||||||
group_ids: user.group_ids ? user.group_ids.split(',').map(id => parseInt(id)) : []
|
|
||||||
}));
|
|
||||||
|
|
||||||
res.json(formattedUsers);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// API для получения доступных групп для пользователя
|
|
||||||
router.get('/api/users/:userId/available-groups', requireAdmin, (req, res) => {
|
|
||||||
const { userId } = req.params;
|
|
||||||
|
|
||||||
db.all(`
|
|
||||||
SELECT g.*,
|
|
||||||
CASE WHEN ugm.user_id IS NOT NULL THEN 1 ELSE 0 END as is_member
|
|
||||||
FROM user_groups g
|
|
||||||
LEFT JOIN user_group_memberships ugm ON g.id = ugm.group_id AND ugm.user_id = ?
|
|
||||||
ORDER BY g.name
|
|
||||||
`, [userId], (err, groups) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка получения групп:', err);
|
|
||||||
return res.status(500).json({ error: 'Ошибка получения данных' });
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(groups || []);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// API для массового обновления групп пользователя
|
|
||||||
router.put('/api/users/:userId/groups', requireAdmin, (req, res) => {
|
|
||||||
const { userId } = req.params;
|
|
||||||
const { groupIds } = req.body; // массив ID групп
|
|
||||||
|
|
||||||
if (!Array.isArray(groupIds)) {
|
|
||||||
return res.status(400).json({ error: 'groupIds должен быть массивом' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверяем существование пользователя
|
|
||||||
db.get(`SELECT id FROM users WHERE id = ?`, [userId], (err, user) => {
|
|
||||||
if (err || !user) {
|
|
||||||
return res.status(404).json({ error: 'Пользователь не найден' });
|
|
||||||
}
|
|
||||||
|
|
||||||
db.serialize(() => {
|
|
||||||
// Удаляем все текущие группы пользователя
|
|
||||||
db.run(`DELETE FROM user_group_memberships WHERE user_id = ?`, [userId], (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка удаления старых групп:', err);
|
|
||||||
return res.status(500).json({ error: 'Ошибка обновления групп' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Добавляем новые группы
|
|
||||||
if (groupIds.length > 0) {
|
|
||||||
const placeholders = groupIds.map(() => '(?, ?)').join(',');
|
|
||||||
const values = groupIds.reduce((acc, groupId) => {
|
|
||||||
acc.push(userId, groupId);
|
|
||||||
return acc;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
db.run(`
|
|
||||||
INSERT INTO user_group_memberships (user_id, group_id)
|
|
||||||
VALUES ${placeholders}
|
|
||||||
`, values, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка добавления новых групп:', err);
|
|
||||||
return res.status(500).json({ error: 'Ошибка обновления групп' });
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
message: 'Группы пользователя обновлены'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
message: 'Группы пользователя обновлены'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// API для получения пользователей, которые могут согласовывать документы
|
|
||||||
router.get('/api/approvers', requireAdmin, (req, res) => {
|
|
||||||
db.all(`
|
|
||||||
SELECT DISTINCT u.id, u.login, u.name, u.email, u.role,
|
|
||||||
g.name as group_name, g.color as group_color
|
|
||||||
FROM users u
|
|
||||||
JOIN user_group_memberships ugm ON u.id = ugm.user_id
|
|
||||||
JOIN user_groups g ON ugm.group_id = g.id
|
|
||||||
WHERE g.can_approve_documents = 1
|
|
||||||
ORDER BY u.name
|
|
||||||
`, [], (err, approvers) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка получения согласующих:', err);
|
|
||||||
return res.status(500).json({ error: 'Ошибка получения данных' });
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(approvers || []);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// API для получения групп, которые могут согласовывать документы
|
|
||||||
router.get('/api/approver-groups', (req, res) => {
|
|
||||||
const isAdmin = req.session.user && req.session.user.role === 'admin';
|
|
||||||
|
|
||||||
db.all(`
|
|
||||||
SELECT g.*,
|
|
||||||
COUNT(DISTINCT ugm.user_id) as member_count
|
|
||||||
FROM user_groups g
|
|
||||||
LEFT JOIN user_group_memberships ugm ON g.id = ugm.group_id
|
|
||||||
WHERE g.can_approve_documents = 1
|
|
||||||
GROUP BY g.id
|
|
||||||
ORDER BY g.name
|
|
||||||
`, [], (err, groups) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('❌ Ошибка получения групп согласующих:', err);
|
|
||||||
return res.status(500).json({ error: 'Ошибка получения данных' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Для обычных пользователей скрываем ID пользователей в группах
|
|
||||||
if (!isAdmin) {
|
|
||||||
groups = groups.map(group => ({
|
|
||||||
...group,
|
|
||||||
members: undefined
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(groups || []);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return router;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { setupGroupManagement };
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
// server-init.js
|
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
const { setupUploadMiddleware } = require('./upload-middleware');
|
|
||||||
const { setupTaskEndpoints } = require('./task-endpoints');
|
|
||||||
|
|
||||||
async function initializeServer(app) {
|
|
||||||
console.log('🚀 Инициализация сервера...');
|
|
||||||
|
|
||||||
try {
|
|
||||||
const { initializeDatabase, getDb, isInitialized } = require('./database');
|
|
||||||
const authService = require('./auth');
|
|
||||||
const postgresLogger = require('./postgres');
|
|
||||||
|
|
||||||
// 1. Инициализируем базу данных
|
|
||||||
console.log('🔧 Инициализация базы данных...');
|
|
||||||
await initializeDatabase();
|
|
||||||
|
|
||||||
// 2. Получаем объект БД
|
|
||||||
const db = getDb();
|
|
||||||
console.log('✅ База данных готова');
|
|
||||||
|
|
||||||
// 3. Настраиваем authService с БД
|
|
||||||
authService.setDatabase(db);
|
|
||||||
console.log('✅ Сервис аутентификации готов');
|
|
||||||
|
|
||||||
// 4. Настраиваем загрузку файлов
|
|
||||||
const upload = setupUploadMiddleware();
|
|
||||||
console.log('✅ Middleware загрузки файлов настроен');
|
|
||||||
|
|
||||||
// 5. Настраиваем endpoint'ы для задач
|
|
||||||
setupTaskEndpoints(app, db, upload);
|
|
||||||
console.log('✅ Endpoint\'ы задач настроены');
|
|
||||||
|
|
||||||
// 6. Загружаем админ роутер
|
|
||||||
try {
|
|
||||||
const adminRouter = require('./admin-server');
|
|
||||||
console.log('Admin router loaded:', adminRouter);
|
|
||||||
console.log('Type:', typeof adminRouter);
|
|
||||||
|
|
||||||
if (adminRouter && typeof adminRouter === 'function') {
|
|
||||||
app.use(adminRouter);
|
|
||||||
console.log('✅ Админ роутер подключен');
|
|
||||||
} else {
|
|
||||||
console.error('❌ Admin router is not a valid middleware function');
|
|
||||||
// Создаем заглушку, чтобы сервер работал
|
|
||||||
const express = require('express');
|
|
||||||
const stubRouter = express.Router();
|
|
||||||
stubRouter.get('*', (req, res) => {
|
|
||||||
res.status(501).json({ error: 'Admin router not available' });
|
|
||||||
});
|
|
||||||
app.use(stubRouter);
|
|
||||||
console.log('⚠️ Используется заглушка для админ роутера');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ Ошибка загрузки админ роутера:', error.message);
|
|
||||||
console.error('Stack:', error.stack);
|
|
||||||
|
|
||||||
// Создаем заглушку, чтобы сервер не падал
|
|
||||||
const express = require('express');
|
|
||||||
const stubRouter = express.Router();
|
|
||||||
stubRouter.get('*', (req, res) => {
|
|
||||||
res.status(503).json({
|
|
||||||
error: 'Admin panel temporarily unavailable',
|
|
||||||
message: error.message
|
|
||||||
});
|
|
||||||
});
|
|
||||||
app.use(stubRouter);
|
|
||||||
console.log('⚠️ Создана заглушка для админ роутера из-за ошибки');
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('✅ Сервер полностью инициализирован');
|
|
||||||
|
|
||||||
return { db, upload };
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ Ошибка инициализации сервера:', error.message);
|
|
||||||
console.error(error.stack);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { initializeServer };
|
|
||||||
Reference in New Issue
Block a user