Reflex/backend/controllers/reportController.js

246 lines
7.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const Report = require('../models/Report');
const User = require('../models/User');
// @desc Подать жалобу на пользователя
// @route POST /api/reports
// @access Private
const createReport = async (req, res, next) => {
try {
const { reportedUserId, reason, description } = req.body;
const reporterId = req.user._id;
// Проверяем, что пользователь не подает жалобу на самого себя
if (reporterId.equals(reportedUserId)) {
const error = new Error('Вы не можете подать жалобу на самого себя');
error.statusCode = 400;
return next(error);
}
// Проверяем, существует ли пользователь, на которого подается жалоба
const reportedUser = await User.findById(reportedUserId);
if (!reportedUser) {
const error = new Error('Пользователь не найден');
error.statusCode = 404;
return next(error);
}
// Проверяем, нет ли уже жалобы от этого пользователя на этого же пользователя
const existingReport = await Report.findOne({
reporter: reporterId,
reportedUser: reportedUserId
});
if (existingReport) {
const error = new Error('Вы уже подавали жалобу на этого пользователя');
error.statusCode = 400;
return next(error);
}
// Создаем новую жалобу
const newReport = new Report({
reporter: reporterId,
reportedUser: reportedUserId,
reason,
description: description || ''
});
await newReport.save();
console.log(`[REPORT_CTRL] Создана жалоба ${newReport._id} от пользователя ${reporterId} на пользователя ${reportedUserId}`);
res.status(201).json({
message: 'Жалоба успешно подана. Мы рассмотрим её в ближайшее время.',
reportId: newReport._id
});
} catch (error) {
console.error('[REPORT_CTRL] Ошибка при создании жалобы:', error.message);
next(error);
}
};
// @desc Получить список всех жалоб (для админов)
// @route GET /api/admin/reports
// @access Admin
const getAllReports = async (req, res, next) => {
try {
const { page = 1, limit = 20, status = 'all' } = req.query;
const skip = (page - 1) * limit;
// Строим фильтр
let filter = {};
if (status !== 'all') {
filter.status = status;
}
// Получаем жалобы с информацией о пользователях
const reports = await Report.find(filter)
.populate('reporter', 'name email')
.populate('reportedUser', 'name email isActive')
.populate('reviewedBy', 'name email')
.skip(skip)
.limit(parseInt(limit))
.sort({ createdAt: -1 });
// Получаем общее количество жалоб
const total = await Report.countDocuments(filter);
res.json({
reports,
pagination: {
page: parseInt(page),
limit: parseInt(limit),
total,
pages: Math.ceil(total / limit)
}
});
} catch (error) {
console.error('[REPORT_CTRL] Ошибка при получении списка жалоб:', error.message);
next(error);
}
};
// @desc Получить детали жалобы
// @route GET /api/admin/reports/:id
// @access Admin
const getReportById = async (req, res, next) => {
try {
const { id } = req.params;
const report = await Report.findById(id)
.populate('reporter', 'name email photos')
.populate('reportedUser', 'name email photos isActive')
.populate('reviewedBy', 'name email');
if (!report) {
const error = new Error('Жалоба не найдена');
error.statusCode = 404;
return next(error);
}
res.json(report);
} catch (error) {
console.error('[REPORT_CTRL] Ошибка при получении деталей жалобы:', error.message);
next(error);
}
};
// @desc Обновить статус жалобы
// @route PUT /api/admin/reports/:id
// @access Admin
const updateReportStatus = async (req, res, next) => {
try {
const { id } = req.params;
const { status, adminComment, actionTaken } = req.body;
const adminId = req.user._id;
const report = await Report.findById(id);
if (!report) {
const error = new Error('Жалоба не найдена');
error.statusCode = 404;
return next(error);
}
// Обновляем жалобу
report.status = status;
report.reviewedBy = adminId;
report.reviewedAt = new Date();
if (adminComment) {
report.adminComment = adminComment;
}
if (actionTaken) {
report.actionTaken = actionTaken;
}
await report.save();
// Если было предпринято действие, применяем его к пользователю
if (actionTaken && actionTaken !== 'none') {
const reportedUser = await User.findById(report.reportedUser);
if (reportedUser) {
switch (actionTaken) {
case 'temporary_ban':
case 'permanent_ban':
case 'profile_removal':
reportedUser.isActive = false;
await reportedUser.save();
console.log(`[REPORT_CTRL] Пользователь ${reportedUser._id} заблокирован по жалобе ${id}`);
break;
}
}
}
console.log(`[REPORT_CTRL] Жалоба ${id} обновлена администратором ${adminId}`);
res.json({
message: 'Жалоба успешно обновлена',
report: await Report.findById(id)
.populate('reporter', 'name email')
.populate('reportedUser', 'name email isActive')
.populate('reviewedBy', 'name email')
});
} catch (error) {
console.error('[REPORT_CTRL] Ошибка при обновлении жалобы:', error.message);
next(error);
}
};
// @desc Получить статистику жалоб
// @route GET /api/admin/reports/stats
// @access Admin
const getReportsStats = async (req, res, next) => {
try {
// Общее количество жалоб
const totalReports = await Report.countDocuments();
// Жалобы по статусам
const pendingReports = await Report.countDocuments({ status: 'pending' });
const reviewedReports = await Report.countDocuments({ status: 'reviewed' });
const resolvedReports = await Report.countDocuments({ status: 'resolved' });
const dismissedReports = await Report.countDocuments({ status: 'dismissed' });
// Жалобы за последние 30 дней
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
const recentReports = await Report.countDocuments({
createdAt: { $gte: thirtyDaysAgo }
});
// Топ причин жалоб
const topReasons = await Report.aggregate([
{ $group: { _id: '$reason', count: { $sum: 1 } } },
{ $sort: { count: -1 } },
{ $limit: 5 }
]);
const stats = {
total: totalReports,
byStatus: {
pending: pendingReports,
reviewed: reviewedReports,
resolved: resolvedReports,
dismissed: dismissedReports
},
recent: recentReports,
topReasons
};
res.json(stats);
} catch (error) {
console.error('[REPORT_CTRL] Ошибка при получении статистики жалоб:', error.message);
next(error);
}
};
module.exports = {
createReport,
getAllReports,
getReportById,
updateReportStatus,
getReportsStats
};