feat: add document file download and admin page file display

1. 新增将文档元数据存入L1向量库的功能
2. 新增文档文件下载API接口,支持路径安全校验
3. 后端文档详情接口新增文件信息返回字段
4. 管理后台页面新增原始文件信息展示与下载链接
This commit is contained in:
2026-07-31 22:46:13 +08:00
parent 92b062c048
commit e2e8e6829d
4 changed files with 105 additions and 4 deletions
+28 -1
View File
@@ -8,7 +8,7 @@ from typing import Any
import structlog
from fastapi import APIRouter, Depends, File, Form, Query, UploadFile
from fastapi.responses import JSONResponse
from fastapi.responses import FileResponse, JSONResponse
from app.api.deps import get_current_user
from app.api.response import ApiError, ok
@@ -219,6 +219,33 @@ async def get_document(doc_id: str) -> dict[str, Any]:
return ok(detail)
@router.get("/documents/{doc_id}/file")
async def download_document_file(doc_id: str) -> FileResponse:
"""下载文档关联的原始文件(免登录)
从 L1 metadata 读取 raw_file_path,校验路径位于 upload_dir 之内后返回 FileResponse
文档不存在 / 无关联文件 / 文件缺失 / 路径越界统一返回 1004。
"""
meta = await _get_qdrant().get_l1_metadata(doc_id)
if not meta:
raise ApiError(1004, "文档不存在或未关联文件")
raw_path = meta.get("raw_file_path", "")
if not raw_path:
raise ApiError(1004, "文档未关联文件")
path = Path(raw_path).resolve()
# 路径越界校验:只允许读取 upload_dir 下的文件
try:
upload_dir = Path(settings.upload_dir).resolve()
path.relative_to(upload_dir)
except ValueError:
logger.warning("文件路径越界", doc_id=doc_id, raw_path=raw_path)
raise ApiError(1004, "文件不存在") from None
if not path.is_file():
raise ApiError(1004, "文件不存在")
filename = meta.get("original_filename", path.name)
return FileResponse(path, filename=filename)
@router.delete("/documents/{doc_id}")
async def delete_document(
doc_id: str, user: UserRecord = Depends(get_current_user)