обновил критерии

This commit is contained in:
2025-11-21 23:47:56 +03:00
parent 599170df2c
commit 4c35decfd7

View File

@@ -119,27 +119,30 @@ router.get('/statistics', async (req, res) => {
} }
}); });
// GET /api/ratings/top3 - топ-3 команды/участники // GET /api/ratings/top3 - топ-3 команды и топ-3 участники отдельно
// ВАЖНО: всегда возвращаем объект вида { teams: Top3Item[], participants: Top3Item[] },
// чтобы фронтенд мог безопасно работать с data.teams / data.participants
router.get('/top3', async (req, res) => { router.get('/top3', async (req, res) => {
try { try {
const { type, eventId } = req.query; const { type, eventId } = req.query;
// Получаем статистику // Получаем все активные команды/участников
const teamFilter = { isActive: true }; const teamFilter = { isActive: true };
if (type) teamFilter.type = type;
if (eventId) teamFilter.eventId = eventId; if (eventId) teamFilter.eventId = eventId;
const teams = await Team.find(teamFilter); const teams = await Team.find(teamFilter);
const ratingFilter = {}; const ratingFilter = {};
if (eventId) ratingFilter.eventId = eventId; if (eventId) ratingFilter.eventId = eventId;
const ratings = await Rating.find(ratingFilter) const ratings = await Rating.find(ratingFilter).populate('teamId', 'name type projectName');
.populate('teamId', 'name type projectName');
// Группируем и считаем средние баллы const calculateTop3 = (sourceTeams) => {
const teamScores = teams.map(team => { const teamScores = sourceTeams.map((team) => {
const teamRatings = ratings.filter(r => r.teamId && r.teamId._id.toString() === team._id.toString()); const teamRatings = ratings.filter(
(r) => r.teamId && r.teamId._id.toString() === team._id.toString()
);
const totalScore = teamRatings.length > 0 const totalScore =
teamRatings.length > 0
? teamRatings.reduce((sum, r) => sum + r.totalScore, 0) / teamRatings.length ? teamRatings.reduce((sum, r) => sum + r.totalScore, 0) / teamRatings.length
: 0; : 0;
@@ -150,18 +153,30 @@ router.get('/top3', async (req, res) => {
type: team.type, type: team.type,
projectName: team.projectName projectName: team.projectName
}, },
totalScore: totalScore, totalScore,
ratingsCount: teamRatings.length ratingsCount: teamRatings.length
}; };
}); });
// Сортируем по баллам и берем топ-3 return teamScores
const top3 = teamScores .filter((t) => t.ratingsCount > 0)
.filter(t => t.ratingsCount > 0)
.sort((a, b) => b.totalScore - a.totalScore) .sort((a, b) => b.totalScore - a.totalScore)
.slice(0, 3); .slice(0, 3);
};
res.json(top3); const teamEntities = teams.filter((t) => t.type === 'team');
const participantEntities = teams.filter((t) => t.type === 'participant');
const teamTop3 = calculateTop3(teamEntities);
const participantTop3 = calculateTop3(participantEntities);
// Параметр type управляет только содержимым, но не форматом ответа
const response = {
teams: !type || type === 'team' ? teamTop3 : [],
participants: !type || type === 'participant' ? participantTop3 : []
};
res.json(response);
} catch (error) { } catch (error) {
res.status(500).json({ error: error.message }); res.status(500).json({ error: error.message });
} }