From fe445598c98d66c15ee0c0d0d5157feb8fed0144 Mon Sep 17 00:00:00 2001
From: thzxx <1440196015@qq.com>
Date: Tue, 18 Aug 2026 09:37:07 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20v0.4.2=20=E5=AF=BC=E5=87=BA=E8=8F=9C?=
=?UTF-8?q?=E5=8D=95=E6=BA=A2=E5=87=BA=E4=BF=AE=E5=A4=8D=E4=B8=8E=20HTML?=
=?UTF-8?q?=20=E6=8A=A5=E5=91=8A=E5=8F=AF=E8=AF=BB=E6=80=A7=E9=87=8D?=
=?UTF-8?q?=E8=AE=BE=E8=AE=A1=20-=20=E5=BA=95=E9=83=A8=E5=B7=A5=E5=85=B7?=
=?UTF-8?q?=E6=A0=8F=E5=AF=BC=E5=87=BA=E8=8F=9C=E5=8D=95=E6=94=B9=E5=90=91?=
=?UTF-8?q?=E4=B8=8A=E5=BC=B9=E5=87=BA=EF=BC=88=E4=BF=AE=E5=A4=8D=E8=B6=85?=
=?UTF-8?q?=E5=87=BA=E7=AA=97=E5=8F=A3=E5=BA=95=E8=BE=B9=E9=80=89=E4=B8=8D?=
=?UTF-8?q?=E5=88=B0=EF=BC=89=E3=80=81HTML=20=E6=8A=A5=E5=91=8A=E5=85=A8?=
=?UTF-8?q?=E6=96=B0=E8=AE=BE=E8=AE=A1=EF=BC=88Hero=20=E6=A6=82=E8=A7=88/?=
=?UTF-8?q?=E4=BA=BA=E8=AF=9D=E7=BB=93=E8=AE=BA/=E6=96=87=E4=BB=B6?=
=?UTF-8?q?=E5=8D=A1=E7=89=87/=E7=BB=9F=E8=AE=A1=E5=8D=A1/=E5=9B=BE?=
=?UTF-8?q?=E4=BE=8B/=E5=B7=AE=E5=BC=82=E5=88=86=E5=9D=97=E7=9B=AE?=
=?UTF-8?q?=E5=BD=95/=E7=9B=B8=E5=90=8C=E6=AE=B5=E6=8A=98=E5=8F=A0?=
=?UTF-8?q?=E5=8F=AF=E5=B1=95=E5=BC=80/=E6=89=93=E5=8D=B0=E4=BA=AE?=
=?UTF-8?q?=E8=89=B2/=E7=AA=84=E5=B1=8F=E9=80=82=E9=85=8D=EF=BC=8C?=
=?UTF-8?q?=E9=9B=B6=20JS=EF=BC=89=E3=80=81TXT=20=E4=B8=8E=20Markdown=20?=
=?UTF-8?q?=E6=8A=A5=E5=91=8A=E5=A4=B4=E9=83=A8=E8=A1=A5=E4=BA=BA=E8=AF=9D?=
=?UTF-8?q?=E7=BB=93=E8=AE=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 4 +-
docs/应用开发与版本迭代规范.md | 5 +-
docs/测试策略与方案.md | 10 +-
package.json | 2 +-
src/renderer/src/components/Toolbar.test.tsx | 6 +
src/renderer/src/components/Toolbar.tsx | 2 +-
src/renderer/src/diff/report.test.ts | 157 ++++++-
src/renderer/src/diff/report.ts | 455 ++++++++++++++++---
src/renderer/src/styles/global.css | 6 +
9 files changed, 582 insertions(+), 65 deletions(-)
diff --git a/README.md b/README.md
index 8fe818f..70c14cb 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ DiffLens 是一款跨平台桌面文本对比工具,帮助你快速定位两
- **大文件防护**:超过 10MB 的文件自动拦截并提示;行数过多时给出耗时预警;超长单行自动跳过词级高亮,避免卡顿
- **二进制文件预警**:疑似二进制内容给出乱码提示,避免误读为差异
- **差异统计徽章**:实时统计新增 / 删除 / 修改行数
-- **导出一键报告**:将对比结果导出为 HTML / 纯文本 / Markdown 三种格式(始终包含全量行),便于分享与归档
+- **导出一键报告**:将对比结果导出为 HTML / 纯文本 / Markdown 三种格式(始终包含全量行)。HTML 报告为"给人看"设计:一句话结论、文件卡片、统计概览、图例说明、差异分块目录导航,相同内容段自动折叠(点击展开零丢失),并支持打印与窄屏
- **拖拽与按钮双入口**:支持文件拖拽导入,也可通过界面按钮选择文件或粘贴文本
- **滚动联动**:左右两个面板滚动位置自动同步
@@ -96,7 +96,7 @@ src/
- 作者:thzxx
- 组织:MetonaTeam
- 许可证:MIT License(见 [LICENSE](./LICENSE))
-- 版本:0.4.1
+- 版本:0.4.2
---
diff --git a/docs/应用开发与版本迭代规范.md b/docs/应用开发与版本迭代规范.md
index cd94df2..ddddfcb 100644
--- a/docs/应用开发与版本迭代规范.md
+++ b/docs/应用开发与版本迭代规范.md
@@ -20,7 +20,7 @@ z = 补丁版本号(Patch)
> **`x` 永远是 `0`,永远不要提升到 `1.0.0`。**
> 版本迭代**只允许修改 `y` 和 `z`**,`x` 保持 `0` 不变。
-当前基线版本:**`0.4.1`**
+当前基线版本:**`0.4.2`**
---
@@ -67,7 +67,8 @@ z = 补丁版本号(Patch)
0.3.1 ← 稳健性与测试补强(已发布):超长单行词级 diff 防护 · 打开对话框补“所有文件”筛选 · 虚拟滚动 minWidth 测试覆盖 · 滚动同步去锁化重构
0.3.2 ← 报告对齐与性能收尾(已发布):纯文本报告行号右对齐 · 超长行列宽封顶防卡顿 · 对话框与拖拽扩展名清单对齐 · 右键菜单打开时导航快捷键守卫 · 清理导出死属性
0.4.0 ← 差异计算 worker 化(已发布):大文件 diff 移入 Worker 后台计算不阻塞界面 · 输入去抖与过期任务丢弃(终止重建实现取消) · 小输入同步快路径 · 无 Worker 环境回退 · 计算中遮罩与导出禁用
-0.4.1 ← worker 创建开销优化与文档对齐(当前):worker 延迟至去抖到期才创建(去抖期内取消零创建开销,无 Worker 回退同样走去抖) · 质量门禁文档补 npm test · README 架构树补 hooks · Markdown 报告标题移出引用块 · 安装包排除开发期文件
+0.4.1 ← worker 创建开销优化与文档对齐(已发布):worker 延迟至去抖到期才创建(去抖期内取消零创建开销,无 Worker 回退同样走去抖) · 质量门禁文档补 npm test · README 架构树补 hooks · Markdown 报告标题移出引用块 · 安装包排除开发期文件
+0.4.2 ← 导出菜单溢出修复与报告可读性重设计(当前):底部工具栏导出菜单改向上弹出(修复超出窗口底边选不到) · HTML 报告全新设计(Hero 概览/人话结论/文件卡片/统计卡/图例/差异分块目录/相同段折叠可展开/打印亮色/窄屏适配,零 JS) · TXT 与 Markdown 报告头部补人话结论
0.5.0 ← 新增功能(候选:主进程解码 worker 化 · Playwright E2E · 文件夹对比)
...
0.y.z ← 长期停留,永不进入 1.x
diff --git a/docs/测试策略与方案.md b/docs/测试策略与方案.md
index f69cc78..9e752fc 100644
--- a/docs/测试策略与方案.md
+++ b/docs/测试策略与方案.md
@@ -60,7 +60,7 @@ src/renderer/src/
│ ├── ContextMenu.test.tsx # 右键菜单(含边缘防溢出)
│ ├── DiffView.test.tsx # 对比视图(渲染/滚动同步/右键/拖放)
│ ├── TextInputModal.test.tsx # 粘贴文本弹窗
-│ └── Toolbar.test.tsx # 工具栏(选项/导航/导出菜单/计算中禁用)
+│ └── Toolbar.test.tsx # 工具栏(选项/导航/导出菜单向上弹出/计算中禁用)
└── __tests__/
├── App.test.tsx # 应用集成级测试(加载/拖拽/粘贴/导出/容错/大输入回退)
└── main.test.ts # 入口挂载冒烟测试
@@ -82,9 +82,11 @@ src/renderer/src/
- 行切分:结尾换行不产生多余空行
### 5.2 报告生成(`report.ts`)
-- HTML:输出合法文档、含文件名/统计/类型高亮语义
-- 纯文本:含增删改标记(`+ -`)、行号按最大位数右对齐
-- Markdown:表格化、管道符转义保持表格结构
+- HTML:输出合法文档;Hero 区含人话结论(verdict)、文件卡片、统计卡与图例;差异分块(hunk-head)与块内行渲染;多块时输出目录锚点(toc/href="#seg-N"),单块不输出;相同内容段折叠(details/summary)且折叠段内保留全量行数据;一致场景 verdict ok;两侧空内容提示
+- 纯文本:含增删改标记(`+ -`)、行号按最大位数右对齐、头部人话结论
+- Markdown:表格化、管道符转义保持表格结构、引用块含人话结论
+- 差异分块(`buildSegments`):空行集 / 无变更单段全展示 / 上下文 3 行与边界收敛 / 相邻区间合并 / 远距分两段省略数正确 / 自定义 context
+- 人话总结(`plainSummary`):无差异一致结论 / 为 0 项省略 / 三类齐全完整罗列
- 格式分发与扩展名映射(`REPORT_EXT`)
### 5.3 文本工具(`textUtils.ts`)
diff --git a/package.json b/package.json
index 805cea2..b47b5d5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "DiffLens",
- "version": "0.4.1",
+ "version": "0.4.2",
"description": "DiffLens — 精美酷炫的文本对比桌面应用",
"author": "thzxx",
"license": "MIT",
diff --git a/src/renderer/src/components/Toolbar.test.tsx b/src/renderer/src/components/Toolbar.test.tsx
index 9e1715a..0de8c32 100644
--- a/src/renderer/src/components/Toolbar.test.tsx
+++ b/src/renderer/src/components/Toolbar.test.tsx
@@ -86,6 +86,12 @@ describe('Toolbar', () => {
expect(onExport).toHaveBeenCalledWith('html')
})
+ it('导出菜单向上弹出(工具栏贴窗口底部,防止溢出底边)', () => {
+ const { container } = setup()
+ fireEvent.click(screen.getByText('导出报告'))
+ expect(container.querySelector('.export-menu.up')).not.toBeNull()
+ })
+
it('点击外部区域关闭导出菜单', () => {
setup()
fireEvent.click(screen.getByText('导出报告'))
diff --git a/src/renderer/src/components/Toolbar.tsx b/src/renderer/src/components/Toolbar.tsx
index 1858f11..d953216 100644
--- a/src/renderer/src/components/Toolbar.tsx
+++ b/src/renderer/src/components/Toolbar.tsx
@@ -125,7 +125,7 @@ export default function Toolbar({
导出报告
{exportOpen && (
-
+
{FORMATS.map((f) => (