refactor: 下沉处理历史筛选到 audit 服务层
This commit is contained in:
@@ -133,6 +133,53 @@ def create_notification_record(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def build_history_list_context(
|
||||||
|
*,
|
||||||
|
scenario_id: str = "",
|
||||||
|
keyword: str = "",
|
||||||
|
notify_status: str = "",
|
||||||
|
risk_status: str = "",
|
||||||
|
) -> dict:
|
||||||
|
"""
|
||||||
|
组装处理历史列表页所需的筛选结果与展示上下文。
|
||||||
|
|
||||||
|
View 只负责读取 query params,筛选逻辑和列表聚合统一在服务层完成。
|
||||||
|
"""
|
||||||
|
logs = AgentAuditLog.objects.all()
|
||||||
|
if scenario_id:
|
||||||
|
logs = logs.filter(scenario_id=scenario_id)
|
||||||
|
if keyword:
|
||||||
|
logs = logs.filter(product_name__icontains=keyword) | logs.filter(batch_id__icontains=keyword)
|
||||||
|
if notify_status:
|
||||||
|
matched_pairs = list(
|
||||||
|
NotificationRecord.objects.filter(message_status=notify_status).values_list(
|
||||||
|
"batch_id",
|
||||||
|
"conversation_id",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
logs = [
|
||||||
|
log
|
||||||
|
for log in logs
|
||||||
|
if (log.batch_id, log.conversation_id) in matched_pairs
|
||||||
|
]
|
||||||
|
if risk_status:
|
||||||
|
logs = [
|
||||||
|
log
|
||||||
|
for log in logs
|
||||||
|
if (log.structured_output or {}).get("highest_risk_level") == risk_status
|
||||||
|
or (log.structured_output or {}).get("risk_level") == risk_status
|
||||||
|
]
|
||||||
|
history_rows = build_history_rows(logs)
|
||||||
|
return {
|
||||||
|
"history_rows": history_rows,
|
||||||
|
"history_metrics": build_history_metrics(history_rows),
|
||||||
|
"selected_scenario_id": scenario_id,
|
||||||
|
"keyword": keyword,
|
||||||
|
"notify_status": notify_status,
|
||||||
|
"risk_status": risk_status,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def build_history_rows(logs) -> list[dict]:
|
def build_history_rows(logs) -> list[dict]:
|
||||||
"""
|
"""
|
||||||
为处理历史列表补齐风险状态和通知状态。
|
为处理历史列表补齐风险状态和通知状态。
|
||||||
|
|||||||
@@ -4,55 +4,20 @@ from .models import AgentAuditLog, NotificationRecord
|
|||||||
from apps.chat.models import Conversation
|
from apps.chat.models import Conversation
|
||||||
from .services import (
|
from .services import (
|
||||||
build_detail_summary,
|
build_detail_summary,
|
||||||
build_history_metrics,
|
build_history_list_context,
|
||||||
build_history_rows,
|
|
||||||
normalize_conversation_node_results,
|
normalize_conversation_node_results,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def log_list(request):
|
def log_list(request):
|
||||||
# 处理历史页支持按批次、产品和状态筛选。
|
# 处理历史页支持按批次、产品和状态筛选。
|
||||||
scenario_id = (request.GET.get("scenario_id") or "").strip()
|
context = build_history_list_context(
|
||||||
keyword = (request.GET.get("keyword") or "").strip()
|
scenario_id=(request.GET.get("scenario_id") or "").strip(),
|
||||||
notify_status = (request.GET.get("notify_status") or "").strip()
|
keyword=(request.GET.get("keyword") or "").strip(),
|
||||||
risk_status = (request.GET.get("risk_status") or "").strip()
|
notify_status=(request.GET.get("notify_status") or "").strip(),
|
||||||
logs = AgentAuditLog.objects.all()
|
risk_status=(request.GET.get("risk_status") or "").strip(),
|
||||||
if scenario_id:
|
|
||||||
logs = logs.filter(scenario_id=scenario_id)
|
|
||||||
if keyword:
|
|
||||||
logs = logs.filter(product_name__icontains=keyword) | logs.filter(batch_id__icontains=keyword)
|
|
||||||
if notify_status:
|
|
||||||
matched_pairs = list(
|
|
||||||
NotificationRecord.objects.filter(message_status=notify_status).values_list(
|
|
||||||
"batch_id",
|
|
||||||
"conversation_id",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
logs = [
|
|
||||||
log
|
|
||||||
for log in logs
|
|
||||||
if (log.batch_id, log.conversation_id) in matched_pairs
|
|
||||||
]
|
|
||||||
if risk_status:
|
|
||||||
logs = [
|
|
||||||
log
|
|
||||||
for log in logs
|
|
||||||
if (log.structured_output or {}).get("highest_risk_level") == risk_status
|
|
||||||
or (log.structured_output or {}).get("risk_level") == risk_status
|
|
||||||
]
|
|
||||||
history_rows = build_history_rows(logs)
|
|
||||||
return render(
|
|
||||||
request,
|
|
||||||
"audit/log_list.html",
|
|
||||||
{
|
|
||||||
"history_rows": history_rows,
|
|
||||||
"history_metrics": build_history_metrics(history_rows),
|
|
||||||
"selected_scenario_id": scenario_id,
|
|
||||||
"keyword": keyword,
|
|
||||||
"notify_status": notify_status,
|
|
||||||
"risk_status": risk_status,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
return render(request, "audit/log_list.html", context)
|
||||||
|
|
||||||
|
|
||||||
def log_detail(request, log_id: int):
|
def log_detail(request, log_id: int):
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from django.urls import reverse
|
|||||||
|
|
||||||
from agent_core.results import AgentResult
|
from agent_core.results import AgentResult
|
||||||
from apps.audit.models import AgentAuditLog, DemoBusinessRecord, NotificationRecord
|
from apps.audit.models import AgentAuditLog, DemoBusinessRecord, NotificationRecord
|
||||||
from apps.audit.services import create_audit_log, create_notification_record
|
from apps.audit.services import build_history_list_context, create_audit_log, create_notification_record
|
||||||
from apps.chat.models import Conversation
|
from apps.chat.models import Conversation
|
||||||
from apps.documents.models import SubmissionBatch
|
from apps.documents.models import SubmissionBatch
|
||||||
from agent_core.tools.builtin_tools import query_demo_records
|
from agent_core.tools.builtin_tools import query_demo_records
|
||||||
@@ -344,6 +344,71 @@ def test_audit_list_can_filter_by_risk_status(client, db):
|
|||||||
assert "产品B" not in content
|
assert "产品B" not in content
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_history_list_context_filters_by_keyword_notify_and_risk(db):
|
||||||
|
create_audit_log(
|
||||||
|
"document_review",
|
||||||
|
"注册审核智能体",
|
||||||
|
"问题一",
|
||||||
|
AgentResult(
|
||||||
|
answer="回答一",
|
||||||
|
status="success",
|
||||||
|
structured_output={"highest_risk_level": "high"},
|
||||||
|
),
|
||||||
|
batch_id="SUB-20260604-011",
|
||||||
|
conversation_id="conv-011",
|
||||||
|
product_name="产品A",
|
||||||
|
)
|
||||||
|
create_audit_log(
|
||||||
|
"document_review",
|
||||||
|
"注册审核智能体",
|
||||||
|
"问题二",
|
||||||
|
AgentResult(
|
||||||
|
answer="回答二",
|
||||||
|
status="success",
|
||||||
|
structured_output={"highest_risk_level": "low"},
|
||||||
|
),
|
||||||
|
batch_id="SUB-20260604-012",
|
||||||
|
conversation_id="conv-012",
|
||||||
|
product_name="产品B",
|
||||||
|
)
|
||||||
|
create_notification_record(
|
||||||
|
batch_id="SUB-20260604-011",
|
||||||
|
conversation_id="conv-011",
|
||||||
|
product_name="产品A",
|
||||||
|
trigger_source="risk_report",
|
||||||
|
notify_reason="task_completed",
|
||||||
|
owner_role="注册资料负责人",
|
||||||
|
feishu_user_id="ou_demo_11",
|
||||||
|
message_status="sent",
|
||||||
|
web_detail_url="https://example.com/detail/11",
|
||||||
|
receipt={"message_id": "msg-11"},
|
||||||
|
)
|
||||||
|
create_notification_record(
|
||||||
|
batch_id="SUB-20260604-012",
|
||||||
|
conversation_id="conv-012",
|
||||||
|
product_name="产品B",
|
||||||
|
trigger_source="risk_report",
|
||||||
|
notify_reason="task_failed",
|
||||||
|
owner_role="注册资料负责人",
|
||||||
|
feishu_user_id="ou_demo_12",
|
||||||
|
message_status="failed",
|
||||||
|
web_detail_url="https://example.com/detail/12",
|
||||||
|
receipt={"message_id": "msg-12"},
|
||||||
|
)
|
||||||
|
|
||||||
|
context = build_history_list_context(
|
||||||
|
keyword="产品A",
|
||||||
|
notify_status="sent",
|
||||||
|
risk_status="high",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert context["keyword"] == "产品A"
|
||||||
|
assert context["notify_status"] == "sent"
|
||||||
|
assert context["risk_status"] == "high"
|
||||||
|
assert len(context["history_rows"]) == 1
|
||||||
|
assert context["history_rows"][0]["log"].product_name == "产品A"
|
||||||
|
|
||||||
|
|
||||||
def test_audit_detail_page_shows_conversation_node_results(client, db):
|
def test_audit_detail_page_shows_conversation_node_results(client, db):
|
||||||
Conversation.objects.create(
|
Conversation.objects.create(
|
||||||
conversation_id="conv-001",
|
conversation_id="conv-001",
|
||||||
|
|||||||
Reference in New Issue
Block a user