优化图文页

This commit is contained in:
2026-04-28 17:11:42 +08:00
parent 674c202264
commit 040273586b
69 changed files with 3939 additions and 2302 deletions
+43 -22
View File
@@ -5,7 +5,7 @@ import { NextRequest, NextResponse } from "next/server";
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ awemeId: string }> }
{ params }: { params: Promise<{ awemeId: string }> },
) {
const awemeId = (await params).awemeId;
const searchParams = request.nextUrl.searchParams;
@@ -13,7 +13,8 @@ export async function GET(
const take = parseInt(searchParams.get("take") || "20", 10);
// ranked 模式参数(均为可选,提供合理默认值)
const seed = searchParams.get("seed") || new Date().toISOString().slice(0, 10); // 默认按日期稳定
const seed =
searchParams.get("seed") || new Date().toISOString().slice(0, 10); // 默认按日期稳定
const snapshotIso = searchParams.get("snapshot");
const snapshot = snapshotIso ? new Date(snapshotIso) : new Date(); // 用于时间衰减的基准时间,确保单次会话稳定
const halfLifeHours = parseFloat(searchParams.get("halfLifeHours") || "24");
@@ -21,8 +22,6 @@ export async function GET(
const wTime = parseFloat(searchParams.get("wTime") || "2"); // 时间衰减权重
const wJit = parseFloat(searchParams.get("wJit") || "10"); // 随机扰动权重(稳定随机)
try {
// 查找是视频还是图文
const [video, post] = await Promise.all([
@@ -41,9 +40,7 @@ export async function GET(
}
// 构建查询条件
const where = video
? { videoId: awemeId }
: { imagePostId: awemeId };
const where = video ? { videoId: awemeId } : { imagePostId: awemeId };
// 按「热度 + 时间衰减 + 稳定随机扰动」打分排序;否则使用稳定的时间排序
const total = await prisma.comment.count({ where });
@@ -68,7 +65,9 @@ export async function GET(
${wJit} * ${jitterExpr}
)`;
const whereField = (await video) ? Prisma.sql`c."videoId"` : Prisma.sql`c."imagePostId"`;
const whereField = (await video)
? Prisma.sql`c."videoId"`
: Prisma.sql`c."imagePostId"`;
const rows: Array<{
cid: string;
@@ -92,22 +91,41 @@ export async function GET(
ORDER BY ${scoreExpr} DESC, c."created_at" DESC, c."cid" ASC
OFFSET ${skip}
LIMIT ${take}
`
`,
);
// 批量查询每条评论的配图/贴纸
const cids = rows.map(r => r.cid);
const cids = rows.map((r) => r.cid);
const images = cids.length
? await prisma.commentImage.findMany({
where: { commentId: { in: cids } },
orderBy: { order: 'asc' },
select: { commentId: true, url: true, width: true, height: true, order: true },
})
where: { commentId: { in: cids } },
orderBy: { order: "asc" },
select: {
commentId: true,
url: true,
width: true,
height: true,
order: true,
},
})
: [];
const group = new Map<string, { url: string; width?: number | null; height?: number | null; order: number }[]>();
const group = new Map<
string,
{
url: string;
width?: number | null;
height?: number | null;
order: number;
}[]
>();
for (const img of images) {
const arr = group.get(img.commentId) || [];
arr.push({ url: img.url, width: img.width, height: img.height, order: img.order });
arr.push({
url: img.url,
width: img.width,
height: img.height,
order: img.order,
});
group.set(img.commentId, arr);
}
const formattedComments = rows.map((c) => ({
@@ -117,9 +135,15 @@ export async function GET(
digg_count: Number(c.digg_count),
user: {
nickname: c.nickname,
avatar_url: getFileUrl(c.avatar_url || 'default_avatar.png'),
avatar_url: getFileUrl(c.avatar_url || "default_avatar.png"),
},
images: (group.get(c.cid) || []).sort((a, b) => a.order - b.order).map(i => ({ url: getFileUrl(i.url), width: i.width ?? undefined, height: i.height ?? undefined })),
images: (group.get(c.cid) || [])
.sort((a, b) => a.order - b.order)
.map((i) => ({
url: getFileUrl(i.url),
width: i.width ?? undefined,
height: i.height ?? undefined,
})),
}));
return NextResponse.json({
@@ -134,9 +158,6 @@ export async function GET(
});
} catch (error) {
console.error("获取评论失败:", error);
return NextResponse.json(
{ error: "获取评论失败" },
{ status: 500 }
);
return NextResponse.json({ error: "获取评论失败" }, { status: 500 });
}
}