main.py 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. """压缩机 3D 部件查看服务(FastAPI)。
  2. 接口:
  3. GET /api/models 可用模型列表
  4. GET /api/state?model=x 读取配色状态
  5. POST /api/state?model=x 保存配色状态
  6. GET /models/<file> GLB / glTF 模型文件
  7. GET /* 前端构建产物(frontend/dist),SPA 回退 index.html
  8. """
  9. from fastapi import FastAPI, HTTPException
  10. from fastapi.middleware.cors import CORSMiddleware
  11. from fastapi.responses import FileResponse
  12. from config import FRONTEND_DIST
  13. from routers import alarms, fault_map, files, scenes, series, state
  14. app = FastAPI(title="压缩机 3D 部件查看服务", version="0.1.0")
  15. app.add_middleware(
  16. CORSMiddleware,
  17. allow_origins=["*"],
  18. allow_methods=["*"],
  19. allow_headers=["*"],
  20. )
  21. app.include_router(alarms.router)
  22. app.include_router(fault_map.router)
  23. app.include_router(files.router)
  24. app.include_router(scenes.router)
  25. app.include_router(series.router)
  26. app.include_router(state.router)
  27. @app.get("/{full_path:path}")
  28. def serve_frontend(full_path: str) -> FileResponse:
  29. if full_path.startswith(("api/", "models/")):
  30. raise HTTPException(status_code=404, detail="Not Found")
  31. resolved_dist = FRONTEND_DIST.resolve()
  32. if full_path:
  33. candidate = (FRONTEND_DIST / full_path).resolve()
  34. if resolved_dist in candidate.parents and candidate.is_file():
  35. return FileResponse(candidate)
  36. index = FRONTEND_DIST / "index.html"
  37. if index.is_file():
  38. return FileResponse(index)
  39. raise HTTPException(status_code=404, detail="前端未构建:请先 cd 3d/frontend && npm run build")