Files
2026-07-17 09:24:47 +08:00

38 lines
1.3 KiB
Python

"""将 Vue 前端构建产物挂载到 FastAPI,实现单端口 Web 访问。"""
from pathlib import Path
from fastapi import FastAPI, HTTPException
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
def mount_frontend(app: FastAPI, static_dir: Path) -> bool:
"""挂载 frontend/dist。成功返回 True,目录不存在返回 False。"""
static_dir = static_dir.resolve()
index = static_dir / "index.html"
if not index.is_file():
return False
assets_dir = static_dir / "assets"
if assets_dir.is_dir():
app.mount("/assets", StaticFiles(directory=assets_dir), name="assets")
@app.get("/", include_in_schema=False)
async def serve_index():
return FileResponse(index)
@app.get("/{filename}", include_in_schema=False)
async def serve_root_static(filename: str):
if filename.startswith("api") or filename in ("docs", "redoc", "openapi.json"):
raise HTTPException(status_code=404, detail="Not Found")
file_path = (static_dir / filename).resolve()
try:
file_path.relative_to(static_dir)
except ValueError:
raise HTTPException(status_code=404, detail="Not Found")
if file_path.is_file():
return FileResponse(file_path)
return FileResponse(index)
return True