Files
hci_work/backend/app/main.py
T
2026-06-06 23:54:11 +08:00

97 lines
3.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from __future__ import annotations
import logging
from fastapi import FastAPI, HTTPException, Request
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from fastapi.staticfiles import StaticFiles
from app.api.routes_admin import router as admin_router
from app.api.routes_auth import router as auth_router
from app.api.routes_student import router as student_router
from app.core.database import get_connection
from app.core.settings import FRONTEND_ORIGINS, UPLOADS_DIR, ensure_runtime_dirs
from app.services.repository import init_db
logger = logging.getLogger(__name__)
ERROR_DETAIL_MAP: dict[str, str] = {
"missing_token": "缺少认证令牌",
"invalid_token": "认证已过期,请重新登录",
"invalid_credentials": "用户名或密码错误",
"student_only": "此功能仅限学生使用",
"admin_only": "此功能仅限管理员使用",
"order_not_found": "工单不存在或已被删除",
"session_not_found": "诊断会话已过期,请重新描述故障",
"order_not_completed": "维修尚未完成,无法执行此操作",
"order_not_ready_for_feedback": "当前状态不可评价",
"order_cannot_cancel": "当前状态无法取消,仅已提交或待处理的工单可取消",
"order_not_in_rework": "当前工单不在返工申请状态",
"unsupported_file_type": "仅支持上传图片文件(jpg, png, gif, webp",
"file_too_large": "文件大小超过限制(最大10MB",
"validation_error": "请求参数有误",
}
ensure_runtime_dirs()
with get_connection() as conn:
init_db(conn)
conn.execute("DELETE FROM sessions WHERE expires_at < datetime('now')")
conn.commit()
app = FastAPI(title="Dorm Repair API", version="0.1.0")
app.add_middleware(
CORSMiddleware,
allow_origins=FRONTEND_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(auth_router)
app.include_router(student_router)
app.include_router(admin_router)
app.mount("/uploads", StaticFiles(directory=UPLOADS_DIR), name="uploads")
@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
error_code = str(exc.detail) if not isinstance(exc.detail, dict) else exc.detail.get("error_code", str(exc.detail))
detail = ERROR_DETAIL_MAP.get(error_code, str(exc.detail))
return JSONResponse(
status_code=exc.status_code,
content={"detail": detail, "error_code": error_code},
)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError) -> JSONResponse:
return JSONResponse(
status_code=422,
content={"detail": "请求参数有误", "error_code": "validation_error"},
)
@app.exception_handler(Exception)
async def unhandled_exception_handler(request: Request, exc: Exception) -> JSONResponse:
logger.exception("Unhandled exception: %s", exc)
return JSONResponse(
status_code=500,
content={"detail": "服务器内部错误", "error_code": "internal_error"},
)
@app.on_event("shutdown")
async def shutdown() -> None:
from app.services.diagnosis import close_diagnosis_provider
await close_diagnosis_provider()
@app.get("/api/health")
def health() -> dict[str, str]:
return {"status": "ok"}