From 11f2131e4b2a965e94984957edd02f3f57394124 Mon Sep 17 00:00:00 2001
From: freefire
Date: Fri, 2 Oct 2026 01:47:14 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E4=B9=A6=E5=BA=93=E9=98=85=E8=AF=BB?=
=?UTF-8?q?=E9=A1=B5/=E5=B8=96=E5=AD=90=E8=AF=A6=E6=83=85=E9=A1=B5/SiteDoc?=
=?UTF-8?q?Masthead/TOC=20=E7=AD=89=E5=89=8D=E7=AB=AF=E7=BB=86=E8=8A=82?=
=?UTF-8?q?=E4=BF=AE=E5=A4=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
frontend/app/library/[slug]/read/page.tsx | 6 +++---
frontend/app/post/[id]/page.tsx | 8 ++++----
frontend/components/site-doc/SiteDocMasthead.tsx | 5 +++--
frontend/lib/toc.ts | 8 ++++++++
4 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/frontend/app/library/[slug]/read/page.tsx b/frontend/app/library/[slug]/read/page.tsx
index f5c266e..13554be 100644
--- a/frontend/app/library/[slug]/read/page.tsx
+++ b/frontend/app/library/[slug]/read/page.tsx
@@ -16,7 +16,7 @@ import {
groupSections,
type ChapterNav,
} from "@/lib/librarySections";
-import { extractToc, estimateReadingMinutes, markdownHeadingToc, buildTocFromSegments } from "@/lib/toc";
+import { extractToc, estimateReadingMinutes, formatReadingDuration, markdownHeadingToc, buildTocFromSegments } from "@/lib/toc";
import { splitContentSegments } from "@/lib/directiveBlocks";
import { wrapImplicitEntries } from "@/lib/entryBlocks";
import PostToc, { type TocItem } from "@/components/PostToc";
@@ -223,7 +223,7 @@ export default async function LibraryReadPage({ params, searchParams }: PageProp
{current.title}
- 第 {nav.index + 1} / {nav.total} 章 · 约 {chapterMinutes} 分钟
+ 第 {nav.index + 1} / {nav.total} 章 · 约 {formatReadingDuration(chapterMinutes)} 读完
>
}
@@ -265,7 +265,7 @@ export default async function LibraryReadPage({ params, searchParams }: PageProp
- 第 {nav.index + 1} / {nav.total} 章 · 约 {chapterMinutes} 分钟
+ 第 {nav.index + 1} / {nav.total} 章 · 约 {formatReadingDuration(chapterMinutes)} 读完
{post.title}
- 约 {readingMinutes} 分钟读完
+ 约 {formatReadingDuration(readingMinutes)} 读完
>
}
left={leftRailNode ? { label: "导航", content: leftRailNode } : undefined}
@@ -599,8 +599,8 @@ export default async function PostDetailPage({ params, searchParams }: PageProps
{post.comment_count} 评论
) : null}
-
- 约 {readingMinutes} 分钟读完
+
+ 约 {formatReadingDuration(readingMinutes)} 读完
diff --git a/frontend/components/site-doc/SiteDocMasthead.tsx b/frontend/components/site-doc/SiteDocMasthead.tsx
index 17fc342..f8ad77e 100644
--- a/frontend/components/site-doc/SiteDocMasthead.tsx
+++ b/frontend/components/site-doc/SiteDocMasthead.tsx
@@ -1,6 +1,7 @@
import type { ReactNode } from "react";
import { Clock } from "lucide-react";
import { formatDate } from "@/lib/format";
+import { formatReadingDuration } from "@/lib/toc";
function formatDateTime(dateStr: string) {
return new Date(dateStr).toLocaleString("zh-CN", {
@@ -83,9 +84,9 @@ export default function SiteDocMasthead({
{readingMinutes != null ? (
- 约 {readingMinutes} 分钟读完
+ 约 {formatReadingDuration(readingMinutes)} 读完
) : null}
diff --git a/frontend/lib/toc.ts b/frontend/lib/toc.ts
index c946d90..a1b507c 100644
--- a/frontend/lib/toc.ts
+++ b/frontend/lib/toc.ts
@@ -167,3 +167,11 @@ export function estimateReadingMinutes(text: string, fallbackLen = 0): number {
const len = text.trim().length > 0 ? text.trim().length : fallbackLen;
return Math.max(1, Math.ceil(len / 400));
}
+
+/** 阅读时长展示:≥60 分钟换算成「X 小时 Y 分钟」,避免大分钟数需口算 */
+export function formatReadingDuration(minutes: number): string {
+ if (minutes < 60) return `${minutes} 分钟`;
+ const h = Math.floor(minutes / 60);
+ const m = minutes % 60;
+ return m > 0 ? `${h} 小时 ${m} 分钟` : `${h} 小时`;
+}