From b8381b3ba16e0df5e65b3ed2acb7a72a06062e3b Mon Sep 17 00:00:00 2001 From: bruce Date: Thu, 4 Jun 2026 00:58:11 +0800 Subject: [PATCH] =?UTF-8?q?style:=20=E5=AF=B9=E9=BD=90=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E6=99=BA=E8=83=BD=E4=BD=93=E8=8A=82=E7=82=B9=E4=B8=8E=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E5=8D=A1=E5=8E=9F=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/chat/services.py | 18 ++++++++++--- apps/chat/views.py | 19 ++++++++++++++ templates/chat/index.html | 20 +++++++++++++-- tests/test_chat.py | 54 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 6 deletions(-) diff --git a/apps/chat/services.py b/apps/chat/services.py index 6df668a..2cd6e15 100644 --- a/apps/chat/services.py +++ b/apps/chat/services.py @@ -14,13 +14,23 @@ def create_conversation_for_batch(batch_id: str, product_name: str) -> Conversat product_name=product_name, batch_id=batch_id, task_status=Conversation.STATUS_PENDING, - node_results=[ - {"code": "package_import", "label": "资料包导入", "status": "已完成"}, - {"code": "overview", "label": "目录汇总", "status": "处理中"}, - ], + node_results=_build_initial_node_results(), ) return conversation def _generate_conversation_id() -> str: 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": "待处理"}, + ] diff --git a/apps/chat/views.py b/apps/chat/views.py index f6ab9ea..74d0f7d 100644 --- a/apps/chat/views.py +++ b/apps/chat/views.py @@ -72,6 +72,7 @@ def detail(request, conversation_id: str): ) _persist_notification_records(result) active_node = "risk" + workspace_summary = _build_workspace_summary(conversation, batch) return render( request, @@ -88,6 +89,7 @@ def detail(request, conversation_id: str): "task_modes": task_modes, "node_results": conversation.node_results, "active_node": active_node, + "workspace_summary": workspace_summary, }, ) @@ -110,3 +112,20 @@ def _persist_notification_records(result: AgentResult) -> None: web_detail_url="", 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, + } diff --git a/templates/chat/index.html b/templates/chat/index.html index fd9c617..270817a 100644 --- a/templates/chat/index.html +++ b/templates/chat/index.html @@ -108,7 +108,7 @@

上传区

-

资料包导入入口在资料包页统一维护,当前会话只展示绑定关系。

+

右侧保留资料包上传入口和当前会话的资料上下文。

{% if batch %}
  • @@ -120,6 +120,7 @@
{% else %} @@ -130,8 +131,23 @@

动态信息卡

    +
  • + 最高风险等级 +
    {{ workspace_summary.highest_risk_level }}
    +
  • +
  • + 是否允许正式导出 +
    {{ workspace_summary.export_allowed }}
    +
  • +
  • + 通知状态 +
    {{ workspace_summary.notify_status }}
    +
  • +
  • + 导出状态 +
    {{ workspace_summary.export_status }}
    +
  • 当前会话围绕 `conversation_id / batch_id / product_name` 串联。
  • -
  • 任务模式:目录汇总、完整性检查、字段抽取、一致性核查、风险预警。
  • {% if audit_log %}
  • 查看本次处理历史
  • {% endif %} diff --git a/tests/test_chat.py b/tests/test_chat.py index 5477878..e314a49 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -4,6 +4,7 @@ from agent_core.results import AgentResult from apps.audit.models import AgentAuditLog from apps.audit.models import NotificationRecord from apps.chat.models import Conversation +from apps.chat.services import create_conversation_for_batch 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() assert record.notify_reason == "task_completed" 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