"""MoKeeText — FastAPI 入口""" from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse, Response from logger import logger from middleware.user_context import UserContextMiddleware from routes.notes import router as notes_router from routes.websites import router as websites_router from routes.import_api import router as import_router from routes.share import router as share_router from routes.upload import router as upload_router app = FastAPI(title="MoKeeText", version="2.1.0") # CORS — 允许网关域名、前端域名、后端域名跨域 # 注意:allow_credentials=True 时不能使用 allow_origins=["*"] app.add_middleware( CORSMiddleware, allow_origins=[ "https://mokeetext.zgitm.com", "https://mokeetext.server.zgitm.com", # 分享页 + 图片直连 "https://gw.server.zgitm.com", "http://localhost:5173", ], allow_methods=["*"], allow_headers=["*"], allow_credentials=True, ) # 用户上下文中间件 — 在 CORS 之后注册,读取网关转发的 X-User-* 请求头 app.add_middleware(UserContextMiddleware) @app.on_event("startup") async def startup(): logger.info("MoKeeText 服务启动") @app.on_event("shutdown") async def shutdown(): logger.info("MoKeeText 服务关闭") # 请求日志中间件 @app.middleware("http") async def log_requests(request: Request, call_next): response = await call_next(request) logger.info(f"{request.method} {request.url.path} → {response.status_code}") return response # 静态文件 app.mount("/static", StaticFiles(directory="static"), name="static") # API 路由 app.include_router(notes_router) app.include_router(websites_router) app.include_router(import_router) app.include_router(share_router) app.include_router(upload_router) @app.get("/favicon.ico") async def favicon(): return FileResponse("static/favicon.ico") if __import__('os').path.exists("static/favicon.ico") else Response(status_code=204)