from django.contrib import messages from django.shortcuts import get_object_or_404, redirect, render from django.views.decorators.http import require_POST from apps.scenarios.services import list_scenarios from .forms import DocumentUploadForm from .models import UploadedDocument from .services import create_uploaded_document, index_document def document_list(request): # 列表页只负责展示文档元数据和可执行操作,不处理入库细节。 documents = UploadedDocument.objects.all() status_counts = { "uploaded": documents.filter(status=UploadedDocument.STATUS_UPLOADED).count(), "indexed": documents.filter(status=UploadedDocument.STATUS_INDEXED).count(), "failed": documents.filter(status=UploadedDocument.STATUS_FAILED).count(), "total": documents.count(), } processing_pipeline = [ {"title": "原始文件接收", "detail": "校验格式、大小和场景归属后保存原件。"}, {"title": "文本与表格抽取", "detail": "按 PDF / DOCX / MD / TXT 使用不同解析策略。"}, {"title": "页数统计与可信度评估", "detail": "对 Word 页数采用估算与可信度标记。"}, {"title": "章节点归类", "detail": "基于文件名、标题和正文线索识别 CH 节点。"}, {"title": "切片与索引入库", "detail": "生成知识切片,供 RAG、规则定位和审计引用使用。"}, ] exception_items = [ {"level": "待确认", "title": "CH1.2 监管信息目录.docx", "detail": "目录页码与正文页数存在偏差,建议人工复核。"}, {"level": "低可信度", "title": "目标产品说明书.docx", "detail": "Word 页数为估算值,表格抽取质量良好。"}, {"level": "失败", "title": "沟通记录扫描件.pdf", "detail": "疑似扫描件,需补做 OCR 或重新上传清晰版。"}, ] return render( request, "documents/document_list.html", { "documents": documents, "status_counts": status_counts, "processing_pipeline": processing_pipeline, "exception_items": exception_items, }, ) def upload(request): # 上传成功后仅保存文件和元数据,是否入库由用户显式触发。 if request.method == "POST": form = DocumentUploadForm(request.POST, request.FILES) if form.is_valid(): create_uploaded_document(form.cleaned_data["scenario_id"], form.cleaned_data["file"]) messages.success(request, "文件已上传,可继续执行入库。") return redirect("documents:list") else: form = DocumentUploadForm() return render( request, "documents/upload.html", { "form": form, "scenarios": list_scenarios(), "upload_checks": [ "文件格式支持 PDF、DOCX、MD、TXT", "业务资料与法规依据资料需分开归属", "目录类文件会优先参与完整性校验", "上传完成后建议立即进入解析与入库流程", ], }, ) @require_POST def index(request, document_id: int): document = get_object_or_404(UploadedDocument, pk=document_id) document = index_document(document) if document.status == UploadedDocument.STATUS_INDEXED: messages.success(request, "文档入库成功,当前文档已可参与检索。") else: messages.error(request, "文档入库失败,请检查错误原因后重试。") return redirect("documents:list")