feat: align with upstream 1.5.9.9

This commit is contained in:
2026-09-12 18:21:11 +08:00
commit 34f0679117
805 changed files with 376275 additions and 0 deletions
+98
View File
@@ -0,0 +1,98 @@
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', '获取投票人员列表失败')
}
})