feat: 打通Word导出文件生成与下载闭环

This commit is contained in:
2026-06-04 02:28:42 +08:00
parent e81f0f891e
commit 0250bd360a
5 changed files with 387 additions and 1 deletions

View File

@@ -1,3 +1,6 @@
import zipfile
from django.test import override_settings
from django.urls import reverse
from django.core.files.uploadedfile import SimpleUploadedFile
@@ -465,3 +468,82 @@ def test_chat_upload_keeps_existing_conversation_binding_and_adds_documents(clie
assert UploadedDocument.objects.filter(batch=batch, original_name="新增补充资料.txt").exists()
assert "新增补充资料.txt" in content
assert "已补充到当前资料包" in content
@override_settings(MEDIA_URL="/media/")
def test_generate_registration_export_creates_real_docx_file(db, tmp_path, settings):
from apps.chat.export_service import generate_registration_export
settings.MEDIA_ROOT = tmp_path / "uploads"
batch, conversation = _create_conversation_with_batch()
risk_summary = {
"output_type": "registration_risk_report",
"summary": "存在高风险项,正式版导出应被阻断,但允许生成草稿。",
"highest_risk_level": "high",
"pass_status": "blocked",
"manual_review_items": ["CH1.11.5 沟通记录待补齐"],
"risk_items": [
{"title": "产品名称跨文档不一致", "risk_level": "high"},
],
}
report = generate_registration_export(
batch=batch,
conversation=conversation,
upstream_summary=risk_summary,
)
export_path = settings.MEDIA_ROOT / report["output_file"]["relative_path"]
assert report["output_type"] == "registration_word_export_report"
assert report["can_export_formally"] is False
assert report["export_status"] == "draft_only"
assert report["download_url"].startswith("/media/exports/")
assert export_path.exists()
with zipfile.ZipFile(export_path) as archive:
document_xml = archive.read("word/document.xml").decode("utf-8")
assert batch.product_name in document_xml
assert "产品名称跨文档不一致" in document_xml
@override_settings(MEDIA_URL="/media/")
def test_chat_export_word_route_persists_real_download_link(client, db, tmp_path, settings):
settings.MEDIA_ROOT = tmp_path / "uploads"
batch, conversation = _create_conversation_with_batch()
conversation.node_results = [
{"label": "资料包导入", "status": "已完成"},
{"label": "目录汇总", "status": "已完成"},
{"label": "法规完整性检查", "status": "已完成"},
{"label": "字段抽取", "status": "已完成"},
{"label": "一致性核查", "status": "已完成"},
{"label": "风险预警", "status": "已阻断"},
{"label": "Word 回填导出", "status": "待处理"},
{"label": "飞书通知", "status": "待处理"},
]
conversation.latest_summary = {
"structured_output": {
"output_type": "registration_risk_report",
"summary": "存在高风险项,允许草稿导出。",
"highest_risk_level": "high",
"pass_status": "blocked",
"manual_review_items": ["CH1.11.5 沟通记录待补齐"],
"risk_items": [{"title": "产品名称跨文档不一致", "risk_level": "high"}],
}
}
conversation.save(update_fields=["node_results", "latest_summary", "updated_at"])
response = client.post(
reverse("chat:export-word", args=[conversation.conversation_id]),
follow=True,
)
content = response.content.decode("utf-8")
conversation.refresh_from_db()
export_report = conversation.latest_summary["structured_output"]
export_path = settings.MEDIA_ROOT / export_report["output_file"]["relative_path"]
assert response.status_code == 200
assert export_report["output_type"] == "registration_word_export_report"
assert export_report["download_url"].startswith("/media/exports/")
assert export_path.exists()
assert "下载导出文件" in content
assert export_report["download_url"] in content
assert AgentAuditLog.objects.filter(conversation_id=conversation.conversation_id).count() == 1