Files
qiji/backend/app/api/leaves.py
T

128 lines
4.0 KiB
Python

from uuid import UUID
from fastapi import APIRouter, Depends, Query, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
from app.middleware.auth import get_current_user
from app.schemas.leave import LeaveCreate, LeaveUpdate
from app.services import leaves as leave_service
router = APIRouter(prefix="/leaves", tags=["Leaves"])
@router.get("")
async def list_leaves(
manager_id: str | None = Query(None),
status: str | None = Query(None),
page: int = Query(1, ge=1),
page_size: int = Query(25, ge=1, le=100),
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
):
"""List leave records. Managers see only their own."""
return await leave_service.get_leaves(
db=db,
user_id=current_user["user_id"],
role=current_user["role"],
manager_id=manager_id,
status=status,
page=page,
page_size=page_size,
)
@router.post("")
async def create_leave(
data: LeaveCreate,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
):
"""Create a leave record. Director can create for anyone; manager only for self."""
try:
leave = await leave_service.create_leave(
db=db,
data=data.model_dump(),
submitted_by=UUID(current_user["user_id"]),
role=current_user["role"],
)
return {
"id": str(leave.id),
"manager_id": str(leave.manager_id),
"leave_type": leave.leave_type,
"start_date": str(leave.start_date),
"end_date": str(leave.end_date),
"reason": leave.reason,
"submitted_by": str(leave.submitted_by),
}
except PermissionError as e:
raise HTTPException(status_code=403, detail=str(e))
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
@router.put("/{leave_id}")
async def update_leave(
leave_id: UUID,
data: LeaveUpdate,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
):
"""Update a leave record."""
try:
leave = await leave_service.update_leave(
db=db,
leave_id=leave_id,
data=data.model_dump(exclude_none=True),
user_id=UUID(current_user["user_id"]),
role=current_user["role"],
)
return {
"id": str(leave.id),
"manager_id": str(leave.manager_id),
"leave_type": leave.leave_type,
"start_date": str(leave.start_date),
"end_date": str(leave.end_date),
"reason": leave.reason,
}
except PermissionError as e:
raise HTTPException(status_code=403, detail=str(e))
except ValueError as e:
raise HTTPException(status_code=404 if "不存在" in str(e) else 400, detail=str(e))
@router.delete("/{leave_id}")
async def delete_leave(
leave_id: UUID,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
):
"""Delete a leave record."""
try:
ok = await leave_service.delete_leave(
db=db,
leave_id=leave_id,
user_id=UUID(current_user["user_id"]),
role=current_user["role"],
)
if not ok:
raise HTTPException(status_code=404, detail="请假记录不存在")
return {"status": "deleted"}
except PermissionError as e:
raise HTTPException(status_code=403, detail=str(e))
@router.get("/overview")
async def leave_overview(
reference_date: str | None = Query(None),
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
):
"""Get weekly leave overview for dashboard card."""
from datetime import date
ref = date.fromisoformat(reference_date) if reference_date else None
return await leave_service.get_leave_overview(
db=db,
user_id=current_user["user_id"],
role=current_user["role"],
reference_date=ref,
)