diff --git a/backend/app/api/v1/endpoints/webhooks.py b/backend/app/api/v1/endpoints/webhooks.py index 8437c3f..41d15ee 100644 --- a/backend/app/api/v1/endpoints/webhooks.py +++ b/backend/app/api/v1/endpoints/webhooks.py @@ -176,9 +176,10 @@ async def _append_warehouse_task( product_id=product.id, parent_task_id=last_main_task.id if last_main_task else None, task_name=task_name, - assignee_id="MOM 仓储系统", + # ★ assignee_id 显式置 None:不能填非 UUID 字符串,否则前端解析头像/用户信息报错导致节点跳过渲染 + assignee_id=None, status="COMPLETED", - task_type="TRANSFER", # 现有主线枚举 → is_main=True,画在中央主干道 + task_type="WAREHOUSE", # 仓储任务类型(is_main 判断已兼容 WAREHOUSE → 画在中央主干道) completed_at=_dt.now(), remark=record_remark, ) diff --git a/backend/app/services/product_service.py b/backend/app/services/product_service.py index 11a8e87..30186df 100644 --- a/backend/app/services/product_service.py +++ b/backend/app/services/product_service.py @@ -140,7 +140,7 @@ async def get_product_by_serial(db: AsyncSession, serial_number: str) -> Product all_mains: list = [] def _collect_main(tasks): for t in tasks: - if not t.parent_task_id or t.task_type in ("TRANSFER", "RECOVERY"): + if not t.parent_task_id or t.task_type in ("TRANSFER", "RECOVERY", "WAREHOUSE"): all_mains.append(t) if t.child_tasks: _collect_main(t.child_tasks) @@ -465,7 +465,7 @@ async def update_overall_status( Task.status.in_(["WIP", "PENDING"]), or_( Task.parent_task_id.is_(None), - Task.task_type.in_(["TRANSFER", "RECOVERY"]), + Task.task_type.in_(["TRANSFER", "RECOVERY", "WAREHOUSE"]), ), ).order_by(Task.created_at.desc()).limit(1) ) @@ -657,7 +657,7 @@ async def get_all_products( Task.product_id.in_(product_ids), or_( Task.parent_task_id.is_(None), - Task.task_type.in_(["TRANSFER", "RECOVERY"]), + Task.task_type.in_(["TRANSFER", "RECOVERY", "WAREHOUSE"]), ), ) prio_expr = sa_case( diff --git a/frontend/src/components/TaskTree/TaskFlowView.tsx b/frontend/src/components/TaskTree/TaskFlowView.tsx index 5bf5b89..2c69ad8 100644 --- a/frontend/src/components/TaskTree/TaskFlowView.tsx +++ b/frontend/src/components/TaskTree/TaskFlowView.tsx @@ -3,7 +3,7 @@ */ import { memo, useMemo, useState, useEffect } from "react"; import { Image } from "antd"; -import { FileText, User, X } from "lucide-react"; +import { FileText, Package, User, X } from "lucide-react"; import type { TaskResponse } from "../../types/api"; import { TASK_STATUS } from "../../types/api"; import { getStatusConfig } from "../../constants/task"; @@ -13,7 +13,7 @@ import type { ModalTarget } from "./TaskTreeViewer"; // 工具 // ============================================================ function fmtTime(d: string | null) { if (!d) return ""; const dt = new Date(d); const pad = (n: number) => String(n).padStart(2, "0"); return `${dt.getFullYear()}-${pad(dt.getMonth() + 1)}-${pad(dt.getDate())} ${pad(dt.getHours())}:${pad(dt.getMinutes())}`; } -function isMain(t: TaskResponse) { return !t.parent_task_id || t.task_type === "TRANSFER" || t.task_type === "RECOVERY"; } +function isMain(t: TaskResponse) { return !t.parent_task_id || t.task_type === "TRANSFER" || t.task_type === "RECOVERY" || t.task_type === "WAREHOUSE"; } function active(s: string) { return s === "WIP" || s === "PENDING"; } /** 微型右箭头 SVG */ function ArrowRight({ color = "#9ca3af", big }: { color?: string; big?: boolean }) { @@ -117,17 +117,29 @@ const SlimCard = memo(function SlimCard({ {cfg.label}
{task.task_name}
- {/* 操作人(带用户图标)+ 在库转入人 */} + {/* 操作人(带用户图标)+ 在库转入人;仓储任务防御性渲染为系统节点 */}
diff --git a/track-uniapp/src/pages/scan/components/FlowCard.vue b/track-uniapp/src/pages/scan/components/FlowCard.vue
index 2c02c89..96e6d6f 100644
--- a/track-uniapp/src/pages/scan/components/FlowCard.vue
+++ b/track-uniapp/src/pages/scan/components/FlowCard.vue
@@ -8,8 +8,10 @@