108 lines
3.8 KiB
Python
108 lines
3.8 KiB
Python
from django.contrib.auth.decorators import login_required
|
|
from django.http import Http404, JsonResponse
|
|
from django.views.decorators.http import require_http_methods
|
|
|
|
from review_agent.models import Conversation, FileAttachment
|
|
from review_agent.models import FileSummaryBatch, WorkflowEvent
|
|
from .events import serialize_event
|
|
|
|
from .storage import save_uploaded_attachment, serialize_attachment
|
|
|
|
|
|
def _conversation_for_user(user, conversation_id: int) -> Conversation:
|
|
conversation = Conversation.objects.filter(pk=conversation_id, user=user).first()
|
|
if not conversation:
|
|
raise Http404("对话不存在。")
|
|
return conversation
|
|
|
|
|
|
@require_http_methods(["POST", "GET"])
|
|
@login_required
|
|
def attachments(request, conversation_id: int):
|
|
conversation = _conversation_for_user(request.user, conversation_id)
|
|
|
|
if request.method == "POST":
|
|
files = request.FILES.getlist("files")
|
|
if not files:
|
|
return JsonResponse({"error": "请选择至少一个文件。"}, status=400)
|
|
saved = [
|
|
save_uploaded_attachment(
|
|
conversation=conversation,
|
|
user=request.user,
|
|
uploaded_file=uploaded_file,
|
|
)
|
|
for uploaded_file in files
|
|
]
|
|
return JsonResponse({"attachments": [serialize_attachment(item) for item in saved]})
|
|
|
|
queryset = FileAttachment.objects.filter(conversation=conversation).order_by(
|
|
"original_name",
|
|
"-version_no",
|
|
)
|
|
return JsonResponse({"attachments": [serialize_attachment(item) for item in queryset]})
|
|
|
|
|
|
@require_http_methods(["DELETE"])
|
|
@login_required
|
|
def attachment_detail(request, conversation_id: int, attachment_id: int):
|
|
conversation = _conversation_for_user(request.user, conversation_id)
|
|
attachment = FileAttachment.objects.filter(
|
|
pk=attachment_id,
|
|
conversation=conversation,
|
|
user=request.user,
|
|
).first()
|
|
if not attachment:
|
|
raise Http404("附件不存在。")
|
|
|
|
attachment.upload_status = FileAttachment.UploadStatus.DELETED
|
|
attachment.is_active = False
|
|
attachment.save(update_fields=["upload_status", "is_active"])
|
|
return JsonResponse({"ok": True, "attachment": serialize_attachment(attachment)})
|
|
|
|
|
|
@require_http_methods(["GET"])
|
|
@login_required
|
|
def batch_status(request, batch_id: int):
|
|
batch = FileSummaryBatch.objects.filter(pk=batch_id, user=request.user).first()
|
|
if not batch:
|
|
raise Http404("批次不存在。")
|
|
return JsonResponse(
|
|
{
|
|
"batch": {
|
|
"id": batch.pk,
|
|
"batch_no": batch.batch_no,
|
|
"status": batch.status,
|
|
"product_name": batch.product_name,
|
|
"total_files": batch.total_files,
|
|
"success_files": batch.success_files,
|
|
"failed_files": batch.failed_files,
|
|
"total_pages": batch.total_pages,
|
|
},
|
|
"nodes": [
|
|
{
|
|
"node_code": node.node_code,
|
|
"node_name": node.node_name,
|
|
"status": node.status,
|
|
"progress": node.progress,
|
|
"message": node.message,
|
|
}
|
|
for node in batch.node_runs.order_by("id")
|
|
],
|
|
}
|
|
)
|
|
|
|
|
|
@require_http_methods(["GET"])
|
|
@login_required
|
|
def batch_events(request, batch_id: int):
|
|
batch = FileSummaryBatch.objects.filter(pk=batch_id, user=request.user).first()
|
|
if not batch:
|
|
raise Http404("批次不存在。")
|
|
after = request.GET.get("after") or "0"
|
|
try:
|
|
after_id = int(after)
|
|
except ValueError:
|
|
after_id = 0
|
|
events = WorkflowEvent.objects.filter(batch=batch, pk__gt=after_id).order_by("id")
|
|
return JsonResponse({"events": [serialize_event(event) for event in events]})
|