"""应用入口:FastAPI 装配、异常处理、静态资源挂载、开发服务器。""" from pathlib import Path from fastapi import FastAPI, Request from fastapi.exceptions import RequestValidationError from fastapi.staticfiles import StaticFiles from huamenchuang.api.router import api_router from huamenchuang.core.database import init_db from huamenchuang.core.deps import ModuleLockedError, NotAuthedError from huamenchuang.core.response import fail, ok, paywall app = FastAPI(title="华门窗云平台", version="0.1.0") @app.on_event("startup") async def startup() -> None: await init_db() @app.exception_handler(NotAuthedError) async def auth_handler(request: Request, exc: NotAuthedError): return _json({"code": 401, "message": str(exc), "data": "", "other_data": "", "other_data2": ""}) @app.exception_handler(ModuleLockedError) async def module_locked_handler(request: Request, exc: ModuleLockedError): return _json(paywall(exc.module)) @app.exception_handler(RequestValidationError) async def validation_handler(request: Request, exc: RequestValidationError): """参数校验失败 → 422 语义 envelope(列出字段,不泄漏内部细节)。""" fields = [f"{'.'.join(str(x) for x in e['loc'][1:])}" for e in exc.errors()] return _json(fail(f"参数错误: {', '.join(fields)}")) @app.exception_handler(Exception) async def unhandled_handler(request: Request, exc: Exception): """兜底异常:统一 500 envelope(不回栈信息)。""" return _json(fail("服务器内部错误,请稍后再试")) def _json(payload: dict): from fastapi.responses import JSONResponse return JSONResponse(payload) @api_router.get("/health", tags=["系统"]) async def health(): return ok(data={"status": "up"}, message="ok") app.include_router(api_router) # 静态资源:样板平面图(data/windoor-images) _imgdir = Path(__file__).resolve().parents[2] / "data" / "windoor-images" if _imgdir.exists(): app.mount("/static/windoor-images", StaticFiles(directory=str(_imgdir)), name="windoor-images") # 前端构建产物挂载(前后端规范:构建到后端目录) _dist = Path(__file__).resolve().parents[2] / "frontend" / "dist" if _dist.exists(): app.mount("/", StaticFiles(directory=str(_dist), html=True), name="frontend") def main() -> None: import uvicorn uvicorn.run("huamenchuang.main:app", host="0.0.0.0", port=8000, reload=True) if __name__ == "__main__": main()