并发模型: spawn派发协助分支 + 转交简化为单线 + 子分支未完成拦截(409)
This commit is contained in:
@ -236,6 +236,9 @@ async def end_task(
|
||||
"""
|
||||
task = await _get_task_or_404(db, task_id)
|
||||
|
||||
# 校验:必须等待所有协助分支完成
|
||||
await _check_children_done(db, task_id)
|
||||
|
||||
if task.status == TASK_STATUS_COMPLETED:
|
||||
raise HTTPException(status_code=409, detail="此分支已经结束")
|
||||
if task.status == TASK_STATUS_PENDING:
|
||||
@ -253,6 +256,62 @@ async def end_task(
|
||||
return _to_response(task)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 核心业务 0.5:派发协助分支(不改变父任务状态)
|
||||
# ============================================================
|
||||
|
||||
async def spawn_subtask(
|
||||
db: AsyncSession, task_id: uuid.UUID, data, operator_id: str | None = None
|
||||
) -> TaskResponse:
|
||||
"""在当前任务下创建并行子任务,父任务状态保持不变。"""
|
||||
task = await _get_task_or_404(db, task_id)
|
||||
|
||||
if task.status == TASK_STATUS_COMPLETED:
|
||||
raise HTTPException(status_code=409, detail="任务已完成,无法派发协助分支")
|
||||
if task.status == TASK_STATUS_REJECTED:
|
||||
raise HTTPException(status_code=409, detail="任务已驳回,无法派发协助分支")
|
||||
|
||||
child = Task(
|
||||
product_id=task.product_id,
|
||||
parent_task_id=task.id,
|
||||
task_name=data.task_name,
|
||||
assignee_id=data.assignee_id,
|
||||
status=TASK_STATUS_PENDING,
|
||||
notify_parent_on_complete=False,
|
||||
is_rework=False,
|
||||
remark=data.remark or None,
|
||||
)
|
||||
db.add(child)
|
||||
await db.flush()
|
||||
|
||||
await _create_task_log(db, child.id, action_type="create", operator_id=operator_id,
|
||||
remark=f"协助分支(由「{task.task_name}」派发,分配给 {data.assignee_id})")
|
||||
await db.commit()
|
||||
await db.refresh(child)
|
||||
return _to_response(child)
|
||||
|
||||
|
||||
async def _check_children_done(db: AsyncSession, task_id: uuid.UUID):
|
||||
"""检查当前任务的所有子任务是否都已完结。未完结则抛出 409。"""
|
||||
result = await db.execute(
|
||||
select(Task).where(Task.parent_task_id == task_id)
|
||||
)
|
||||
children = result.scalars().all()
|
||||
incomplete = [c for c in children if c.status not in (
|
||||
TASK_STATUS_COMPLETED, TASK_STATUS_REJECTED, ARCHIVED_STATUS
|
||||
)]
|
||||
if incomplete:
|
||||
names = "、".join(c.task_name for c in incomplete)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail=f"当前工序还有未完成的协助分支({names}),必须等待分支结束才能转交或完工!",
|
||||
)
|
||||
return True
|
||||
|
||||
|
||||
ARCHIVED_STATUS = "ARCHIVED"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 核心业务 1:确认接收 (PENDING → WIP)
|
||||
# ============================================================
|
||||
@ -429,6 +488,9 @@ async def transfer_task(
|
||||
"""
|
||||
task = await _get_task_or_404(db, task_id)
|
||||
|
||||
# 校验:必须等待所有协助分支完成
|
||||
await _check_children_done(db, task_id)
|
||||
|
||||
# 校验:不能重复完成
|
||||
if task.status == TASK_STATUS_COMPLETED:
|
||||
raise HTTPException(
|
||||
|
||||
Reference in New Issue
Block a user