feat(about): 用户选定方案 A——关于页改「白纸直编」单字段(5k T1/T2 落地)
用户在 /about-preview/ 五案中选 A。落地:
- siteAbout schema 增 `doc`(双语整页 markdown);about.yaml 现有内容已合成
doc(身份语 + 关于我 + 找到我 + 本站如何构建,双语齐备)
- AboutPage 四级回落:**doc 白纸直编 → blocks 块式 → intro → 内置默认**
(doc 非空时整页只渲染它,IdCard 仍在顶部;blocks 降为 legacy 通道)
- 后台「关于页」最顶部即「整页正文」markdown 字段(这就是方案 A 的编辑模型),
块式结构标注 legacy
- 删除两个已完成的预览路由(/about-preview/、/heatmap-preview/)与 HeatGrid
预览组件、content-lint 白名单整体移除
- docs/管理台 新增「关于页正文」一节(四级回落说明)
验证: 构建 50 页 exit 0;content-lint 51 页 0/0/0;config-check 234 字段/74 hint;
产物断言 doc 渲染(汇文+红身份语 / 找到我链接 / mono 小标题);
E2E 56/56(含书架开合翻转与 5j 数据板口径更新)
Spec: 2026-11-04_blog-5k-about-designs (T1/T2)
Co-authored-by: GLM-5.3
This commit is contained in:
1 parent
b41b4ba8a5
commit
4153c6d33f
11 files changed
+108
-793
No files matched your search
@@ -1,58 +0,0 @@
|
||||
---
|
||||
/**
|
||||
* 热力图网格(可复用渲染件):给 5 个动效方案预览共用,避免把 371 个格子抄五遍。
|
||||
*
|
||||
* 每格带 `data-c/--c`(列=周)与 `data-r/--r`(行=星期),动效方案靠这两个自定义属性
|
||||
* 算错峰延迟;`data-l` 是灰阶档(0–4,复用 tokens 的 --ink-1..4)。
|
||||
* 全部格子 aria-hidden:语义由外层 role="img" + aria-label 概括(371 个 aria 节点是噪音)。
|
||||
*/
|
||||
import { levelOf, type HeatDay } from '../../lib/heatmap';
|
||||
|
||||
interface Props {
|
||||
weeks: HeatDay[][];
|
||||
/** 网格类型,仅用于选择器命名(不动行为) */
|
||||
variant: string;
|
||||
/** 单元格错峰延迟基数(ms),0 = 不设延迟 */
|
||||
step?: number;
|
||||
}
|
||||
|
||||
const { weeks, variant, step = 0 } = Astro.props;
|
||||
---
|
||||
|
||||
<div class={`hg hg-${variant}`} data-hg={variant}>
|
||||
{weeks.map((week, ci) =>
|
||||
week.map((day, ri) => (
|
||||
<span
|
||||
class={`hg-c hg-l${levelOf(day.count)}`}
|
||||
data-c={ci}
|
||||
data-r={ri}
|
||||
data-count={day.count}
|
||||
data-date={day.date}
|
||||
style={step ? `--c:${ci};--r:${ri};--d:${(ci + ri) * step}ms` : `--c:${ci};--r:${ri}`}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
)),
|
||||
)}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.hg {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-template-rows: repeat(7, 10px);
|
||||
grid-auto-columns: 10px;
|
||||
gap: 3px;
|
||||
}
|
||||
.hg-c {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
/* 与线上热力图同口径:空格用 hairline 描边、四档用 ink 灰阶(亮暗自动跟随),
|
||||
accent 只留给各方案的"高亮"(glow / flow / 连续数字),不参与数据编码 */
|
||||
}
|
||||
.hg-l0 { border: 1px solid var(--line); }
|
||||
.hg-l1 { background: var(--ink-4); }
|
||||
.hg-l2 { background: var(--ink-3); }
|
||||
.hg-l3 { background: var(--ink-2); }
|
||||
.hg-l4 { background: var(--ink-1); }
|
||||
</style>
|
||||
@@ -5,6 +5,8 @@ import { t } from '../../i18n/ui';
|
||||
import type { Locale } from '../../lib/locale';
|
||||
import { aboutIntroMarkdown, pageTypography, renderMarkdown } from '../../lib/site-content';
|
||||
import { getAboutPage } from '../../lib/page-blocks';
|
||||
import { getCollection } from 'astro:content';
|
||||
import { pickBi } from '../../lib/site-content';
|
||||
import BlockRenderer from '../blocks/BlockRenderer.astro';
|
||||
|
||||
// /en/ 侧由 T4 薄页传 locale='en';zh 路由无人传参,默认 zh 零回归
|
||||
@@ -12,10 +14,14 @@ interface Props {
|
||||
locale?: Locale;
|
||||
}
|
||||
const { locale = 'zh' } = Astro.props;
|
||||
// 三级回落(零回归):blocks 驱动 → intro markdown → 内置默认文案
|
||||
// 四级回落(Phase 5k 方案 A):doc 白纸直编 → blocks 块式 → intro markdown → 内置默认
|
||||
// doc 非空时整页就是这一段 markdown(用户拍板的编辑模型:想写什么写什么)
|
||||
const entry = (await getCollection('siteAbout'))[0];
|
||||
const { blocks, showIdCard } = await getAboutPage(locale);
|
||||
const docMd = pickBi(entry?.data.doc, { zh: '', en: '' }, locale);
|
||||
const docHtml = docMd.trim() ? await renderMarkdown(docMd) : '';
|
||||
const introHtml =
|
||||
blocks.length === 0 ? await renderMarkdown(await aboutIntroMarkdown(locale)) : '';
|
||||
!docHtml && blocks.length === 0 ? await renderMarkdown(await aboutIntroMarkdown(locale)) : '';
|
||||
const typo = await pageTypography('siteAbout', 'about');
|
||||
---
|
||||
|
||||
@@ -23,7 +29,12 @@ const typo = await pageTypography('siteAbout', 'about');
|
||||
<h1 class="page-title">{t('about_title', locale)}</h1>
|
||||
|
||||
<div class={typo.className || undefined} style={typo.style || undefined}>
|
||||
{blocks.length > 0 ? (
|
||||
{docHtml ? (
|
||||
<>
|
||||
{showIdCard && <IdCard />}
|
||||
<article class="about-doc rich" set:html={docHtml} />
|
||||
</>
|
||||
) : blocks.length > 0 ? (
|
||||
<>
|
||||
{blocks.map((block) => <BlockRenderer block={block} />)}
|
||||
{showIdCard && <IdCard />}
|
||||
@@ -157,4 +168,14 @@ const typo = await pageTypography('siteAbout', 'about');
|
||||
color: var(--ink-2);
|
||||
max-width: var(--measure);
|
||||
}
|
||||
/* 方案 A 白纸直编:单栏、行距放宽,交给全局 .rich 排版体系 */
|
||||
.about-doc { max-width: var(--measure); }
|
||||
.about-doc :global(h2) {
|
||||
font-size: 15px;
|
||||
font-family: var(--font-mono);
|
||||
color: var(--ink-3);
|
||||
letter-spacing: 0.06em;
|
||||
margin: var(--space-6) 0 var(--space-3);
|
||||
}
|
||||
.about-doc :global(p) { line-height: 1.85; }
|
||||
</style>
|
||||
Reference in new issue
Block a user