import type { Metadata } from "next"; import type { CSSProperties } from "react"; import Link from "next/link"; import { BookOpen, FileDown } from "lucide-react"; import { fetchLibraryList, type LibraryDocListItem } from "@/lib/api"; import { coverHue } from "@/lib/coverColor"; import { getPublicSettingsCached } from "@/lib/serverData"; import { requestCanonical } from "@/lib/canonicalMeta"; import { libraryPath, libraryDocPath } from "@/lib/urlStyle"; function formatSize(n: number): string { if (!Number.isFinite(n) || n <= 0) return "0 B"; if (n < 1024) return `${n} B`; if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`; return `${(n / (1024 * 1024)).toFixed(1)} MB`; } /** 文字封面:无图时用完整书名 + 书名派生稳定色相洗底(lib/coverColor.ts) */ function TextCover({ title }: { title: string }) { const name = title.trim() || "书"; return (
{name}
); } function ExtChip({ ext }: { ext: string }) { return ( {ext} ); } function DocCard({ doc, href, }: { doc: LibraryDocListItem; href: string; }) { const exts = Array.from(new Set(doc.files.map((f) => f.ext))).slice(0, 4); const totalSize = doc.files.reduce((acc, f) => acc + f.size, 0); return (
{doc.cover_url ? ( // eslint-disable-next-line @next/next/no-img-element {doc.title} ) : ( )}

{doc.title}

{exts.map((ext) => ( ))} {doc.file_count > 0 ? `${doc.file_count} 个文件 · ${formatSize(totalSize)}` : "暂无文件"}
); } export async function generateMetadata(): Promise { const settings = await getPublicSettingsCached(); return { title: "书库", description: settings.site_description, ...(await requestCanonical(libraryPath(settings.url_style))), }; } export default async function LibraryPage() { const settings = await getPublicSettingsCached(); const urlStyle = settings.url_style; // 接口失败降级为空态,不让页面 500 let docs: LibraryDocListItem[] = []; try { const res = await fetchLibraryList(); docs = res.docs ?? []; } catch { /* 降级空态 */ } return (
{/* Hero:渐变洗底(与排行榜同语言) */}

书库

书籍、文档与页面作品,在线阅读或下载

{docs.length === 0 ? (

书库还没有内容

管理员可在后台「书库管理」发布条目

) : (
{docs.map((d) => ( ))}
)}
); }