feat(linkage): 鞍座改为预备生产位 + 在线改人工触发 + 计划删除

- 上卷鞍座=预备生产位(不生产);投入生产后离开鞍座、进入生产中并转入物料跟踪,鞍座随即空出
- 在线状态改为人工触发:移动到入口端才变在线,引擎不再自动上线(ensure_online 置空)
- 单卷在产:投入生产时若已有在产卷则拒绝
- 物料跟踪显示在产卷实时进度(客户端外推带头长度/进度条)
- 入口跟踪鞍座卡片改为预备生产展示(去掉进度)
- 计划管理新增删除按钮 + DELETE /plan/{id}(生产中不可删)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-29 15:20:16 +08:00
parent 1a6deea4bb
commit 62c484411e
6 changed files with 103 additions and 94 deletions

View File

@@ -115,6 +115,18 @@ async def update_plan(
return Response.ok(PlanOut.model_validate(plan))
@router.delete("/{plan_id}", response_model=Response[dict])
async def delete_plan(plan_id: int, db: AsyncSession = Depends(get_db), _ = Depends(get_current_user)):
result = await db.execute(select(ProductionPlan).where(ProductionPlan.id == plan_id))
plan = result.scalar_one_or_none()
if not plan:
raise HTTPException(status_code=404, detail="计划不存在")
if plan.status == "producing":
raise HTTPException(status_code=400, detail="生产中的计划不可删除")
await db.delete(plan)
return Response.ok({"deleted": plan_id})
@router.patch("/{plan_id}/confirm", response_model=Response[PlanOut])
async def confirm_plan(plan_id: int, db: AsyncSession = Depends(get_db), _ = Depends(get_current_user)):
result = await db.execute(select(ProductionPlan).where(ProductionPlan.id == plan_id))
@@ -171,7 +183,10 @@ async def commit_producing(plan_id: int, db: AsyncSession = Depends(get_db), _ =
plan = result.scalar_one_or_none()
if not plan:
raise HTTPException(status_code=404, detail="计划不存在")
await line_service.commit_plan(db, plan)
try:
await line_service.commit_plan(db, plan)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
await db.flush()
await db.refresh(plan)
return Response.ok(PlanOut.model_validate(plan))