style: 对齐审核智能体节点与信息卡原型

This commit is contained in:
2026-06-04 00:58:11 +08:00
parent cac9a4aaeb
commit b8381b3ba1
4 changed files with 105 additions and 6 deletions

View File

@@ -14,13 +14,23 @@ def create_conversation_for_batch(batch_id: str, product_name: str) -> Conversat
product_name=product_name, product_name=product_name,
batch_id=batch_id, batch_id=batch_id,
task_status=Conversation.STATUS_PENDING, task_status=Conversation.STATUS_PENDING,
node_results=[ node_results=_build_initial_node_results(),
{"code": "package_import", "label": "资料包导入", "status": "已完成"},
{"code": "overview", "label": "目录汇总", "status": "处理中"},
],
) )
return conversation return conversation
def _generate_conversation_id() -> str: def _generate_conversation_id() -> str:
return f"conv-{Conversation.objects.count() + 1:03d}" return f"conv-{Conversation.objects.count() + 1:03d}"
def _build_initial_node_results() -> list[dict]:
return [
{"code": "package_import", "label": "资料包导入", "status": "已完成"},
{"code": "overview", "label": "目录汇总", "status": "处理中"},
{"code": "completeness", "label": "法规完整性检查", "status": "待处理"},
{"code": "field_extraction", "label": "字段抽取", "status": "待处理"},
{"code": "consistency", "label": "一致性核查", "status": "待处理"},
{"code": "risk", "label": "风险预警", "status": "待处理"},
{"code": "word_export", "label": "Word 回填导出", "status": "待处理"},
{"code": "feishu_notify", "label": "飞书通知", "status": "待处理"},
]

View File

@@ -72,6 +72,7 @@ def detail(request, conversation_id: str):
) )
_persist_notification_records(result) _persist_notification_records(result)
active_node = "risk" active_node = "risk"
workspace_summary = _build_workspace_summary(conversation, batch)
return render( return render(
request, request,
@@ -88,6 +89,7 @@ def detail(request, conversation_id: str):
"task_modes": task_modes, "task_modes": task_modes,
"node_results": conversation.node_results, "node_results": conversation.node_results,
"active_node": active_node, "active_node": active_node,
"workspace_summary": workspace_summary,
}, },
) )
@@ -110,3 +112,20 @@ def _persist_notification_records(result: AgentResult) -> None:
web_detail_url="", web_detail_url="",
receipt={"status": result.status}, receipt={"status": result.status},
) )
def _build_workspace_summary(conversation: Conversation, batch: SubmissionBatch | None) -> dict:
node_status_map = {node.get("label"): node.get("status", "") for node in conversation.node_results}
risk_status = node_status_map.get("风险预警", "待处理")
notify_status = node_status_map.get("飞书通知", "待处理")
export_status = node_status_map.get("Word 回填导出", "待处理")
highest_risk_level = "" if risk_status in {"已阻断", "待复核"} else ""
export_allowed = "" if risk_status in {"已阻断", "待复核"} else ""
return {
"highest_risk_level": highest_risk_level,
"export_allowed": export_allowed,
"notify_status": notify_status,
"export_status": export_status,
"file_count": batch.file_count if batch else 0,
"page_count": batch.page_count if batch else 0,
}

View File

@@ -108,7 +108,7 @@
<div class="stack"> <div class="stack">
<article class="panel"> <article class="panel">
<h2 class="section-title">上传区</h2> <h2 class="section-title">上传区</h2>
<p class="section-copy">资料包导入入口在资料包页统一维护,当前会话只展示绑定关系</p> <p class="section-copy">右侧保留资料包上传入口和当前会话的资料上下文</p>
{% if batch %} {% if batch %}
<ul class="detail-list"> <ul class="detail-list">
<li class="detail-item"> <li class="detail-item">
@@ -120,6 +120,7 @@
</li> </li>
</ul> </ul>
<div class="button-row" style="margin-top: 16px;"> <div class="button-row" style="margin-top: 16px;">
<a class="button button-primary" href="{% url 'documents:upload' %}">继续上传资料</a>
<a class="button" href="{% url 'documents:list' %}">返回资料包</a> <a class="button" href="{% url 'documents:list' %}">返回资料包</a>
</div> </div>
{% else %} {% else %}
@@ -130,8 +131,23 @@
<article class="panel"> <article class="panel">
<h2 class="section-title">动态信息卡</h2> <h2 class="section-title">动态信息卡</h2>
<ul class="detail-list"> <ul class="detail-list">
<li class="detail-item">
<strong>最高风险等级</strong>
<div>{{ workspace_summary.highest_risk_level }}</div>
</li>
<li class="detail-item">
<strong>是否允许正式导出</strong>
<div>{{ workspace_summary.export_allowed }}</div>
</li>
<li class="detail-item">
<strong>通知状态</strong>
<div>{{ workspace_summary.notify_status }}</div>
</li>
<li class="detail-item">
<strong>导出状态</strong>
<div>{{ workspace_summary.export_status }}</div>
</li>
<li class="detail-item">当前会话围绕 `conversation_id / batch_id / product_name` 串联。</li> <li class="detail-item">当前会话围绕 `conversation_id / batch_id / product_name` 串联。</li>
<li class="detail-item">任务模式:目录汇总、完整性检查、字段抽取、一致性核查、风险预警。</li>
{% if audit_log %} {% if audit_log %}
<li class="detail-item"><a href="{% url 'audit:detail' audit_log.id %}">查看本次处理历史</a></li> <li class="detail-item"><a href="{% url 'audit:detail' audit_log.id %}">查看本次处理历史</a></li>
{% endif %} {% endif %}

View File

@@ -4,6 +4,7 @@ from agent_core.results import AgentResult
from apps.audit.models import AgentAuditLog from apps.audit.models import AgentAuditLog
from apps.audit.models import NotificationRecord from apps.audit.models import NotificationRecord
from apps.chat.models import Conversation from apps.chat.models import Conversation
from apps.chat.services import create_conversation_for_batch
from apps.documents.models import SubmissionBatch, UploadedDocument from apps.documents.models import SubmissionBatch, UploadedDocument
@@ -169,3 +170,56 @@ def test_chat_execution_creates_notification_record_from_agent_result(client, db
record = NotificationRecord.objects.get() record = NotificationRecord.objects.get()
assert record.notify_reason == "task_completed" assert record.notify_reason == "task_completed"
assert record.batch_id == batch.batch_id assert record.batch_id == batch.batch_id
def test_create_conversation_for_batch_initializes_eight_workflow_nodes(db):
conversation = create_conversation_for_batch(
"SUB-20260604-001",
"新型冠状病毒 2019-nCoV 核酸检测试剂盒",
)
labels = [node["label"] for node in conversation.node_results]
assert len(labels) == 8
assert labels == [
"资料包导入",
"目录汇总",
"法规完整性检查",
"字段抽取",
"一致性核查",
"风险预警",
"Word 回填导出",
"飞书通知",
]
def test_chat_page_shows_upload_entry_and_dynamic_context_cards(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.save(update_fields=["node_results"])
UploadedDocument.objects.create(
batch=batch,
scenario_id="document_review",
original_name="说明书.md",
file_type="md",
size=1,
status=UploadedDocument.STATUS_INDEXED,
)
response = client.get(reverse("chat:detail", args=[conversation.conversation_id]))
content = response.content.decode("utf-8")
assert response.status_code == 200
assert "继续上传资料" in content
assert "最高风险等级" in content
assert "是否允许正式导出" in content
assert "通知状态" in content
assert "飞书通知 / 待处理" in content