PayrollManagementSystem/backend/app/api/v1/business/ratings.py
liuwenxin 1625907380 feat(business): 客户评级等级映射配置接口(区间重叠判定/名称唯一)
- 判定=按 sort_order 升序首个 min_score≤总分,边界相邻不算重叠
- 新增同样执行重叠判定(判定表语义下插出重叠即脏配置)
- 等级配置无下游引用(评级为纯计算器,对照表 #25),允许清空

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 12:01:47 +08:00

75 lines
2.9 KiB
Python
Raw Permalink 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.

"""客户评级等级配置接口(需求 2.2.5)。
评级计算器的等级映射判定表:判定按 sort_order 升序取首个 min_score ≤ 总分
的等级,max_score 仅展示。区间合法(0≤min≤max≤100)与互不重叠由后端校验
—— 前端表单只是展示约束,后端校验是唯一防线。
列表不分页全量返回:等级映射是判定表,数量个位数,分页无意义。
业务数据属业务操作,登录用户即可访问(区别于系统管理模块的 AdminUser);
写操作经 RequestMetaDep 带入请求元信息,由 service 层写入操作日志。
"""
from typing import Annotated
from fastapi import APIRouter, Depends, Path
from app.api.deps import DbSession, RequestMetaDep, get_current_user
from app.core.response import ApiResponse, ok
from app.models import User
from app.schemas.rating import RatingGradeCreateIn, RatingGradeOut, RatingGradeUpdateIn
from app.services import rating_service
CurrentUser = Annotated[User, Depends(get_current_user)]
router = APIRouter(prefix="/rating-grades", tags=["客户评级"])
@router.get("", response_model=ApiResponse[list[RatingGradeOut]], summary="评级等级列表")
def list_grades(
session: DbSession,
_: CurrentUser,
) -> ApiResponse[list[RatingGradeOut]]:
"""全量等级列表,按判定顺序(sort_order 升序)返回,不分页。"""
return ok(rating_service.list_grades(session))
@router.post("", response_model=ApiResponse[RatingGradeOut], summary="新增评级等级")
def create_grade(
session: DbSession,
current_user: CurrentUser,
payload: RatingGradeCreateIn,
meta: RequestMetaDep,
) -> ApiResponse[RatingGradeOut]:
"""新增评级等级。区间须 0≤min≤max≤100 且与既有等级不重叠。"""
return ok(
rating_service.create_grade(session, payload, operator=current_user, meta=meta),
message="评级等级已创建",
)
@router.put("/{grade_id}", response_model=ApiResponse[RatingGradeOut], summary="编辑评级等级")
def update_grade(
session: DbSession,
current_user: CurrentUser,
grade_id: Annotated[int, Path(ge=1)],
payload: RatingGradeUpdateIn,
meta: RequestMetaDep,
) -> ApiResponse[RatingGradeOut]:
"""编辑评级等级(全量替换)。区间须合法且与其他等级不重叠。"""
return ok(
rating_service.update_grade(session, grade_id, payload, operator=current_user, meta=meta),
message="已保存",
)
@router.delete("/{grade_id}", response_model=ApiResponse[None], summary="删除评级等级")
def delete_grade(
session: DbSession,
current_user: CurrentUser,
grade_id: Annotated[int, Path(ge=1)],
meta: RequestMetaDep,
) -> ApiResponse[None]:
"""物理删除评级等级(等级表无下游引用,允许清空,理由见 service 说明)。"""
rating_service.delete_grade(session, grade_id, operator=current_user, meta=meta)
return ok(message="评级等级已删除")