add backend source code

This commit is contained in:
2026-02-28 15:06:52 +08:00
parent 1bc330e20c
commit 2c37aa9064
67 changed files with 11654 additions and 0 deletions

View File

@@ -0,0 +1,165 @@
"""
API路由 - 绩效考核管理
"""
from typing import Annotated, Optional, List
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 (
AssessmentCreate, AssessmentUpdate, AssessmentResponse,
AssessmentListResponse, ResponseBase
)
from app.services.assessment_service import AssessmentService
from app.models.models import User
router = APIRouter(prefix="/assessments", tags=["绩效考核"])
@router.get("", summary="获取考核列表")
async def get_assessments(
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)
):
"""获取考核列表"""
assessments, total = await AssessmentService.get_list(
db, staff_id, department_id, period_year, period_month, status, page, page_size
)
# 转换响应
result = []
for assessment in assessments:
item = AssessmentListResponse.model_validate(assessment).model_dump()
item["staff_name"] = assessment.staff.name if assessment.staff else None
item["department_name"] = assessment.staff.department.name if assessment.staff and assessment.staff.department else None
result.append(item)
return {
"code": 200,
"message": "success",
"data": result,
"total": total,
"page": page,
"page_size": page_size
}
@router.get("/{assessment_id}", summary="获取考核详情")
async def get_assessment(
assessment_id: int,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
"""获取考核详情"""
assessment = await AssessmentService.get_by_id(db, assessment_id)
if not assessment:
raise HTTPException(status_code=404, detail="考核记录不存在")
result = AssessmentResponse.model_validate(assessment).model_dump()
result["staff_name"] = assessment.staff.name if assessment.staff else None
result["department_name"] = assessment.staff.department.name if assessment.staff and assessment.staff.department else None
# 添加明细指标名称
for detail in result.get("details", []):
for d in assessment.details:
if d.id == detail["id"] and d.indicator:
detail["indicator_name"] = d.indicator.name
break
return {"code": 200, "message": "success", "data": result}
@router.post("", summary="创建考核记录")
async def create_assessment(
assessment_data: AssessmentCreate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
"""创建考核记录"""
assessment = await AssessmentService.create(db, assessment_data)
return {"code": 200, "message": "创建成功", "data": {"id": assessment.id}}
@router.put("/{assessment_id}", summary="更新考核记录")
async def update_assessment(
assessment_id: int,
assessment_data: AssessmentUpdate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
"""更新考核记录"""
assessment = await AssessmentService.update(db, assessment_id, assessment_data)
if not assessment:
raise HTTPException(status_code=400, detail="无法更新,考核记录不存在或状态不允许")
return {"code": 200, "message": "更新成功", "data": {"id": assessment.id}}
@router.post("/{assessment_id}/submit", summary="提交考核")
async def submit_assessment(
assessment_id: int,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
"""提交考核"""
assessment = await AssessmentService.submit(db, assessment_id)
if not assessment:
raise HTTPException(status_code=400, detail="无法提交,考核记录不存在或状态不允许")
return {"code": 200, "message": "提交成功"}
@router.post("/{assessment_id}/review", summary="审核考核")
async def review_assessment(
assessment_id: int,
approved: bool = Query(..., description="是否通过"),
remark: Optional[str] = Query(None, description="审核意见"),
db: AsyncSession = Depends(get_db),
current_user: Annotated[User, Depends(get_current_manager_user)] = None
):
"""审核考核(需要管理员或经理权限)"""
# 从当前用户获取审核人ID
reviewer_id = current_user.id
assessment = await AssessmentService.review(db, assessment_id, reviewer_id, approved, remark)
if not assessment:
raise HTTPException(status_code=400, detail="无法审核,考核记录不存在或状态不允许")
return {"code": 200, "message": "审核通过" if approved else "已驳回"}
@router.post("/{assessment_id}/finalize", summary="确认考核")
async def finalize_assessment(
assessment_id: int,
db: AsyncSession = Depends(get_db),
current_user: Annotated[User, Depends(get_current_manager_user)] = None
):
"""确认考核(需要管理员或经理权限)"""
assessment = await AssessmentService.finalize(db, assessment_id)
if not assessment:
raise HTTPException(status_code=400, detail="无法确认,考核记录不存在或状态不允许")
return {"code": 200, "message": "确认成功"}
@router.post("/batch-create", summary="批量创建考核")
async def batch_create_assessments(
department_id: int = Query(..., description="科室ID"),
period_year: int = Query(..., description="年度"),
period_month: int = Query(..., description="月份"),
indicators: List[int] = Query(..., description="指标ID列表"),
db: AsyncSession = Depends(get_db),
current_user: Annotated[User, Depends(get_current_manager_user)] = None
):
"""为科室批量创建考核(需要管理员或经理权限)"""
assessments = await AssessmentService.batch_create_for_department(
db, department_id, period_year, period_month, indicators
)
return {
"code": 200,
"message": f"成功创建 {len(assessments)} 条考核记录",
"data": {"count": len(assessments)}
}