# -*- coding: utf-8 -*- """首页与静态资源。 - GET / 首页:优先服务 React 构建产物 frontend/dist/index.html; dist 未构建时回退旧版 templates/index.html(平滑过渡) - 静态资源由 Starlette StaticFiles 挂载 /assets 与 /static(见 web/app.py) """ from pathlib import Path from fastapi import APIRouter, Request from fastapi.responses import HTMLResponse router = APIRouter() _PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent _DIST_INDEX = _PROJECT_ROOT / 'frontend' / 'dist' / 'index.html' _LEGACY_TEMPLATE = _PROJECT_ROOT / 'templates' / 'index.html' def _render_index() -> str: """渲染首页 HTML:React 构建产物优先,缺失时回退旧模板。""" if _DIST_INDEX.is_file(): return _DIST_INDEX.read_text(encoding='utf-8') import jinja2 env = jinja2.Environment( loader=jinja2.FileSystemLoader(str(_LEGACY_TEMPLATE.parent)), autoescape=True, ) return env.get_template(_LEGACY_TEMPLATE.name).render() @router.get('/', response_class=HTMLResponse) async def index(request: Request) -> HTMLResponse: """首页(禁止缓存,确保前端更新即时生效)。""" return HTMLResponse( content=_render_index(), headers={'Cache-Control': 'no-cache, no-store, must-revalidate'}, )