WuYongJie f646b71813
Some checks failed
CI Check / check (push) Has been cancelled
chore: 初始化本地仓库并同步最近改动
2025-11-18 17:50:16 +08:00

88 lines
2.4 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 { NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
// 获取排行榜数据
export async function GET() {
try {
// 1. 贡献排行榜(上传素材数量最多)
// 优化:使用SQL聚合查询,保持与其他排行榜一致
const contributors = await prisma.$queryRaw<Array<{
userId: string
username: string
materialCount: bigint
}>>`
SELECT
u.id as "userId",
u.username,
COUNT(m.id)::bigint as "materialCount"
FROM users u
LEFT JOIN materials m ON u.id = m."userId"
GROUP BY u.id, u.username
ORDER BY "materialCount" DESC
LIMIT 10
`
// 2. 下载排行榜(素材被下载次数最多的作者)
// 优化:使用SQL聚合查询,避免N+1问题
const downloadRankings = await prisma.$queryRaw<Array<{
userId: string
totalDownloads: bigint
username: string
}>>`
SELECT
m."userId",
COALESCE(SUM(m."downloadCount"), 0)::bigint as "totalDownloads",
u.username
FROM materials m
INNER JOIN users u ON m."userId" = u.id
GROUP BY m."userId", u.username
ORDER BY "totalDownloads" DESC
LIMIT 10
`
const downloadUsers = downloadRankings.map((item) => ({
username: item.username || '未知用户',
count: Number(item.totalDownloads),
}))
// 3. 点赞排行榜(素材被点赞次数最多的作者)
// 优化:使用SQL聚合查询,避免N+1问题
const likeRankings = await prisma.$queryRaw<Array<{
userId: string
totalLikes: bigint
username: string
}>>`
SELECT
m."userId",
COALESCE(SUM(m."likeCount"), 0)::bigint as "totalLikes",
u.username
FROM materials m
INNER JOIN users u ON m."userId" = u.id
GROUP BY m."userId", u.username
ORDER BY "totalLikes" DESC
LIMIT 10
`
const likeUsers = likeRankings.map((item) => ({
username: item.username || '未知用户',
count: Number(item.totalLikes),
}))
return NextResponse.json({
contributors: contributors.map((user) => ({
username: user.username || '未知用户',
count: Number(user.materialCount),
})),
downloads: downloadUsers,
likes: likeUsers,
})
} catch (error) {
console.error('[Rankings] GET error:', error)
return NextResponse.json(
{ error: '获取排行榜失败' },
{ status: 500 }
)
}
}