feat: 增强审核智能体页Word导出能力卡展示

This commit is contained in:
2026-06-04 02:49:27 +08:00
parent 08dcb62834
commit 20f3883b8c
3 changed files with 141 additions and 1 deletions

View File

@@ -85,6 +85,7 @@ def detail(request, conversation_id: str):
active_node = "risk"
conversation.refresh_from_db()
workspace_summary = _build_workspace_summary(conversation, batch)
export_card = _build_export_card(result, conversation)
return render(
request,
@@ -103,6 +104,7 @@ def detail(request, conversation_id: str):
"active_node": active_node,
"workspace_summary": workspace_summary,
"upload_form": upload_form,
"export_card": export_card,
},
)
@@ -240,6 +242,29 @@ def _build_workspace_summary(conversation: Conversation, batch: SubmissionBatch
}
def _build_export_card(result: AgentResult | None, conversation: Conversation) -> dict:
"""
统一组装 Word 导出能力卡上下文。
优先使用本次执行结果;若本次未执行,则回退到会话最新摘要。
"""
structured_output = {}
if result and result.structured_output:
structured_output = result.structured_output
else:
structured_output = (conversation.latest_summary or {}).get("structured_output") or {}
if structured_output.get("output_type") != "registration_word_export_report":
return {}
return {
"template_name": structured_output.get("template_name", ""),
"template_version": structured_output.get("template_version", ""),
"export_status": structured_output.get("export_status", ""),
"filled_fields": structured_output.get("filled_fields") or [],
"blocked_fields": structured_output.get("blocked_fields") or [],
"download_url": structured_output.get("download_url", ""),
}
def _apply_agent_result_to_conversation(conversation: Conversation, result: AgentResult) -> None:
conversation.task_status = result.status
if result.node_results:

View File

@@ -88,7 +88,68 @@
<article class="panel">
<h2 class="section-title">节点式结果</h2>
{% if result and result.structured_output %}
{% if export_card %}
<div class="stack">
<div class="detail-item">
<strong>Word 导出能力卡</strong>
<div>模板:{{ export_card.template_name }} / {{ export_card.template_version|default:"-" }}</div>
<div>当前导出状态:{{ export_card.export_status|default:"-" }}</div>
</div>
<div class="panel" style="padding: 14px;">
<h3 class="section-title" style="font-size: 1rem;">回填字段表</h3>
<div class="table-wrap">
<table class="data-table">
<thead>
<tr>
<th>占位符</th>
<th>字段名</th>
<th>字段值</th>
<th>来源</th>
<th>回填状态</th>
<th>是否必填</th>
</tr>
</thead>
<tbody>
{% for item in export_card.filled_fields %}
<tr>
<td>{{ item.placeholder }}</td>
<td>{{ item.field_name }}</td>
<td>{{ item.field_value }}</td>
<td>{{ item.source }}</td>
<td>{{ item.fill_status }}</td>
<td>{{ item.required|yesno:"是,否" }}</td>
</tr>
{% empty %}
<tr><td colspan="6">当前暂无回填字段。</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="panel" style="padding: 14px;">
<h3 class="section-title" style="font-size: 1rem;">拦截项区</h3>
<ul class="detail-list">
{% for item in export_card.blocked_fields %}
<li class="detail-item">
<strong>{{ item.field_name }}</strong>
<div>拦截原因:{{ item.block_reason }}</div>
<div class="muted">来源:{{ item.risk_source }}</div>
</li>
{% empty %}
<li class="detail-item">当前无拦截项。</li>
{% endfor %}
</ul>
</div>
<div class="button-row">
<a class="button" href="{% url 'platform_ui:knowledge-base' %}?view=template_mappings">维护 Word 模板</a>
<a class="button" href="{% url 'platform_ui:knowledge-base' %}?view=field_schemas">维护字段映射</a>
<a class="button" href="{% url 'audit:list' %}">查看导出记录</a>
</div>
</div>
{% elif result and result.structured_output %}
<table class="kv-table">
<tbody>
{% for key, value in result.structured_output.items %}

View File

@@ -433,6 +433,60 @@ def test_chat_page_uses_structured_formal_export_flag_when_node_status_is_comple
assert "/downloads/review-only.docx" in content
def test_chat_page_shows_word_export_field_table_and_governance_entries(client, db):
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_word_export_report",
"template_name": "注册证导出模板",
"template_version": "V1.0",
"export_status": "draft_only",
"filled_fields": [
{
"placeholder": "{{ product_name }}",
"field_name": "产品名称",
"field_value": "新型冠状病毒 2019-nCoV 核酸检测试剂盒",
"source": "资料包主信息",
"fill_status": "filled",
"required": True,
}
],
"blocked_fields": [
{
"field_name": "产品名称跨文档不一致",
"block_reason": "待人工复核",
"risk_source": "registration_risk_report",
}
],
"download_url": "/media/exports/20260604/SUB-20260604-001-draft.docx",
}
}
conversation.save(update_fields=["node_results", "latest_summary", "updated_at"])
response = client.get(reverse("chat:detail", args=[conversation.conversation_id]))
content = response.content.decode("utf-8")
assert response.status_code == 200
assert "Word 导出能力卡" in content
assert "回填字段表" in content
assert "产品名称" in content
assert "资料包主信息" in content
assert "拦截项区" in content
assert "产品名称跨文档不一致" in content
assert "维护 Word 模板" in content
assert "维护字段映射" in content
def test_chat_upload_keeps_existing_conversation_binding_and_adds_documents(client, db):
batch, conversation = _create_conversation_with_batch()
existing_document = UploadedDocument.objects.create(