"""压缩机 3D 部件查看服务(FastAPI)。 接口: GET /api/models 可用模型列表 GET /api/state?model=x 读取配色状态 POST /api/state?model=x 保存配色状态 GET /models/ GLB / glTF 模型文件 GET /* 前端构建产物(frontend/dist),SPA 回退 index.html """ from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse from config import FRONTEND_DIST from routers import alarms, fault_map, files, scenes, series, state app = FastAPI(title="压缩机 3D 部件查看服务", version="0.1.0") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) app.include_router(alarms.router) app.include_router(fault_map.router) app.include_router(files.router) app.include_router(scenes.router) app.include_router(series.router) app.include_router(state.router) @app.get("/{full_path:path}") def serve_frontend(full_path: str) -> FileResponse: if full_path.startswith(("api/", "models/")): raise HTTPException(status_code=404, detail="Not Found") resolved_dist = FRONTEND_DIST.resolve() if full_path: candidate = (FRONTEND_DIST / full_path).resolve() if resolved_dist in candidate.parents and candidate.is_file(): return FileResponse(candidate) index = FRONTEND_DIST / "index.html" if index.is_file(): return FileResponse(index) raise HTTPException(status_code=404, detail="前端未构建:请先 cd 3d/frontend && npm run build")