51 lines
1.8 KiB
Python
51 lines
1.8 KiB
Python
import os
|
||
|
||
from fastapi import FastAPI, HTTPException
|
||
from fastapi.responses import FileResponse
|
||
from fastapi.staticfiles import StaticFiles
|
||
|
||
from plugin.base import Plugin
|
||
from uvicorn.server import logger
|
||
|
||
|
||
class SpaProxy(Plugin):
|
||
def __init__(self, app: FastAPI, dist: str = "dist"):
|
||
self.app = app
|
||
self.dist = dist
|
||
self.name = "SPA Proxy"
|
||
self.version = "1.0.0"
|
||
|
||
def install(self):
|
||
# --- [新增] 挂载前端静态文件 --
|
||
frontend_dir = os.path.join(os.getcwd(), self.dist)
|
||
if not os.path.isdir(frontend_dir):
|
||
return
|
||
|
||
# 1. 挂载静态资源(如 /assets/...)
|
||
assets_dir = os.path.join(frontend_dir, "assets")
|
||
if os.path.isdir(assets_dir):
|
||
self.app.mount("/assets", StaticFiles(directory=assets_dir), name="assets")
|
||
|
||
# 2. 【关键】兜底路由:处理所有未被 API 匹配的路径(支持前端路由如 /analysis)
|
||
@self.app.get("/{full_path:path}")
|
||
async def serve_frontend(full_path: str):
|
||
# 如果请求的是 API 路径,不应走到这里(因为 API 路由已先注册)
|
||
index_path = os.path.join(frontend_dir, "index.html")
|
||
if os.path.isfile(index_path):
|
||
return FileResponse(index_path)
|
||
raise HTTPException(status_code=404, detail="Frontend not found")
|
||
|
||
# 3. 显式处理根路径(可选,但更清晰)
|
||
@self.app.get("/")
|
||
async def root():
|
||
return await serve_frontend("")
|
||
|
||
# self.app.add_api_route(
|
||
# "/{full_path:path}",
|
||
# serve_frontend,
|
||
# methods=["GET"],
|
||
# response_class=FileResponse,
|
||
# )
|
||
|
||
logger.info(f"前端静态文件挂载: {frontend_dir} ✅")
|