import { db, songs, songReplayRequests, users, semesters } from '~/drizzle/db' import { desc, eq, sql, and, or } from 'drizzle-orm' export default defineEventHandler(async (event) => { // 1. 检查权限 const user = event.context.user if (!user || !['ADMIN', 'SUPER_ADMIN'].includes(user.role)) { throw createError({ statusCode: 403, message: '权限不足' }) } // 获取查询参数 const query = getQuery(event) const status = (query.status as string) || 'PENDING' // PENDING, FULFILLED, REJECTED, ALL const semesterName = query.semester as string // 构建查询条件 const conditions = [] if (status !== 'ALL') { conditions.push(eq(songReplayRequests.status, status as any)) } if (semesterName && semesterName !== 'all') { conditions.push(eq(songs.semester, semesterName)) } // 2. 查询 // 获取歌曲信息及重播申请数量,同时关联用户信息 const requestsQuery = db .select({ song: songs, requester: { id: users.id, name: users.name, grade: users.grade, class: users.class }, requestCount: sql`count(${songReplayRequests.id})` .mapWith(Number) .as('request_count'), lastRequestedAt: sql`max(${songReplayRequests.createdAt})`.as('last_requested_at') }) .from(songs) .innerJoin(songReplayRequests, eq(songs.id, songReplayRequests.songId)) .leftJoin(users, eq(songs.requesterId, users.id)) .where(conditions.length > 0 ? and(...conditions) : undefined) .groupBy(songs.id, users.id, users.name, users.grade, users.class) .orderBy(desc(sql`request_count`)) const requests = await requestsQuery // 获取所有用户姓名,用于处理同名情况 const allUsers = await db .select({ name: users.name, grade: users.grade }) .from(users) const nameToUsers = new Map() allUsers.forEach((u) => { if (u.name) { if (!nameToUsers.has(u.name)) { nameToUsers.set(u.name, []) } nameToUsers.get(u.name).push(u) } }) const formatClassInfo = (userObj: any) => { if (!userObj) return '' const parts: string[] = [] if (userObj.grade) parts.push(String(userObj.grade)) if (userObj.class) parts.push(String(userObj.class)) return parts.join(' ').trim() } const formatDisplayName = (userObj: any) => { if (!userObj) return '未知用户' const name = userObj.name ? String(userObj.name).trim() : '' const classInfo = formatClassInfo(userObj) if (!name) return classInfo || '未知用户' return classInfo ? `${classInfo} ${name}` : name } const subConditions = [] if (status !== 'ALL') { subConditions.push(eq(songReplayRequests.status, status as any)) } if (semesterName && semesterName !== 'all') { subConditions.push(eq(songs.semester, semesterName)) } // 获取详细的重播申请人信息 let requestDetailsQuery = db .select({ songId: songReplayRequests.songId, user: { name: users.name, grade: users.grade, class: users.class }, createdAt: songReplayRequests.createdAt, status: songReplayRequests.status }) .from(songReplayRequests) .innerJoin(users, eq(songReplayRequests.userId, users.id)) .innerJoin(songs, eq(songReplayRequests.songId, songs.id)) .where(subConditions.length > 0 ? and(...subConditions) : undefined) .orderBy(desc(songReplayRequests.createdAt)) const requestDetails = await requestDetailsQuery const detailsMap = new Map() requestDetails.forEach((d) => { if (!detailsMap.has(d.songId)) detailsMap.set(d.songId, []) detailsMap.get(d.songId).push({ name: formatDisplayName(d.user), grade: d.user.grade, class: d.user.class, createdAt: d.createdAt, status: d.status }) }) return requests.map((item) => ({ ...item.song, requester: formatDisplayName(item.requester), requesterGrade: item.requester?.grade, requesterClass: item.requester?.class, voteCount: item.requestCount, requestCount: item.requestCount, lastRequestedAt: item.lastRequestedAt, requestDetails: detailsMap.get(item.song.id) || [] })) })