From 945a9ee610471151c228bf5b269544d65e9e4493 Mon Sep 17 00:00:00 2001 From: wait4xx Date: Sun, 25 Oct 2026 00:11:34 +0800 Subject: [PATCH] =?UTF-8?q?feat(pages):=20=E4=BA=94=E9=A1=B5=E5=9E=8B?= =?UTF-8?q?=E8=90=BD=E5=9C=B0=E2=80=94=E2=80=94=E9=A6=96=E9=A1=B5/?= =?UTF-8?q?=E6=96=87=E7=AB=A0=E5=8F=8C=E6=A8=A1=E6=9D=BF/=E5=9B=BE?= =?UTF-8?q?=E5=BA=93=20masonry/=E7=9E=AC=E9=97=B4/=E5=85=B3=E4=BA=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 首页:名片+身份陈述空槽+按年分组分轨列表(情绪色/mono标签)+影像格+项目墙 - 文章 /archives/{slug}(与 Halo 旧 URL 1:1):reading→衬线纸墨 / tech→ TOC 侧栏(≥1120 sticky)+2px 进度条+Artalk 容器占位 - 图库:grid masonry(构建期 aspect-ratio 零 JS)+原生 dialog lightbox (←→/Esc+EXIF 底栏)+分组筛选 - 瞬间时间线 / 关于(三轨版图+构建说明) - sharp ^0.35.5 入依赖(Astro 7 不内置,astro:assets 缩略图管线前提) - 裸 blockquote 默认吃 A 墨线样式(markdown 原生输出无类名的缝隙) - 车道 30min 超时,产物完整,主会话补 sharp+断言脚本递归修正后收编 验证: pnpm astro build exit 0(7 页);五路由产物断言过; scripts/check-responsive.sh 11/11 ok(1120/820/760/560 全档) Spec: 2026-10-24_add-blog-skeleton Co-authored-by: GLM-5.3 --- .../2026-10-24_add-blog-skeleton/tasks.md | 6 +- package.json | 3 +- pnpm-lock.yaml | 10 +- scripts/check-responsive.sh | 13 +- src/components/Avatar.astro | 42 +++ src/components/IdCard.astro | 27 ++ src/components/PostList.astro | 137 +++++++ src/pages/about.astro | 118 ++++++ src/pages/archives/[...slug].astro | 270 +++++++++++++ src/pages/archives/index.astro | 31 ++ src/pages/gallery/index.astro | 357 ++++++++++++++++++ src/pages/index.astro | 139 ++++++- src/pages/moments/index.astro | 142 +++++++ src/styles/global.css | 4 +- 14 files changed, 1281 insertions(+), 18 deletions(-) create mode 100644 src/components/Avatar.astro create mode 100644 src/components/IdCard.astro create mode 100644 src/components/PostList.astro create mode 100644 src/pages/about.astro create mode 100644 src/pages/archives/[...slug].astro create mode 100644 src/pages/archives/index.astro create mode 100644 src/pages/gallery/index.astro create mode 100644 src/pages/moments/index.astro diff --git a/.spec/specs/2026-10-24_add-blog-skeleton/tasks.md b/.spec/specs/2026-10-24_add-blog-skeleton/tasks.md index 17348ef..f0fd69c 100644 --- a/.spec/specs/2026-10-24_add-blog-skeleton/tasks.md +++ b/.spec/specs/2026-10-24_add-blog-skeleton/tasks.md @@ -35,10 +35,10 @@ - boundary: 只写 src/layouts/BaseLayout.astro 与 src/components/{Header,Footer,ThemeScript}.astro;导航 ≤4 项;页脚 ICP+built-from 槽位;inline 防闪烁脚本 - verify: `pnpm astro build && grep -q "陕ICP备2026014860号" dist/index.html` -- [ ] T6 五页型(首页/文章双模板/图库/瞬间/关于) +- [x] T6 五页型(首页/文章双模板/图库/瞬间/关于) - depends-on: task_0004, task_0005 - - claim: lane-pages(子代理,预留 src/components 与 src/pages 除 index 外路由) - - boundary: 只写页面与页面级组件(名片开场/分轨列表/书评衬线模板+引文组件/技术模板+TOC+进度条/图库 masonry+lightbox/瞬间时间线/关于含身份陈述空槽位);排版参数按报告 §3 + - claim: lane-pages(子代理)→ 超时由主会话收编 + - boundary: 只写页面与页面级组件(名片开场/分轨列表/书评衬线模板+引文组件/技术模板+TOC+进度条/图库 masonry+lightbox/瞬间时间线/关于含身份陈述空槽位);排版参数按报告 §3。豁免注记:sharp ^0.35.5 入 dependencies(supervisor 批复——Astro 7 不内置、照片管线设计依赖 astro:assets 缩略图,T1 骨架缺口) - verify: `pnpm astro build && test -f dist/archives/deng-dai-ge-duo/index.html -a -f dist/gallery/index.html -a -f dist/moments/index.html -a -f dist/about/index.html` - [ ] T7 极客层 P0(键盘+帮助/build-info/View Transitions/项目墙) diff --git a/package.json b/package.json index 9c4efd9..c3c1954 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@fontsource/noto-sans-sc": "^5.3.1", "astro": "^7.3.8", "exifr": "^7.1.3", - "lxgw-wenkai-screen-webfont": "^1.7.0" + "lxgw-wenkai-screen-webfont": "^1.7.0", + "sharp": "^0.35.5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 19b4c18..aa10da9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: lxgw-wenkai-screen-webfont: specifier: ^1.7.0 version: 1.7.0 + sharp: + specifier: ^0.35.5 + version: 0.35.5 packages: @@ -1428,8 +1431,7 @@ snapshots: '@fontsource/noto-sans-sc@5.3.1': {} - '@img/colour@1.1.0': - optional: true + '@img/colour@1.1.0': {} '@img/sharp-darwin-arm64@0.35.5': optionalDependencies: @@ -2181,8 +2183,7 @@ snapshots: sax@1.6.1: {} - semver@7.8.5: - optional: true + semver@7.8.5: {} sharp@0.35.5: dependencies: @@ -2215,7 +2216,6 @@ snapshots: '@img/sharp-win32-arm64': 0.35.5 '@img/sharp-win32-ia32': 0.35.5 '@img/sharp-win32-x64': 0.35.5 - optional: true shiki@4.5.0: dependencies: diff --git a/scripts/check-responsive.sh b/scripts/check-responsive.sh index 12ade6c..dfbde7b 100644 --- a/scripts/check-responsive.sh +++ b/scripts/check-responsive.sh @@ -1,19 +1,20 @@ #!/bin/sh # 响应式结构自查(§4e):四档断点 + 触屏 44px + 安全区 + dvh 的静态断言 # 依据:docs/博客重设计调研报告.md §4e;断点 1120/820/760/560 +# 扫描用 -r 递归(src/pages 有子目录,一层 glob 会漏检 archives/gallery/moments) set -e cd "$(dirname "$0")/.." fail=0 check() { if eval "$2"; then echo " ok $1"; else echo " FAIL $1"; fail=1; fi } -CSS_SRC="src/styles/global.css src/components/*.astro src/layouts/*.astro" +DIRS="src/styles src/components src/layouts src/pages" check "断点 1120px(宽屏 TOC 常驻档)" \ - "grep -rqE 'max-width: ?1120px|min-width: ?1120px|@container' \$CSS_SRC src/pages/*.astro 2>/dev/null" + "grep -rEq '(max|min)-width: ?1120px|@container' $DIRS" check "断点 820px(笔电 TOC 收起档)" \ - "grep -rqE 'max-width: ?820px|min-width: ?820px' \$CSS_SRC src/pages/*.astro 2>/dev/null" + "grep -rEq '(max|min)-width: ?820px' $DIRS" check "断点 760px(平板竖屏档)" \ - "grep -rqE 'max-width: ?760px|min-width: ?760px' \$CSS_SRC src/pages/*.astro 2>/dev/null" + "grep -rEq '(max|min)-width: ?760px' $DIRS" check "断点 560px(手机档 + 正文降 18px)" \ "grep -rq 'max-width: 560px' src/styles/global.css" check "移动端降档:--prose-size 到 18px" \ @@ -24,8 +25,8 @@ check "安全区 env(safe-area-inset-*) 使用" \ "grep -rq 'safe-area-inset' src/styles src/components src/layouts" check "视口 viewport-fit=cover(刘海屏)" \ "grep -q 'viewport-fit=cover' src/layouts/BaseLayout.astro" -check "100dvh 或未使用视口高度陷阱(出现 100vh 即 FAIL)" \ - "! grep -rn '100vh' src/ ; true" +check "无 100vh 视口陷阱(属性值上下文;注释提及不算)" \ + "! grep -rEq ':\\s*100vh|100vh\\s*[;)]' src/ --include='*.astro' --include='*.css' && ! grep -rEq 'height:\\s*100vh|min-height:\\s*100vh' src/" check "动效总闸 prefers-reduced-motion" \ "grep -q 'prefers-reduced-motion: reduce' src/styles/global.css" check "构建产物含 viewport-fit 与主题色 meta" \ diff --git a/src/components/Avatar.astro b/src/components/Avatar.astro new file mode 100644 index 0000000..90b472b --- /dev/null +++ b/src/components/Avatar.astro @@ -0,0 +1,42 @@ +--- +// 名片头像占位:内联 SVG 渐变 60px;真实头像接入后整体替换本组件即可 +--- + + + + + + + + + + + + + w4 + + + + diff --git a/src/components/IdCard.astro b/src/components/IdCard.astro new file mode 100644 index 0000000..5e5b33c --- /dev/null +++ b/src/components/IdCard.astro @@ -0,0 +1,27 @@ +--- +// 名片区(首页/关于共用):渐变头像占位 + 称呼;图标行等内容由使用页经 slot 注入 +import Avatar from './Avatar.astro'; +--- + +
+ +
+

wait4x

+ + +
+
+ + diff --git a/src/components/PostList.astro b/src/components/PostList.astro new file mode 100644 index 0000000..af3f718 --- /dev/null +++ b/src/components/PostList.astro @@ -0,0 +1,137 @@ +--- +// 年份分组 + 轨道分节的文章列表(首页与 /archives/ 共用) +// 轨道标签单一事实源:content.config 的 POST_TRACKS,此处不另立词表 +import type { CollectionEntry } from 'astro:content'; +import { POST_TRACKS, trackOf, type PostCategory } from '../content.config'; + +interface Props { + /** 调用方已完成 draft 过滤与 pubDate 倒序 */ + posts: CollectionEntry<'posts'>[]; +} +const { posts } = Astro.props; + +const byYear = new Map[]>(); +for (const post of posts) { + const year = post.data.pubDate.getUTCFullYear(); + const bucket = byYear.get(year); + if (bucket) bucket.push(post); + else byYear.set(year, [post]); +} +const mmdd = (d: Date) => + `${String(d.getUTCMonth() + 1).padStart(2, '0')}-${String(d.getUTCDate()).padStart(2, '0')}`; +--- + +
+ {[...byYear.entries()].map(([year, list]) => ( +
+

{year}

+ {(Object.keys(POST_TRACKS) as PostCategory[]).map((cat) => { + const rows = list.filter((post) => post.data.category === cat); + if (rows.length === 0) return null; + return ( +