feat: show feishu notification status
This commit is contained in:
@@ -11,6 +11,7 @@ from review_agent.application_form_fill.workflow import (
|
||||
start_application_form_fill_workflow,
|
||||
)
|
||||
from review_agent.models import ApplicationFormFillBatch, Conversation, ExportedSummaryFile, FileSummaryBatch, WorkflowNodeRun
|
||||
from review_agent.notifications.presenter import serialize_notification_records
|
||||
|
||||
|
||||
@require_http_methods(["GET"])
|
||||
@@ -75,6 +76,7 @@ def batch_status(request, batch_id: int):
|
||||
workflow_type="application_form_fill",
|
||||
workflow_batch_id=batch.pk,
|
||||
).order_by("id")
|
||||
notifications = serialize_notification_records("application_form_fill", batch.pk)
|
||||
return JsonResponse(
|
||||
{
|
||||
"batch": {
|
||||
@@ -112,6 +114,8 @@ def batch_status(request, batch_id: int):
|
||||
}
|
||||
for export in exports
|
||||
],
|
||||
"notifications": notifications,
|
||||
"latest_notification": notifications[0] if notifications else None,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ from django.views.decorators.http import require_http_methods
|
||||
|
||||
from review_agent.models import ApplicationFormFillBatch, Conversation, ExportedSummaryFile, FileAttachment, Message
|
||||
from review_agent.models import FileSummaryBatch, WorkflowEvent
|
||||
from review_agent.notifications.presenter import serialize_notification_records
|
||||
from .events import serialize_event
|
||||
from .paths import resolve_storage_path
|
||||
|
||||
@@ -225,6 +226,7 @@ def batch_status(request, batch_id: int):
|
||||
batch = FileSummaryBatch.objects.filter(pk=batch_id, user=request.user).first()
|
||||
if not batch:
|
||||
raise Http404("批次不存在。")
|
||||
notifications = serialize_notification_records("file_summary", batch.pk)
|
||||
return JsonResponse(
|
||||
{
|
||||
"batch": {
|
||||
@@ -249,6 +251,8 @@ def batch_status(request, batch_id: int):
|
||||
}
|
||||
for node in batch.node_runs.order_by("id")
|
||||
],
|
||||
"notifications": notifications,
|
||||
"latest_notification": notifications[0] if notifications else None,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
42
review_agent/notifications/presenter.py
Normal file
42
review_agent/notifications/presenter.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from review_agent.models import WorkflowNotificationRecord
|
||||
|
||||
|
||||
def get_notification_records(workflow_type: str, batch_id: int):
|
||||
return WorkflowNotificationRecord.objects.filter(
|
||||
workflow_type=workflow_type,
|
||||
workflow_batch_id=batch_id,
|
||||
).order_by("-created_at", "-id")
|
||||
|
||||
|
||||
def serialize_notification_record(record: WorkflowNotificationRecord) -> dict[str, object]:
|
||||
return {
|
||||
"id": record.pk,
|
||||
"channel": record.channel,
|
||||
"target": record.target,
|
||||
"receiver": record.at_display_name or record.target,
|
||||
"identifier_type": record.at_identifier_type,
|
||||
"identifier_masked": record.at_identifier_masked,
|
||||
"send_status": record.send_status,
|
||||
"status_label": notification_status_label(record),
|
||||
"sent_at": record.sent_at.isoformat() if record.sent_at else "",
|
||||
"created_at": record.created_at.isoformat(),
|
||||
"error_code": record.error_code,
|
||||
"error_message": record.error_message,
|
||||
}
|
||||
|
||||
|
||||
def serialize_notification_records(workflow_type: str, batch_id: int) -> list[dict[str, object]]:
|
||||
return [serialize_notification_record(record) for record in get_notification_records(workflow_type, batch_id)]
|
||||
|
||||
|
||||
def notification_status_label(record: WorkflowNotificationRecord) -> str:
|
||||
labels = {
|
||||
WorkflowNotificationRecord.SendStatus.SUCCESS: "飞书通知已发送",
|
||||
WorkflowNotificationRecord.SendStatus.FAILED: "飞书通知失败",
|
||||
WorkflowNotificationRecord.SendStatus.DISABLED: "飞书通知未启用",
|
||||
WorkflowNotificationRecord.SendStatus.SKIPPED_DUPLICATE: "飞书通知已跳过重复发送",
|
||||
WorkflowNotificationRecord.SendStatus.PENDING: "飞书通知待发送",
|
||||
}
|
||||
return labels.get(record.send_status, record.send_status)
|
||||
@@ -8,6 +8,7 @@ from django.views.decorators.http import require_http_methods
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from review_agent.models import FileSummaryBatch, RegulatoryReviewBatch, WorkflowNodeRun
|
||||
from review_agent.notifications.presenter import serialize_notification_records
|
||||
from review_agent.regulatory_review.events import record_event
|
||||
from review_agent.regulatory_review.services.info_extract import ensure_regulatory_condition_candidates
|
||||
from review_agent.regulatory_review.services.rectification_review import review_missing_issues
|
||||
@@ -25,6 +26,7 @@ def batch_status(request, batch_id: int):
|
||||
workflow_type="regulatory_review",
|
||||
workflow_batch_id=batch.pk,
|
||||
).order_by("id")
|
||||
notifications = serialize_notification_records("regulatory_review", batch.pk)
|
||||
payload = {
|
||||
"batch": {
|
||||
"id": batch.pk,
|
||||
@@ -46,6 +48,8 @@ def batch_status(request, batch_id: int):
|
||||
}
|
||||
for node in nodes
|
||||
],
|
||||
"notifications": notifications,
|
||||
"latest_notification": notifications[0] if notifications else None,
|
||||
}
|
||||
if batch.status == RegulatoryReviewBatch.Status.WAITING_USER and condition_candidates:
|
||||
payload["condition_confirmation"] = {
|
||||
|
||||
Reference in New Issue
Block a user