feat: 状态渲染修复+中文姓名映射+SUPERVISOR/SUPER_ADMIN权限控制(前端+后端)
This commit is contained in:
@ -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(
|
||||
|
||||
Reference in New Issue
Block a user