feat: 状态渲染修复+中文姓名映射+SUPERVISOR/SUPER_ADMIN权限控制(前端+后端)

This commit is contained in:
2026-08-07 17:26:14 +08:00
parent 592bde7cab
commit 65ff05fb2f
4 changed files with 110 additions and 43 deletions

View File

@ -30,6 +30,20 @@ from app.schemas.task import (
# 特殊位置常量
VIRTUAL_WAREHOUSE = "virtual_warehouse"
# 管理员/主管角色白名单 — 拥有上帝视角操作权限
ADMIN_ROLES = {"SUPER_ADMIN", "SUPERVISOR"}
def _check_permission(task_assignee_id: str | None, operator_id: str | None, operator_role: str | None = None) -> None:
"""权限校验:本人 或 管理员/主管 可操作"""
if operator_role and operator_role in ADMIN_ROLES:
return # 上帝视角,直接放行
if operator_id and task_assignee_id and operator_id != task_assignee_id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"您无权操作此任务,当前任务负责人为 {task_assignee_id}",
)
# ============================================================
# 内部辅助函数
@ -433,6 +447,7 @@ ARCHIVED_STATUS = "ARCHIVED"
async def receive_task(
db: AsyncSession, task_id: uuid.UUID, operator_id: str | None = None,
remark: str | None = None, task_name: str | None = None,
operator_role: str | None = None,
) -> TaskResponse:
"""
操作员确认接收任务。工人选定工序名称后接收。
@ -442,12 +457,8 @@ async def receive_task(
"""
task = await _get_task_or_404(db, task_id)
# 权限校验:只有负责人本人可接收
if operator_id and task.assignee_id and operator_id != task.assignee_id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"您无权操作此任务,当前任务负责人为 {task.assignee_id}",
)
# 权限校验:本人 或 管理员/主管 可操作
_check_permission(task.assignee_id, operator_id, operator_role)
# 校验:只有 PENDING 状态可接收
if task.status != TASK_STATUS_PENDING:
@ -492,7 +503,8 @@ async def receive_task(
# ============================================================
async def reject_task(
db: AsyncSession, task_id: uuid.UUID, request: TaskRejectRequest, operator_id: str | None = None
db: AsyncSession, task_id: uuid.UUID, request: TaskRejectRequest, operator_id: str | None = None,
operator_role: str | None = None,
) -> TaskResponse:
"""
品质驳回:将当前任务标记为 REJECTED并自动创建返工任务给上一道工序负责人。
@ -507,12 +519,8 @@ async def reject_task(
"""
task = await _get_task_or_404(db, task_id)
# 权限校验:只有负责人本人可驳回
if operator_id and task.assignee_id and operator_id != task.assignee_id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"您无权操作此任务,当前任务负责人为 {task.assignee_id}",
)
# 权限校验:本人 或 管理员/主管 可驳回
_check_permission(task.assignee_id, operator_id, operator_role)
# 校验:不能重复驳回已完成/已驳回的任务
if task.status in (TASK_STATUS_COMPLETED, TASK_STATUS_REJECTED):
@ -612,7 +620,8 @@ async def reject_task(
# ============================================================
async def transfer_task(
db: AsyncSession, task_id: uuid.UUID, request: TaskTransferRequest, operator_id: str | None = None
db: AsyncSession, task_id: uuid.UUID, request: TaskTransferRequest, operator_id: str | None = None,
operator_role: str | None = None,
) -> TaskTransferResponse:
"""
完工并裂变转交:
@ -633,6 +642,9 @@ async def transfer_task(
"""
task = await _get_task_or_404(db, task_id)
# 权限校验:本人 或 管理员/主管 可转交
_check_permission(task.assignee_id, operator_id, operator_role)
# 校验:不能重复完成
if task.status == TASK_STATUS_COMPLETED:
raise HTTPException(