diff --git a/frontend/src/pages/admin/AdminDashboard.tsx b/frontend/src/pages/admin/AdminDashboard.tsx index 160f1ae..baf3986 100644 --- a/frontend/src/pages/admin/AdminDashboard.tsx +++ b/frontend/src/pages/admin/AdminDashboard.tsx @@ -81,7 +81,7 @@ function WipRow({ t }: { t: WipTask }) { const nav = useNavigate(); const handleClick = () => { if (t.product_sn) { - nav(`/scan?sn=${t.product_sn}`); + nav(`/admin/tasks?sn=${t.product_sn}`); } }; return ( diff --git a/frontend/src/pages/admin/AdminTasksPage.tsx b/frontend/src/pages/admin/AdminTasksPage.tsx index aa58b27..f54ea75 100644 --- a/frontend/src/pages/admin/AdminTasksPage.tsx +++ b/frontend/src/pages/admin/AdminTasksPage.tsx @@ -1,5 +1,6 @@ /** 任务全景 Dashboard — 按订单聚合 + 关键词搜索 + 状态筛选 */ import { useState, useEffect, useMemo, useCallback } from "react"; +import { useSearchParams } from "react-router-dom"; import { Search, Loader2, Package, ChevronDown, ChevronRight, Warehouse, GitBranch, X, @@ -35,6 +36,7 @@ interface OrderGroup { export default function AdminTasksPage() { const { toast } = useToast(); const { user: currentUser } = useAuth(); + const [searchParams] = useSearchParams(); // 搜索 & 筛选 const [keyword, setKeyword] = useState(""); @@ -57,6 +59,9 @@ export default function AdminTasksPage() { const [submitting, setSubmitting] = useState(false); const [qrSerial, setQrSerial] = useState(null); // 🔧 QR弹窗 + // 从看板跳转: ?sn=xxx → 自动搜索 + 自动展开流转树 + const autoSn = searchParams.get("sn") || ""; + // ---- 加载产品列表(始终拉全量,不做服务端状态过滤) ---- async function loadProducts(kw: string) { setLoading(true); @@ -66,14 +71,27 @@ export default function AdminTasksPage() { if (kw.trim()) params.keyword = kw.trim(); const { data } = await api.get("/products/", { params }); setProducts(data); + return data; } catch { setError("加载产品列表失败,请检查后端服务"); + return []; } finally { setLoading(false); } } - useEffect(() => { loadProducts(keyword); }, []); // eslint-disable-line react-hooks/exhaustive-deps + useEffect(() => { + if (autoSn) { + setKeyword(autoSn); + loadProducts(autoSn).then((data) => { + // 产品加载完成后自动展开流转树 + const found = data.find((p: ProductResponse) => p.serial_number === autoSn); + if (found) toggleProductTree(found.serial_number); + }); + } else { + loadProducts(keyword); + } + }, []); // eslint-disable-line react-hooks/exhaustive-deps function handleSearch(e?: React.FormEvent) { e?.preventDefault();