feat: add document file download and admin page file display
1. 新增将文档元数据存入L1向量库的功能 2. 新增文档文件下载API接口,支持路径安全校验 3. 后端文档详情接口新增文件信息返回字段 4. 管理后台页面新增原始文件信息展示与下载链接
This commit is contained in:
+28
-1
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user