import os from pathlib import Path from apiflask import APIBlueprint from flask import abort, current_app, send_from_directory bp = APIBlueprint("front", __name__, tag="前端") def _get_frontend_path(): frontend_path = current_app.config.get("FRONTEND_PATH") if not frontend_path: abort(404) path = Path(frontend_path) if not path.is_absolute(): base_dir = Path(current_app.config.get("BASE_DIR", os.getcwd())) path = base_dir / path return path.resolve() @bp.get("/") def index(): """渲染前端 SPA 入口页面""" frontend_path = _get_frontend_path() index_path = frontend_path / "index.html" if not index_path.exists(): abort(404) return send_from_directory(frontend_path, "index.html") @bp.get("/") def fallback(fallback): """兜底: 避免history模式下的影响""" frontend_path = _get_frontend_path() target_path = frontend_path / fallback if target_path.exists() and target_path.is_file(): return send_from_directory(frontend_path, fallback) index_path = frontend_path / "index.html" if not index_path.exists(): abort(404) return send_from_directory(frontend_path, "index.html")