22from sqlalchemy .ext .asyncio import AsyncSession
33from app .utils .get_db import get_db
44from app .schemas .articleDB import UploadArticle , GetArticle , DeLArticle , GetResponse
5- from app .curd .articleDB import create_article_in_db , get_article_in_db
6-
5+ from app .curd .articleDB import create_article_in_db , get_article_in_db , get_article_in_db_by_id
6+ from app .core .config import settings
7+ import os
8+ import uuid
9+ from fastapi .responses import FileResponse
10+ from urllib .parse import quote
711router = APIRouter ()
812
913@router .put ("/upload" , response_model = dict )
@@ -17,8 +21,19 @@ async def upload_article(
1721 """
1822 Upload an article to the database.
1923 """
24+ # 将文件保存到指定目录
25+ if not os .path .exists (settings .UPLOAD_FOLDER ):
26+ os .makedirs (settings .UPLOAD_FOLDER )
27+
28+ # 生成文件名,可以使用 UUID 或者其他方式来确保文件名唯一
29+ file_name = f"{ uuid .uuid4 ()} .pdf"
30+ file_path = os .path .join (settings .UPLOAD_FOLDER , file_name )
2031 try :
21- await create_article_in_db (db = db , upload_article = UploadArticle (title = title , author = author , url = url ))
32+ with open (file_path , "wb" ) as f :
33+ while chunk := await file .read (1024 ): # 每次读取 1024 字节
34+ f .write (chunk )
35+
36+ await create_article_in_db (db = db , upload_article = UploadArticle (title = title , author = author , url = url , file_path = file_path ))
2237 return {"msg" : "Article uploaded successfully" }
2338 except Exception as e :
2439 raise HTTPException (status_code = 500 , detail = str (e ))
@@ -36,4 +51,30 @@ async def get_article(get_article: GetArticle = Depends(), db: AsyncSession = De
3651 "total_count" : total_count
3752 },
3853 "articles" : [articles .model_dump () for articles in articles ]
39- }
54+ }
55+
56+ @router .get ("/download/{article_id}" , response_model = dict )
57+ async def download_article (article_id : int , db : AsyncSession = Depends (get_db )):
58+ """
59+ Download an article file by its ID.
60+ """
61+ # 根据 ID 查询文章信息
62+ article = await get_article_in_db_by_id (db = db , article_id = article_id )
63+ if not article or not article .file_path :
64+ raise HTTPException (status_code = 404 , detail = "File not found" )
65+
66+ if not os .path .exists (article .file_path ):
67+ raise HTTPException (status_code = 404 , detail = "File not found on server" )
68+
69+ # 从文件路径获取文件名
70+ file_name = os .path .basename (article .file_path )
71+
72+ # 设置原始文件名,如果有标题,使用标题作为文件名
73+ download_filename = f"{ article .title } .pdf" if article .title else file_name
74+
75+ # 返回文件,并设置文件名(使用 quote 处理中文文件名)
76+ return FileResponse (
77+ path = article .file_path ,
78+ filename = quote (download_filename ),
79+ media_type = "application/pdf"
80+ )
0 commit comments