feat: 补齐Word导出报告结构化字段口径
This commit is contained in:
@@ -6,6 +6,7 @@ from xml.sax.saxutils import escape
|
||||
import zipfile
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
|
||||
from agent_core.governance import load_governance_config
|
||||
from apps.documents.services import create_export_record
|
||||
@@ -31,6 +32,8 @@ def generate_registration_export(*, batch, conversation, upstream_summary: dict
|
||||
absolute_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
fillable_items = _build_fillable_items(batch, conversation)
|
||||
filled_fields = _build_filled_fields(fillable_items)
|
||||
blocked_fields = _build_blocked_fields(blocked_items)
|
||||
_write_minimal_docx(
|
||||
absolute_path,
|
||||
product_name=batch.product_name or conversation.product_name or "未命名资料包",
|
||||
@@ -59,11 +62,13 @@ def generate_registration_export(*, batch, conversation, upstream_summary: dict
|
||||
"formal_export_status": "completed" if can_export_formally else "blocked",
|
||||
"can_export_formally": can_export_formally,
|
||||
"fillable_items": fillable_items,
|
||||
"filled_fields": filled_fields,
|
||||
"fillable_field_count": len(fillable_items),
|
||||
"filled_field_count": len(fillable_items),
|
||||
"filled_field_count": len(filled_fields),
|
||||
"blocked_items": blocked_items,
|
||||
"blocked_field_count": len(blocked_items),
|
||||
"manual_review_field_count": len(blocked_items),
|
||||
"blocked_fields": blocked_fields,
|
||||
"blocked_field_count": len(blocked_fields),
|
||||
"manual_review_field_count": len(blocked_fields),
|
||||
"layout_check_status": "passed",
|
||||
"download_url": download_url,
|
||||
"output_file": {
|
||||
@@ -71,6 +76,8 @@ def generate_registration_export(*, batch, conversation, upstream_summary: dict
|
||||
"relative_path": relative_path.as_posix(),
|
||||
"absolute_path": str(absolute_path),
|
||||
"export_mode": export_mode,
|
||||
"output_version": export_mode,
|
||||
"generated_at": timezone.now().isoformat(),
|
||||
},
|
||||
}
|
||||
create_export_record(
|
||||
@@ -142,11 +149,71 @@ def _can_export_formally(upstream_summary: dict, blocked_items: list[str]) -> bo
|
||||
|
||||
def _build_fillable_items(batch, conversation) -> list[dict]:
|
||||
return [
|
||||
{"placeholder": "{{ product_name }}", "field_name": "产品名称", "field_value": batch.product_name},
|
||||
{"placeholder": "{{ batch_id }}", "field_name": "批次号", "field_value": batch.batch_id},
|
||||
{"placeholder": "{{ conversation_id }}", "field_name": "会话编号", "field_value": conversation.conversation_id},
|
||||
{"placeholder": "{{ file_count }}", "field_name": "文件数", "field_value": str(batch.file_count)},
|
||||
{"placeholder": "{{ page_count }}", "field_name": "页数", "field_value": str(batch.page_count)},
|
||||
{
|
||||
"placeholder": "{{ product_name }}",
|
||||
"field_name": "产品名称",
|
||||
"field_value": batch.product_name,
|
||||
"source": "资料包主信息",
|
||||
"fill_status": "filled",
|
||||
"required": True,
|
||||
},
|
||||
{
|
||||
"placeholder": "{{ batch_id }}",
|
||||
"field_name": "批次号",
|
||||
"field_value": batch.batch_id,
|
||||
"source": "资料包主信息",
|
||||
"fill_status": "filled",
|
||||
"required": True,
|
||||
},
|
||||
{
|
||||
"placeholder": "{{ conversation_id }}",
|
||||
"field_name": "会话编号",
|
||||
"field_value": conversation.conversation_id,
|
||||
"source": "会话主信息",
|
||||
"fill_status": "filled",
|
||||
"required": True,
|
||||
},
|
||||
{
|
||||
"placeholder": "{{ file_count }}",
|
||||
"field_name": "文件数",
|
||||
"field_value": str(batch.file_count),
|
||||
"source": "资料包统计",
|
||||
"fill_status": "filled",
|
||||
"required": False,
|
||||
},
|
||||
{
|
||||
"placeholder": "{{ page_count }}",
|
||||
"field_name": "页数",
|
||||
"field_value": str(batch.page_count),
|
||||
"source": "资料包统计",
|
||||
"fill_status": "filled",
|
||||
"required": False,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def _build_filled_fields(fillable_items: list[dict]) -> list[dict]:
|
||||
return [
|
||||
{
|
||||
"placeholder": item["placeholder"],
|
||||
"field_name": item["field_name"],
|
||||
"field_value": item["field_value"],
|
||||
"source": item["source"],
|
||||
"fill_status": item["fill_status"],
|
||||
"required": item["required"],
|
||||
}
|
||||
for item in fillable_items
|
||||
]
|
||||
|
||||
|
||||
def _build_blocked_fields(blocked_items: list[str]) -> list[dict]:
|
||||
return [
|
||||
{
|
||||
"field_name": item,
|
||||
"block_reason": "待人工复核",
|
||||
"risk_source": "registration_risk_report",
|
||||
}
|
||||
for item in blocked_items
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -497,6 +497,11 @@ def test_generate_registration_export_creates_real_docx_file(db, tmp_path, setti
|
||||
assert report["output_type"] == "registration_word_export_report"
|
||||
assert report["can_export_formally"] is False
|
||||
assert report["export_status"] == "draft_only"
|
||||
assert report["filled_fields"][0]["field_name"] == "产品名称"
|
||||
assert report["filled_fields"][0]["fill_status"] == "filled"
|
||||
assert report["blocked_fields"][0]["block_reason"] == "待人工复核"
|
||||
assert report["output_file"]["output_version"] == "draft"
|
||||
assert report["output_file"]["generated_at"]
|
||||
assert report["download_url"].startswith("/media/exports/")
|
||||
assert export_path.exists()
|
||||
with zipfile.ZipFile(export_path) as archive:
|
||||
|
||||
Reference in New Issue
Block a user