обновил критерии
This commit is contained in:
@@ -119,49 +119,64 @@ 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.reduce((sum, r) => sum + r.totalScore, 0) / teamRatings.length
|
teamRatings.length > 0
|
||||||
: 0;
|
? teamRatings.reduce((sum, r) => sum + r.totalScore, 0) / teamRatings.length
|
||||||
|
: 0;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
team: {
|
team: {
|
||||||
_id: team._id,
|
_id: team._id,
|
||||||
name: team.name,
|
name: team.name,
|
||||||
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 });
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user