fix: 四Bug—权限互斥+中文姓名+记录弹窗+后端位置回溯(含RecordsModal)

This commit is contained in:
2026-08-09 17:55:40 +08:00
parent ab935a8c95
commit 3c4c16a1cc
2 changed files with 223 additions and 163 deletions

View File

@ -34,6 +34,46 @@ VIRTUAL_WAREHOUSE = "virtual_warehouse"
ADMIN_ROLES = {"SUPER_ADMIN", "SUPERVISOR"}
async def _recalc_product_location(db: AsyncSession, product_id: uuid.UUID) -> None:
"""
任务完工/结束时触发:沿任务树向上回溯,
将产品 current_location 更新为最近一个 WIP 任务的负责人。
若无进行中任务,位置置空。
"""
from sqlalchemy import select as sa_select
product_result = await db.execute(sa_select(Product).where(Product.id == product_id))
product = product_result.scalar_one_or_none()
if not product:
return
# 查找所有 WIP 状态的任务
task_result = await db.execute(
sa_select(Task).where(
Task.product_id == product_id,
Task.status == TASK_STATUS_WIP,
).order_by(Task.created_at.desc())
)
wip_tasks = task_result.scalars().all()
if wip_tasks:
# 有进行中的任务 → 位置更新为最新WIP任务的负责人
latest_wip = wip_tasks[0]
new_location = latest_wip.assignee_id or product.current_location_id
else:
# 无进行中任务 → 查找最新的COMPLETED任务负责人保留最后完工者
done_result = await db.execute(
sa_select(Task).where(
Task.product_id == product_id,
Task.status == TASK_STATUS_COMPLETED,
).order_by(Task.completed_at.desc()).limit(1)
)
last_done = done_result.scalar_one_or_none()
new_location = last_done.assignee_id if last_done else None
if product.current_location_id != new_location:
product.current_location_id = new_location
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:
@ -324,6 +364,9 @@ async def end_task(
await _create_task_log(db, task_id, action_type="end",
operator_id=operator_id, remark=f"分支「{task.task_name}」已终止(无下游)")
# 🔧 位置回溯:分支结束后重新计算产品当前位置
await _recalc_product_location(db, task.product_id)
await db.commit()
await db.refresh(task)
return _to_response(task)
@ -763,6 +806,10 @@ async def transfer_task(
product.current_location_id = real_branches[0][1]
product.overall_status = real_branches[0][0]
# 🔧 位置回溯如果有新任务创建优先新任务负责人否则回溯到上级WIP任务
if not real_branches and not has_warehouse:
await _recalc_product_location(db, task.product_id)
await db.commit()
# --- 构建响应 ---
@ -861,6 +908,9 @@ async def complete_task(
remark=f"由任务「{task.task_name}」完成后转交创建",
)
# 🔧 位置回溯:老接口也触发
await _recalc_product_location(db, task.product_id)
await db.commit()
# --- 5. 构建响应 ---