Files
BYW-VoiceHub/server/api/songs/[id]/voters.get.ts
T

99 lines
2.7 KiB
TypeScript
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.
import { createError, defineEventHandler, getRouterParam } from 'h3'
import { db } from '~/drizzle/db'
import { songs, users, votes } from '~/drizzle/schema'
import { eq } from 'drizzle-orm'
import { createApiError } from '~~/server/utils/apiError'
export default defineEventHandler(async (event) => {
try {
// 检查用户认证
const user = event.context.user
if (!user) {
throw createApiError(401, 'SONG_LOGIN_REQUIRED_VIEW_VOTERS', '需要登录才能查看投票人员')
}
// 检查管理员权限
if (!['SONG_ADMIN', 'ADMIN', 'SUPER_ADMIN'].includes(user.role)) {
throw createApiError(403, 'SONG_VOTERS_ADMIN_ONLY', '只有管理员才能查看投票人员列表')
}
// 获取歌曲ID
const songId = parseInt(getRouterParam(event, 'id') || '0')
if (!songId || isNaN(songId)) {
throw createApiError(400, 'SONG_INVALID_ID', '无效的歌曲ID')
}
// 检查歌曲是否存在
const songResult = await db
.select({
id: songs.id,
title: songs.title,
artist: songs.artist
})
.from(songs)
.where(eq(songs.id, songId))
.limit(1)
const song = songResult[0]
if (!song) {
throw createApiError(404, 'SONG_NOT_FOUND', '歌曲不存在')
}
// 获取投票人员列表
const votesResult = await db
.select({
userId: votes.userId,
createdAt: votes.createdAt,
userName: users.name,
username: users.username,
grade: users.grade,
class: users.class
})
.from(votes)
.innerJoin(users, eq(votes.userId, users.id))
.where(eq(votes.songId, songId))
.orderBy(votes.createdAt)
// 处理用户名显示逻辑,总是显示年级和班级信息
const votersWithDisplayName = votesResult.map((vote) => {
let displayName = vote.userName || vote.username
// 如果有年级信息,添加年级和班级后缀
if (vote.grade) {
if (vote.class) {
displayName = `${displayName}(${vote.grade} ${vote.class})`
} else {
displayName = `${displayName}(${vote.grade})`
}
}
return {
id: vote.userId,
name: displayName,
votedAt: vote.createdAt
}
})
return {
song: {
id: song.id,
title: song.title,
artist: song.artist
},
voters: votersWithDisplayName,
totalVotes: votersWithDisplayName.length
}
} catch (error: any) {
console.error('获取投票人员列表失败:', error)
if (error.statusCode) {
throw error
}
throw createApiError(500, 'SONG_FETCH_VOTERS_FAILED', '获取投票人员列表失败')
}
})