feat: 优化导出文件质量
This commit is contained in:
@@ -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 %}
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -598,6 +598,27 @@ fix: 增强 SQLite 数据库恢复与异常提示
|
||||
feat: 优化导出文件质量
|
||||
```
|
||||
|
||||
完成记录:
|
||||
|
||||
```text
|
||||
完成日期:2026-07-03
|
||||
相关 commit:feat: 优化导出文件质量
|
||||
验证命令:
|
||||
- .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
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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():
|
||||
|
||||
Reference in New Issue
Block a user