""" API路由 - 工资核算管理 """ from typing import Annotated, Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.core.security import get_current_active_user, get_current_manager_user from app.schemas.schemas import ( SalaryRecordCreate, SalaryRecordUpdate, SalaryRecordResponse, ResponseBase ) from app.services.salary_service import SalaryService from app.models.models import User router = APIRouter(prefix="/salary", tags=["工资核算"]) @router.get("", summary="获取工资记录列表") async def get_salary_records( staff_id: Optional[int] = Query(None, description="员工ID"), department_id: Optional[int] = Query(None, description="科室ID"), period_year: Optional[int] = Query(None, description="年度"), period_month: Optional[int] = Query(None, description="月份"), status: Optional[str] = Query(None, description="状态"), page: int = Query(1, ge=1, description="页码"), page_size: int = Query(20, ge=1, le=100, description="每页数量"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取工资记录列表""" records, total = await SalaryService.get_list( db, staff_id, department_id, period_year, period_month, status, page, page_size ) result = [] for record in records: item = SalaryRecordResponse.model_validate(record).model_dump() item["staff_name"] = record.staff.name if record.staff else None item["department_name"] = record.staff.department.name if record.staff and record.staff.department else None result.append(item) return { "code": 200, "message": "success", "data": result, "total": total, "page": page, "page_size": page_size } @router.get("/{record_id}", summary="获取工资记录详情") async def get_salary_record( record_id: int, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """获取工资记录详情""" record = await SalaryService.get_by_id(db, record_id) if not record: raise HTTPException(status_code=404, detail="工资记录不存在") result = SalaryRecordResponse.model_validate(record).model_dump() result["staff_name"] = record.staff.name if record.staff else None result["department_name"] = record.staff.department.name if record.staff and record.staff.department else None return {"code": 200, "message": "success", "data": result} @router.post("", summary="创建工资记录") async def create_salary_record( record_data: SalaryRecordCreate, db: AsyncSession = Depends(get_db), current_user: Annotated[User, Depends(get_current_manager_user)] = None ): """创建工资记录(需要管理员或经理权限)""" record = await SalaryService.create(db, record_data) return {"code": 200, "message": "创建成功", "data": {"id": record.id}} @router.put("/{record_id}", summary="更新工资记录") async def update_salary_record( record_id: int, record_data: SalaryRecordUpdate, db: AsyncSession = Depends(get_db), current_user: Annotated[User, Depends(get_current_manager_user)] = None ): """更新工资记录(需要管理员或经理权限)""" record = await SalaryService.update(db, record_id, record_data) if not record: raise HTTPException(status_code=400, detail="无法更新,记录不存在或状态不允许") return {"code": 200, "message": "更新成功", "data": {"id": record.id}} @router.post("/generate", summary="根据考核生成工资") async def generate_salary( staff_id: int = Query(..., description="员工ID"), period_year: int = Query(..., description="年度"), period_month: int = Query(..., description="月份"), db: AsyncSession = Depends(get_db), current_user: Annotated[User, Depends(get_current_manager_user)] = None ): """根据考核记录生成工资记录(需要管理员或经理权限)""" record = await SalaryService.generate_from_assessment( db, staff_id, period_year, period_month ) if not record: raise HTTPException(status_code=400, detail="无法生成,未找到已确认的考核记录或已存在工资记录") return {"code": 200, "message": "生成成功", "data": {"id": record.id}} @router.post("/batch-generate", summary="批量生成工资") async def batch_generate_salary( department_id: int = Query(..., description="科室ID"), period_year: int = Query(..., description="年度"), period_month: int = Query(..., description="月份"), db: AsyncSession = Depends(get_db), current_user: Annotated[User, Depends(get_current_manager_user)] = None ): """为科室批量生成工资记录(需要管理员或经理权限)""" records = await SalaryService.batch_generate_for_department( db, department_id, period_year, period_month ) return { "code": 200, "message": f"成功生成 {len(records)} 条工资记录", "data": {"count": len(records)} } @router.post("/{record_id}/confirm", summary="确认工资") async def confirm_salary( record_id: int, db: AsyncSession = Depends(get_db), current_user: Annotated[User, Depends(get_current_manager_user)] = None ): """确认工资(需要管理员或经理权限)""" record = await SalaryService.confirm(db, record_id) if not record: raise HTTPException(status_code=400, detail="无法确认,记录不存在或状态不允许") return {"code": 200, "message": "确认成功"} @router.post("/batch-confirm", summary="批量确认工资") async def batch_confirm_salary( period_year: int = Query(..., description="年度"), period_month: int = Query(..., description="月份"), department_id: Optional[int] = Query(None, description="科室ID"), db: AsyncSession = Depends(get_db), current_user: Annotated[User, Depends(get_current_manager_user)] = None ): """批量确认工资(需要管理员或经理权限)""" count = await SalaryService.batch_confirm(db, period_year, period_month, department_id) return {"code": 200, "message": f"成功确认 {count} 条工资记录", "data": {"count": count}}