2187be7aeb
本次累积提交包含以下功能: 1. 修复:el-date-picker 缺失 value-format 导致日期保存偏移(8处) 2. 新增:协同拜访 visit_group_id 去重机制(完整副本 + 周报合并 + 亮灯去重) 3. 新增:计划自动完成(创建计划检测已有拜访 / 编辑拜访触发) 4. 新增:拜访表单选择客户后自动预填过期计划内容 5. 新增:移动端主题切换按钮 + 后端持久化 6. 新增:操作日志系统 (audit_logs),全覆盖 8 个模块 CRUD 7. 新增:PC端「我的数据」支局长/领导视角客户经理列 Co-Authored-By: Claude <noreply@anthropic.com>
131 lines
4.1 KiB
Python
131 lines
4.1 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"],
|
|
operator_name=current_user["name"],
|
|
)
|
|
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"],
|
|
operator_name=current_user["name"],
|
|
)
|
|
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"],
|
|
operator_name=current_user["name"],
|
|
)
|
|
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,
|
|
)
|