From 7522a9f809dab611061461c9877c159ddb2f2aa2 Mon Sep 17 00:00:00 2001 From: Mohan Date: Mon, 10 Aug 2026 13:38:50 +0800 Subject: [PATCH] feat(component): add ArticleMetaBar with reading-time estimate and meta icons on article pages --- src/components/ArticleCard.vue | 19 ++++---- src/components/ArticleMetaBar.vue | 74 +++++++++++++++++++++++++++++++ src/utils/readingTime.ts | 12 +++++ src/views/ArticleDetailView.vue | 24 +++++----- 4 files changed, 107 insertions(+), 22 deletions(-) create mode 100644 src/components/ArticleMetaBar.vue create mode 100644 src/utils/readingTime.ts diff --git a/src/components/ArticleCard.vue b/src/components/ArticleCard.vue index b6a1990..46af432 100644 --- a/src/components/ArticleCard.vue +++ b/src/components/ArticleCard.vue @@ -1,16 +1,11 @@ + + + + \ No newline at end of file diff --git a/src/utils/readingTime.ts b/src/utils/readingTime.ts new file mode 100644 index 0000000..35390e0 --- /dev/null +++ b/src/utils/readingTime.ts @@ -0,0 +1,12 @@ +export function estimateReadingTime(content: string = ''): string { + const noWhitespace = content.replace(/\s/g, '').length + const minutes = Math.ceil(noWhitespace / 400) + return `${minutes} 分钟` +} + +export function formatDay(iso: string): string { + const d = new Date(iso) + if (isNaN(d.getTime())) return iso + const pad = (n: number) => String(n).padStart(2, '0') + return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` +} \ No newline at end of file diff --git a/src/views/ArticleDetailView.vue b/src/views/ArticleDetailView.vue index 5c0a1f5..9c2b51d 100644 --- a/src/views/ArticleDetailView.vue +++ b/src/views/ArticleDetailView.vue @@ -6,6 +6,7 @@ import { renderMarkdown } from '@/utils/markdown' import { setPageMeta } from '@/utils/seo' import { useApi } from '@/composables/useApi' import CommentSection from '@/components/CommentSection.vue' +import ArticleMetaBar from '@/components/ArticleMetaBar.vue' import type { ArticleDetail, ResponseArticleDetail } from '@/generated/api' const route = useRoute() @@ -22,13 +23,6 @@ const renderedContent = computed(() => { return renderMarkdown(article.value.content) }) -function formatDate(iso?: string): string { - if (!iso) return '' - const d = new Date(iso) - if (isNaN(d.getTime())) return iso - return d.toLocaleString('zh-CN', { hour12: false }) -} - function applyMeta(data: ArticleDetail) { setPageMeta({ title: data.title, @@ -59,8 +53,12 @@ watch(slug, load, { immediate: true })

{{ article.summary }}

作者:{{ article.authorName }} - 发布于:{{ formatDate(article.publishedAt || article.createdAt) }} - 浏览:{{ article.viewCount }} +
{{ tag }} @@ -79,11 +77,11 @@ watch(slug, load, { immediate: true }) } .detail-title { - font-family: var(--song-font-display); - font-weight: 400; + font-family: 'Noto Serif SC', 'SimSun', 'STSong', serif; + font-weight: 600; letter-spacing: 0.02em; margin: 0 0 12px; - font-size: 26px; + font-size: 28px; } .detail-summary { @@ -108,7 +106,7 @@ watch(slug, load, { immediate: true }) margin-right: 8px; padding: 2px 10px; background: var(--ac-primary-bg); - color: var(--ac-primary-strong); + color: var(--ac-primary-ink); border-radius: var(--song-radius-m); font-size: 12px; }