diff --git a/apps/audit/models.py b/apps/audit/models.py index 7132245..b1b8749 100644 --- a/apps/audit/models.py +++ b/apps/audit/models.py @@ -99,3 +99,11 @@ class NotificationRecord(models.Model): def __str__(self) -> str: return f"{self.notify_reason}:{self.batch_id}" + + def get_message_status_display_text(self) -> str: + """返回通知状态的中文展示文案。""" + return { + self.STATUS_PENDING: "处理中", + self.STATUS_SENT: "已发送", + self.STATUS_FAILED: "失败", + }.get(self.message_status, self.message_status) diff --git a/apps/audit/services.py b/apps/audit/services.py index 6b805d4..3e395af 100644 --- a/apps/audit/services.py +++ b/apps/audit/services.py @@ -7,6 +7,36 @@ from .models import AgentAuditLog, NotificationRecord SUPPORTED_NOTIFY_REASONS = {"task_completed", "task_failed"} +RISK_STATUS_DISPLAY = { + "high": "已阻断", + "medium": "待复核", + "low": "已完成", + "failed": "失败", + "processing": "处理中", + "pending": "处理中", +} + +EXPORT_STATUS_DISPLAY = { + "completed": "已完成", + "draft_only": "待复核", + "review_required": "待复核", + "manual_review": "待复核", + "blocked": "已阻断", + "failed": "失败", + "processing": "处理中", + "pending": "处理中", +} + +CONVERSATION_STATUS_DISPLAY = { + "success": "已完成", + "completed": "已完成", + "review_required": "待复核", + "blocked": "已阻断", + "failed": "失败", + "processing": "处理中", + "pending": "处理中", +} + def create_audit_log( scenario_id: str, @@ -138,11 +168,15 @@ def build_history_rows(logs) -> list[dict]: "conversation": conversation, "batch_scale": f"{batch.file_count} 份 / {batch.page_count} 页" if batch else "-", "batch_status": batch.get_import_status_display_text() if batch else "-", - "conversation_status": conversation.task_status if conversation else "-", - "risk_status": structured_output.get("highest_risk_level") - or structured_output.get("risk_level") - or "-", - "notify_status": notification.message_status if notification else "-", + "conversation_status": _get_conversation_status_display_text( + conversation.task_status if conversation else "-" + ), + "risk_status": _get_risk_status_display_text( + structured_output.get("highest_risk_level") + or structured_output.get("risk_level") + or "-" + ), + "notify_status": notification.get_message_status_display_text() if notification else "-", "notify_reason": notification.notify_reason if notification else "-", } ) @@ -161,13 +195,13 @@ def build_history_metrics(history_rows: list[dict]) -> list[dict]: """ total_count = len(history_rows) success_count = sum(1 for row in history_rows if row["log"].status == "success") - notify_sent_count = sum(1 for row in history_rows if row.get("notify_status") == "sent") - blocked_count = sum(1 for row in history_rows if row.get("risk_status") == "high") + notify_sent_count = sum(1 for row in history_rows if row.get("notify_status") == "已发送") + blocked_count = sum(1 for row in history_rows if row.get("risk_status") == "已阻断") return [ {"label": "处理任务数", "value": total_count, "note": "按当前筛选条件回看执行留痕。"}, {"label": "成功执行", "value": success_count, "note": "执行完成并写入审计快照。"}, - {"label": "通知已发送", "value": notify_sent_count, "note": "已生成 sent 状态的通知留痕。"}, - {"label": "高风险阻断", "value": blocked_count, "note": "风险等级为 high 的处理记录。"}, + {"label": "通知已发送", "value": notify_sent_count, "note": "已生成已发送状态的通知留痕。"}, + {"label": "高风险阻断", "value": blocked_count, "note": "当前风险状态为已阻断的处理记录。"}, ] @@ -187,15 +221,33 @@ def build_detail_summary(log: AgentAuditLog, conversation, notifications) -> dic ) latest_notification = notifications.first() if hasattr(notifications, "first") else None return { - "export_status": structured_output.get("export_status") or (export_node or {}).get("status", "-"), + "export_status": _get_export_status_display_text( + structured_output.get("export_status") or (export_node or {}).get("status", "-") + ), "download_url": structured_output.get("download_url", ""), "output_file_name": output_file.get("file_name", ""), "output_file_relative_path": output_file.get("relative_path", ""), "export_mode": output_file.get("export_mode", ""), "template_name": structured_output.get("template_name", ""), "template_version": structured_output.get("template_version", ""), - "draft_export_status": structured_output.get("draft_export_status", ""), - "formal_export_status": structured_output.get("formal_export_status", ""), + "draft_export_status": _get_export_status_display_text( + structured_output.get("draft_export_status", "") + ), + "formal_export_status": _get_export_status_display_text( + structured_output.get("formal_export_status", "") + ), "blocked_items": structured_output.get("blocked_items") or [], "notification_receipt": latest_notification.receipt if latest_notification else {}, } + + +def _get_risk_status_display_text(status: str) -> str: + return RISK_STATUS_DISPLAY.get(status, status or "-") + + +def _get_export_status_display_text(status: str) -> str: + return EXPORT_STATUS_DISPLAY.get(status, status or "-") + + +def _get_conversation_status_display_text(status: str) -> str: + return CONVERSATION_STATUS_DISPLAY.get(status, status or "-") diff --git a/templates/audit/log_detail.html b/templates/audit/log_detail.html index e23020b..4b41e1a 100644 --- a/templates/audit/log_detail.html +++ b/templates/audit/log_detail.html @@ -100,7 +100,7 @@ {{ item.notify_reason }} {{ item.owner_role }} {{ item.feishu_user_id }} - {{ item.message_status }} + {{ item.get_message_status_display_text }} {{ item.web_detail_url|default:"-" }} {% empty %} diff --git a/templates/audit/log_list.html b/templates/audit/log_list.html index 51e1a0d..9fb72fa 100644 --- a/templates/audit/log_list.html +++ b/templates/audit/log_list.html @@ -35,17 +35,17 @@
@@ -117,7 +117,7 @@ - + {{ row.conversation_status }} @@ -126,7 +126,7 @@ {{ row.log.get_status_display_text }} - + {{ row.risk_status }} @@ -134,7 +134,7 @@ {{ row.notify_reason }} - + {{ row.notify_status }} diff --git a/tests/test_audit.py b/tests/test_audit.py index 3598eed..3510daa 100644 --- a/tests/test_audit.py +++ b/tests/test_audit.py @@ -249,9 +249,9 @@ def test_audit_list_shows_risk_and_notification_status(client, db): content = response.content.decode("utf-8") assert response.status_code == 200 assert "风险状态" in content - assert "high" in content + assert "已阻断" in content assert "通知状态" in content - assert "sent" in content + assert "已发送" in content assert "通知原因" in content assert "task_completed" in content @@ -414,7 +414,7 @@ def test_audit_list_shows_batch_scale_and_conversation_status(client, db): assert "资料规模" in content assert "4 份 / 26 页" in content assert "会话状态" in content - assert "failed" in content + assert "失败" in content assert "待复核" in content @@ -476,6 +476,8 @@ def test_audit_list_shows_history_metrics_and_context_links(client, db): assert reverse("chat:detail", args=["conv-009"]) in content assert f"{reverse('documents:list')}?keyword=SUB-20260604-009" in content assert f"{reverse('audit:list')}?keyword=产品C" in content + assert "已发送" in content + assert "待复核" in content def test_audit_detail_page_shows_export_summary_and_notification_receipt(client, db): @@ -525,11 +527,12 @@ def test_audit_detail_page_shows_export_summary_and_notification_receipt(client, content = response.content.decode("utf-8") assert response.status_code == 200 assert "导出状态摘要" in content - assert "draft_only" in content + assert "待复核" in content assert "/downloads/registration-report.docx" in content assert "风险项未清零" in content assert "通知回执" in content assert "msg-9" in content + assert "已发送" in content def test_audit_detail_page_shows_export_file_name_and_mode(client, db): @@ -578,3 +581,16 @@ def test_audit_detail_page_shows_export_file_name_and_mode(client, db): assert "draft" in content assert "模板版本" in content assert "V1.0" in content + assert "待复核" in content + + +def test_audit_list_uses_chinese_filter_labels_for_risk_and_notification_status(client, db): + response = client.get(reverse("audit:list")) + + 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