feat: 优化导出文件质量

This commit is contained in:
meijiali
2026-07-03 15:29:55 +08:00
parent 11f129c4aa
commit b14834e806
5 changed files with 54 additions and 4 deletions
+11 -2
View File
@@ -11,8 +11,17 @@
<div class="d-flex justify-content-between align-items-center mb-3">
<h1 class="h3 mb-0">{{ hotspot.title }} 汇总报告</h1>
<div class="d-flex gap-2">
<a class="btn btn-outline-primary" href="/api/export/hotspots/{{ hotspot.id }}.md">导出 Markdown 报告</a>
<a class="btn btn-outline-secondary" href="/api/export/hotspots/{{ hotspot.id }}/comments.csv">导出热点评论 CSV</a>
<button
class="btn btn-outline-primary"
onclick="downloadExport('/api/export/hotspots/{{ hotspot.id }}.md', 'hotspot-report.md', event)"
{% if not report %}disabled title="报告尚未生成"{% endif %}>
导出 Markdown 报告
</button>
<button
class="btn btn-outline-secondary"
onclick="downloadExport('/api/export/hotspots/{{ hotspot.id }}/comments.csv', 'hotspot-comments.csv', event)">
导出热点评论 CSV
</button>
</div>
</div>
{% if report %}
+11 -2
View File
@@ -12,8 +12,17 @@
<div class="d-flex justify-content-between align-items-center mb-3">
<h1 class="h3 mb-0">{{ item.title or item.source_item_id }}</h1>
<div class="d-flex gap-2">
<a class="btn btn-outline-primary" href="/api/export/items/{{ item.id }}.md">导出 Markdown 报告</a>
<a class="btn btn-outline-secondary" href="/api/export/items/{{ item.id }}/comments.csv">导出评论 CSV</a>
<button
class="btn btn-outline-primary"
onclick="downloadExport('/api/export/items/{{ item.id }}.md', 'item-report.md', event)"
{% if not report %}disabled title="报告尚未生成"{% endif %}>
导出 Markdown 报告
</button>
<button
class="btn btn-outline-secondary"
onclick="downloadExport('/api/export/items/{{ item.id }}/comments.csv', 'item-comments.csv', event)">
导出评论 CSV
</button>
</div>
</div>
{% if report %}
+21
View File
@@ -598,6 +598,27 @@ fix: 增强 SQLite 数据库恢复与异常提示
feat: 优化导出文件质量
```
完成记录:
```text
完成日期:2026-07-03
相关 commitfeat: 优化导出文件质量
验证命令:
- .venv/bin/python -m pytest tests/unit/test_export.py tests/integration/test_routes.py::test_result_pages_render_seeded_data tests/integration/test_routes.py::test_report_pages_render_empty_state_when_report_missing tests/integration/test_routes.py::test_export_routes_return_csv_and_markdown -q
- .venv/bin/python -m pytest tests/unit tests/integration -q
- docker compose up -d --build
- curl -f http://localhost:8000/health
- 抽样检查内容 CSV UTF-8-BOM、CSV 列数、Markdown 总结章节和页面 downloadExport 按钮
- .venv/bin/python -m pytest tests/unit tests/integration --cov=app --cov-branch --cov-report=term-missing
验收结论:
- CSV 导出已覆盖 =、+、-、@ 公式注入前缀防护。
- CSV 导出会替换 \n、\r、\r\n,避免单条评论破坏行结构。
- CSV 导出使用 UTF-8-BOM,抽样文件以 BOM 开头。
- 热点/内容报告和评论导出按钮使用 downloadExport,报告缺失时 Markdown 按钮置灰并提示“报告尚未生成”。
- Markdown 导出读取预生成 report.markdown_content,抽样包含“## 总结”章节。
遗留问题:评论为空时 CSV 仍返回只有表头的文件,后续可在 WO-09 文档说明空文件语义。
```
### WO-08 Docker 与部署前清理
优先级:P1
+6
View File
@@ -262,6 +262,8 @@ def test_result_pages_render_seeded_data():
assert 'onclick="window.location.reload()"' in task_response.text
assert hotspot_response.status_code == 200
assert "热点总结" in hotspot_response.text
assert "downloadExport('/api/export/hotspots/hot-result.md'" in hotspot_response.text
assert "downloadExport('/api/export/hotspots/hot-result/comments.csv'" in hotspot_response.text
assert "评论样本" in hotspot_response.text
assert "关联内容" in hotspot_response.text
assert "正向" in hotspot_response.text
@@ -272,6 +274,8 @@ def test_result_pages_render_seeded_data():
assert "<pre" not in hotspot_response.text
assert item_response.status_code == 200
assert "内容总结" in item_response.text
assert "downloadExport('/api/export/items/item-result.md'" in item_response.text
assert "downloadExport('/api/export/items/item-result/comments.csv'" in item_response.text
assert "评论样本" in item_response.text
assert "Top 标签" in item_response.text
assert "评论内容" in item_response.text
@@ -306,8 +310,10 @@ def test_report_pages_render_empty_state_when_report_missing():
assert hotspot_response.status_code == 200
assert "报告生成中,请稍候" in hotspot_response.text
assert 'title="报告尚未生成"' in hotspot_response.text
assert item_response.status_code == 200
assert "报告生成中,请稍候" in item_response.text
assert 'title="报告尚未生成"' in item_response.text
def test_report_pages_warn_when_ai_sample_is_insufficient():
+5
View File
@@ -8,7 +8,12 @@ def test_labels_to_text_joins_json_array_with_chinese_comma():
def test_safe_csv_field_prevents_formula_injection_and_newlines():
assert safe_csv_field("=1+1") == "'=1+1"
assert safe_csv_field("+1+1") == "'+1+1"
assert safe_csv_field("-1+1") == "'-1+1"
assert safe_csv_field("@SUM(1,1)") == "'@SUM(1,1)"
assert safe_csv_field("hello\nworld") == "hello world"
assert safe_csv_field("hello\r\nworld") == "hello world"
assert safe_csv_field("hello\rworld") == "hello world"
def test_safe_filename_replaces_illegal_chars_and_truncates_keyword():