Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
10 KiB
TASK · 报告页打磨(生成入口、到底部、导出、目录、表格、字段文案)· 2026-09-29
执行方:coding agent。验收:Claude。 分支
codex/report-reader-polish-20260929,worktree.worktrees/report-reader-polish-20260929,基于origin/staging。 串行关系:本单先做、先合入 staging。TASK-report-english-edition-20260929.md改同一批文件(report-actions.tsx、report-export-drawer.tsx、pl9_reader_export.py),必须基于本单合入后的 staging 开工。
0. 基线
- 基线 commit:
origin/staging=5febb111(开工时以实测为准,写进进度记录)。 - 进度记录:
docs/tasks/PROGRESS-report-reader-polish-20260929.md。
1. 事故实证(产品截图 2026-09-29,行号按符号定位)
| # | 现象 | 代码位置 |
|---|---|---|
| P1 | /reports 的「生成报告」是标题栏右上角的小描边按钮,空状态里又写「点击'生成完整报告'」,按钮名和文案对不上 |
personal-report-center.tsx → PersonalReportCenter 中的 <SecondaryPageShell actions={<GeneratePersonalReportButton …/>}> 与 .report-center-empty 段;generate-personal-report-button.tsx → GeneratePersonalReportButton(variant="outline" size="sm") |
| P2 | 报告详情页没有「到底部」的入口;正文按章节懒渲染,未渲染的章节只占一个 h2 高度,直接 scrollTo(bottom) 会停在半路 |
personal-report-markdown-view.tsx → LazyMarkdownSection(IntersectionObserver,rootMargin: "280px 0px") |
| P3 | 导出入口是 ghost 样式、只有图标的按钮,很难发现 | report-actions.tsx → ReportActions(size="icon" variant="ghost" aria-label="导出报告") |
| P4 | 目录里一级标题(如「强度、关系与 Ashtakavarga 技术页」)和二级标题字号、颜色完全相同,二级只缩进 --space-3。一级标题没被选中时,看上去像上一组的子项 |
globals.css → .personal-report-toc a、.personal-report-toc li[data-level="3"] |
| P5 | 标题里出现用户看不懂的「字段」:「Birth Chart 星主与状态字段」「Birth Particulars 原版补充字段」「Special Lagnas and Points 原版补充字段」,以及替换表里的 field_状态 → 字段状态 |
scripts/pl9_reader_export.py:'#### p6 Birth Chart 星主与状态字段'、'#### p3 Birth Particulars 原版补充字段'、'#### p17 Special Lagnas and Points 原版补充字段';_strip_pl9_user_engineering_markers 末尾的 text.replace("field_状态", "字段状态") |
| P6 | 同一张表的「状态」列出现重复:「入旺(入旺)」「落陷(落陷)」「入敌(敌对星座)」。表头 RL / NL / SL / SS / SB、Planet 用户看不懂 |
同上表的行渲染(row.get('status'))经 _strip_pl9_user_engineering_markers 的 glossary_terms 逐词替换后,括号内外被翻成同一个词。上游 status 字符串的原始形状由执行方先打印确认再修,不得猜 |
| P7 | 报告内表格没有任何底色,只有很淡的横线,行与行分不清 | globals.css → .markdown-table th/td(仅 border-bottom);报告页包在 .personal-report-table-wrap 里 |
| P8 | 分块导出弹窗只显示字数,不显示文件大小;图盘块里带着整段 SVG,字数和文件大小差得很远 | report-export-drawer.tsx → ReportExportDrawer 的 .report-export-count;report-export-blocks.ts → buildReportExportBlocks(chars = Array.from(text).length,图盘块 text 含 SVG) |
2. 根因
都是呈现层的遗漏,不涉及计算:入口放在了标题栏的次要位置;懒渲染没有配套「到底部」;导出做成了只有图标的次要按钮;目录层级只靠 12px 缩进区分;引擎侧的工程词(field、字段)和英文缩写表头直接透给了用户;中文化是逐词替换,没有处理「译文(原文)」译完后两边相同的情况;表格样式沿用了聊天气泡里的极简样式。
3. 决策记录(产品 2026-09-29 授权)
-
生成入口挪进页面主体,按产品图一的布局:页面上半部分是一块「生成报告」卡片,按钮居中,说明文字放在按钮下方;下半部分是「过往的报告」列表。标题栏右上角的「生成报告」按钮删除,不保留两个入口(产品偏好:多余入口宁可删除)。卡片在有报告、没报告时都显示;没报告时,下半部分显示一句轻提示,不再重复一个大空状态。
-
报告详情页加「到底部」悬浮按钮,位置在右下角。点击时先让所有
LazyMarkdownSection立即渲染,在同一次点击内滚到文末。不得出现先停在半路、要再点一次的情况。滚到接近底部时按钮隐藏;可以同时提供「回到顶部」,但一次只显示一个按钮。 -
导出按钮改成带文字的「导出」按钮(带图标、描边或实心,按
DESIGN.md的次级主操作规格),留在操作栏右侧。英文版导出提示不在本单做,由英文版任务书负责。 -
目录:一级标题加粗、用
--color-ink,组与组之间留间距;二级标题缩进加大到约--space-5、用--color-ink-secondary。当前项高亮样式不变。 -
「字段」一词从用户可见标题里全部去掉,用下面的新标题(中文口径对照
VOICE.md):原标题 新标题 p6 Birth Chart 星主与状态字段 行星主星与状态 p3 Birth Particulars 原版补充字段 出生资料补充 p17 Special Lagnas and Points 原版补充字段 特殊上升与派生点补充 field_状态 → 字段状态改为「状态」 -
「行星主星与状态」一表的表头改成中文:
Planet → 行星、RL → 星座主、NL → 星宿主、SL → 分主、SS → 分分主、SB → 力量。表下加一行小字说明这几个名称的含义,不超过一句。状态列同义重复时只保留一个(「入旺(入旺)」→「入旺」);括号内是不同信息的保留(如「入敌(敌对星座)」要先确认上游原文再决定)。 -
表格加淡底色,只作用于报告阅读页和打印,聊天气泡里的
.markdown-table不动:表头一层淡底,正文隔行一层更淡的底(斑马纹),颜色取现有 token 的color-mix,不新增硬编码色值;深色模式同样适用。打印时底色保留,但要更浅,保证黑白打印可读。 -
分块导出弹窗显示预估文件大小:取真实要下载的字节数,即
new TextEncoder().encode(joinExportBlocks(selected)).length,按 KB / MB 取整显示,例如「约 186 KB」。不按字数估算。全篇大小和已选大小都显示。
4. 硬红线
- 不改报告的计算与数值;Python 改动只限 §3-5、§3-6 的标题、表头和状态去重。
report-reader-main-fictional.jsongolden 除这几处文案外,逐字节不变(执行方用 diff 证明)。 - 不新增第二套滚动跟随;「到底部」是报告页自己的按钮,不接入
useConversationScrollAnchor。揭幕后不得出现 spinner 或骨架。 - 不动数据库、不动迁移、不动
.gitea/。 - 改 UI 的同一提交内更新
frontend/DESIGN.md(报告中心、报告阅读页、表格三处);新文案对照frontend/docs/VOICE.md。 - AGENTS §7-8:动类名、文案、组件之前先
git grep -n "<符号>" -- tests/ frontend/。至少要查:GeneratePersonalReportButton、report-center-empty、还没有个人报告、生成完整报告、导出报告、report-export-count、personal-report-toc、星主与状态、原版补充字段、字段状态、markdown-table。被牵连的断言按「原值 / 新值 / 原因」三栏写进进度记录。
5. 任务分解
| 编号 | 内容 | 验收标准 |
|---|---|---|
| R1 | 报告中心改版(§3-1) | 标题栏不再有生成按钮;主体上方是生成卡片,下方是「过往的报告」;无报告、有报告、生成中三种状态的截图或组件测试各一份;原按钮的防重复点击、错误提示逻辑不变(classifyCreateResponse 测试照过) |
| R2 | 到底部按钮(§3-2) | 组件测试:未渲染章节存在时点击,所有章节变成已渲染,且触发一次滚到底部;接近底部时按钮不显示 |
| R3 | 导出按钮(§3-3) | 按钮有可见文字「导出」;键盘可达;打印时隐藏(沿用 personal-report-screen-only) |
| R4 | 目录层级(§3-4) | 一级、二级样式可区分;DESIGN.md 写明规格 |
| R5 | 字段文案与表头(§3-5、§3-6) | Python 定向测试断言新标题和新表头;golden 中不再出现「字段」二字,也没有 X(X) 形式的同义重复 |
| R6 | 表格底色(§3-7) | 仅报告页生效;聊天页表格的计算样式不变(写一条选择器作用域断言或截图对比) |
| R7 | 导出大小(§3-8) | 单测:选中块的显示大小等于 TextEncoder 字节数的格式化结果;含 SVG 的图盘块大小明显大于字数 |
6. 让步顺序
时间不够时按这个顺序往后砍:R6 → R4 → R2。R1、R3、R5、R7 必须交付。
7. 开工前置命令
git fetch origin --prune
git worktree add -b codex/report-reader-polish-20260929 .worktrees/report-reader-polish-20260929 origin/staging
cd .worktrees/report-reader-polish-20260929
grep -oE "BUG-[0-9]{4}" docs/BUG_HISTORY.md | sort -u | tail -1 # 核对最大号
cd frontend && npm test 2>&1 | grep -E "^(not )?ok [0-9]+ - " | sed -E 's/^(not )?ok [0-9]+ - //' | sort > /tmp/names-before.txt
8. BUG 编号
开工时 BUG_HISTORY.md 最大号为 BUG-1089,BUG-1090/1091 已被 holdout 任务书预留。本单从 BUG-1092 起,预计用到 BUG-1094:P5 + P6 各记一条,P1~P4、P7、P8 合记一条「报告页可用性」。开工时如果号已被占用,顺延,并在进度记录写明。
9. 交付
- 推 staging 前:
tsc --noEmit0 错;npm run lint0 error;npm test测试名单与开工时对比,只增不减;npm run build后/仍是 Static;首屏 gzip 在 ±2% 内;.venv/bin/python -m pytest tests/<相关文件>通过;run_quality_gate.py --profile quick通过。 - 真机清单写进
docs/testing/report-reader-polish-20260929.md(桌面端、手机端各走一遍 R1~R3、R6)。 CHANGELOG.md记一条。