feat: hashtag 列表显示按共现计算的相关 tag

- 新增 /api/hashtag/related:从作品描述实时解析 hashtag,按「同一作品里一起出现」计算相关 tag
- 打分取子话题(候选多与目标同现)与上位话题(目标多与热门候选同现)两者较大值,
  过滤 cos、二次元等万金油 tag 与平台活动、纯数字 tag
- 播放页侧栏的 hashtag 列表顶部显示相关 tag,点击在侧栏内预览(不打断当前播放),
  在预览里点作品才切换到该 tag 的列表

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-09 01:18:04 +08:00
co-authored by Claude Opus 5.5
parent b84fcec77b
commit 2391abdeea
7 changed files with 279 additions and 7 deletions
+28
View File
@@ -0,0 +1,28 @@
import { NextResponse } from "next/server";
import { normalizeHashtag } from "@/lib/hashtag";
import { relatedHashtags } from "@/lib/hashtag-related.server";
import { json } from "@/lib/json";
// 相关 hashtag(按共现计算):GET /api/hashtag/related?name=丰川祥子
export async function GET(req: Request) {
const { searchParams } = new URL(req.url);
const name = normalizeHashtag(searchParams.get("name") || "");
if (!name) {
return NextResponse.json({ error: "Invalid hashtag" }, { status: 400 });
}
const limit = Math.min(
30,
Math.max(1, Math.floor(Number(searchParams.get("limit")) || 12)),
);
try {
return json(await relatedHashtags(name, limit));
} catch (err) {
console.error("Related hashtags error:", err);
return NextResponse.json(
{ error: "Related hashtags failed" },
{ status: 500 },
);
}
}
export const dynamic = "force-dynamic";