""" 文件服务路由 (图片、下载等) """ import logging from pathlib import Path from fastapi import APIRouter, HTTPException, status from fastapi.responses import FileResponse from app.core.config import settings logger = logging.getLogger(__name__) router = APIRouter() @router.get("/image/{filename}", summary="获取图片文件") async def serve_image(filename: str): """ 获取可视化图片文件 """ try: file_path = settings.get_upload_path(filename) if not file_path.exists(): logger.error(f"图片未找到: {filename}") raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="图片未找到" ) logger.info(f"提供图片: {filename}") return FileResponse( path=str(file_path), media_type='image/png', filename=filename ) except HTTPException: raise except Exception as e: logger.error(f"获取图片异常: {str(e)}", exc_info=True) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e) ) @router.get("/download/{filename}", summary="下载文件") async def download_file(filename: str): """ 下载报告或其他文件 """ try: file_path = settings.get_upload_path(filename) if not file_path.exists(): logger.error(f"文件未找到: {filename}") raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="文件未找到" ) logger.info(f"下载文件: {filename}") return FileResponse( path=str(file_path), filename=filename, media_type='application/octet-stream' ) except HTTPException: raise except Exception as e: logger.error(f"下载文件异常: {str(e)}", exc_info=True) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e) ) @router.get("/list_uploads", summary="列出上传的文件") async def list_uploads(): """ 列出 uploads 目录中的文件 """ try: uploads_dir = settings.UPLOAD_DIR if not uploads_dir.exists(): return { "success": True, "files": [] } files = [] for file_path in uploads_dir.iterdir(): if file_path.is_file(): files.append({ "name": file_path.name, "size": file_path.stat().st_size, "modified": file_path.stat().st_mtime }) logger.info(f"列出 {len(files)} 个文件") return { "success": True, "files": sorted(files, key=lambda x: x['modified'], reverse=True) } except Exception as e: logger.error(f"列出文件异常: {str(e)}", exc_info=True) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e) )