From 27f5987b258174a9ed48884b0aab9eed5742e5cd Mon Sep 17 00:00:00 2001 From: sunlei Date: Wed, 1 Jul 2026 12:56:21 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=9D=E7=95=99Blog=E7=A9=BA=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=85=9C=E5=BA=95=E6=96=87=E7=AB=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/__tests__/useBlogArticles.spec.ts | 6 +++--- src/hooks/useBlogArticles.ts | 12 ++++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e80550a..a8a26da 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ pnpm exec playwright test e2e/argon-parity/baseline.spec.ts --project=chromium - `e2e/argon-parity` 保存与线上 `https://blog.kwitsukasa.top/` 对齐的页面、视口和交互矩阵。 - 本地 hash 路由按语义映射 WordPress query 路由:文章、分类、标签、搜索和月份归档都用同一套矩阵验证。 - 页面根节点通过 `kt-blog--home/search/category/tag/archive/post` 暴露 Argon 页面语义,方便样式、测试和 Admin iframe 预览复用。 +- 公开 Blog API 返回非空文章列表时优先使用 API;API 不可用或返回空列表时保留内置 WordPress 抓取文章种子,避免数据未迁移期间线上静态站变成空站。 - 文章正文以线上 WordPress `#post_content` 渲染结果和 Argon `style.css` / `argontheme.js` 为准;代码块控制条、复制 toast、Fancybox 图片预览、正文链接 hover、分隔线和图片 lazyload 都必须有 Playwright 断言。 - `hljs-codeblock` 静态快照需要恢复 Argon `highlightjs-line-numbers` 运行时生成的 `data-line-number` 与 `.hljs-ln-n::before`,否则行号列会坍塌成 0px。 - 左栏 overview sticky/relative 切换用 no-headroom 回归用例固定,解除 fixed 后不得重放卡片入场动画或产生缩放闪烁。 diff --git a/src/__tests__/useBlogArticles.spec.ts b/src/__tests__/useBlogArticles.spec.ts index 0cbfeb4..e953b10 100644 --- a/src/__tests__/useBlogArticles.spec.ts +++ b/src/__tests__/useBlogArticles.spec.ts @@ -123,7 +123,7 @@ describe('useBlogArticles', () => { expect(blogArticles.articles.value).toEqual(fallbackArticles); }); - it('keeps an empty list when blog public list is reachable but has no articles', async () => { + it('falls back to static articles when blog public list is reachable but has no articles', async () => { mockFetch([ { body: { @@ -141,8 +141,8 @@ describe('useBlogArticles', () => { await blogArticles.loadArticles(); - expect(blogArticles.loadedFromApi.value).toBe(true); - expect(blogArticles.articles.value).toEqual([]); + expect(blogArticles.loadedFromApi.value).toBe(false); + expect(blogArticles.articles.value).toEqual(fallbackArticles); }); it('fetches public article detail when cached list data does not include html content', async () => { diff --git a/src/hooks/useBlogArticles.ts b/src/hooks/useBlogArticles.ts index 0245f70..20f63db 100644 --- a/src/hooks/useBlogArticles.ts +++ b/src/hooks/useBlogArticles.ts @@ -121,6 +121,13 @@ export function useBlogArticles() { }; } +/** + * Loads the public WordPress article list and keeps the static capture when the API has no usable rows. + * + * The production Blog API can be reachable before WordPress article data is migrated. An empty successful + * response is therefore treated as an unavailable content source so the Argon mirror keeps rendering the + * captured WordPress article set instead of turning every route into an empty state. + */ async function loadArticles() { if (loadedFromApi.value) return; if (loadPromise) return loadPromise; @@ -129,6 +136,11 @@ async function loadArticles() { loadPromise = fetchBlogArticleList() .then((result) => { const nextArticles = result.list.map(normalizeWordpressArticle); + if (!nextArticles.length) { + blogArticles.value = fallbackArticles; + loadedFromApi.value = false; + return; + } blogArticles.value = nextArticles; loadedFromApi.value = true; })