fix(report): group chart cards in the existing grid and stop remounting on scroll (BUG-616, BUG-617)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+33
-1
@@ -9426,7 +9426,7 @@
|
||||
- 修复:引擎在每张 SVG 旁追加 `jyotish-chart` 围栏 JSON;阅读页只认围栏,zod 校验后用北印式菱形组件自绘。导出 `.md` 前剥掉围栏,保留 SVG 给外部阅读器。
|
||||
- 验证:`tests/test_report_chart_block.py` 7 项(22 块围栏 == 22 个 `<svg>`,度数/星座/逆行与 core_chart 一致,且该文件在 `CORE_PYTEST_TARGETS`);`frontend/tests/report-chart-block.test.ts`、`frontend/tests/personal-report-markdown-view.test.tsx`(组件 SVG 有 `role="img"`,不含引擎 `viewBox="0 0 420 480"`,坏块显示「图盘数据无效」且无 `<script`)。全量 `npm test` 2975 tests / 2971 pass / 4 fail,失败 4 条均为 Docker Postgres fixture,与图盘无关。`tsc --noEmit` 0 错;`next build --webpack` 后 `/` 仍为 Static。
|
||||
- 防复发:Markdown 阅读页继续 `skipHtml` / 禁止 `rehype-raw`;图盘文本只来自白名单映射。上述测试锁住围栏块数与渲染通路。
|
||||
- 相关记录:`TASK-report-md-page-20260906.md`、`TASK-report-chart-render-20260909.md`
|
||||
- 相关记录:`TASK-report-md-page-20260906.md`、`TASK-report-chart-render-20260909.md`、BUG-616、BUG-617
|
||||
- 复发自:无(09-06 直渲回归,不是旧 BUG 编号复发)
|
||||
- 修复版本:待发布
|
||||
|
||||
@@ -9525,3 +9525,35 @@
|
||||
- 相关记录:BUG-612(同一次事故的空回答)、`TASK-consultation-daily-empty-answer-20260909.md`
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
|
||||
## BUG-616 | 报告页 22 张北印盘叠在同一位置
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-09
|
||||
- 最近更新:2026-09-09
|
||||
- 影响面:`/personal-report` Markdown 阅读页、`personal-report-markdown-view.tsx`、`globals.css`、`report-chart-grid-rehype.ts`
|
||||
- 用户现象:「Birth Chart / Vargas」里 D1 / D9 / Moon 三张盘叠在同一块;Vargas I 的 19 个 `####` 标题挤在左上角,19 张盘全部叠在一起,「Shodashvarga 星座总表」和后面的表也压在盘上。
|
||||
- 触发条件:打开含 `jyotish-chart` 围栏的个人长报告详情页,宽于 720px 的桌面视口。
|
||||
- 根因:BUG-607 用浮动 + `margin-left: -50%` 在扁平 Markdown 兄弟节点上凑两栏。负 margin 让每个 figure 的 margin box 宽度为 0,浮动算法认为它不占横向空间,连续多对标题+盘必然重叠。`renderToStaticMarkup` 只看 DOM,看不见布局,所以当时的 golden 全绿。
|
||||
- 修复:删掉 `.personal-report-chart-*` 上的 float / 负 margin。rehype 插件把「`h4`(D… / Moon Chart)+ 可选一段说明 + `pre > code.language-jyotish-chart`」包进 `.personal-report-chart-card`,相邻卡片再包进既有的 `.personal-report-chart-grid`(单张加 `is-single`)。不放开 `skipHtml`,不引入 `rehype-raw`。
|
||||
- 验证:`frontend/tests/personal-report-markdown-view.test.tsx`:3 对连续标题+围栏(第 3 对夹一段 `p`)得到 1 个 grid / 3 张卡,卡内顺序为 `h4` →(`p`)→ `figure`,后面的普通 `h4` 不在卡内;单对带 `is-single`;golden 22 张 `figure` 全在卡内;`globals.css` 中同时含 `personal-report-chart` 与 `float:` / `margin-left: -50%` 的规则为 0。
|
||||
- 防复发:布局合同走 DOM 结构(grid/card 包裹)和 CSS 禁令,不只看「有没有 `<svg>`」。
|
||||
- 相关记录:BUG-607、`TASK-report-chart-layout-fix-20260909.md`
|
||||
- 复发自:无(BUG-607 的两栏浮动方案回归,不是「标题下没图」复发)
|
||||
- 修复版本:待发布
|
||||
|
||||
## BUG-617 | 滚动报告时整篇 Markdown 卸载重建,页面卡顿
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-09
|
||||
- 最近更新:2026-09-09
|
||||
- 影响面:`personal-report-markdown-view.tsx` 目录高亮与文章树
|
||||
- 用户现象:长报告页(尤其 Vargas I 19 张盘揭开后)一滚动就明显卡,像整页在闪。
|
||||
- 触发条件:打开含星盘围栏的长报告,滚动使目录高亮从一个 `h2`/`h3` 切到下一个。
|
||||
- 根因:`activeId` 放在 `PersonalReportMarkdownView` 顶层,IntersectionObserver 每次切换都 `setActiveId`。`markdownComponents()` 每渲染新建一套 `h2`/`h3`/`h4`/`pre` 函数;React 按元素 type 引用比较,type 变了就卸载重建整棵子树。09-06 Markdown 直渲时已是这个结构,当时没有 SVG,代价没被感知;22 张盘进来后每次滚过一个标题就销毁再创建全部多边形和 `<text>`。
|
||||
- 修复:目录高亮下沉到 `ReportToc`;`PersonalReportMarkdownView` 不再持有滚动态。lead 与 `LazyMarkdownSection` 的 `renderMarkdown` 结果整树 `useMemo`,`LazyMarkdownSection` 本身 `memo()`。
|
||||
- 验证:源码合同:`renderMarkdown(` 只在 `useMemo` 内调用;`PersonalReportMarkdownView` 函数体没有 `useState`。本仓测试是 `renderToStaticMarkup`,数不了重渲染次数;真机条目写在 `docs/testing/report-chart-render-20260909.md` 第 7 节。
|
||||
- 防复发:文章树不得订阅目录高亮 state。`components` 映射可以每次 `renderMarkdown` 新建(id 去重 cursor 需要),但调用点必须被 `useMemo` 包住。
|
||||
- 相关记录:BUG-616、`TASK-report-md-page-20260906.md`、`TASK-report-chart-layout-fix-20260909.md`
|
||||
- 复发自:无(09-06 直渲结构在星盘进入后才变成可感知卡顿)
|
||||
- 修复版本:待发布
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
# PROGRESS · 报告页星盘重叠 + 滚动重建(2026-09-09)
|
||||
|
||||
- 工作树:`.worktrees/report-chart-layout-fix-20260909`
|
||||
- 分支:`codex/report-chart-layout-fix-20260909`(track `origin/staging`)
|
||||
- 基线:`origin/staging` @ `584a56bd`(任务书本身;代码基线 `17b36f3a`)
|
||||
- BUG:**BUG-616**、**BUG-617**
|
||||
- 未改 `.gitea/workflows/**`、`frontend/src/app/page.tsx`、下载剥围栏;不提升 `main`,未 push
|
||||
|
||||
## 做了什么
|
||||
|
||||
| 任务 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 1 两栏成组 | 完成 | `report-chart-grid-rehype.ts` 把 D… / Moon Chart 标题 + 可选 `p` + `jyotish-chart` 围栏包进 `.personal-report-chart-card`,相邻卡进既有 `.personal-report-chart-grid`;删 float / `margin-left: -50%` |
|
||||
| 2 滚动不重建 | 完成 | `ReportToc` 持有 `activeId` 与 observer;lead / `LazyMarkdownSection` 的 `renderMarkdown` 在 `useMemo` 内;`LazyMarkdownSection` `memo()` |
|
||||
| 3 记录 | 完成 | BUG-616/617、CHANGELOG、DESIGN、走查清单第 7 节、本文件;任务板改「待验收」 |
|
||||
|
||||
没有砍让步项。rehype 两栏一次做成,未退到 D2 单栏。
|
||||
|
||||
## 口径(与任务书一致)
|
||||
|
||||
- 两栏保留,不再用浮动凑。
|
||||
- `skipHtml` / 禁止 `rehype-raw` / 不新增 npm 依赖。
|
||||
- 下载 `.md` 仍剥围栏、保留标题。
|
||||
- 本仓测试无 DOM 运行时,重渲染次数不能自动验;真机两条写在走查清单第 7 节。
|
||||
|
||||
## 组件树(改动前后)
|
||||
|
||||
改前:
|
||||
|
||||
```
|
||||
PersonalReportMarkdownView
|
||||
useState(activeId) + IntersectionObserver ← 目录一变,整树重渲染
|
||||
renderMarkdown(lead) ← 每次新建 components,子树卸载
|
||||
LazyMarkdownSection (无 memo)
|
||||
renderMarkdown(section) ← 同上
|
||||
```
|
||||
|
||||
改后:
|
||||
|
||||
```
|
||||
PersonalReportMarkdownView ← 无 useState,只随 markdown 变
|
||||
ReportToc
|
||||
useState(activeId) + IntersectionObserver
|
||||
TocList × 2
|
||||
article
|
||||
lead = useMemo(renderMarkdown)
|
||||
memo(LazyMarkdownSection)
|
||||
content = useMemo(renderMarkdown | h2 占位)
|
||||
```
|
||||
|
||||
滚动只重绘 `ReportToc`。文章树里的 SVG 保持同一组 DOM 节点(真机第 7 节)。
|
||||
|
||||
## 偏离
|
||||
|
||||
1. **两栏折断点跟既有 document-view grid,是 760px 而不是任务书正文里的 860px。** `globals.css` 里 `.personal-report-chart-grid` 的单栏媒体查询一直是 `max-width: 760px`;860px 只折叠 TOC。未改这个既有数字。
|
||||
2. **rehype 插件导出了 `groupReportChartNodes`。** 给同一文件的工厂函数用,测试仍走 `PersonalReportMarkdownView` 的静态标记,没有另开 hast 单测。
|
||||
|
||||
## 测试数字
|
||||
|
||||
| 项 | 本轮实测 | 结论 |
|
||||
| --- | --- | --- |
|
||||
| `tsc --noEmit` | 0 错 | 通过 |
|
||||
| `npm run lint` | 0 error / 108 warning | warning 数与 BUG-607 收工相同;新文件无 error |
|
||||
| `tsx --test tests/personal-report-markdown-view.test.tsx` | 6 passed | 原 1 条 + 本单 5 条 |
|
||||
| `globals.css` gzip | 开工 `35791` B → 工作树 `35612` B | −179 B / −0.50%,在 ±2% 内 |
|
||||
| `next build --webpack` `/` | `○ Static` | 交叉 `node_modules` 符号链接,与 BUG-607 相同改用 webpack |
|
||||
| 首页 CSS gzip(构建产物) | 最大块 `a083d2bd2a5e75cb.css` = 36,083 B | 相对 BUG-607 的 35,779 B 为 +0.85%,在 ±2% 内 |
|
||||
| `npm test` tests | 3008 | 高于 BUG-607 的 2975(staging 后来加了测试,本单 +5) |
|
||||
| `npm test` pass | 2997 | |
|
||||
| `npm test` fail | 11 | 全是 Docker Postgres fixture / 迁移 / 超时 / onboarding deadline flake,与图盘无关 |
|
||||
| `npm test` skipped | 0 | Docker 可用 |
|
||||
|
||||
11 条失败(均非本轮图盘代码):
|
||||
|
||||
1. `admin-database.test.ts` — `database migration failed`
|
||||
2. `database-admin-account-reset.test.ts` — 同上
|
||||
3. `database-admin-owner-recovery.test.ts` — 同上
|
||||
4. `database-billing-audit.test.ts` — 同上(billing order adjustments…)
|
||||
5. `database-billing-product-admin.test.ts` — 300s 超时(当时并行跑过 `next build`)
|
||||
6. `database-migrate.test.ts` — 300s 超时(同上)
|
||||
7. `database-self-hosted-identity.test.ts` — Better Auth OTP fixture
|
||||
8. `onboarding-route.test.ts` — `slow Agent generation` 把 `deadline` 当成了失败(flake)
|
||||
9–11. `rectification-v9-database.test.ts` 三条 — `database migration failed`
|
||||
|
||||
无 Docker 基线 28 条本轮未复跑(Docker 可用)。图盘相关 6 条 markdown-view + 既有 `report-chart-block.test.ts` 全绿。
|
||||
|
||||
## 没做的
|
||||
|
||||
- **没有在浏览器里打开过一份真实 `/reports/<id>`。** 无登录态。走查清单第 4 节和第 7 节待真机。
|
||||
- 未 push。代码进 staging 会走 `Staging Backend Quality Gate`。
|
||||
- 收工时 `origin/staging` 已含 BUG-614~615、BUG-618~620;合并写在本提交之后。
|
||||
@@ -121,7 +121,7 @@
|
||||
| `TASK-report-list-500-20260907.md`(仓库根) | `PROGRESS-report-list-500-20260907.md` | 列表 PostgREST JSON 路径 500 | 待验收 | `b466a6fc`(BUG-574) |
|
||||
| — | `PROGRESS-report-progress-20260909.md` | 生成等待屏只有 spinner 与秒表:后端 `progressPercent` / `progressPhase` 与分章行已产出,前端解析后一字未渲染,且分章行在 `generating` 时根本不出服务端。改为按章分格进度条 + 章节清单,停滞 90 秒改「用时较长,仍在写」;不画百分比条、不做插值动画、不报预计剩余 | 已验收 | `848e39e6`、`5565b632`(BUG-601) |
|
||||
| `TASK-report-chart-render-20260909.md` | `PROGRESS-report-chart-render-20260909.md` | 报告页所有分盘标题下空白:引擎 22 张 `<svg>` 被 `skipHtml` 丢弃(09-06 Markdown 直渲回归)。引擎旁加 ```jyotish-chart 围栏 JSON,前端 zod 校验后用自绘北印式组件全部渲染;不放开原始 HTML | 已验收(2fdcb14f):tsc/lint 0 error、chart 测试 29/29、`/` Static、gzip +0.96%;围栏构造在 try 外的 P2 并入 `TASK-upstream-sync2-fix-20260909.md` 任务 3 | `codex/report-chart-render-20260909`(BUG-607) |
|
||||
| `TASK-report-chart-layout-fix-20260909.md` | — | 星盘渲染回归修复:22 张北印盘全部重叠(浮动 + 负 margin 凑两栏对连续多对无效)+ 滚动时 `components` 每渲染新建导致整篇报告卸载重建、页面卡;改 rehype 成组进既有两栏 grid、文章树 `useMemo`、目录状态下沉 | 待领取 | 分支 `codex/report-chart-layout-fix-20260909`(BUG-616/617) |
|
||||
| `TASK-report-chart-layout-fix-20260909.md` | `PROGRESS-report-chart-layout-fix-20260909.md` | 星盘渲染回归修复:22 张北印盘全部重叠(浮动 + 负 margin 凑两栏对连续多对无效)+ 滚动时 `components` 每渲染新建导致整篇报告卸载重建、页面卡;改 rehype 成组进既有两栏 grid、文章树 `useMemo`、目录状态下沉 | 待验收 | `codex/report-chart-layout-fix-20260909`(BUG-616/617) |
|
||||
|
||||
### 前端基础与工程
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
## 4. 手机与打印
|
||||
|
||||
- [ ] iPhone Safari 竖屏:图单列、居中,不撑出左右滚动(宽表除外)。
|
||||
- [ ] 桌面 ≥720px:Vargas I 的图是两列。
|
||||
- [ ] iPhone Safari 竖屏:图单列,不撑出左右滚动(宽表除外),标题在卡内、图在标题下,互不重叠。
|
||||
- [ ] 桌面宽于 760px:Vargas I 的图是两列卡片,标题在各自卡顶,没有叠盘、没有标题堆成一列。
|
||||
- [ ] 打印预览:图仍是单列,不会变成两列挤在纸上。
|
||||
|
||||
## 5. 导出 `.md`
|
||||
@@ -37,4 +37,11 @@
|
||||
|
||||
- [ ] 打开一份 09-06 之后、本修复之前生成的报告:标题还在,不报错,不出现「图盘数据无效」(因为根本没有围栏块)。图可以没有。
|
||||
|
||||
未打勾的项写成「未验证」。发现南印度方格、空白标题、导出文件里大段 JSON,或暗色主题下图看不见,把现象和报告页截图贴回。
|
||||
## 7. 滚动不重建(BUG-617)
|
||||
|
||||
本仓前端测试是 `renderToStaticMarkup`,没有 DOM 运行时,数不了 React 重渲染。下面两条必须在真机(Chrome)上对照一份 Vargas I 已全部揭开的新报告。
|
||||
|
||||
- [ ] Vargas I 全部揭开后连续滚动 10 秒:Chrome Performance 没有 >100ms 的长帧。
|
||||
- [ ] Elements 面板选中 D1 的 `<svg>` 之后滚动、目录高亮切换:选中不丢,该 `<svg>` DOM 节点还是同一个。
|
||||
|
||||
未打勾的项写成「未验证」。发现南印度方格、空白标题、导出文件里大段 JSON、暗色主题下图看不见、盘重叠,或滚动时 Elements 里 SVG 被替换,把现象和报告页截图贴回。
|
||||
|
||||
Reference in New Issue
Block a user