47 lines
1.3 KiB
TypeScript
47 lines
1.3 KiB
TypeScript
import { prisma } from "@/lib/prisma";
|
|
import { ok, ERR } from "@/lib/api-response";
|
|
|
|
/**
|
|
* GET /api/ranking
|
|
* 返回完整 35 人实时排名(按 voteCount 降序)。
|
|
*
|
|
* 该接口适合每分钟轮询。生产环境会优先读 Redis 缓存(由后台聚合任务每分钟刷新)。
|
|
*/
|
|
export async function GET() {
|
|
try {
|
|
const artists = await prisma.artist.findMany({
|
|
where: { status: "ACTIVE" },
|
|
orderBy: [{ voteCount: "desc" }, { no: "asc" }],
|
|
select: {
|
|
id: true,
|
|
no: true,
|
|
name: true,
|
|
enName: true,
|
|
slogan: true,
|
|
themeColor: true,
|
|
avatar: true,
|
|
portrait: true,
|
|
voteCount: true,
|
|
currentRank: true,
|
|
},
|
|
});
|
|
|
|
type ArtistRanked = (typeof artists)[number] & { rank: number };
|
|
// 计算实时排名(即使 currentRank 字段没及时更新)
|
|
const ranked: ArtistRanked[] = artists.map(
|
|
(a: (typeof artists)[number], i: number) => ({ ...a, rank: i + 1 }),
|
|
);
|
|
|
|
return ok({
|
|
list: ranked,
|
|
top3: ranked.slice(0, 3),
|
|
top12: ranked.slice(0, 12),
|
|
candidates: ranked.slice(12),
|
|
generatedAt: new Date().toISOString(),
|
|
});
|
|
} catch (e) {
|
|
console.error("[GET /api/ranking]", e);
|
|
return ERR.INTERNAL();
|
|
}
|
|
}
|